diff --git a/AssetStudio/StudioClasses/FBXExporter.cs b/AssetStudio/StudioClasses/FBXExporter.cs index f099d50..fffb21c 100644 --- a/AssetStudio/StudioClasses/FBXExporter.cs +++ b/AssetStudio/StudioClasses/FBXExporter.cs @@ -1076,48 +1076,6 @@ namespace AssetStudio } } - private static float[] QuatToEuler(float[] q) - { - double eax = 0; - double eay = 0; - double eaz = 0; - - float qx = q[0]; - float qy = q[1]; - float qz = q[2]; - float qw = q[3]; - - double[,] M = new double[4, 4]; - - double Nq = qx * qx + qy * qy + qz * qz + qw * qw; - double s = (Nq > 0.0) ? (2.0 / Nq) : 0.0; - double xs = qx * s, ys = qy * s, zs = qz * s; - double wx = qw * xs, wy = qw * ys, wz = qw * zs; - double xx = qx * xs, xy = qx * ys, xz = qx * zs; - double yy = qy * ys, yz = qy * zs, zz = qz * zs; - - M[0, 0] = 1.0 - (yy + zz); M[0, 1] = xy - wz; M[0, 2] = xz + wy; - M[1, 0] = xy + wz; M[1, 1] = 1.0 - (xx + zz); M[1, 2] = yz - wx; - M[2, 0] = xz - wy; M[2, 1] = yz + wx; M[2, 2] = 1.0 - (xx + yy); - M[3, 0] = M[3, 1] = M[3, 2] = M[0, 3] = M[1, 3] = M[2, 3] = 0.0; M[3, 3] = 1.0; - - double test = Math.Sqrt(M[0, 0] * M[0, 0] + M[1, 0] * M[1, 0]); - if (test > 16 * 1.19209290E-07F)//FLT_EPSILON - { - eax = Math.Atan2(M[2, 1], M[2, 2]); - eay = Math.Atan2(-M[2, 0], test); - eaz = Math.Atan2(M[1, 0], M[0, 0]); - } - else - { - eax = Math.Atan2(-M[1, 2], M[1, 1]); - eay = Math.Atan2(-M[2, 0], test); - eaz = 0; - } - - return new[] { (float)(eax * 180 / Math.PI), (float)(eay * 180 / Math.PI), (float)(eaz * 180 / Math.PI) }; - } - private static byte[] RandomColorGenerator(string name) { int nameHash = name.GetHashCode(); diff --git a/AssetStudio/StudioClasses/ModelConverter.cs b/AssetStudio/StudioClasses/ModelConverter.cs index a19dfec..2c4c5cd 100644 --- a/AssetStudio/StudioClasses/ModelConverter.cs +++ b/AssetStudio/StudioClasses/ModelConverter.cs @@ -191,12 +191,10 @@ namespace AssetStudio assetsfileList.TryGetGameObject(trans.m_GameObject, out var m_GameObject); frame.Name = m_GameObject.m_Name; frame.InitChildren(trans.m_Children.Count); - Quaternion mirroredRotation = new Quaternion(trans.m_LocalRotation[0], trans.m_LocalRotation[1], trans.m_LocalRotation[2], trans.m_LocalRotation[3]); - mirroredRotation.Y *= -1; - mirroredRotation.Z *= -1; - var m_LocalScale = new Vector3(trans.m_LocalScale[0], trans.m_LocalScale[1], trans.m_LocalScale[2]); - var m_LocalPosition = new Vector3(trans.m_LocalPosition[0], trans.m_LocalPosition[1], trans.m_LocalPosition[2]); - frame.Matrix = Matrix.Scaling(m_LocalScale) * Matrix.RotationQuaternion(mirroredRotation) * Matrix.Translation(-m_LocalPosition.X, m_LocalPosition.Y, m_LocalPosition.Z); + var m_EulerRotation = QuatToEuler(new[] { trans.m_LocalRotation[0], -trans.m_LocalRotation[1], -trans.m_LocalRotation[2], trans.m_LocalRotation[3] }); + frame.LocalRotation = new[] { m_EulerRotation[0], m_EulerRotation[1], m_EulerRotation[2] }; + frame.LocalScale = new[] { trans.m_LocalScale[0], trans.m_LocalScale[1], trans.m_LocalScale[2] }; + frame.LocalPosition = new[] { -trans.m_LocalPosition[0], trans.m_LocalPosition[1], trans.m_LocalPosition[2] }; return frame; } @@ -385,21 +383,25 @@ namespace AssetStudio continue; } } - - var om = new Matrix(); - for (int x = 0; x < 4; x++) - { - for (int y = 0; y < 4; y++) - { - om[x, y] = mesh.m_BindPose[i][x, y]; - } - } - var m = Matrix.Transpose(om); - m.Decompose(out var s, out var q, out var t); - t.X *= -1; - q.Y *= -1; - q.Z *= -1; - bone.Matrix = Matrix.Scaling(s) * Matrix.RotationQuaternion(q) * Matrix.Translation(t); + var om = new float[4, 4]; + var m = mesh.m_BindPose[i]; + om[0, 0] = m[0, 0]; + om[0, 1] = -m[1, 0]; + om[0, 2] = -m[2, 0]; + om[0, 3] = m[3, 0]; + om[1, 0] = -m[0, 1]; + om[1, 1] = m[1, 1]; + om[1, 2] = m[2, 1]; + om[1, 3] = m[3, 1]; + om[2, 0] = -m[0, 2]; + om[2, 1] = m[1, 2]; + om[2, 2] = m[2, 2]; + om[2, 3] = m[3, 2]; + om[3, 0] = -m[0, 3]; + om[3, 1] = m[1, 3]; + om[3, 2] = m[2, 3]; + om[3, 3] = m[3, 3]; + bone.Matrix = om; iMesh.BoneList.Add(bone); } @@ -470,26 +472,25 @@ namespace AssetStudio foreach (var root in FrameList) { var frame = ImportedHelpers.FindFrame(m_GameObject.m_Name, root); - if (frame != null) + if (frame?.Parent != null) { - if (frame.Parent != null) + var parent = frame; + while (true) { - var parent = frame; - while (true) + if (parent.Parent != null) { - if (parent.Parent != null) - { - parent = parent.Parent; - } - else - { - frame.Matrix = parent.Matrix; - break; - } + parent = parent.Parent; + } + else + { + frame.LocalRotation = parent.LocalRotation; + frame.LocalScale = parent.LocalScale; + frame.LocalPosition = parent.LocalPosition; + break; } } - break; } + break; } } @@ -671,9 +672,7 @@ namespace AssetStudio foreach (var m_Curve in m_RotationCurve.curve.m_Curve) { var value = Fbx.QuaternionToEuler(new Quaternion(m_Curve.value.X, -m_Curve.value.Y, -m_Curve.value.Z, m_Curve.value.W)); - var inSlope = Fbx.QuaternionToEuler(new Quaternion(m_Curve.inSlope.X, -m_Curve.inSlope.Y, -m_Curve.inSlope.Z, m_Curve.inSlope.W)); - var outSlope = Fbx.QuaternionToEuler(new Quaternion(m_Curve.outSlope.X, -m_Curve.outSlope.Y, -m_Curve.outSlope.Z, m_Curve.outSlope.W)); - track.Rotations.Add(new ImportedKeyframe(m_Curve.time, value, inSlope, outSlope)); + track.Rotations.Add(new ImportedKeyframe(m_Curve.time, value)); } } foreach (var m_PositionCurve in clip.m_PositionCurves) @@ -689,11 +688,7 @@ namespace AssetStudio } foreach (var m_Curve in m_PositionCurve.curve.m_Curve) { - track.Translations.Add(new ImportedKeyframe( - m_Curve.time, - new Vector3(-m_Curve.value.X, m_Curve.value.Y, m_Curve.value.Z), - new Vector3(-m_Curve.inSlope.X, m_Curve.inSlope.Y, m_Curve.inSlope.Z), - new Vector3(-m_Curve.outSlope.X, m_Curve.outSlope.Y, m_Curve.outSlope.Z))); + track.Translations.Add(new ImportedKeyframe(m_Curve.time, new Vector3(-m_Curve.value.X, m_Curve.value.Y, m_Curve.value.Z))); } } foreach (var m_ScaleCurve in clip.m_ScaleCurves) @@ -709,11 +704,7 @@ namespace AssetStudio } foreach (var m_Curve in m_ScaleCurve.curve.m_Curve) { - track.Scalings.Add(new ImportedKeyframe( - m_Curve.time, - new Vector3(m_Curve.value.X, m_Curve.value.Y, m_Curve.value.Z), - new Vector3(m_Curve.inSlope.X, m_Curve.inSlope.Y, m_Curve.inSlope.Z), - new Vector3(m_Curve.outSlope.X, m_Curve.outSlope.Y, m_Curve.outSlope.Z))); + track.Scalings.Add(new ImportedKeyframe(m_Curve.time, new Vector3(m_Curve.value.X, m_Curve.value.Y, m_Curve.value.Z))); } } diff --git a/AssetStudio/StudioClasses/Studio.cs b/AssetStudio/StudioClasses/Studio.cs index a78a0b9..a5f1b6d 100644 --- a/AssetStudio/StudioClasses/Studio.cs +++ b/AssetStudio/StudioClasses/Studio.cs @@ -735,6 +735,48 @@ namespace AssetStudio } } + public static float[] QuatToEuler(float[] q) + { + double eax = 0; + double eay = 0; + double eaz = 0; + + float qx = q[0]; + float qy = q[1]; + float qz = q[2]; + float qw = q[3]; + + double[,] M = new double[4, 4]; + + double Nq = qx * qx + qy * qy + qz * qz + qw * qw; + double s = (Nq > 0.0) ? (2.0 / Nq) : 0.0; + double xs = qx * s, ys = qy * s, zs = qz * s; + double wx = qw * xs, wy = qw * ys, wz = qw * zs; + double xx = qx * xs, xy = qx * ys, xz = qx * zs; + double yy = qy * ys, yz = qy * zs, zz = qz * zs; + + M[0, 0] = 1.0 - (yy + zz); M[0, 1] = xy - wz; M[0, 2] = xz + wy; + M[1, 0] = xy + wz; M[1, 1] = 1.0 - (xx + zz); M[1, 2] = yz - wx; + M[2, 0] = xz - wy; M[2, 1] = yz + wx; M[2, 2] = 1.0 - (xx + yy); + M[3, 0] = M[3, 1] = M[3, 2] = M[0, 3] = M[1, 3] = M[2, 3] = 0.0; M[3, 3] = 1.0; + + double test = Math.Sqrt(M[0, 0] * M[0, 0] + M[1, 0] * M[1, 0]); + if (test > 16 * 1.19209290E-07F)//FLT_EPSILON + { + eax = Math.Atan2(M[2, 1], M[2, 2]); + eay = Math.Atan2(-M[2, 0], test); + eaz = Math.Atan2(M[1, 0], M[0, 0]); + } + else + { + eax = Math.Atan2(-M[1, 2], M[1, 1]); + eay = Math.Atan2(-M[2, 0], test); + eaz = 0; + } + + return new[] { (float)(eax * 180 / Math.PI), (float)(eay * 180 / Math.PI), (float)(eaz * 180 / Math.PI) }; + } + public static string GetScriptString(AssetPreloadData assetPreloadData) { if (!moduleLoaded) diff --git a/AssetStudioFBX/AssetStudioFBXExporter.cpp b/AssetStudioFBX/AssetStudioFBXExporter.cpp index cedc2e4..c98b77e 100644 --- a/AssetStudioFBX/AssetStudioFBXExporter.cpp +++ b/AssetStudioFBX/AssetStudioFBXExporter.cpp @@ -286,14 +286,9 @@ namespace AssetStudio Marshal::FreeHGlobal((IntPtr)pName); } - Vector3 scale, translate; - Quaternion rotate; - frame->Matrix.Decompose(scale, rotate, translate); - Vector3 rotateVector = Fbx::QuaternionToEuler(rotate); - - pFrameNode->LclScaling.Set(FbxVector4(scale.X, scale.Y, scale.Z)); - pFrameNode->LclRotation.Set(FbxVector4(FbxDouble3(rotateVector.X, rotateVector.Y, rotateVector.Z))); - pFrameNode->LclTranslation.Set(FbxVector4(translate.X, translate.Y, translate.Z)); + pFrameNode->LclScaling.Set(FbxDouble3(frame->LocalScale[0], frame->LocalScale[1], frame->LocalScale[2])); + pFrameNode->LclRotation.Set(FbxDouble3(frame->LocalRotation[0], frame->LocalRotation[1], frame->LocalRotation[2])); + pFrameNode->LclTranslation.Set(FbxDouble3(frame->LocalPosition[0], frame->LocalPosition[1], frame->LocalPosition[2])); pParentNode->AddChild(pFrameNode); if (imported->MeshList != nullptr && ImportedHelpers::FindMesh(frame, imported->MeshList) != nullptr) @@ -595,7 +590,7 @@ namespace AssetStudio if (pCluster->GetControlPointIndicesCount() > 0) { FbxNode* pBoneNode = pBoneNodeList->GetAt(j); - Matrix boneMatrix = boneList[j]->Matrix; + auto boneMatrix = boneList[j]->Matrix; FbxAMatrix lBoneMatrix; for (int m = 0; m < 4; m++) { diff --git a/AssetStudioUtility/Imported.cs b/AssetStudioUtility/Imported.cs index 64ee5dc..556262d 100644 --- a/AssetStudioUtility/Imported.cs +++ b/AssetStudioUtility/Imported.cs @@ -19,7 +19,9 @@ namespace AssetStudio public class ImportedFrame : IEnumerable { public string Name { get; set; } - public Matrix Matrix { get; set; } + public float[] LocalRotation { get; set; } + public float[] LocalPosition { get; set; } + public float[] LocalScale { get; set; } public ImportedFrame Parent { get; set; } private List children; @@ -110,7 +112,7 @@ namespace AssetStudio public class ImportedBone { public string Name { get; set; } - public Matrix Matrix { get; set; } + public float[,] Matrix { get; set; } } public class ImportedMaterial @@ -172,15 +174,11 @@ namespace AssetStudio { public float time { get; set; } public T value { get; set; } - public T inSlope { get; set; } - public T outSlope { get; set; } - public ImportedKeyframe(float time, T value, T inSlope, T outSlope) + public ImportedKeyframe(float time, T value) { this.time = time; this.value = value; - this.inSlope = inSlope; - this.outSlope = outSlope; } }