From 9bbcc7ec6823b0bc4cf594b692ce77789cc54b3d Mon Sep 17 00:00:00 2001 From: Benjamin Jillich <43751992+amzn-jillich@users.noreply.github.com> Date: Fri, 23 Apr 2021 19:11:43 +0200 Subject: [PATCH] [LYN-3252] EMotion FX: Morph target buffer only found on first Atom mesh (#280) We were using the first Atom mesh to check for morph target buffers by getting access to the buffer asset from the buffer asset view. This won't work for models with multiple meshes while the first mesh is not morphed. --- Gems/EMotionFX/Code/EMotionFX/Source/Actor.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Actor.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Actor.cpp index 2b99f823ff..aea4668c50 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Actor.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Actor.cpp @@ -3012,17 +3012,22 @@ namespace EMotionFX jointInfo.mStack->InsertDeformer(/*deformerPosition=*/0, morphTargetDeformer); } - // The lod has shared buffers that combine the data from each submesh. These buffers can be accessed through the first submesh in their entirety - const AZ::RPI::ModelLodAsset::Mesh& sourceMesh = sourceMeshes[0]; + // The lod has shared buffers that combine the data from each submesh. In case any of the submeshes has a + // morph target buffer view we can access the entire morph target buffer via the buffer asset. AZStd::array_view morphTargetDeltaView; - if (const auto* bufferAssetView = sourceMesh.GetSemanticBufferAssetView(AZ::Name("MORPHTARGET_VERTEXDELTAS"))) + for (const AZ::RPI::ModelLodAsset::Mesh& sourceMesh : sourceMeshes) { - if (const auto* bufferAsset = bufferAssetView->GetBufferAsset().Get()) + if (const auto* bufferAssetView = sourceMesh.GetSemanticBufferAssetView(AZ::Name("MORPHTARGET_VERTEXDELTAS"))) { - // The buffer of the view is the buffer of the whole LOD, not just the source mesh. - morphTargetDeltaView = bufferAsset->GetBuffer(); + if (const auto* bufferAsset = bufferAssetView->GetBufferAsset().Get()) + { + // The buffer of the view is the buffer of the whole LOD, not just the source mesh. + morphTargetDeltaView = bufferAsset->GetBuffer(); + break; + } } } + AZ_Assert(morphTargetDeltaView.data(), "Unable to find MORPHTARGET_VERTEXDELTAS buffer"); const AZ::RPI::PackedCompressedMorphTargetDelta* vertexDeltas = reinterpret_cast(morphTargetDeltaView.data());