#pragma once #include "globalincs/vmallocator.h" #include "model/model.h" #include #include #include bool model_exists(const SCP_string& filename); bool read_virtual_model_file(polymodel* pm, const SCP_string& filename, model_parse_depth depth, int ferror, model_read_deferred_tasks& deferredTasks); void virtual_pof_purge_cache(); void virtual_pof_init(); struct VirtualPOFDefinition; class VirtualPOFOperation { public: virtual ~VirtualPOFOperation() = default; virtual void process(polymodel* pm, model_read_deferred_tasks& subsysList, model_parse_depth depth, const VirtualPOFDefinition& virtualPof) const = 0; }; struct VirtualPOFDefinition { SCP_string name, basePOF; SCP_vector> operationList; }; using VirtualPOFNameReplacementMap = SCP_unordered_map; class VirtualPOFOperationRenameSubobjects : public VirtualPOFOperation { VirtualPOFNameReplacementMap replacements; friend class VirtualPOFOperationAddSubmodel; friend class VirtualPOFOperationAddTurret; public: VirtualPOFOperationRenameSubobjects(); void process(polymodel* pm, model_read_deferred_tasks& deferredTasks, model_parse_depth depth, const VirtualPOFDefinition& virtualPof) const override; }; class VirtualPOFOperationAddSubmodel : public VirtualPOFOperation { SCP_string subobjNameSrc, subobjNameDest; SCP_string appendingPOF; std::unique_ptr rename = nullptr; bool copyChildren = true; bool copyTurrets = false; bool copyGlowpoints = false; public: VirtualPOFOperationAddSubmodel(); void process(polymodel* pm, model_read_deferred_tasks& deferredTasks, model_parse_depth depth, const VirtualPOFDefinition& virtualPof) const override; }; class VirtualPOFOperationAddTurret : public VirtualPOFOperation { SCP_string baseNameSrc, baseNameDest; tl::optional barrelNameDest; SCP_string appendingPOF; std::unique_ptr rename = nullptr; public: VirtualPOFOperationAddTurret(); void process(polymodel* pm, model_read_deferred_tasks& deferredTasks, model_parse_depth depth, const VirtualPOFDefinition& virtualPof) const override; }; class VirtualPOFOperationAddEngine : public VirtualPOFOperation { mpark::variant sourceId; tl::optional renameSubsystem; tl::optional moveEngine; SCP_string appendingPOF; public: VirtualPOFOperationAddEngine(); void process(polymodel* pm, model_read_deferred_tasks& deferredTasks, model_parse_depth depth, const VirtualPOFDefinition& virtualPof) const override; }; class VirtualPOFOperationAddGlowpoint : public VirtualPOFOperation { int sourceId; SCP_string renameSubmodel; tl::optional moveGlowpoint; SCP_string appendingPOF; public: VirtualPOFOperationAddGlowpoint(); void process(polymodel* pm, model_read_deferred_tasks& deferredTasks, model_parse_depth depth, const VirtualPOFDefinition& virtualPof) const override; }; class VirtualPOFOperationAddSpecialSubsystem : public VirtualPOFOperation { SCP_string sourceSubsystem; tl::optional renameSubsystem; SCP_string appendingPOF; public: VirtualPOFOperationAddSpecialSubsystem(); void process(polymodel* pm, model_read_deferred_tasks& deferredTasks, model_parse_depth depth, const VirtualPOFDefinition& virtualPof) const override; }; class VirtualPOFOperationChangeData : public VirtualPOFOperation { SCP_string submodel; tl::optional setOffset = tl::nullopt; public: VirtualPOFOperationChangeData(); void process(polymodel* pm, model_read_deferred_tasks& deferredTasks, model_parse_depth depth, const VirtualPOFDefinition& virtualPof) const override; }; class VirtualPOFOperationHeaderData : public VirtualPOFOperation { tl::optional radius = tl::nullopt; tl::optional> boundingbox = tl::nullopt; public: VirtualPOFOperationHeaderData(); void process(polymodel* pm, model_read_deferred_tasks& deferredTasks, model_parse_depth depth, const VirtualPOFDefinition& virtualPof) const override; };