Fix blend shapes importing

#2672
This commit is contained in:
Wojtek Figat
2024-07-26 23:54:27 +02:00
parent e3bb38f13b
commit c4f37741b7
2 changed files with 35 additions and 33 deletions

View File

@@ -304,18 +304,15 @@ void MeshData::BuildIndexBuffer()
dstBlendShape.Name = srcBlendShape.Name; dstBlendShape.Name = srcBlendShape.Name;
dstBlendShape.Weight = srcBlendShape.Weight; dstBlendShape.Weight = srcBlendShape.Weight;
dstBlendShape.Vertices.Resize(newVertexCounter); dstBlendShape.Vertices.EnsureCapacity(srcBlendShape.Vertices.Count());
for (int32 i = 0, j = 0; i < srcBlendShape.Vertices.Count(); i++) for (int32 i = 0; i < srcBlendShape.Vertices.Count(); i++)
{ {
const auto idx = mapping[i]; auto& v = srcBlendShape.Vertices[i];
if (idx != INVALID_INDEX) int32 newVertexIndex = v.VertexIndex < (uint32)vertexCount ? mapping[v.VertexIndex] : INVALID_INDEX;
if (newVertexIndex != INVALID_INDEX)
{ {
auto& v = srcBlendShape.Vertices[i]; v.VertexIndex = newVertexIndex;
ASSERT_LOW_LAYER(v.VertexIndex < (uint32)vertexCount); dstBlendShape.Vertices.Add(v);
ASSERT_LOW_LAYER(mapping[v.VertexIndex] != INVALID_INDEX);
v.VertexIndex = mapping[v.VertexIndex];
ASSERT_LOW_LAYER(v.VertexIndex < (uint32)newVertexCounter);
dstBlendShape.Vertices[j++] = v;
} }
} }
} }

View File

@@ -915,44 +915,46 @@ bool ProcessMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh*
{ {
const ofbx::BlendShapeChannel* channel = blendShape->getBlendShapeChannel(channelIndex); const ofbx::BlendShapeChannel* channel = blendShape->getBlendShapeChannel(channelIndex);
// Use last shape // Use the last shape
const int targetShapeCount = channel->getShapeCount(); const int targetShapeCount = channel->getShapeCount();
if (targetShapeCount == 0) if (targetShapeCount == 0)
continue; continue;
const ofbx::Shape* shape = channel->getShape(targetShapeCount - 1); const ofbx::Shape* shape = channel->getShape(targetShapeCount - 1);
const ofbx::Vec3* shapeVertices = shape->getVertices();
if (shape->getVertexCount() != vertexCount) const ofbx::Vec3* shapeNormals = shape->getNormals();
const int* shapeIndices = shape->getIndices();
const int shapeVertexCount = shape->getVertexCount();
const int shapeIndexCount = shape->getIndexCount();
if (shapeVertexCount != shapeIndexCount)
{ {
LOG(Error, "Blend shape '{0}' in mesh '{1}' has different amount of vertices ({2}) than mesh ({3})", String(shape->name), mesh.Name, shape->getVertexCount(), vertexCount); LOG(Error, "Blend shape '{0}' in mesh '{1}' has different amount of vertices ({2}) and indices ({3})", String(shape->name), mesh.Name, shapeVertexCount, shapeIndexCount);
continue; continue;
} }
BlendShape& blendShapeData = mesh.BlendShapes.AddOne(); BlendShape& blendShapeData = mesh.BlendShapes.AddOne();
blendShapeData.Name = shape->name; blendShapeData.Name = shape->name;
blendShapeData.Weight = channel->getShapeCount() > 1 ? (float)(channel->getDeformPercent() / 100.0) : 1.0f; blendShapeData.Weight = channel->getShapeCount() > 1 ? (float)(channel->getDeformPercent() / 100.0) : 1.0f;
blendShapeData.Vertices.EnsureCapacity(shapeIndexCount);
blendShapeData.Vertices.Resize(vertexCount); for (int32 i = 0; i < shapeIndexCount; i++)
for (int32 i = 0; i < blendShapeData.Vertices.Count(); i++)
blendShapeData.Vertices.Get()[i].VertexIndex = i;
auto shapeVertices = shape->getVertices();
for (int32 i = 0; i < blendShapeData.Vertices.Count(); i++)
{ {
auto delta = ToFloat3(shapeVertices[i]) - mesh.Positions.Get()[i]; int shapeIndex = shapeIndices[i];
blendShapeData.Vertices.Get()[i].PositionDelta = delta; Float3 positionDelta = ToFloat3(shapeVertices[i]);
} Float3 normalDelta = shapeNormals ? ToFloat3(shapeNormals[i]) : Float3::Zero;
for (int32 vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++)
auto shapeNormals = shape->getNormals();
for (int32 i = 0; i < blendShapeData.Vertices.Count(); i++)
{
auto delta = ToFloat3(shapeNormals[i]);
if (data.ConvertRH)
{ {
// Mirror normals along the Z axis int sourceIndex = triangulatedIndices[vertexIndex];
delta.Z *= -1.0f; sourceIndex = positions.indices[sourceIndex];
if (sourceIndex == shapeIndex)
{
// Add blend shape vertex
BlendShapeVertex v;
v.VertexIndex = vertexIndex;
v.PositionDelta = positionDelta;
v.NormalDelta = normalDelta;
blendShapeData.Vertices.Add(v);
}
} }
delta = delta - mesh.Normals.Get()[i];
blendShapeData.Vertices.Get()[i].NormalDelta = delta;
} }
} }
} }
@@ -965,7 +967,10 @@ bool ProcessMesh(ModelData& result, OpenFbxImporterData& data, const ofbx::Mesh*
for (auto& blendShapeData : mesh.BlendShapes) for (auto& blendShapeData : mesh.BlendShapes)
{ {
for (auto& v : blendShapeData.Vertices) for (auto& v : blendShapeData.Vertices)
{
v.PositionDelta.Z *= -1.0f; v.PositionDelta.Z *= -1.0f;
v.NormalDelta.Z *= -1.0f;
}
} }
} }