From bc2469e11a1c325572b0403ddc88161183b41462 Mon Sep 17 00:00:00 2001 From: Perfare Date: Mon, 9 Apr 2018 08:18:45 +0800 Subject: [PATCH] improve QuaternionToEuler --- AssetStudio/StudioClasses/ModelConverter.cs | 54 +++++++++++++++++++-- AssetStudioFBX/ImportedFBXExporter.cpp | 9 ++-- AssetStudioUtility/Imported.cs | 2 +- 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/AssetStudio/StudioClasses/ModelConverter.cs b/AssetStudio/StudioClasses/ModelConverter.cs index 0972254..294a19a 100644 --- a/AssetStudio/StudioClasses/ModelConverter.cs +++ b/AssetStudio/StudioClasses/ModelConverter.cs @@ -580,13 +580,21 @@ namespace AssetStudio track.Name = boneName; iAnim.TrackList.Add(track); } + Vector3 prevKey = new Vector3(); foreach (var m_Curve in m_RotationCurve.curve.m_Curve) { - track.Rotations.Add(new ImportedKeyframe( + 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)); + + ReplaceOutOfBound(ref prevKey, ref value); + prevKey = value; + + track.Rotations.Add(new ImportedKeyframe( m_Curve.time, - new Quaternion(m_Curve.value.X, -m_Curve.value.Y, -m_Curve.value.Z, m_Curve.value.W), - new Quaternion(m_Curve.inSlope.X, -m_Curve.inSlope.Y, -m_Curve.inSlope.Z, m_Curve.inSlope.W), - new Quaternion(m_Curve.outSlope.X, -m_Curve.outSlope.Y, -m_Curve.outSlope.Z, m_Curve.outSlope.W))); + value, + inSlope, + outSlope)); } } foreach (var m_PositionCurve in clip.m_PositionCurves) @@ -862,5 +870,43 @@ namespace AssetStudio CreateBonePathHash(child); } } + + private void ReplaceOutOfBound(ref Vector3 prevKey, ref Vector3 curKey) + { + curKey.X = ReplaceOutOfBound(prevKey.X, curKey.X); + curKey.Y = ReplaceOutOfBound(prevKey.Y, curKey.Y); + curKey.Z = ReplaceOutOfBound(prevKey.Z, curKey.Z); + } + + private float ReplaceOutOfBound(float prevValue, float curValue) + { + double prev = prevValue; + double cur = curValue; + + double prevAbs = Math.Abs(prev); + double prevSign = Math.Sign(prev); + + double prevShift = 180.0 + prevAbs; + double count = Math.Floor(prevShift / 360.0) * prevSign; + double prevRemain = 180.0 + (prev - count * 360.0); + + double curShift = 180.0 + cur; + + if (prevRemain - curShift > 180) + { + count++; + } + else if (prevRemain - curShift < -180) + { + count--; + } + + double newValue = count * 360.0 + cur; + if (newValue != cur) + { + + } + return (float)newValue; + } } } diff --git a/AssetStudioFBX/ImportedFBXExporter.cpp b/AssetStudioFBX/ImportedFBXExporter.cpp index f36fc09..3373cff 100644 --- a/AssetStudioFBX/ImportedFBXExporter.cpp +++ b/AssetStudioFBX/ImportedFBXExporter.cpp @@ -796,12 +796,9 @@ namespace AssetStudio { lTime.SetSecondDouble(Rotation->time); - Vector3 rotation = Fbx::QuaternionToEuler(Rotation->value); - Vector3 inSlope = Fbx::QuaternionToEuler(Rotation->inSlope); - Vector3 outSlope = Fbx::QuaternionToEuler(Rotation->outSlope); - lCurveRX->KeySet(lCurveRX->KeyAdd(lTime), lTime, rotation.X); - lCurveRY->KeySet(lCurveRY->KeyAdd(lTime), lTime, rotation.Y); - lCurveRZ->KeySet(lCurveRZ->KeyAdd(lTime), lTime, rotation.Z); + lCurveRX->KeySet(lCurveRX->KeyAdd(lTime), lTime, Rotation->value.X); + lCurveRY->KeySet(lCurveRY->KeyAdd(lTime), lTime, Rotation->value.Y); + lCurveRZ->KeySet(lCurveRZ->KeyAdd(lTime), lTime, Rotation->value.Z); } for each (auto Translation in keyframeList->Translations) { diff --git a/AssetStudioUtility/Imported.cs b/AssetStudioUtility/Imported.cs index b7669c9..45c01ce 100644 --- a/AssetStudioUtility/Imported.cs +++ b/AssetStudioUtility/Imported.cs @@ -140,7 +140,7 @@ namespace AssetStudio public class ImportedAnimationKeyframedTrack : ImportedAnimationTrack { public List> Scalings = new List>(); - public List> Rotations = new List>(); + public List> Rotations = new List>(); public List> Translations = new List>(); }