From 7f81602fe7189cc2f84ae73750eaf0eaeae656c2 Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Mon, 3 May 2021 15:43:42 -0700 Subject: [PATCH] Use the material id from the base mesh when optimizing blend shapes (#517) This is cherry-picked from #311 When processing meshes with blend shapes, the mesh optimizer disables the optimize duplicates setting, to prevent potential vertex reodering that could cause the base mesh vertices to become out of sync with the blend shape. However, it will still reorder vertices based on their material. It places all triangles that use the same material in the same submesh, grouping them together in the resulting mesh. The SceneAPI does not track material ids for blend shapes. To ensure that the blend shape triangles are reordered in the same way as the base shape, this change makes the blend shape optimization use the material id from the base shape. --- .../MeshOptimizer/MeshOptimizerComponent.cpp | 16 ++++------------ .../MeshOptimizer/MeshOptimizerComponent.h | 4 +--- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp b/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp index 8be67fe89b..592a8e2a75 100644 --- a/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp +++ b/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp @@ -290,7 +290,7 @@ namespace AZ::SceneGenerationComponents const bool hasBlendShapes = HasAnyBlendShapeChild(graph, nodeIndex); - auto [optimizedMesh, optimizedUVs, optimizedTangents, optimizedBitangents, optimizedVertexColors, optimizedSkinWeights] = OptimizeMesh(mesh, uvDatas, tangentDatas, bitangentDatas, colorDatas, skinWeightDatas, meshGroup, hasBlendShapes); + auto [optimizedMesh, optimizedUVs, optimizedTangents, optimizedBitangents, optimizedVertexColors, optimizedSkinWeights] = OptimizeMesh(mesh, mesh, uvDatas, tangentDatas, bitangentDatas, colorDatas, skinWeightDatas, meshGroup, hasBlendShapes); const NodeIndex optimizedMeshNodeIndex = graph.AddChild(graph.GetNodeParent(nodeIndex), name.c_str(), AZStd::move(optimizedMesh)); @@ -322,7 +322,7 @@ namespace AZ::SceneGenerationComponents for (const NodeIndex& blendShapeNodeIndex : nodeIndexes(Containers::MakeDerivedFilterView(childNodes(nodeIndex)))) { const IBlendShapeData* blendShapeNode = static_cast(graph.GetNodeContent(blendShapeNodeIndex).get()); - auto [optimizedBlendShape, _1, _2, _3 , _4, _5] = OptimizeMesh(blendShapeNode, {}, {}, {}, {}, {}, meshGroup, hasBlendShapes); + auto [optimizedBlendShape, _1, _2, _3 , _4, _5] = OptimizeMesh(blendShapeNode, mesh, {}, {}, {}, {}, {}, meshGroup, hasBlendShapes); const AZStd::string optimizedName {graph.GetNodeName(blendShapeNodeIndex).GetName(), graph.GetNodeName(blendShapeNodeIndex).GetNameLength()}; const NodeIndex optimizedNodeIndex = graph.AddChild(optimizedMeshNodeIndex, optimizedName.c_str(), AZStd::move(optimizedBlendShape)); @@ -383,6 +383,7 @@ namespace AZ::SceneGenerationComponents AZStd::unique_ptr > MeshOptimizerComponent::OptimizeMesh( const MeshDataType* meshData, + const IMeshData* baseMesh, const AZStd::vector>& uvs, const AZStd::vector>& tangents, const AZStd::vector>& bitangents, @@ -441,7 +442,7 @@ namespace AZ::SceneGenerationComponents const AZ::u32 faceCount = meshData->GetFaceCount(); for (AZ::u32 faceIndex = 0; faceIndex < faceCount; ++faceIndex) { - meshBuilder.BeginPolygon(GetFaceMaterialId(meshData, faceIndex)); + meshBuilder.BeginPolygon(baseMesh->GetFaceMaterialId(faceIndex)); for (const AZ::u32 vertexIndex : meshData->GetFaceInfo(faceIndex).vertexIndex) { const int orgVertexNumber = meshData->GetUsedPointIndexForControlPoint(meshData->GetControlPointIndex(vertexIndex)); @@ -584,15 +585,6 @@ namespace AZ::SceneGenerationComponents ); } - unsigned int MeshOptimizerComponent::GetFaceMaterialId([[maybe_unused]] const AZ::SceneAPI::DataTypes::IBlendShapeData* meshData, [[maybe_unused]] unsigned int index) - { - return 0; - } - unsigned int MeshOptimizerComponent::GetFaceMaterialId(const AZ::SceneAPI::DataTypes::IMeshData* meshData, unsigned int index) - { - return meshData->GetFaceMaterialId(index); - } - void MeshOptimizerComponent::AddFace(AZ::SceneData::GraphData::BlendShapeData* blendShape, unsigned int index1, unsigned int index2, unsigned int index3, [[maybe_unused]] unsigned int faceMaterialId) { blendShape->AddFace({index1, index2, index3}); diff --git a/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.h b/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.h index ee8fa5afe5..e499f30e2e 100644 --- a/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.h +++ b/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.h @@ -66,6 +66,7 @@ namespace AZ::SceneGenerationComponents AZStd::unique_ptr > OptimizeMesh( const MeshDataType* meshData, + const SceneAPI::DataTypes::IMeshData* baseMesh, const AZStd::vector>& uvs, const AZStd::vector>& tangents, const AZStd::vector>& bitangents, @@ -74,9 +75,6 @@ namespace AZ::SceneGenerationComponents const AZ::SceneAPI::DataTypes::IMeshGroup& meshGroup, bool hasBlendShapes); - static unsigned int GetFaceMaterialId(const AZ::SceneAPI::DataTypes::IBlendShapeData* meshData, unsigned int index); - static unsigned int GetFaceMaterialId(const AZ::SceneAPI::DataTypes::IMeshData* meshData, unsigned int index); - static void AddFace(AZ::SceneData::GraphData::BlendShapeData* blendShape, unsigned int index1, unsigned int index2, unsigned int index3, unsigned int faceMaterialId); static void AddFace(AZ::SceneData::GraphData::MeshData* mesh, unsigned int index1, unsigned int index2, unsigned int index3, unsigned int faceMaterialId); };