diff --git a/Source/Engine/Graphics/Models/ModelData.h b/Source/Engine/Graphics/Models/ModelData.h index 8874fecb3..1516554fe 100644 --- a/Source/Engine/Graphics/Models/ModelData.h +++ b/Source/Engine/Graphics/Models/ModelData.h @@ -366,12 +366,32 @@ struct FLAXENGINE_API MaterialSlotEntry bool UsesProperties() const; }; +/// +/// Data container for model hierarchy node. +/// +struct FLAXENGINE_API ModelDataNode +{ + /// + /// The parent node index. The root node uses value -1. + /// + int32 ParentIndex; + + /// + /// The local transformation of the node, relative to the parent node. + /// + Transform LocalTransform; + + /// + /// The name of this node. + /// + String Name; +}; + /// /// Data container for LOD metadata and sub meshes. /// -class FLAXENGINE_API ModelLodData +struct FLAXENGINE_API ModelLodData { -public: /// /// The screen size to switch LODs. Bottom limit of the model screen size to render this LOD. /// @@ -382,14 +402,6 @@ public: /// Array Meshes; -public: - /// - /// Initializes a new instance of the class. - /// - ModelLodData() - { - } - /// /// Finalizes an instance of the class. /// @@ -426,7 +438,7 @@ public: Array Materials; /// - /// Array with all LODs. The first element is the top most LOD0 followed by the LOD1, LOD2, etc. + /// Array with all Level Of Details that contain meshes. The first element is the top most LOD0 followed by the LOD1, LOD2, etc. /// Array LODs; @@ -435,6 +447,11 @@ public: /// SkeletonData Skeleton; + /// + /// The scene nodes (in hierarchy). + /// + Array Nodes; + /// /// The node animations. /// diff --git a/Source/Engine/Tools/ModelTool/ModelTool.Assimp.cpp b/Source/Engine/Tools/ModelTool/ModelTool.Assimp.cpp index 3d9be61d2..ffcce99fc 100644 --- a/Source/Engine/Tools/ModelTool/ModelTool.Assimp.cpp +++ b/Source/Engine/Tools/ModelTool/ModelTool.Assimp.cpp @@ -238,7 +238,7 @@ void ProcessNodes(AssimpImporterData& data, aiNode* aNode, int32 parentIndex) } } -bool ProcessMesh(ImportedModelData& result, AssimpImporterData& data, const aiMesh* aMesh, MeshData& mesh, String& errorMsg) +bool ProcessMesh(ModelData& result, AssimpImporterData& data, const aiMesh* aMesh, MeshData& mesh, String& errorMsg) { // Properties mesh.Name = aMesh->mName.C_Str(); @@ -363,7 +363,7 @@ bool ProcessMesh(ImportedModelData& result, AssimpImporterData& data, const aiMe } // Blend Indices and Blend Weights - if (aMesh->mNumBones > 0 && aMesh->mBones && EnumHasAnyFlags(result.Types, ImportDataTypes::Skeleton)) + if (aMesh->mNumBones > 0 && aMesh->mBones && EnumHasAnyFlags(data.Options.ImportTypes, ImportDataTypes::Skeleton)) { const int32 vertexCount = mesh.Positions.Count(); mesh.BlendIndices.Resize(vertexCount); @@ -444,7 +444,7 @@ bool ProcessMesh(ImportedModelData& result, AssimpImporterData& data, const aiMe } // Blend Shapes - if (aMesh->mNumAnimMeshes > 0 && EnumHasAnyFlags(result.Types, ImportDataTypes::Skeleton) && data.Options.ImportBlendShapes) + if (aMesh->mNumAnimMeshes > 0 && EnumHasAnyFlags(data.Options.ImportTypes, ImportDataTypes::Skeleton) && data.Options.ImportBlendShapes) { mesh.BlendShapes.EnsureCapacity(aMesh->mNumAnimMeshes); for (unsigned int animMeshIndex = 0; animMeshIndex < aMesh->mNumAnimMeshes; animMeshIndex++) @@ -489,7 +489,7 @@ bool ProcessMesh(ImportedModelData& result, AssimpImporterData& data, const aiMe return false; } -bool ImportTexture(ImportedModelData& result, AssimpImporterData& data, aiString& aFilename, int32& textureIndex, TextureEntry::TypeHint type) +bool ImportTexture(ModelData& result, AssimpImporterData& data, aiString& aFilename, int32& textureIndex, TextureEntry::TypeHint type) { // Find texture file path const String filename = String(aFilename.C_Str()).TrimTrailing(); @@ -514,7 +514,7 @@ bool ImportTexture(ImportedModelData& result, AssimpImporterData& data, aiString return true; } -bool ImportMaterialTexture(ImportedModelData& result, AssimpImporterData& data, const aiMaterial* aMaterial, aiTextureType aTextureType, int32& textureIndex, TextureEntry::TypeHint type) +bool ImportMaterialTexture(ModelData& result, AssimpImporterData& data, const aiMaterial* aMaterial, aiTextureType aTextureType, int32& textureIndex, TextureEntry::TypeHint type) { aiString aFilename; if (aMaterial->GetTexture(aTextureType, 0, &aFilename, nullptr, nullptr, nullptr, nullptr) == AI_SUCCESS) @@ -560,7 +560,7 @@ bool ImportMaterialTexture(ImportedModelData& result, AssimpImporterData& data, return false; } -bool ImportMaterials(ImportedModelData& result, AssimpImporterData& data, String& errorMsg) +bool ImportMaterials(ModelData& result, AssimpImporterData& data, String& errorMsg) { const uint32 materialsCount = data.Scene->mNumMaterials; result.Materials.Resize(materialsCount, false); @@ -574,7 +574,7 @@ bool ImportMaterials(ImportedModelData& result, AssimpImporterData& data, String materialSlot.Name = String(aName.C_Str()).TrimTrailing(); materialSlot.AssetID = Guid::Empty; - if (EnumHasAnyFlags(result.Types, ImportDataTypes::Materials)) + if (EnumHasAnyFlags(data.Options.ImportTypes, ImportDataTypes::Materials)) { aiColor3D aColor; if (aMaterial->Get(AI_MATKEY_COLOR_DIFFUSE, aColor) == AI_SUCCESS) @@ -586,7 +586,7 @@ bool ImportMaterials(ImportedModelData& result, AssimpImporterData& data, String if (aMaterial->Get(AI_MATKEY_OPACITY, aFloat) == AI_SUCCESS) materialSlot.Opacity.Value = aFloat; - if (EnumHasAnyFlags(result.Types, ImportDataTypes::Textures)) + if (EnumHasAnyFlags(data.Options.ImportTypes, ImportDataTypes::Textures)) { ImportMaterialTexture(result, data, aMaterial, aiTextureType_DIFFUSE, materialSlot.Diffuse.TextureIndex, TextureEntry::TypeHint::ColorRGB); ImportMaterialTexture(result, data, aMaterial, aiTextureType_EMISSIVE, materialSlot.Emissive.TextureIndex, TextureEntry::TypeHint::ColorRGB); @@ -612,7 +612,7 @@ bool IsMeshInvalid(const aiMesh* aMesh) return aMesh->mPrimitiveTypes != aiPrimitiveType_TRIANGLE || aMesh->mNumVertices == 0 || aMesh->mNumFaces == 0 || aMesh->mFaces[0].mNumIndices != 3; } -bool ImportMesh(int32 i, ImportedModelData& result, AssimpImporterData& data, String& errorMsg) +bool ImportMesh(int32 i, ModelData& result, AssimpImporterData& data, String& errorMsg) { const auto aMesh = data.Scene->mMeshes[i]; @@ -739,7 +739,7 @@ void ImportCurve(aiQuatKey* keys, uint32 keysCount, LinearCurve& cur } } -bool ModelTool::ImportDataAssimp(const char* path, ImportedModelData& data, Options& options, String& errorMsg) +bool ModelTool::ImportDataAssimp(const char* path, ModelData& data, Options& options, String& errorMsg) { auto context = (AssimpImporterData*)options.SplitContext; if (!context) @@ -750,8 +750,8 @@ bool ModelTool::ImportDataAssimp(const char* path, ImportedModelData& data, Opti AssimpInited = true; LOG(Info, "Assimp {0}.{1}.{2}", aiGetVersionMajor(), aiGetVersionMinor(), aiGetVersionRevision()); } - bool importMeshes = EnumHasAnyFlags(data.Types, ImportDataTypes::Geometry); - bool importAnimations = EnumHasAnyFlags(data.Types, ImportDataTypes::Animations); + bool importMeshes = EnumHasAnyFlags(options.ImportTypes, ImportDataTypes::Geometry); + bool importAnimations = EnumHasAnyFlags(options.ImportTypes, ImportDataTypes::Animations); context = New(path, options); // Setup import flags @@ -820,7 +820,7 @@ bool ModelTool::ImportDataAssimp(const char* path, ImportedModelData& data, Opti } // Import geometry - if (EnumHasAnyFlags(data.Types, ImportDataTypes::Geometry) && context->Scene->HasMeshes()) + if (EnumHasAnyFlags(options.ImportTypes, ImportDataTypes::Geometry) && context->Scene->HasMeshes()) { const int meshCount = context->Scene->mNumMeshes; if (options.SplitObjects && options.ObjectIndex == -1 && meshCount > 1) @@ -863,7 +863,7 @@ bool ModelTool::ImportDataAssimp(const char* path, ImportedModelData& data, Opti } // Import skeleton - if (EnumHasAnyFlags(data.Types, ImportDataTypes::Skeleton)) + if (EnumHasAnyFlags(options.ImportTypes, ImportDataTypes::Skeleton)) { data.Skeleton.Nodes.Resize(context->Nodes.Count(), false); for (int32 i = 0; i < context->Nodes.Count(); i++) @@ -893,7 +893,7 @@ bool ModelTool::ImportDataAssimp(const char* path, ImportedModelData& data, Opti } // Import animations - if (EnumHasAnyFlags(data.Types, ImportDataTypes::Animations) && context->Scene->HasAnimations()) + if (EnumHasAnyFlags(options.ImportTypes, ImportDataTypes::Animations) && context->Scene->HasAnimations()) { const int32 animCount = (int32)context->Scene->mNumAnimations; if (options.SplitObjects && options.ObjectIndex == -1 && animCount > 1) @@ -948,7 +948,7 @@ bool ModelTool::ImportDataAssimp(const char* path, ImportedModelData& data, Opti } // Import nodes - if (EnumHasAnyFlags(data.Types, ImportDataTypes::Nodes)) + if (EnumHasAnyFlags(options.ImportTypes, ImportDataTypes::Nodes)) { data.Nodes.Resize(context->Nodes.Count()); for (int32 i = 0; i < context->Nodes.Count(); i++) diff --git a/Source/Engine/Tools/ModelTool/ModelTool.OpenFBX.cpp b/Source/Engine/Tools/ModelTool/ModelTool.OpenFBX.cpp index 490318ba7..b3e5ecdc8 100644 --- a/Source/Engine/Tools/ModelTool/ModelTool.OpenFBX.cpp +++ b/Source/Engine/Tools/ModelTool/ModelTool.OpenFBX.cpp @@ -182,7 +182,7 @@ struct OpenFbxImporterData #endif } - bool ImportMaterialTexture(ImportedModelData& result, const ofbx::Material* mat, ofbx::Texture::TextureType textureType, int32& textureIndex, TextureEntry::TypeHint type) const + bool ImportMaterialTexture(ModelData& result, const ofbx::Material* mat, ofbx::Texture::TextureType textureType, int32& textureIndex, TextureEntry::TypeHint type) const { const ofbx::Texture* tex = mat->getTexture(textureType); if (tex) @@ -217,7 +217,7 @@ struct OpenFbxImporterData return false; } - int32 AddMaterial(ImportedModelData& result, const ofbx::Material* mat) + int32 AddMaterial(ModelData& result, const ofbx::Material* mat) { int32 index = Materials.Find(mat); if (index == -1) @@ -229,11 +229,11 @@ struct OpenFbxImporterData if (mat) material.Name = String(mat->name).TrimTrailing(); - if (mat && EnumHasAnyFlags(result.Types, ImportDataTypes::Materials)) + if (mat && EnumHasAnyFlags(Options.ImportTypes, ImportDataTypes::Materials)) { material.Diffuse.Color = ToColor(mat->getDiffuseColor()); - if (EnumHasAnyFlags(result.Types, ImportDataTypes::Textures)) + if (EnumHasAnyFlags(Options.ImportTypes, ImportDataTypes::Textures)) { ImportMaterialTexture(result, mat, ofbx::Texture::DIFFUSE, material.Diffuse.TextureIndex, TextureEntry::TypeHint::ColorRGB); ImportMaterialTexture(result, mat, ofbx::Texture::EMISSIVE, material.Emissive.TextureIndex, TextureEntry::TypeHint::ColorRGB); @@ -522,7 +522,7 @@ bool ImportBones(OpenFbxImporterData& data, String& errorMsg) return false; } -bool ProcessMesh(ImportedModelData& result, OpenFbxImporterData& data, const ofbx::Mesh* aMesh, MeshData& mesh, String& errorMsg, int32 triangleStart, int32 triangleEnd) +bool ProcessMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh* aMesh, MeshData& mesh, String& errorMsg, int32 triangleStart, int32 triangleEnd) { // Prepare const int32 firstVertexOffset = triangleStart * 3; @@ -682,7 +682,7 @@ bool ProcessMesh(ImportedModelData& result, OpenFbxImporterData& data, const ofb } // Blend Indices and Blend Weights - if (skin && skin->getClusterCount() > 0 && EnumHasAnyFlags(result.Types, ImportDataTypes::Skeleton)) + if (skin && skin->getClusterCount() > 0 && EnumHasAnyFlags(data.Options.ImportTypes, ImportDataTypes::Skeleton)) { mesh.BlendIndices.Resize(vertexCount); mesh.BlendWeights.Resize(vertexCount); @@ -746,7 +746,7 @@ bool ProcessMesh(ImportedModelData& result, OpenFbxImporterData& data, const ofb } // Blend Shapes - if (blendShape && blendShape->getBlendShapeChannelCount() > 0 && EnumHasAnyFlags(result.Types, ImportDataTypes::Skeleton) && data.Options.ImportBlendShapes) + if (blendShape && blendShape->getBlendShapeChannelCount() > 0 && EnumHasAnyFlags(data.Options.ImportTypes, ImportDataTypes::Skeleton) && data.Options.ImportBlendShapes) { mesh.BlendShapes.EnsureCapacity(blendShape->getBlendShapeChannelCount()); for (int32 channelIndex = 0; channelIndex < blendShape->getBlendShapeChannelCount(); channelIndex++) @@ -853,7 +853,7 @@ bool ProcessMesh(ImportedModelData& result, OpenFbxImporterData& data, const ofb return false; } -bool ImportMesh(ImportedModelData& result, OpenFbxImporterData& data, const ofbx::Mesh* aMesh, String& errorMsg, int32 triangleStart, int32 triangleEnd) +bool ImportMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh* aMesh, String& errorMsg, int32 triangleStart, int32 triangleEnd) { // Find the parent node int32 nodeIndex = data.FindNode(aMesh); @@ -906,7 +906,7 @@ bool ImportMesh(ImportedModelData& result, OpenFbxImporterData& data, const ofbx return false; } -bool ImportMesh(int32 index, ImportedModelData& result, OpenFbxImporterData& data, String& errorMsg) +bool ImportMesh(int32 index, ModelData& result, OpenFbxImporterData& data, String& errorMsg) { const auto aMesh = data.Scene->getMesh(index); const auto aGeometry = aMesh->getGeometry(); @@ -1006,7 +1006,7 @@ void ImportCurve(const ofbx::AnimationCurveNode* curveNode, LinearCurve& curv } } -bool ImportAnimation(int32 index, ImportedModelData& data, OpenFbxImporterData& importerData) +bool ImportAnimation(int32 index, ModelData& data, OpenFbxImporterData& importerData) { const ofbx::AnimationStack* stack = importerData.Scene->getAnimationStack(index); const ofbx::AnimationLayer* layer = stack->getLayer(0); @@ -1103,7 +1103,7 @@ static Float3 FbxVectorFromAxisAndSign(int axis, int sign) return { 0.f, 0.f, 0.f }; } -bool ModelTool::ImportDataOpenFBX(const char* path, ImportedModelData& data, Options& options, String& errorMsg) +bool ModelTool::ImportDataOpenFBX(const char* path, ModelData& data, Options& options, String& errorMsg) { auto context = (OpenFbxImporterData*)options.SplitContext; if (!context) @@ -1116,7 +1116,7 @@ bool ModelTool::ImportDataOpenFBX(const char* path, ImportedModelData& data, Opt return true; } ofbx::u64 loadFlags = 0; - if (EnumHasAnyFlags(data.Types, ImportDataTypes::Geometry)) + if (EnumHasAnyFlags(options.ImportTypes, ImportDataTypes::Geometry)) { loadFlags |= (ofbx::u64)ofbx::LoadFlags::TRIANGULATE; if (!options.ImportBlendShapes) @@ -1161,7 +1161,7 @@ bool ModelTool::ImportDataOpenFBX(const char* path, ImportedModelData& data, Opt #endif // Extract embedded textures - if (EnumHasAnyFlags(data.Types, ImportDataTypes::Textures)) + if (EnumHasAnyFlags(options.ImportTypes, ImportDataTypes::Textures)) { String outputPath; for (int i = 0, c = scene->getEmbeddedDataCount(); i < c; i++) @@ -1232,7 +1232,7 @@ bool ModelTool::ImportDataOpenFBX(const char* path, ImportedModelData& data, Opt DeleteMe contextCleanup(options.SplitContext ? nullptr : context); // Build final skeleton bones hierarchy before importing meshes - if (EnumHasAnyFlags(data.Types, ImportDataTypes::Skeleton)) + if (EnumHasAnyFlags(options.ImportTypes, ImportDataTypes::Skeleton)) { if (ImportBones(*context, errorMsg)) { @@ -1244,7 +1244,7 @@ bool ModelTool::ImportDataOpenFBX(const char* path, ImportedModelData& data, Opt } // Import geometry (meshes and materials) - if (EnumHasAnyFlags(data.Types, ImportDataTypes::Geometry) && context->Scene->getMeshCount() > 0) + if (EnumHasAnyFlags(options.ImportTypes, ImportDataTypes::Geometry) && context->Scene->getMeshCount() > 0) { const int meshCount = context->Scene->getMeshCount(); if (options.SplitObjects && options.ObjectIndex == -1 && meshCount > 1) @@ -1303,7 +1303,7 @@ bool ModelTool::ImportDataOpenFBX(const char* path, ImportedModelData& data, Opt } // Import skeleton - if (EnumHasAnyFlags(data.Types, ImportDataTypes::Skeleton)) + if (EnumHasAnyFlags(options.ImportTypes, ImportDataTypes::Skeleton)) { data.Skeleton.Nodes.Resize(context->Nodes.Count(), false); for (int32 i = 0; i < context->Nodes.Count(); i++) @@ -1343,7 +1343,7 @@ bool ModelTool::ImportDataOpenFBX(const char* path, ImportedModelData& data, Opt } // Import animations - if (EnumHasAnyFlags(data.Types, ImportDataTypes::Animations)) + if (EnumHasAnyFlags(options.ImportTypes, ImportDataTypes::Animations)) { const int animCount = context->Scene->getAnimationStackCount(); if (options.SplitObjects && options.ObjectIndex == -1 && animCount > 1) @@ -1386,7 +1386,7 @@ bool ModelTool::ImportDataOpenFBX(const char* path, ImportedModelData& data, Opt } // Import nodes - if (EnumHasAnyFlags(data.Types, ImportDataTypes::Nodes)) + if (EnumHasAnyFlags(options.ImportTypes, ImportDataTypes::Nodes)) { data.Nodes.Resize(context->Nodes.Count()); for (int32 i = 0; i < context->Nodes.Count(); i++) diff --git a/Source/Engine/Tools/ModelTool/ModelTool.cpp b/Source/Engine/Tools/ModelTool/ModelTool.cpp index 6d0a418ad..38f010e28 100644 --- a/Source/Engine/Tools/ModelTool/ModelTool.cpp +++ b/Source/Engine/Tools/ModelTool/ModelTool.cpp @@ -332,26 +332,6 @@ bool ModelTool::GenerateModelSDF(Model* inputModel, ModelData* modelData, float #if USE_EDITOR -BoundingBox ImportedModelData::LOD::GetBox() const -{ - if (Meshes.IsEmpty()) - return BoundingBox::Empty; - - BoundingBox box; - Meshes[0]->CalculateBox(box); - for (int32 i = 1; i < Meshes.Count(); i++) - { - if (Meshes[i]->Positions.HasItems()) - { - BoundingBox t; - Meshes[i]->CalculateBox(t); - BoundingBox::Merge(box, t, box); - } - } - - return box; -} - void ModelTool::Options::Serialize(SerializeStream& stream, const void* otherObj) { SERIALIZE_GET_OTHER_OBJ(ModelTool::Options); @@ -463,7 +443,7 @@ void RemoveNamespace(String& name) name = name.Substring(namespaceStart + 1); } -bool ModelTool::ImportData(const String& path, ImportedModelData& data, Options& options, String& errorMsg) +bool ModelTool::ImportData(const String& path, ModelData& data, Options& options, String& errorMsg) { // Validate options options.Scale = Math::Clamp(options.Scale, 0.0001f, 100000.0f); @@ -610,7 +590,7 @@ bool ModelTool::ImportData(const String& path, ImportedModelData& data, Options& } // Flip normals of the imported geometry - if (options.FlipNormals && EnumHasAnyFlags(data.Types, ImportDataTypes::Geometry)) + if (options.FlipNormals && EnumHasAnyFlags(options.ImportTypes, ImportDataTypes::Geometry)) { for (auto& lod : data.LODs) { @@ -783,30 +763,29 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& op const auto startTime = DateTime::NowUTC(); // Import data - ImportDataTypes importDataTypes; switch (options.Type) { case ModelType::Model: - importDataTypes = ImportDataTypes::Geometry | ImportDataTypes::Nodes; + options.ImportTypes = ImportDataTypes::Geometry | ImportDataTypes::Nodes; if (options.ImportMaterials) - importDataTypes |= ImportDataTypes::Materials; + options.ImportTypes |= ImportDataTypes::Materials; if (options.ImportTextures) - importDataTypes |= ImportDataTypes::Textures; + options.ImportTypes |= ImportDataTypes::Textures; break; case ModelType::SkinnedModel: - importDataTypes = ImportDataTypes::Geometry | ImportDataTypes::Nodes | ImportDataTypes::Skeleton; + options.ImportTypes = ImportDataTypes::Geometry | ImportDataTypes::Nodes | ImportDataTypes::Skeleton; if (options.ImportMaterials) - importDataTypes |= ImportDataTypes::Materials; + options.ImportTypes |= ImportDataTypes::Materials; if (options.ImportTextures) - importDataTypes |= ImportDataTypes::Textures; + options.ImportTypes |= ImportDataTypes::Textures; break; case ModelType::Animation: - importDataTypes = ImportDataTypes::Animations; + options.ImportTypes = ImportDataTypes::Animations; break; default: return true; } - ImportedModelData data(importDataTypes); + ModelData data; if (ImportData(path, data, options, errorMsg)) return true; @@ -965,7 +944,7 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& op auto& texture = data.Textures[i]; // Auto-import textures - if (autoImportOutput.IsEmpty() || (data.Types & ImportDataTypes::Textures) == ImportDataTypes::None || texture.FilePath.IsEmpty()) + if (autoImportOutput.IsEmpty() || (options.ImportTypes & ImportDataTypes::Textures) == ImportDataTypes::None || texture.FilePath.IsEmpty()) continue; String filename = StringUtils::GetFileNameWithoutExtension(texture.FilePath); for (int32 j = filename.Length() - 1; j >= 0; j--) @@ -1012,7 +991,7 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& op material.Name = TEXT("Material ") + StringUtils::ToString(i); // Auto-import materials - if (autoImportOutput.IsEmpty() || (data.Types & ImportDataTypes::Materials) == ImportDataTypes::None || !material.UsesProperties()) + if (autoImportOutput.IsEmpty() || (options.ImportTypes & ImportDataTypes::Materials) == ImportDataTypes::None || !material.UsesProperties()) continue; auto filename = material.Name; for (int32 j = filename.Length() - 1; j >= 0; j--) @@ -1124,10 +1103,10 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& op } // Perform simple nodes mapping to single node (will transform meshes to model local space) - SkeletonMapping skeletonMapping(data.Nodes, nullptr); + SkeletonMapping skeletonMapping(data.Nodes, nullptr); // Refresh skeleton updater with model skeleton - SkeletonUpdater hierarchyUpdater(data.Nodes); + SkeletonUpdater hierarchyUpdater(data.Nodes); hierarchyUpdater.UpdateMatrices(); // Move meshes in the new nodes @@ -1421,10 +1400,10 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& op } // Perform simple nodes mapping to single node (will transform meshes to model local space) - SkeletonMapping skeletonMapping(data.Nodes, nullptr); + SkeletonMapping skeletonMapping(data.Nodes, nullptr); // Refresh skeleton updater with model skeleton - SkeletonUpdater hierarchyUpdater(data.Nodes); + SkeletonUpdater hierarchyUpdater(data.Nodes); hierarchyUpdater.UpdateMatrices(); if (options.CalculateBoneOffsetMatrices) diff --git a/Source/Engine/Tools/ModelTool/ModelTool.h b/Source/Engine/Tools/ModelTool/ModelTool.h index 5a8e90d3c..e3da7e2c3 100644 --- a/Source/Engine/Tools/ModelTool/ModelTool.h +++ b/Source/Engine/Tools/ModelTool/ModelTool.h @@ -56,94 +56,6 @@ enum class ImportDataTypes : int32 DECLARE_ENUM_OPERATORS(ImportDataTypes); -/// -/// Imported model data container. Represents unified model source file data (meshes, animations, skeleton, materials). -/// -class ImportedModelData -{ -public: - struct LOD - { - Array Meshes; - - BoundingBox GetBox() const; - }; - - struct Node - { - /// - /// The parent node index. The root node uses value -1. - /// - int32 ParentIndex; - - /// - /// The local transformation of the node, relative to the parent node. - /// - Transform LocalTransform; - - /// - /// The name of this node. - /// - String Name; - }; - -public: - /// - /// The import data types types. - /// - ImportDataTypes Types; - - /// - /// The textures slots. - /// - Array Textures; - - /// - /// The material slots. - /// - Array Materials; - - /// - /// The level of details data with meshes. - /// - Array LODs; - - /// - /// The skeleton data. - /// - SkeletonData Skeleton; - - /// - /// The scene nodes. - /// - Array Nodes; - - /// - /// The node animations. - /// - AnimationData Animation; - -public: - /// - /// Initializes a new instance of the class. - /// - /// The types. - ImportedModelData(ImportDataTypes types) - { - Types = types; - } - - /// - /// Finalizes an instance of the class. - /// - ~ImportedModelData() - { - // Ensure to cleanup data - for (int32 i = 0; i < LODs.Count(); i++) - LODs[i].Meshes.ClearDelete(); - } -}; - #endif struct ModelSDFHeader @@ -382,10 +294,15 @@ public: API_FIELD(Attributes="EditorOrder(3030), EditorDisplay(\"Other\")") String SubAssetFolder = TEXT(""); + public: // Internals + // Runtime data for objects splitting during import (used internally) void* SplitContext = nullptr; Function OnSplitImport; + // Internal flags for objects to import. + ImportDataTypes ImportTypes = ImportDataTypes::None; + public: // [ISerializable] void Serialize(SerializeStream& stream, const void* otherObj) override; @@ -401,7 +318,7 @@ public: /// The import options. /// The error message container. /// True if fails, otherwise false. - static bool ImportData(const String& path, ImportedModelData& data, Options& options, String& errorMsg); + static bool ImportData(const String& path, ModelData& data, Options& options, String& errorMsg); /// /// Imports the model. @@ -444,13 +361,13 @@ public: private: static void CalculateBoneOffsetMatrix(const Array& nodes, Matrix& offsetMatrix, int32 nodeIndex); #if USE_ASSIMP - static bool ImportDataAssimp(const char* path, ImportedModelData& data, Options& options, String& errorMsg); + static bool ImportDataAssimp(const char* path, ModelData& data, Options& options, String& errorMsg); #endif #if USE_AUTODESK_FBX_SDK - static bool ImportDataAutodeskFbxSdk(const char* path, ImportedModelData& data, Options& options, String& errorMsg); + static bool ImportDataAutodeskFbxSdk(const char* path, ModelData& data, Options& options, String& errorMsg); #endif #if USE_OPEN_FBX - static bool ImportDataOpenFBX(const char* path, ImportedModelData& data, Options& options, String& errorMsg); + static bool ImportDataOpenFBX(const char* path, ModelData& data, Options& options, String& errorMsg); #endif #endif };