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 class ImportedMesh
|
||||||
{
|
{
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
|
public List<ImportedVertex> VertexList { get; set; }
|
||||||
public List<ImportedSubmesh> SubmeshList { get; set; }
|
public List<ImportedSubmesh> SubmeshList { get; set; }
|
||||||
public List<ImportedBone> BoneList { get; set; }
|
public List<ImportedBone> BoneList { get; set; }
|
||||||
public bool hasNormal { get; set; }
|
public bool hasNormal { get; set; }
|
||||||
@ -142,9 +143,9 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public class ImportedSubmesh
|
public class ImportedSubmesh
|
||||||
{
|
{
|
||||||
public List<ImportedVertex> VertexList { get; set; }
|
|
||||||
public List<ImportedFace> FaceList { get; set; }
|
public List<ImportedFace> FaceList { get; set; }
|
||||||
public string Material { get; set; }
|
public string Material { get; set; }
|
||||||
|
public int BaseVertex { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ImportedVertex
|
public class ImportedVertex
|
||||||
|
@ -246,14 +246,7 @@ namespace AssetStudio.FbxInterop
|
|||||||
|
|
||||||
var mesh = AsFbxMeshCreateMesh(_pContext, frameNode);
|
var mesh = AsFbxMeshCreateMesh(_pContext, frameNode);
|
||||||
|
|
||||||
var totalVertexCount = 0;
|
AsFbxMeshInitControlPoints(mesh, importedMesh.VertexList.Count);
|
||||||
|
|
||||||
foreach (var m in importedMesh.SubmeshList)
|
|
||||||
{
|
|
||||||
totalVertexCount += m.VertexList.Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
AsFbxMeshInitControlPoints(mesh, totalVertexCount);
|
|
||||||
|
|
||||||
if (importedMesh.hasNormal)
|
if (importedMesh.hasNormal)
|
||||||
{
|
{
|
||||||
@ -282,8 +275,6 @@ namespace AssetStudio.FbxInterop
|
|||||||
|
|
||||||
AsFbxMeshCreateElementMaterial(mesh);
|
AsFbxMeshCreateElementMaterial(mesh);
|
||||||
|
|
||||||
var firstVertex = 0;
|
|
||||||
|
|
||||||
foreach (var meshObj in importedMesh.SubmeshList)
|
foreach (var meshObj in importedMesh.SubmeshList)
|
||||||
{
|
{
|
||||||
var materialIndex = 0;
|
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;
|
var vertexCount = vertexList.Count;
|
||||||
|
|
||||||
@ -354,7 +355,7 @@ namespace AssetStudio.FbxInterop
|
|||||||
var importedVertex = vertexList[j];
|
var importedVertex = vertexList[j];
|
||||||
|
|
||||||
var vertex = importedVertex.Vertex;
|
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)
|
if (importedMesh.hasNormal)
|
||||||
{
|
{
|
||||||
@ -392,23 +393,12 @@ namespace AssetStudio.FbxInterop
|
|||||||
{
|
{
|
||||||
if (boneIndices[k] < totalBoneCount && boneWeights[k] > 0)
|
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)
|
if (hasBones)
|
||||||
{
|
{
|
||||||
|
@ -319,8 +319,28 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
ImportedMaterial iMat = ConvertMaterial(mat);
|
ImportedMaterial iMat = ConvertMaterial(mat);
|
||||||
iSubmesh.Material = iMat.Name;
|
iSubmesh.Material = iMat.Name;
|
||||||
iSubmesh.VertexList = new List<ImportedVertex>((int)submesh.vertexCount);
|
iSubmesh.BaseVertex = (int) mesh.m_SubMeshes[i].firstVertex;
|
||||||
for (var j = mesh.m_SubMeshes[i].firstVertex; j < mesh.m_SubMeshes[i].firstVertex + mesh.m_SubMeshes[i].vertexCount; j++)
|
|
||||||
|
//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();
|
var iVertex = new ImportedVertex();
|
||||||
//Vertices
|
//Vertices
|
||||||
@ -390,22 +410,7 @@ namespace AssetStudio
|
|||||||
iVertex.Weights[k] = inf.weight[k];
|
iVertex.Weights[k] = inf.weight[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
iSubmesh.VertexList.Add(iVertex);
|
iMesh.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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (meshR is SkinnedMeshRenderer sMesh)
|
if (meshR is SkinnedMeshRenderer sMesh)
|
||||||
@ -524,7 +529,7 @@ namespace AssetStudio
|
|||||||
keyframe.VertexList.Add(destVertex);
|
keyframe.VertexList.Add(destVertex);
|
||||||
var morphVertex = mesh.m_Shapes.vertices[j];
|
var morphVertex = mesh.m_Shapes.vertices[j];
|
||||||
destVertex.Index = morphVertex.index;
|
destVertex.Index = morphVertex.index;
|
||||||
var sourceVertex = GetSourceVertex(iMesh.SubmeshList, (int)morphVertex.index);
|
var sourceVertex = iMesh.VertexList[(int)morphVertex.index];
|
||||||
destVertex.Vertex = new ImportedVertex();
|
destVertex.Vertex = new ImportedVertex();
|
||||||
var morphPos = morphVertex.vertex;
|
var morphPos = morphVertex.vertex;
|
||||||
destVertex.Vertex.Vertex = sourceVertex.Vertex + new Vector3(-morphPos.X, morphPos.Y, morphPos.Z);
|
destVertex.Vertex.Vertex = sourceVertex.Vertex + new Vector3(-morphPos.X, morphPos.Y, morphPos.Z);
|
||||||
@ -1014,20 +1019,6 @@ namespace AssetStudio
|
|||||||
return boneName;
|
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)
|
private void CreateBonePathHash(Transform m_Transform)
|
||||||
{
|
{
|
||||||
var name = GetTransformPathByFather(m_Transform);
|
var name = GetTransformPathByFather(m_Transform);
|
||||||
|
Loading…
Reference in New Issue
Block a user