From d841f0c0db73e4c2449360824425f55f1e3a43aa Mon Sep 17 00:00:00 2001 From: amzn-mike <80125227+amzn-mike@users.noreply.github.com> Date: Fri, 4 Jun 2021 16:18:53 -0500 Subject: [PATCH 1/9] Got transform result close for 3 bone chain, longer chains are still not correct (cherry picked from commit 5ac65de6148dcc03b9f2953e97dd943493f23ed9) # Conflicts: # Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp --- .../Importers/AssImpTransformImporter.cpp | 64 +++++++++++++++++-- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp index bcc007e3a7..153dfce69d 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp @@ -61,7 +61,7 @@ namespace AZ } } } - +#pragma optimize("", off) Events::ProcessingResult AssImpTransformImporter::ImportTransform(AssImpSceneNodeAppendedContext& context) { AZ_TraceContext("Importer", "transform"); @@ -79,6 +79,11 @@ namespace AZ auto boneIterator = boneLookup.find(currentNode->mName.C_Str()); const bool isBone = boneIterator != boneLookup.end(); + if (currentNode->mName.C_Str() == AZStd::string("FrontCloth_02")) + { + __debugbreak(); + } + aiMatrix4x4 combinedTransform; if (isBone) @@ -87,20 +92,67 @@ namespace AZ aiMatrix4x4 offsetMatrix = boneIterator->second->mOffsetMatrix; aiMatrix4x4 parentOffset {}; + aiMatrix4x4 parentTransform{}; + + if (parentNode) + { + parentTransform = parentNode->mTransformation; + } + + auto azOffset = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(offsetMatrix); + decltype(azOffset) azParentOffset{}; + AZStd::vector transforms, offsets, inverseTransforms, inverseOffsets; + + auto addTransform = [&](AZStd::string, aiMatrix4x4 mat) + { + auto azMat = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(mat); + transforms.push_back(azMat); + inverseTransforms.push_back(azMat.GetInverseFull()); + }; + auto addOffset = [&]([[maybe_unused]] auto name, aiMatrix4x4 mat) + { + auto azMat = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(mat); + offsets.push_back(azMat); + inverseOffsets.push_back(azMat.GetInverseFull()); + }; + + auto curNode = currentNode; + + while (curNode && boneLookup.count(curNode->mName.C_Str())) + { + AZStd::string name = curNode->mName.C_Str(); + addOffset(name, boneLookup.at(name)->mOffsetMatrix); + addTransform(name, curNode->mTransformation); + + curNode = curNode->mParent; + } + + // Go up the tree to find the root bone. It's parent will be the scene mRootNode + while (parentNode && parentNode->mParent && parentNode->mParent != scene->mRootNode) + { + parentNode = parentNode->mParent; + } auto parentBoneIterator = boneLookup.find(parentNode->mName.C_Str()); + aiMatrix4x4 rootOffsetMatrix{}; - if (parentNode && parentBoneIterator != boneLookup.end()) + if (parentBoneIterator != boneLookup.end()) { - const auto& parentBone = parentBoneIterator->second; - - parentOffset = parentBone->mOffsetMatrix; + rootOffsetMatrix = parentBoneIterator->second->mOffsetMatrix; } auto inverseOffset = offsetMatrix; inverseOffset.Inverse(); - combinedTransform = parentOffset * inverseOffset; + auto parentTransformInverse = parentTransform; + parentTransformInverse.Inverse(); + + //auto azInverse = azOffset.GetInverseFull(); + //auto azCombined = azParentOffset * azInverse; + //combinedTransform = parentOffset * inverseOffset; + + //parentTransform ^-1 * parentParent * azOffsetInverse + combinedTransform = parentTransformInverse * rootOffsetMatrix * inverseOffset; } else { From 66a030b800c0def8a0b15847b3661b990f925837 Mon Sep 17 00:00:00 2001 From: amzn-mike <80125227+amzn-mike@users.noreply.github.com> Date: Wed, 9 Jun 2021 22:35:03 -0500 Subject: [PATCH 2/9] Fix transform data Use first offsetMatrix for a bone (there may be multiple) and calculate using offsetOfParent * inverseRootOffset * rootOffset * inverseOffset (cherry picked from commit a8eae976dda39ad28f9aa235e1e6ba34715ac48a) # Conflicts: # Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp --- .../Importers/AssImpTransformImporter.cpp | 39 ++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp index 153dfce69d..dc59f59147 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp @@ -46,8 +46,9 @@ namespace AZ serializeContext->Class()->Version(1); } } - - void GetAllBones(const aiScene* scene, AZStd::unordered_map& boneLookup) + + void GetAllBones( + const aiScene* scene, AZStd::unordered_multimap& boneLookup) { for (unsigned meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex) { @@ -57,7 +58,7 @@ namespace AZ { const aiBone* bone = mesh->mBones[boneIndex]; - boneLookup[bone->mName.C_Str()] = bone; + boneLookup.emplace(bone->mName.C_Str(), bone); } } } @@ -73,18 +74,19 @@ namespace AZ return Events::ProcessingResult::Ignored; } - AZStd::unordered_map boneLookup; + AZStd::unordered_multimap boneLookup; GetAllBones(scene, boneLookup); auto boneIterator = boneLookup.find(currentNode->mName.C_Str()); const bool isBone = boneIterator != boneLookup.end(); - if (currentNode->mName.C_Str() == AZStd::string("FrontCloth_02")) + if (currentNode->mName.C_Str() == AZStd::string("spine_C0_0_jnt")) { - __debugbreak(); + //__debugbreak(); } aiMatrix4x4 combinedTransform; + DataTypes::MatrixType finalMat; if (isBone) { @@ -121,7 +123,16 @@ namespace AZ while (curNode && boneLookup.count(curNode->mName.C_Str())) { AZStd::string name = curNode->mName.C_Str(); - addOffset(name, boneLookup.at(name)->mOffsetMatrix); + + auto range = boneLookup.equal_range(name); + + for (auto it = range.first; it != range.second; ++it) + { + addOffset(name, it->second->mOffsetMatrix); + break; + } + + //addOffset(name, boneLookup.at(name)->mOffsetMatrix); addTransform(name, curNode->mTransformation); curNode = curNode->mParent; @@ -152,14 +163,24 @@ namespace AZ //combinedTransform = parentOffset * inverseOffset; //parentTransform ^-1 * parentParent * azOffsetInverse - combinedTransform = parentTransformInverse * rootOffsetMatrix * inverseOffset; + //combinedTransform = parentTransformInverse * rootOffsetMatrix * inverseOffset; + + //azNodeLocal = offsets[1] * inverseOffsets[3] * (offsets[3] * inverseOffsets[0]) + finalMat = + offsets.at(AZ::GetMin(offsets.size()-1, (decltype(offsets.size()))1)) * inverseOffsets.at(inverseOffsets.size() - 1) * offsets.at(offsets.size() - 1) * inverseOffsets.at(0); } else { combinedTransform = GetConcatenatedLocalTransform(currentNode); } - DataTypes::MatrixType localTransform = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(combinedTransform); + //DataTypes::MatrixType localTransform = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(combinedTransform); + DataTypes::MatrixType localTransform = finalMat; + + if (localTransform == DataTypes::MatrixType::Identity()) + { + return Events::ProcessingResult::Ignored; + } context.m_sourceSceneSystem.SwapTransformForUpAxis(localTransform); context.m_sourceSceneSystem.ConvertUnit(localTransform); From 10999b699979aed380138557457440f55e3f0938 Mon Sep 17 00:00:00 2001 From: amzn-mike <80125227+amzn-mike@users.noreply.github.com> Date: Sat, 12 Jun 2021 13:26:25 -0500 Subject: [PATCH 3/9] All bones have animations (cherry picked from commit d17a8070010cdc5bc4e08d17b1549736d031414a) --- .../Importers/AssImpAnimationImporter.cpp | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp index d72cdde8e7..f066540c50 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp @@ -255,7 +255,6 @@ namespace AZ { return AZStd::make_pair(animation, anim); } - Events::ProcessingResult AssImpAnimationImporter::ImportAnimation(AssImpSceneNodeAppendedContext& context) { AZ_TraceContext("Importer", "Animation"); @@ -447,24 +446,41 @@ namespace AZ return combinedAnimationResult.GetResult(); } + + AZStd::unordered_set boneList; + + for (int i = 0; i < scene->mNumMeshes; ++i) + { + auto mesh = scene->mMeshes[i]; + + for (auto boneIndex = 0; boneIndex < mesh->mNumBones; ++boneIndex) + { + auto bone = mesh->mBones[boneIndex]; + + boneList.insert(bone->mName.C_Str()); + } + } + decltype(boneAnimations) parentFillerAnimations; // Go through all the animations and make sure we create animations for bones who's parents don't have an animation for (auto&& anim : boneAnimations) { - const aiNode* node = scene->mRootNode->FindNode(anim.first.c_str()); - const aiNode* parent = node->mParent; + //const aiNode* node = scene->mRootNode->FindNode(anim.first.c_str()); + //const aiNode* parent = node->mParent; - while (parent && parent != scene->mRootNode) + //while (parent && parent != scene->mRootNode) + for (auto boneName : boneList) { - if (!IsPivotNode(parent->mName)) + if (!IsPivotNode(aiString(boneName.c_str()))) { - if (boneAnimations.find(parent->mName.C_Str()) == boneAnimations.end() && - parentFillerAnimations.find(parent->mName.C_Str()) == parentFillerAnimations.end()) + if (boneAnimations.find(boneName) == boneAnimations.end() && + parentFillerAnimations.find(boneName) == parentFillerAnimations.end()) { // Create 1 key for each type that just copies the current transform ConsolidatedNodeAnim emptyAnimation; - aiMatrix4x4 globalTransform = GetConcatenatedLocalTransform(parent); + auto node = scene->mRootNode->FindNode(boneName.c_str()); + aiMatrix4x4 globalTransform = GetConcatenatedLocalTransform(node); aiVector3D position, scale; aiQuaternion rotation; @@ -483,11 +499,11 @@ namespace AZ emptyAnimation.mScalingKeys = emptyAnimation.m_ownedScalingKeys.data(); parentFillerAnimations.insert( - AZStd::make_pair(parent->mName.C_Str(), AZStd::make_pair(anim.second.first, AZStd::move(emptyAnimation)))); + AZStd::make_pair(boneName, AZStd::make_pair(anim.second.first, AZStd::move(emptyAnimation)))); } } - parent = parent->mParent; + //parent = parent->mParent; } } From 9b039c1f9da20e7c8b881bdf81d6df88af0342d4 Mon Sep 17 00:00:00 2001 From: amzn-mike <80125227+amzn-mike@users.noreply.github.com> Date: Sat, 12 Jun 2021 13:27:32 -0500 Subject: [PATCH 4/9] Fix creating bone data for non-bones (cherry picked from commit 8d1bdd1456e70e4efc47aa36dce660bc91e7dfcf) --- .../Importers/AssImpBoneImporter.cpp | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp index 5b43941715..694e3566f6 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp @@ -97,7 +97,7 @@ namespace AZ EnumChildren(scene, child, mainBoneList, boneLookup); } } - +#pragma optimize("", off) Events::ProcessingResult AssImpBoneImporter::ImportBone(AssImpNodeEncounteredContext& context) { AZ_TraceContext("Importer", "Bone"); @@ -112,11 +112,11 @@ namespace AZ bool isBone = false; - if (NodeParentIsOfType(context.m_scene.GetGraph(), context.m_currentGraphPosition, DataTypes::IBoneData::TYPEINFO_Uuid())) - { - isBone = true; - } - else + //if (NodeParentIsOfType(context.m_scene.GetGraph(), context.m_currentGraphPosition, DataTypes::IBoneData::TYPEINFO_Uuid())) + //{ + // isBone = true; + //} + //else { AZStd::unordered_map mainBoneList; AZStd::unordered_map boneLookup; @@ -171,11 +171,22 @@ namespace AZ createdBoneData = AZStd::make_shared(); } + // L_Lower_Eyelid_Jnt_01 + if (context.m_sourceNode.GetName() == AZStd::string("L_Lower_Eyelid_Jnt_01")) + { + //__debugbreak(); + } + + AZStd::vector transforms; aiMatrix4x4 transform = currentNode->mTransformation; const aiNode* parent = currentNode->mParent; - + + auto addTrans = [&](auto mat) { transforms.push_back(AssImpSDKWrapper::AssImpTypeConverter::ToTransform(mat)); }; + addTrans(transform); + while (parent) { + addTrans(parent->mTransformation); transform = parent->mTransformation * transform; parent = parent->mParent; } From 7dc4d8438b008ce914734638eb2bd46621107b9d Mon Sep 17 00:00:00 2001 From: amzn-mike <80125227+amzn-mike@users.noreply.github.com> Date: Sat, 12 Jun 2021 20:33:50 -0500 Subject: [PATCH 5/9] Fix non-bone transforms setting the wrong matrix variable (cherry picked from commit 838a8b47da73e50fca4ea9ee5abc7c33250bf25d) --- .../FbxSceneBuilder/Importers/AssImpTransformImporter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp index dc59f59147..3e22bfc671 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp @@ -85,7 +85,7 @@ namespace AZ //__debugbreak(); } - aiMatrix4x4 combinedTransform; + //aiMatrix4x4 combinedTransform; DataTypes::MatrixType finalMat; if (isBone) @@ -171,7 +171,7 @@ namespace AZ } else { - combinedTransform = GetConcatenatedLocalTransform(currentNode); + finalMat = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(GetConcatenatedLocalTransform(currentNode)); } //DataTypes::MatrixType localTransform = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(combinedTransform); From 57b19feca5d113ba6fc727cbc8e92e15bff5a9a9 Mon Sep 17 00:00:00 2001 From: amzn-mike <80125227+amzn-mike@users.noreply.github.com> Date: Wed, 16 Jun 2021 12:03:47 -0500 Subject: [PATCH 6/9] Cleanup code --- .../Importers/AssImpAnimationImporter.cpp | 8 +- .../Importers/AssImpBoneImporter.cpp | 34 ++---- .../Importers/AssImpTransformImporter.cpp | 104 ++++-------------- 3 files changed, 32 insertions(+), 114 deletions(-) diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp index f066540c50..7ab9deb141 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp @@ -463,13 +463,9 @@ namespace AZ decltype(boneAnimations) parentFillerAnimations; - // Go through all the animations and make sure we create animations for bones who's parents don't have an animation + // Go through all the animations and make sure we create placeholder animations for any bones missing them for (auto&& anim : boneAnimations) { - //const aiNode* node = scene->mRootNode->FindNode(anim.first.c_str()); - //const aiNode* parent = node->mParent; - - //while (parent && parent != scene->mRootNode) for (auto boneName : boneList) { if (!IsPivotNode(aiString(boneName.c_str()))) @@ -502,8 +498,6 @@ namespace AZ AZStd::make_pair(boneName, AZStd::make_pair(anim.second.first, AZStd::move(emptyAnimation)))); } } - - //parent = parent->mParent; } } diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp index 694e3566f6..648007ca47 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp @@ -97,7 +97,7 @@ namespace AZ EnumChildren(scene, child, mainBoneList, boneLookup); } } -#pragma optimize("", off) + Events::ProcessingResult AssImpBoneImporter::ImportBone(AssImpNodeEncounteredContext& context) { AZ_TraceContext("Importer", "Bone"); @@ -111,12 +111,7 @@ namespace AZ } bool isBone = false; - - //if (NodeParentIsOfType(context.m_scene.GetGraph(), context.m_currentGraphPosition, DataTypes::IBoneData::TYPEINFO_Uuid())) - //{ - // isBone = true; - //} - //else + { AZStd::unordered_map mainBoneList; AZStd::unordered_map boneLookup; @@ -170,25 +165,14 @@ namespace AZ { createdBoneData = AZStd::make_shared(); } - - // L_Lower_Eyelid_Jnt_01 - if (context.m_sourceNode.GetName() == AZStd::string("L_Lower_Eyelid_Jnt_01")) + + aiMatrix4x4 transform{}; + const aiNode* iteratingNode = currentNode; + + while (iteratingNode) { - //__debugbreak(); - } - - AZStd::vector transforms; - aiMatrix4x4 transform = currentNode->mTransformation; - const aiNode* parent = currentNode->mParent; - - auto addTrans = [&](auto mat) { transforms.push_back(AssImpSDKWrapper::AssImpTypeConverter::ToTransform(mat)); }; - addTrans(transform); - - while (parent) - { - addTrans(parent->mTransformation); - transform = parent->mTransformation * transform; - parent = parent->mParent; + transform = iteratingNode->mTransformation * transform; + iteratingNode = iteratingNode->mParent; } SceneAPI::DataTypes::MatrixType globalTransform = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(transform); diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp index 3e22bfc671..f7a85a161b 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpTransformImporter.cpp @@ -62,7 +62,7 @@ namespace AZ } } } -#pragma optimize("", off) + Events::ProcessingResult AssImpTransformImporter::ImportTransform(AssImpSceneNodeAppendedContext& context) { AZ_TraceContext("Importer", "transform"); @@ -79,104 +79,44 @@ namespace AZ auto boneIterator = boneLookup.find(currentNode->mName.C_Str()); const bool isBone = boneIterator != boneLookup.end(); - - if (currentNode->mName.C_Str() == AZStd::string("spine_C0_0_jnt")) - { - //__debugbreak(); - } - - //aiMatrix4x4 combinedTransform; - DataTypes::MatrixType finalMat; + + DataTypes::MatrixType localTransform; if (isBone) { - auto parentNode = currentNode->mParent; + AZStd::vector offsets, inverseOffsets; + auto iteratingNode = currentNode; - aiMatrix4x4 offsetMatrix = boneIterator->second->mOffsetMatrix; - aiMatrix4x4 parentOffset {}; - aiMatrix4x4 parentTransform{}; - - if (parentNode) + while (iteratingNode && boneLookup.count(iteratingNode->mName.C_Str())) { - parentTransform = parentNode->mTransformation; - } - - auto azOffset = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(offsetMatrix); - decltype(azOffset) azParentOffset{}; - AZStd::vector transforms, offsets, inverseTransforms, inverseOffsets; - - auto addTransform = [&](AZStd::string, aiMatrix4x4 mat) - { - auto azMat = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(mat); - transforms.push_back(azMat); - inverseTransforms.push_back(azMat.GetInverseFull()); - }; - auto addOffset = [&]([[maybe_unused]] auto name, aiMatrix4x4 mat) - { - auto azMat = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(mat); - offsets.push_back(azMat); - inverseOffsets.push_back(azMat.GetInverseFull()); - }; - - auto curNode = currentNode; - - while (curNode && boneLookup.count(curNode->mName.C_Str())) - { - AZStd::string name = curNode->mName.C_Str(); + AZStd::string name = iteratingNode->mName.C_Str(); auto range = boneLookup.equal_range(name); - for (auto it = range.first; it != range.second; ++it) + if (range.first != range.second) { - addOffset(name, it->second->mOffsetMatrix); - break; + // There can be multiple offsetMatrices for a given bone, we're only interested in grabbing the first one + auto boneFirstOffsetMatrix = range.first->second->mOffsetMatrix; + auto azMat = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(boneFirstOffsetMatrix); + offsets.push_back(azMat); + inverseOffsets.push_back(azMat.GetInverseFull()); } - //addOffset(name, boneLookup.at(name)->mOffsetMatrix); - addTransform(name, curNode->mTransformation); - - curNode = curNode->mParent; + iteratingNode = iteratingNode->mParent; } - - // Go up the tree to find the root bone. It's parent will be the scene mRootNode - while (parentNode && parentNode->mParent && parentNode->mParent != scene->mRootNode) - { - parentNode = parentNode->mParent; - } - - auto parentBoneIterator = boneLookup.find(parentNode->mName.C_Str()); - aiMatrix4x4 rootOffsetMatrix{}; - - if (parentBoneIterator != boneLookup.end()) - { - rootOffsetMatrix = parentBoneIterator->second->mOffsetMatrix; - } - - auto inverseOffset = offsetMatrix; - inverseOffset.Inverse(); - - auto parentTransformInverse = parentTransform; - parentTransformInverse.Inverse(); - - //auto azInverse = azOffset.GetInverseFull(); - //auto azCombined = azParentOffset * azInverse; - //combinedTransform = parentOffset * inverseOffset; - - //parentTransform ^-1 * parentParent * azOffsetInverse - //combinedTransform = parentTransformInverse * rootOffsetMatrix * inverseOffset; - - //azNodeLocal = offsets[1] * inverseOffsets[3] * (offsets[3] * inverseOffsets[0]) - finalMat = - offsets.at(AZ::GetMin(offsets.size()-1, (decltype(offsets.size()))1)) * inverseOffsets.at(inverseOffsets.size() - 1) * offsets.at(offsets.size() - 1) * inverseOffsets.at(0); + + localTransform = + offsets.at(AZ::GetMin(offsets.size()-1, static_cast(1))) // parent bone offset, or if there is no parent, then current node offset + * inverseOffsets.at(inverseOffsets.size() - 1) // Inverse of root bone offset + * offsets.at(offsets.size() - 1) // Root bone offset + * inverseOffsets.at(0); // Inverse of current node offset } else { - finalMat = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(GetConcatenatedLocalTransform(currentNode)); + localTransform = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(GetConcatenatedLocalTransform(currentNode)); } - //DataTypes::MatrixType localTransform = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(combinedTransform); - DataTypes::MatrixType localTransform = finalMat; - + // Don't bother adding a node with the identity matrix if (localTransform == DataTypes::MatrixType::Identity()) { return Events::ProcessingResult::Ignored; From ff81b0bfd6eb54bb2e4420b1b709c4ed73bfe22b Mon Sep 17 00:00:00 2001 From: amzn-mike <80125227+amzn-mike@users.noreply.github.com> Date: Thu, 17 Jun 2021 10:40:33 -0500 Subject: [PATCH 7/9] Use contains method instead of find. Rename parentFillerAnimations -> fillerAnimations --- .../Importers/AssImpAnimationImporter.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp index 5bdc5a8add..ed6d7dfe30 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp @@ -461,7 +461,7 @@ namespace AZ } } - decltype(boneAnimations) parentFillerAnimations; + decltype(boneAnimations) fillerAnimations; // Go through all the animations and make sure we create placeholder animations for any bones missing them for (auto&& anim : boneAnimations) @@ -470,8 +470,8 @@ namespace AZ { if (!IsPivotNode(aiString(boneName.c_str()))) { - if (boneAnimations.find(boneName) == boneAnimations.end() && - parentFillerAnimations.find(boneName) == parentFillerAnimations.end()) + if (!boneAnimations.contains(boneName) && + !fillerAnimations.contains(boneName)) { // Create 1 key for each type that just copies the current transform ConsolidatedNodeAnim emptyAnimation; @@ -494,14 +494,14 @@ namespace AZ emptyAnimation.m_ownedScalingKeys.emplace_back(0, scale); emptyAnimation.mScalingKeys = emptyAnimation.m_ownedScalingKeys.data(); - parentFillerAnimations.insert( + fillerAnimations.insert( AZStd::make_pair(boneName, AZStd::make_pair(anim.second.first, AZStd::move(emptyAnimation)))); } } } } - boneAnimations.insert(AZStd::make_move_iterator(parentFillerAnimations.begin()), AZStd::make_move_iterator(parentFillerAnimations.end())); + boneAnimations.insert(AZStd::make_move_iterator(fillerAnimations.begin()), AZStd::make_move_iterator(fillerAnimations.end())); auto animItr = boneAnimations.equal_range(currentNode->mName.C_Str()); From d2d588901e42cddc0a473edc1ffd3aefa59f3db1 Mon Sep 17 00:00:00 2001 From: amzn-mike <80125227+amzn-mike@users.noreply.github.com> Date: Mon, 21 Jun 2021 11:00:27 -0500 Subject: [PATCH 8/9] Address PR feedback --- .../Importers/AssImpAnimationImporter.cpp | 34 +++++++++++-------- .../Importers/AssImpBoneImporter.cpp | 23 ++++++++----- .../Importers/AssImpBoneImporter.h | 1 + 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp index ed6d7dfe30..b81d013b87 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpAnimationImporter.cpp @@ -449,13 +449,13 @@ namespace AZ AZStd::unordered_set boneList; - for (int i = 0; i < scene->mNumMeshes; ++i) + for (int meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex) { - auto mesh = scene->mMeshes[i]; + aiMesh* mesh = scene->mMeshes[meshIndex]; - for (auto boneIndex = 0; boneIndex < mesh->mNumBones; ++boneIndex) + for (int boneIndex = 0; boneIndex < mesh->mNumBones; ++boneIndex) { - auto bone = mesh->mBones[boneIndex]; + aiBone* bone = mesh->mBones[boneIndex]; boneList.insert(bone->mName.C_Str()); } @@ -463,20 +463,22 @@ namespace AZ decltype(boneAnimations) fillerAnimations; - // Go through all the animations and make sure we create placeholder animations for any bones missing them + // Go through all the animations and make sure we create animations for bones who's parents don't have an animation for (auto&& anim : boneAnimations) { - for (auto boneName : boneList) + const aiNode* node = scene->mRootNode->FindNode(anim.first.c_str()); + const aiNode* parent = node->mParent; + + while (parent && parent != scene->mRootNode) { - if (!IsPivotNode(aiString(boneName.c_str()))) + if (!IsPivotNode(parent->mName)) { - if (!boneAnimations.contains(boneName) && - !fillerAnimations.contains(boneName)) + if (!boneAnimations.contains(parent->mName.C_Str()) && + !fillerAnimations.contains(parent->mName.C_Str())) { // Create 1 key for each type that just copies the current transform ConsolidatedNodeAnim emptyAnimation; - auto node = scene->mRootNode->FindNode(boneName.c_str()); - aiMatrix4x4 globalTransform = GetConcatenatedLocalTransform(node); + aiMatrix4x4 globalTransform = GetConcatenatedLocalTransform(parent); aiVector3D position, scale; aiQuaternion rotation; @@ -484,7 +486,7 @@ namespace AZ globalTransform.Decompose(scale, rotation, position); emptyAnimation.mNumRotationKeys = emptyAnimation.mNumPositionKeys = emptyAnimation.mNumScalingKeys = 1; - + emptyAnimation.m_ownedPositionKeys.emplace_back(0, position); emptyAnimation.mPositionKeys = emptyAnimation.m_ownedPositionKeys.data(); @@ -493,11 +495,13 @@ namespace AZ emptyAnimation.m_ownedScalingKeys.emplace_back(0, scale); emptyAnimation.mScalingKeys = emptyAnimation.m_ownedScalingKeys.data(); - - fillerAnimations.insert( - AZStd::make_pair(boneName, AZStd::make_pair(anim.second.first, AZStd::move(emptyAnimation)))); + + fillerAnimations.insert(AZStd::make_pair( + parent->mName.C_Str(), AZStd::make_pair(anim.second.first, AZStd::move(emptyAnimation)))); } } + + parent = parent->mParent; } } diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp index 648007ca47..1958c09b3c 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp @@ -98,6 +98,20 @@ namespace AZ } } + aiMatrix4x4 AssImpBoneImporter::CalculateWorldTransform(const aiNode* currentNode) + { + aiMatrix4x4 transform = {}; + const aiNode* iteratingNode = currentNode; + + while (iteratingNode) + { + transform = iteratingNode->mTransformation * transform; + iteratingNode = iteratingNode->mParent; + } + + return transform; + } + Events::ProcessingResult AssImpBoneImporter::ImportBone(AssImpNodeEncounteredContext& context) { AZ_TraceContext("Importer", "Bone"); @@ -166,14 +180,7 @@ namespace AZ createdBoneData = AZStd::make_shared(); } - aiMatrix4x4 transform{}; - const aiNode* iteratingNode = currentNode; - - while (iteratingNode) - { - transform = iteratingNode->mTransformation * transform; - iteratingNode = iteratingNode->mParent; - } + aiMatrix4x4 transform = CalculateWorldTransform(currentNode); SceneAPI::DataTypes::MatrixType globalTransform = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(transform); diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.h b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.h index bc4bdd474e..47cc1922cb 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.h +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.h @@ -32,6 +32,7 @@ namespace AZ static void Reflect(ReflectContext* context); + aiMatrix4x4 CalculateWorldTransform(const aiNode* currentNode); Events::ProcessingResult ImportBone(AssImpNodeEncounteredContext& context); }; } // namespace FbxSceneBuilder From 514cfc3b4c2bd2aae9704b6bfb71eb2b906ee1e9 Mon Sep 17 00:00:00 2001 From: amzn-mike <80125227+amzn-mike@users.noreply.github.com> Date: Mon, 21 Jun 2021 12:27:13 -0500 Subject: [PATCH 9/9] Fix compile error --- .../SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp | 2 +- .../SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.h | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp index 1958c09b3c..e726547c98 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.cpp @@ -98,7 +98,7 @@ namespace AZ } } - aiMatrix4x4 AssImpBoneImporter::CalculateWorldTransform(const aiNode* currentNode) + aiMatrix4x4 CalculateWorldTransform(const aiNode* currentNode) { aiMatrix4x4 transform = {}; const aiNode* iteratingNode = currentNode; diff --git a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.h b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.h index 47cc1922cb..86069cdd9e 100644 --- a/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.h +++ b/Code/Tools/SceneAPI/FbxSceneBuilder/Importers/AssImpBoneImporter.h @@ -31,8 +31,7 @@ namespace AZ ~AssImpBoneImporter() override = default; static void Reflect(ReflectContext* context); - - aiMatrix4x4 CalculateWorldTransform(const aiNode* currentNode); + Events::ProcessingResult ImportBone(AssImpNodeEncounteredContext& context); }; } // namespace FbxSceneBuilder