Replace ImportedModelData with ModelData for model importing

This commit is contained in:
Wojtek Figat
2023-11-30 11:46:07 +01:00
parent c5df7ad689
commit 6e92d3103c
5 changed files with 87 additions and 174 deletions

View File

@@ -366,12 +366,32 @@ struct FLAXENGINE_API MaterialSlotEntry
bool UsesProperties() const;
};
/// <summary>
/// Data container for model hierarchy node.
/// </summary>
struct FLAXENGINE_API ModelDataNode
{
/// <summary>
/// The parent node index. The root node uses value -1.
/// </summary>
int32 ParentIndex;
/// <summary>
/// The local transformation of the node, relative to the parent node.
/// </summary>
Transform LocalTransform;
/// <summary>
/// The name of this node.
/// </summary>
String Name;
};
/// <summary>
/// Data container for LOD metadata and sub meshes.
/// </summary>
class FLAXENGINE_API ModelLodData
struct FLAXENGINE_API ModelLodData
{
public:
/// <summary>
/// The screen size to switch LODs. Bottom limit of the model screen size to render this LOD.
/// </summary>
@@ -382,14 +402,6 @@ public:
/// </summary>
Array<MeshData*> Meshes;
public:
/// <summary>
/// Initializes a new instance of the <see cref="ModelLodData"/> class.
/// </summary>
ModelLodData()
{
}
/// <summary>
/// Finalizes an instance of the <see cref="ModelLodData"/> class.
/// </summary>
@@ -426,7 +438,7 @@ public:
Array<MaterialSlotEntry> Materials;
/// <summary>
/// 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.
/// </summary>
Array<ModelLodData> LODs;
@@ -435,6 +447,11 @@ public:
/// </summary>
SkeletonData Skeleton;
/// <summary>
/// The scene nodes (in hierarchy).
/// </summary>
Array<ModelDataNode> Nodes;
/// <summary>
/// The node animations.
/// </summary>

View File

@@ -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<Quaternion>& 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<AssimpImporterData>(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++)

View File

@@ -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<T>& 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<OpenFbxImporterData> 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++)

View File

@@ -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<ImportedModelData::Node> skeletonMapping(data.Nodes, nullptr);
SkeletonMapping<ModelDataNode> skeletonMapping(data.Nodes, nullptr);
// Refresh skeleton updater with model skeleton
SkeletonUpdater<ImportedModelData::Node> hierarchyUpdater(data.Nodes);
SkeletonUpdater<ModelDataNode> 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<ImportedModelData::Node> skeletonMapping(data.Nodes, nullptr);
SkeletonMapping<ModelDataNode> skeletonMapping(data.Nodes, nullptr);
// Refresh skeleton updater with model skeleton
SkeletonUpdater<ImportedModelData::Node> hierarchyUpdater(data.Nodes);
SkeletonUpdater<ModelDataNode> hierarchyUpdater(data.Nodes);
hierarchyUpdater.UpdateMatrices();
if (options.CalculateBoneOffsetMatrices)

View File

@@ -56,94 +56,6 @@ enum class ImportDataTypes : int32
DECLARE_ENUM_OPERATORS(ImportDataTypes);
/// <summary>
/// Imported model data container. Represents unified model source file data (meshes, animations, skeleton, materials).
/// </summary>
class ImportedModelData
{
public:
struct LOD
{
Array<MeshData*> Meshes;
BoundingBox GetBox() const;
};
struct Node
{
/// <summary>
/// The parent node index. The root node uses value -1.
/// </summary>
int32 ParentIndex;
/// <summary>
/// The local transformation of the node, relative to the parent node.
/// </summary>
Transform LocalTransform;
/// <summary>
/// The name of this node.
/// </summary>
String Name;
};
public:
/// <summary>
/// The import data types types.
/// </summary>
ImportDataTypes Types;
/// <summary>
/// The textures slots.
/// </summary>
Array<TextureEntry> Textures;
/// <summary>
/// The material slots.
/// </summary>
Array<MaterialSlotEntry> Materials;
/// <summary>
/// The level of details data with meshes.
/// </summary>
Array<LOD> LODs;
/// <summary>
/// The skeleton data.
/// </summary>
SkeletonData Skeleton;
/// <summary>
/// The scene nodes.
/// </summary>
Array<Node> Nodes;
/// <summary>
/// The node animations.
/// </summary>
AnimationData Animation;
public:
/// <summary>
/// Initializes a new instance of the <see cref="ImportedModelData"/> class.
/// </summary>
/// <param name="types">The types.</param>
ImportedModelData(ImportDataTypes types)
{
Types = types;
}
/// <summary>
/// Finalizes an instance of the <see cref="ImportedModelData"/> class.
/// </summary>
~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<bool(Options& splitOptions, const String& objectName)> 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:
/// <param name="options">The import options.</param>
/// <param name="errorMsg">The error message container.</param>
/// <returns>True if fails, otherwise false.</returns>
static bool ImportData(const String& path, ImportedModelData& data, Options& options, String& errorMsg);
static bool ImportData(const String& path, ModelData& data, Options& options, String& errorMsg);
/// <summary>
/// Imports the model.
@@ -444,13 +361,13 @@ public:
private:
static void CalculateBoneOffsetMatrix(const Array<SkeletonNode>& 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
};