Fixed issues with blend shape animations (#3080)

Duplicate blend shape animations are now handled correctly.
Invalid animation targets are now an error instead of a crash in the builder.

Signed-off-by: stankowi <4838196+AMZN-stankowi@users.noreply.github.com>
This commit is contained in:
AMZN-stankowi
2021-08-16 10:18:45 -07:00
committed by GitHub
parent e2b4d8e502
commit b88a7faf64
3 changed files with 107 additions and 15 deletions
@@ -147,7 +147,9 @@ namespace AZ
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<AssImpAnimationImporter, SceneCore::LoadingComponent>()->Version(5); // [LYN-4226] Invert PostRotation matrix in animation chains
// Revision 5: [LYN-4226] Invert PostRotation matrix in animation chains
// Revision 6: Handle duplicate blend shape animations
serializeContext->Class<AssImpAnimationImporter, SceneCore::LoadingComponent>()->Version(6);
}
}
@@ -631,6 +633,15 @@ namespace AZ
for (const auto& [meshIdx, keys] : valueToKeyDataMap)
{
if (static_cast<AZ::u32>(meshIdx) >= mesh->mNumAnimMeshes)
{
AZ_Error(
"AnimationImporter", false,
"Mesh %s has an animation mesh index reference of %d, but only has %d animation meshes. Skipping importing this. This is an error in the source scene file that should be corrected.",
mesh->mName.C_Str(), meshIdx, mesh->mNumAnimMeshes);
continue;
}
AZStd::shared_ptr<SceneData::GraphData::BlendShapeAnimationData> morphAnimNode =
AZStd::make_shared<SceneData::GraphData::BlendShapeAnimationData>();
@@ -656,12 +667,29 @@ namespace AZ
morphAnimNode->AddKeyFrame(weight);
}
// Some DCC tools, like Maya, include a full path separated by '.' in the node names.
// For example, "cone_skin_blendShapeNode.cone_squash"
// Downstream processing doesn't want anything but the last part of that node name,
// so find the last '.' and remove anything before it.
const size_t dotIndex = nodeName.find_last_of('.');
nodeName = nodeName.substr(dotIndex + 1);
morphAnimNode->SetBlendShapeName(nodeName.data());
AZStd::string animNodeName(AZStd::string::format("%s_%s", s_animationNodeName, nodeName.data()));
// Duplicates can exist if an anim mesh had a name with a suffix like .001, in that case
// AssImp will strip off that suffix. Note that this behavior is separate from the
// scan for a period in the node name that came before this.
AZStd::string originalNodeName(AZStd::string::format("%s_%s", s_animationNodeName, nodeName.data()));
AZStd::string animNodeName(originalNodeName);
if (RenamedNodesMap::SanitizeNodeName(
animNodeName, context.m_scene.GetGraph(), context.m_currentGraphPosition, originalNodeName.c_str()))
{
AZ_Warning(
"AnimationImporter", false,
"Duplicate animations were found with the name %s on mesh %s. The duplicate will be named %s.",
originalNodeName.c_str(), mesh->mName.C_Str(), animNodeName.c_str());
}
Containers::SceneGraph::NodeIndex addNode = context.m_scene.GetGraph().AddChild(
context.m_currentGraphPosition, animNodeName.c_str(), AZStd::move(morphAnimNode));
context.m_scene.GetGraph().MakeEndPoint(addNode);