From 757b8ff855a6e9ada52a9e376f207abb619c8959 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Tue, 31 Dec 2024 00:50:42 -0600 Subject: [PATCH] Fix local origin option with multi-mesh import. --- Source/Engine/Graphics/Models/ModelData.h | 2 +- .../Tools/ModelTool/ModelTool.Assimp.cpp | 22 ++------ .../Tools/ModelTool/ModelTool.OpenFBX.cpp | 3 +- Source/Engine/Tools/ModelTool/ModelTool.cpp | 54 +++++++++++++------ 4 files changed, 46 insertions(+), 35 deletions(-) diff --git a/Source/Engine/Graphics/Models/ModelData.h b/Source/Engine/Graphics/Models/ModelData.h index 7278611e6..08903a0eb 100644 --- a/Source/Engine/Graphics/Models/ModelData.h +++ b/Source/Engine/Graphics/Models/ModelData.h @@ -91,7 +91,7 @@ public: Array BlendShapes; /// - /// Global translation for this mesh to be at it's local origin. + /// Local translation for this mesh to be at it's local origin. /// Vector3 OriginTranslation = Vector3::Zero; diff --git a/Source/Engine/Tools/ModelTool/ModelTool.Assimp.cpp b/Source/Engine/Tools/ModelTool/ModelTool.Assimp.cpp index c4f27abf5..3cf47103a 100644 --- a/Source/Engine/Tools/ModelTool/ModelTool.Assimp.cpp +++ b/Source/Engine/Tools/ModelTool/ModelTool.Assimp.cpp @@ -645,24 +645,10 @@ bool ImportMesh(int32 index, ModelData& result, AssimpImporterData& data, String // Link mesh meshData->NodeIndex = nodeIndex; AssimpNode* curNode = &data.Nodes[meshData->NodeIndex]; - Vector3 translation = Vector3::Zero; - Vector3 scale = Vector3::One; - Quaternion rotation = Quaternion::Identity; - - while (true) - { - translation += curNode->LocalTransform.Translation; - scale *= curNode->LocalTransform.Scale; - rotation *= curNode->LocalTransform.Orientation; - - if (curNode->ParentIndex == -1) - break; - curNode = &data.Nodes[curNode->ParentIndex]; - } - - meshData->OriginTranslation = translation; - meshData->OriginOrientation = rotation; - meshData->Scaling = scale; + + meshData->OriginTranslation = curNode->LocalTransform.Translation; + meshData->OriginOrientation = curNode->LocalTransform.Orientation; + meshData->Scaling = curNode->LocalTransform.Scale; if (result.LODs.Count() <= lodIndex) result.LODs.Resize(lodIndex + 1); diff --git a/Source/Engine/Tools/ModelTool/ModelTool.OpenFBX.cpp b/Source/Engine/Tools/ModelTool/ModelTool.OpenFBX.cpp index 98747086a..7cb38ce43 100644 --- a/Source/Engine/Tools/ModelTool/ModelTool.OpenFBX.cpp +++ b/Source/Engine/Tools/ModelTool/ModelTool.OpenFBX.cpp @@ -1026,7 +1026,8 @@ bool ProcessMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh* }*/ // Get local transform for origin shifting translation - auto translation = ToMatrix(aMesh->getGlobalTransform()).GetTranslation(); + + auto translation = Float3((float)aMesh->getLocalTranslation().x, (float)aMesh->getLocalTranslation().y, (float)aMesh->getLocalTranslation().z); auto scale = data.GlobalSettings.UnitScaleFactor; if (data.GlobalSettings.CoordAxis == ofbx::CoordSystem_RightHanded) mesh.OriginTranslation = scale * Vector3(translation.X, translation.Y, -translation.Z); diff --git a/Source/Engine/Tools/ModelTool/ModelTool.cpp b/Source/Engine/Tools/ModelTool/ModelTool.cpp index fec4ba8f5..45353e5b8 100644 --- a/Source/Engine/Tools/ModelTool/ModelTool.cpp +++ b/Source/Engine/Tools/ModelTool/ModelTool.cpp @@ -1549,23 +1549,25 @@ bool ModelTool::ImportModel(const String& path, ModelData& data, Options& option // Prepare import transformation Transform importTransform(options.Translation, options.Rotation, Float3(options.Scale)); - if (options.UseLocalOrigin && data.LODs.HasItems() && data.LODs[0].Meshes.HasItems()) - { - importTransform.Translation -= importTransform.Orientation * data.LODs[0].Meshes[0]->OriginTranslation * importTransform.Scale; - } - if (options.CenterGeometry && data.LODs.HasItems() && data.LODs[0].Meshes.HasItems()) - { - // Calculate the bounding box (use LOD0 as a reference) - BoundingBox box = data.LODs[0].GetBox(); - auto center = data.LODs[0].Meshes[0]->OriginOrientation * importTransform.Orientation * box.GetCenter() * importTransform.Scale * data.LODs[0].Meshes[0]->Scaling; - importTransform.Translation -= center; - } // Apply the import transformation - if (!importTransform.IsIdentity() && data.Nodes.HasItems()) + if ((!importTransform.IsIdentity() || options.UseLocalOrigin || options.CenterGeometry) && data.Nodes.HasItems()) { if (options.Type == ModelType::SkinnedModel) { + // Setup other transform options + if (options.UseLocalOrigin && data.LODs.HasItems() && data.LODs[0].Meshes.HasItems()) + { + importTransform.Translation -= importTransform.Orientation * data.LODs[0].Meshes[0]->OriginTranslation * importTransform.Scale; + } + if (options.CenterGeometry && data.LODs.HasItems() && data.LODs[0].Meshes.HasItems()) + { + // Calculate the bounding box (use LOD0 as a reference) + BoundingBox box = data.LODs[0].GetBox(); + auto center = data.LODs[0].Meshes[0]->OriginOrientation * importTransform.Orientation * box.GetCenter() * importTransform.Scale * data.LODs[0].Meshes[0]->Scaling; + importTransform.Translation -= center; + } + // Transform the root node using the import transformation auto& root = data.Skeleton.RootNode(); Transform meshTransform = root.LocalTransform.WorldToLocal(importTransform).LocalToWorld(root.LocalTransform); @@ -1596,9 +1598,31 @@ bool ModelTool::ImportModel(const String& path, ModelData& data, Options& option } else { - // Transform the root node using the import transformation - auto& root = data.Nodes[0]; - root.LocalTransform = importTransform.LocalToWorld(root.LocalTransform); + // Transform the nodes using the import transformation + if (data.LODs.HasItems() && data.LODs[0].Meshes.HasItems()) + { + for (int i = 0; i < data.LODs[0].Meshes.Count(); ++i) + { + auto* meshData = data.LODs[0].Meshes[i]; + Transform transform = importTransform; + if (options.UseLocalOrigin) + { + transform.Translation -= transform.Orientation * meshData->OriginTranslation * transform.Scale; + } + if (options.CenterGeometry) + { + // Calculate the bounding box (use LOD0 as a reference) + BoundingBox box = data.LODs[0].GetBox(); + auto center = meshData->OriginOrientation * transform.Orientation * box.GetCenter() * transform.Scale * meshData->Scaling; + transform.Translation -= center; + } + + int32 nodeIndex = meshData->NodeIndex; + + auto& node = data.Nodes[nodeIndex]; + node.LocalTransform = transform.LocalToWorld(node.LocalTransform); + } + } } }