Skip to content

Instantly share code, notes, and snippets.

@mafaca
Created April 5, 2018 06:06
Show Gist options
  • Save mafaca/c2ef018d698ba0d36dd7c28f7a47fbc5 to your computer and use it in GitHub Desktop.
Save mafaca/c2ef018d698ba0d36dd7c28f7a47fbc5 to your computer and use it in GitHub Desktop.
public class QuaternionCurve
{
public AnimationCurve<Quaternion> curve { get; set; }
public string path { get; set; }
public QuaternionCurve(string path)
{
curve = new AnimationCurve<Quaternion>();
this.path = path;
}
public QuaternionCurve(EndianBinaryReader reader, int[] version)
{
curve = new AnimationCurve<Quaternion>(reader, reader.ReadQuaternion, version);
path = reader.ReadNameA4();
}
public Vector3Curve ToFBXRotation()
{
Vector3Curve rcurve = new Vector3Curve();
rcurve.path = path;
rcurve.curve = new AnimationCurve<Vector3>();
rcurve.curve.m_PostInfinity = curve.m_PostInfinity;
rcurve.curve.m_PreInfinity = curve.m_PreInfinity;
rcurve.curve.m_RotationOrder = curve.m_RotationOrder;
rcurve.curve.m_Curve = new List<Keyframe<Vector3>>(curve.m_Curve.Count);
Vector3 prevKey = new Vector3();
foreach (var keyframe in curve.m_Curve)
{
float[] valueSrc = new float[] { keyframe.value.X, -keyframe.value.Y, -keyframe.value.Z, keyframe.value.W };
float[] valueAr = UnityStudio.QuatToEuler(valueSrc);
Vector3 value = new Vector3(valueAr[0], valueAr[1], valueAr[2]);
ReplaceOutOfBound(ref prevKey, ref value);
prevKey = value;
float[] inSlopeSrc = new float[] { keyframe.inSlope.X, -keyframe.inSlope.Y, -keyframe.inSlope.Z, keyframe.inSlope.W };
float[] inSlopeAr = UnityStudio.QuatToEuler(inSlopeSrc);
Vector3 inSlope = new Vector3(inSlopeAr[0], inSlopeAr[1], inSlopeAr[2]);
float[] outSlopeSrc = new float[] { keyframe.outSlope.X, -keyframe.outSlope.Y, -keyframe.outSlope.Z, keyframe.outSlope.W };
float[] outSlopeAr = UnityStudio.QuatToEuler(outSlopeSrc);
Vector3 outSlope = new Vector3(outSlopeAr[0], outSlopeAr[1], outSlopeAr[2]);
Keyframe<Vector3> kf = new Keyframe<Vector3>(keyframe.time, value, inSlope, outSlope);
rcurve.curve.m_Curve.Add(kf);
}
return rcurve;
}
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;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment