Replace ImportedModelData with ModelData for model importing
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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++)
|
||||
|
||||
@@ -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++)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user