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.
This commit is contained in:
Chris Burel
2021-05-03 15:43:42 -07:00
committed by GitHub
parent fe0b768d03
commit 7f81602fe7
2 changed files with 5 additions and 15 deletions
@@ -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<IBlendShapeData>(childNodes(nodeIndex))))
{
const IBlendShapeData* blendShapeNode = static_cast<IBlendShapeData*>(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<AZ::SceneAPI::DataTypes::ISkinWeightData>
> MeshOptimizerComponent::OptimizeMesh(
const MeshDataType* meshData,
const IMeshData* baseMesh,
const AZStd::vector<AZStd::reference_wrapper<const IMeshVertexUVData>>& uvs,
const AZStd::vector<AZStd::reference_wrapper<const IMeshVertexTangentData>>& tangents,
const AZStd::vector<AZStd::reference_wrapper<const IMeshVertexBitangentData>>& 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});
@@ -66,6 +66,7 @@ namespace AZ::SceneGenerationComponents
AZStd::unique_ptr<AZ::SceneAPI::DataTypes::ISkinWeightData>
> OptimizeMesh(
const MeshDataType* meshData,
const SceneAPI::DataTypes::IMeshData* baseMesh,
const AZStd::vector<AZStd::reference_wrapper<const AZ::SceneAPI::DataTypes::IMeshVertexUVData>>& uvs,
const AZStd::vector<AZStd::reference_wrapper<const AZ::SceneAPI::DataTypes::IMeshVertexTangentData>>& tangents,
const AZStd::vector<AZStd::reference_wrapper<const AZ::SceneAPI::DataTypes::IMeshVertexBitangentData>>& 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);
};