mirror of
https://github.com/aelurum/AssetStudio.git
synced 2025-05-25 05:40:21 -04:00
Fix blend shape export with multiple submeshes
Share a single vertex list between submeshes in the exported mesh, which makes the blend target vertex list indices line up correctly. As a bonus, the exported FBX file will be smaller for meshes with more than one submesh, since we're not duplicating vertices anymore.
This commit is contained in:
parent
ab98585b6a
commit
08b7bfcf9a
@ -132,6 +132,7 @@ namespace AssetStudio
|
||||
public class ImportedMesh
|
||||
{
|
||||
public string Path { get; set; }
|
||||
public List<ImportedVertex> VertexList { get; set; }
|
||||
public List<ImportedSubmesh> SubmeshList { get; set; }
|
||||
public List<ImportedBone> BoneList { get; set; }
|
||||
public bool hasNormal { get; set; }
|
||||
@ -142,9 +143,9 @@ namespace AssetStudio
|
||||
|
||||
public class ImportedSubmesh
|
||||
{
|
||||
public List<ImportedVertex> VertexList { get; set; }
|
||||
public List<ImportedFace> FaceList { get; set; }
|
||||
public string Material { get; set; }
|
||||
public int BaseVertex { get; set; }
|
||||
}
|
||||
|
||||
public class ImportedVertex
|
||||
|
@ -246,14 +246,7 @@ namespace AssetStudio.FbxInterop
|
||||
|
||||
var mesh = AsFbxMeshCreateMesh(_pContext, frameNode);
|
||||
|
||||
var totalVertexCount = 0;
|
||||
|
||||
foreach (var m in importedMesh.SubmeshList)
|
||||
{
|
||||
totalVertexCount += m.VertexList.Count;
|
||||
}
|
||||
|
||||
AsFbxMeshInitControlPoints(mesh, totalVertexCount);
|
||||
AsFbxMeshInitControlPoints(mesh, importedMesh.VertexList.Count);
|
||||
|
||||
if (importedMesh.hasNormal)
|
||||
{
|
||||
@ -282,8 +275,6 @@ namespace AssetStudio.FbxInterop
|
||||
|
||||
AsFbxMeshCreateElementMaterial(mesh);
|
||||
|
||||
var firstVertex = 0;
|
||||
|
||||
foreach (var meshObj in importedMesh.SubmeshList)
|
||||
{
|
||||
var materialIndex = 0;
|
||||
@ -345,7 +336,17 @@ namespace AssetStudio.FbxInterop
|
||||
}
|
||||
}
|
||||
|
||||
var vertexList = meshObj.VertexList;
|
||||
foreach (var face in meshObj.FaceList)
|
||||
{
|
||||
var index0 = face.VertexIndices[0] + meshObj.BaseVertex;
|
||||
var index1 = face.VertexIndices[1] + meshObj.BaseVertex;
|
||||
var index2 = face.VertexIndices[2] + meshObj.BaseVertex;
|
||||
|
||||
AsFbxMeshAddPolygon(mesh, materialIndex, index0, index1, index2);
|
||||
}
|
||||
}
|
||||
|
||||
var vertexList = importedMesh.VertexList;
|
||||
|
||||
var vertexCount = vertexList.Count;
|
||||
|
||||
@ -354,7 +355,7 @@ namespace AssetStudio.FbxInterop
|
||||
var importedVertex = vertexList[j];
|
||||
|
||||
var vertex = importedVertex.Vertex;
|
||||
AsFbxMeshSetControlPoint(mesh, j + firstVertex, vertex.X, vertex.Y, vertex.Z);
|
||||
AsFbxMeshSetControlPoint(mesh, j, vertex.X, vertex.Y, vertex.Z);
|
||||
|
||||
if (importedMesh.hasNormal)
|
||||
{
|
||||
@ -392,23 +393,12 @@ namespace AssetStudio.FbxInterop
|
||||
{
|
||||
if (boneIndices[k] < totalBoneCount && boneWeights[k] > 0)
|
||||
{
|
||||
AsFbxMeshSetBoneWeight(pClusterArray, boneIndices[k], j + firstVertex, boneWeights[k]);
|
||||
AsFbxMeshSetBoneWeight(pClusterArray, boneIndices[k], j, boneWeights[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var face in meshObj.FaceList)
|
||||
{
|
||||
var index0 = face.VertexIndices[0] + firstVertex;
|
||||
var index1 = face.VertexIndices[1] + firstVertex;
|
||||
var index2 = face.VertexIndices[2] + firstVertex;
|
||||
|
||||
AsFbxMeshAddPolygon(mesh, materialIndex, index0, index1, index2);
|
||||
}
|
||||
|
||||
firstVertex += vertexCount;
|
||||
}
|
||||
|
||||
if (hasBones)
|
||||
{
|
||||
|
@ -319,8 +319,28 @@ namespace AssetStudio
|
||||
}
|
||||
ImportedMaterial iMat = ConvertMaterial(mat);
|
||||
iSubmesh.Material = iMat.Name;
|
||||
iSubmesh.VertexList = new List<ImportedVertex>((int)submesh.vertexCount);
|
||||
for (var j = mesh.m_SubMeshes[i].firstVertex; j < mesh.m_SubMeshes[i].firstVertex + mesh.m_SubMeshes[i].vertexCount; j++)
|
||||
iSubmesh.BaseVertex = (int) mesh.m_SubMeshes[i].firstVertex;
|
||||
|
||||
//Face
|
||||
iSubmesh.FaceList = new List<ImportedFace>(numFaces);
|
||||
var end = firstFace + numFaces;
|
||||
for (int f = firstFace; f < end; f++)
|
||||
{
|
||||
var face = new ImportedFace();
|
||||
face.VertexIndices = new int[3];
|
||||
face.VertexIndices[0] = (int)(mesh.m_Indices[f * 3 + 2] - submesh.firstVertex);
|
||||
face.VertexIndices[1] = (int)(mesh.m_Indices[f * 3 + 1] - submesh.firstVertex);
|
||||
face.VertexIndices[2] = (int)(mesh.m_Indices[f * 3] - submesh.firstVertex);
|
||||
iSubmesh.FaceList.Add(face);
|
||||
}
|
||||
firstFace = end;
|
||||
|
||||
iMesh.SubmeshList.Add(iSubmesh);
|
||||
}
|
||||
|
||||
// Shared vertex list
|
||||
iMesh.VertexList = new List<ImportedVertex>((int)mesh.m_VertexCount);
|
||||
for (var j = 0; j < mesh.m_VertexCount; j++)
|
||||
{
|
||||
var iVertex = new ImportedVertex();
|
||||
//Vertices
|
||||
@ -390,22 +410,7 @@ namespace AssetStudio
|
||||
iVertex.Weights[k] = inf.weight[k];
|
||||
}
|
||||
}
|
||||
iSubmesh.VertexList.Add(iVertex);
|
||||
}
|
||||
//Face
|
||||
iSubmesh.FaceList = new List<ImportedFace>(numFaces);
|
||||
var end = firstFace + numFaces;
|
||||
for (int f = firstFace; f < end; f++)
|
||||
{
|
||||
var face = new ImportedFace();
|
||||
face.VertexIndices = new int[3];
|
||||
face.VertexIndices[0] = (int)(mesh.m_Indices[f * 3 + 2] - submesh.firstVertex);
|
||||
face.VertexIndices[1] = (int)(mesh.m_Indices[f * 3 + 1] - submesh.firstVertex);
|
||||
face.VertexIndices[2] = (int)(mesh.m_Indices[f * 3] - submesh.firstVertex);
|
||||
iSubmesh.FaceList.Add(face);
|
||||
}
|
||||
firstFace = end;
|
||||
iMesh.SubmeshList.Add(iSubmesh);
|
||||
iMesh.VertexList.Add(iVertex);
|
||||
}
|
||||
|
||||
if (meshR is SkinnedMeshRenderer sMesh)
|
||||
@ -524,7 +529,7 @@ namespace AssetStudio
|
||||
keyframe.VertexList.Add(destVertex);
|
||||
var morphVertex = mesh.m_Shapes.vertices[j];
|
||||
destVertex.Index = morphVertex.index;
|
||||
var sourceVertex = GetSourceVertex(iMesh.SubmeshList, (int)morphVertex.index);
|
||||
var sourceVertex = iMesh.VertexList[(int)morphVertex.index];
|
||||
destVertex.Vertex = new ImportedVertex();
|
||||
var morphPos = morphVertex.vertex;
|
||||
destVertex.Vertex.Vertex = sourceVertex.Vertex + new Vector3(-morphPos.X, morphPos.Y, morphPos.Z);
|
||||
@ -1014,20 +1019,6 @@ namespace AssetStudio
|
||||
return boneName;
|
||||
}
|
||||
|
||||
private static ImportedVertex GetSourceVertex(List<ImportedSubmesh> submeshList, int morphVertIndex)
|
||||
{
|
||||
foreach (var submesh in submeshList)
|
||||
{
|
||||
var vertList = submesh.VertexList;
|
||||
if (morphVertIndex < vertList.Count)
|
||||
{
|
||||
return vertList[morphVertIndex];
|
||||
}
|
||||
morphVertIndex -= vertList.Count;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void CreateBonePathHash(Transform m_Transform)
|
||||
{
|
||||
var name = GetTransformPathByFather(m_Transform);
|
||||
|
Loading…
Reference in New Issue
Block a user