#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 VirtualPOFOperationAddWeapons : public VirtualPOFOperation { int sourcebank, destbank = -1; bool primary; SCP_string appendingPOF; public: VirtualPOFOperationAddWeapons(); void process(polymodel* pm, model_read_deferred_tasks& deferredTasks, model_parse_depth depth, const VirtualPOFDefinition& virtualPof) const override; }; class VirtualPOFOperationAddDockPoint : public VirtualPOFOperation { SCP_string sourcedock; tl::optional renameDock; SCP_unordered_map renamePaths; tl::optional targetParentSubsystem; SCP_string appendingPOF; public: VirtualPOFOperationAddDockPoint(); void process(polymodel* pm, model_read_deferred_tasks& deferredTasks, model_parse_depth depth, const VirtualPOFDefinition& virtualPof) const override; }; class VirtualPOFOperationAddPath : public VirtualPOFOperation { SCP_string sourcepath; tl::optional renamePath; tl::optional targetParentSubsystem; SCP_string appendingPOF; public: VirtualPOFOperationAddPath(); 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 VirtualPOFOperationChangeSubsystemData : public VirtualPOFOperation { SCP_string subsystem; tl::optional setPosition = tl::nullopt; tl::optional setRadius = tl::nullopt; tl::optional setProperties = tl::nullopt; bool propertyReplace = true; public: VirtualPOFOperationChangeSubsystemData(); 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; };