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:
+4
-12
@@ -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});
|
||||
|
||||
+1
-3
@@ -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);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user