mirror of
https://github.com/aelurum/AssetStudio.git
synced 2025-05-26 13:50:21 -04:00
improved bone export
This commit is contained in:
parent
e62b6c3d77
commit
de54257eef
@ -333,33 +333,31 @@ namespace AssetStudio
|
|||||||
hasBones = false;
|
hasBones = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FbxArray<FbxNode*>* pBoneNodeList = nullptr;
|
|
||||||
FbxArray<FbxCluster*>* pClusterArray = nullptr;
|
FbxArray<FbxCluster*>* pClusterArray = nullptr;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (hasBones)
|
if (hasBones)
|
||||||
{
|
{
|
||||||
pBoneNodeList = new FbxArray<FbxNode*>();
|
pClusterArray = new FbxArray<FbxCluster*>(boneList->Count);
|
||||||
pBoneNodeList->Reserve(boneList->Count);
|
|
||||||
for (int i = 0; i < boneList->Count; i++)
|
for (int i = 0; i < boneList->Count; i++)
|
||||||
{
|
{
|
||||||
auto bone = boneList[i];
|
auto bone = boneList[i];
|
||||||
auto frame = imported->RootFrame->FindFrameByPath(bone->Path);
|
if (bone->Path != nullptr)
|
||||||
auto frameNode = (FbxNode*)frameToNode[frame];
|
{
|
||||||
pBoneNodeList->Add(frameNode);
|
auto frame = imported->RootFrame->FindFrameByPath(bone->Path);
|
||||||
}
|
auto boneNode = (FbxNode*)frameToNode[frame];
|
||||||
|
FbxString lClusterName = boneNode->GetNameOnly() + FbxString("Cluster");
|
||||||
pClusterArray = new FbxArray<FbxCluster*>();
|
FbxCluster* pCluster = FbxCluster::Create(pScene, lClusterName.Buffer());
|
||||||
pClusterArray->Reserve(boneList->Count);
|
pCluster->SetLink(boneNode);
|
||||||
for (int i = 0; i < boneList->Count; i++)
|
pCluster->SetLinkMode(FbxCluster::eTotalOne);
|
||||||
{
|
pClusterArray->Add(pCluster);
|
||||||
FbxNode* pNode = pBoneNodeList->GetAt(i);
|
}
|
||||||
FbxString lClusterName = pNode->GetNameOnly() + FbxString("Cluster");
|
else
|
||||||
FbxCluster* pCluster = FbxCluster::Create(pScene, lClusterName.Buffer());
|
{
|
||||||
pCluster->SetLink(pNode);
|
pClusterArray->Add(NULL);
|
||||||
pCluster->SetLinkMode(FbxCluster::eTotalOne);
|
}
|
||||||
pClusterArray->Add(pCluster);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -532,7 +530,10 @@ namespace AssetStudio
|
|||||||
if (boneIndices[k] < boneList->Count && weights4[k] > 0)
|
if (boneIndices[k] < boneList->Count && weights4[k] > 0)
|
||||||
{
|
{
|
||||||
FbxCluster* pCluster = pClusterArray->GetAt(boneIndices[k]);
|
FbxCluster* pCluster = pClusterArray->GetAt(boneIndices[k]);
|
||||||
pCluster->AddControlPointIndex(j + firstVertex, weights4[k]);
|
if (pCluster)
|
||||||
|
{
|
||||||
|
pCluster->AddControlPointIndex(j + firstVertex, weights4[k]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -558,20 +559,23 @@ namespace AssetStudio
|
|||||||
for (int j = 0; j < boneList->Count; j++)
|
for (int j = 0; j < boneList->Count; j++)
|
||||||
{
|
{
|
||||||
FbxCluster* pCluster = pClusterArray->GetAt(j);
|
FbxCluster* pCluster = pClusterArray->GetAt(j);
|
||||||
auto boneMatrix = boneList[j]->Matrix;
|
if (pCluster)
|
||||||
FbxAMatrix lBoneMatrix;
|
|
||||||
for (int m = 0; m < 4; m++)
|
|
||||||
{
|
{
|
||||||
for (int n = 0; n < 4; n++)
|
auto boneMatrix = boneList[j]->Matrix;
|
||||||
|
FbxAMatrix lBoneMatrix;
|
||||||
|
for (int m = 0; m < 4; m++)
|
||||||
{
|
{
|
||||||
lBoneMatrix.mData[m][n] = boneMatrix[m, n];
|
for (int n = 0; n < 4; n++)
|
||||||
|
{
|
||||||
|
lBoneMatrix.mData[m][n] = boneMatrix[m, n];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pCluster->SetTransformMatrix(lMeshMatrix);
|
||||||
|
pCluster->SetTransformLinkMatrix(lMeshMatrix * lBoneMatrix.Inverse());
|
||||||
|
|
||||||
|
pSkin->AddCluster(pCluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
pCluster->SetTransformMatrix(lMeshMatrix);
|
|
||||||
pCluster->SetTransformLinkMatrix(lMeshMatrix * lBoneMatrix.Inverse());
|
|
||||||
|
|
||||||
pSkin->AddCluster(pCluster);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pSkin->GetClusterCount() > 0)
|
if (pSkin->GetClusterCount() > 0)
|
||||||
@ -582,10 +586,6 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (pBoneNodeList != NULL)
|
|
||||||
{
|
|
||||||
delete pBoneNodeList;
|
|
||||||
}
|
|
||||||
if (pClusterArray != NULL)
|
if (pClusterArray != NULL)
|
||||||
{
|
{
|
||||||
delete pClusterArray;
|
delete pClusterArray;
|
||||||
|
@ -392,44 +392,78 @@ namespace AssetStudio
|
|||||||
if (meshR is SkinnedMeshRenderer sMesh)
|
if (meshR is SkinnedMeshRenderer sMesh)
|
||||||
{
|
{
|
||||||
//Bone
|
//Bone
|
||||||
|
/*
|
||||||
|
* 0 - None
|
||||||
|
* 1 - m_Bones
|
||||||
|
* 2 - m_BoneNameHashes
|
||||||
|
*/
|
||||||
|
var boneType = 0;
|
||||||
if (sMesh.m_Bones.Length > 0)
|
if (sMesh.m_Bones.Length > 0)
|
||||||
{
|
{
|
||||||
var boneMax = Math.Min(sMesh.m_Bones.Length, mesh.m_BindPose.Length);
|
if (sMesh.m_Bones.Length == mesh.m_BindPose.Length)
|
||||||
iMesh.BoneList = new List<ImportedBone>(boneMax);
|
{
|
||||||
for (int i = 0; i < boneMax; i++)
|
var verifiedBoneCount = sMesh.m_Bones.Count(x => x.TryGet(out _));
|
||||||
|
if (verifiedBoneCount > 0)
|
||||||
|
{
|
||||||
|
boneType = 1;
|
||||||
|
}
|
||||||
|
if (verifiedBoneCount != sMesh.m_Bones.Length)
|
||||||
|
{
|
||||||
|
//尝试使用m_BoneNameHashes 4.3 and up
|
||||||
|
if (mesh.m_BindPose.Length > 0 && (mesh.m_BindPose.Length == mesh.m_BoneNameHashes?.Length))
|
||||||
|
{
|
||||||
|
//有效bone数量是否大于SkinnedMeshRenderer
|
||||||
|
var verifiedBoneCount2 = mesh.m_BoneNameHashes.Count(x => FixBonePath(GetPathFromHash(x)) != null);
|
||||||
|
if (verifiedBoneCount2 > verifiedBoneCount)
|
||||||
|
{
|
||||||
|
boneType = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Logger.Error("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//尝试使用m_BoneNameHashes 4.3 and up
|
||||||
|
if (mesh.m_BindPose.Length > 0 && (mesh.m_BindPose.Length == mesh.m_BoneNameHashes?.Length))
|
||||||
|
{
|
||||||
|
boneType = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (boneType == 1)
|
||||||
|
{
|
||||||
|
var boneCount = sMesh.m_Bones.Length;
|
||||||
|
iMesh.BoneList = new List<ImportedBone>(boneCount);
|
||||||
|
for (int i = 0; i < boneCount; i++)
|
||||||
{
|
{
|
||||||
var bone = new ImportedBone();
|
var bone = new ImportedBone();
|
||||||
if (sMesh.m_Bones[i].TryGet(out var m_Transform))
|
if (sMesh.m_Bones[i].TryGet(out var m_Transform))
|
||||||
{
|
{
|
||||||
bone.Path = GetTransformPath(m_Transform);
|
bone.Path = GetTransformPath(m_Transform);
|
||||||
}
|
}
|
||||||
if (!string.IsNullOrEmpty(bone.Path))
|
var convert = Matrix4x4.Scale(new Vector3(-1, 1, 1));
|
||||||
{
|
bone.Matrix = convert * mesh.m_BindPose[i] * convert;
|
||||||
var convert = Matrix4x4.Scale(new Vector3(-1, 1, 1));
|
iMesh.BoneList.Add(bone);
|
||||||
bone.Matrix = convert * mesh.m_BindPose[i] * convert;
|
|
||||||
iMesh.BoneList.Add(bone);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (iMesh.BoneList == null || iMesh.BoneList.Count == 0)
|
else if (boneType == 2)
|
||||||
{
|
{
|
||||||
if (mesh.m_BindPose.Length > 0 && mesh.m_BoneNameHashes?.Length > 0)
|
var boneCount = mesh.m_BindPose.Length;
|
||||||
|
iMesh.BoneList = new List<ImportedBone>(boneCount);
|
||||||
|
for (int i = 0; i < boneCount; i++)
|
||||||
{
|
{
|
||||||
var boneMax = Math.Min(mesh.m_BindPose.Length, mesh.m_BoneNameHashes.Length);
|
var bone = new ImportedBone();
|
||||||
iMesh.BoneList = new List<ImportedBone>(boneMax);
|
var boneHash = mesh.m_BoneNameHashes[i];
|
||||||
for (int i = 0; i < boneMax; i++)
|
var path = GetPathFromHash(boneHash);
|
||||||
{
|
bone.Path = FixBonePath(path);
|
||||||
var bone = new ImportedBone();
|
var convert = Matrix4x4.Scale(new Vector3(-1, 1, 1));
|
||||||
var boneHash = mesh.m_BoneNameHashes[i];
|
bone.Matrix = convert * mesh.m_BindPose[i] * convert;
|
||||||
var path = GetPathFromHash(boneHash);
|
iMesh.BoneList.Add(bone);
|
||||||
bone.Path = FixBonePath(path);
|
|
||||||
if (!string.IsNullOrEmpty(bone.Path))
|
|
||||||
{
|
|
||||||
var convert = Matrix4x4.Scale(new Vector3(-1, 1, 1));
|
|
||||||
bone.Matrix = convert * mesh.m_BindPose[i] * convert;
|
|
||||||
iMesh.BoneList.Add(bone);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,7 +480,7 @@ namespace AssetStudio
|
|||||||
morph.Channels.Add(channel);
|
morph.Channels.Add(channel);
|
||||||
var shapeChannel = mesh.m_Shapes.channels[i];
|
var shapeChannel = mesh.m_Shapes.channels[i];
|
||||||
|
|
||||||
morphChannelNames.Add(shapeChannel.nameHash, shapeChannel.name);
|
morphChannelNames[shapeChannel.nameHash] = shapeChannel.name;
|
||||||
|
|
||||||
channel.Name = shapeChannel.name;
|
channel.Name = shapeChannel.name;
|
||||||
channel.KeyframeList = new List<ImportedMorphKeyframe>(shapeChannel.frameCount);
|
channel.KeyframeList = new List<ImportedMorphKeyframe>(shapeChannel.frameCount);
|
||||||
|
Loading…
Reference in New Issue
Block a user