public static void UpdateTangentsFromMode(AnimationCurve curve, AnimationClip clip, EditorCurveBinding curveBinding) { if (RotationCurveInterpolation.GetModeFromCurveData(curveBinding) == RotationCurveInterpolation.Mode.NonBaked) { QuaternionCurveTangentCalculation quaternionCurveTangentCalculation = default(QuaternionCurveTangentCalculation); int curveIndexFromName = RotationCurveInterpolation.GetCurveIndexFromName(curveBinding.propertyName); for (int i = 0; i < 3; i++) { if (i == curveIndexFromName) { quaternionCurveTangentCalculation.SetCurve(i, curve); } else { EditorCurveBinding binding = curveBinding; binding.propertyName = "localEulerAngles." + RotationCurveInterpolation.kPostFix[i]; AnimationCurve editorCurve = AnimationUtility.GetEditorCurve(clip, binding); if (editorCurve == null) { return; } quaternionCurveTangentCalculation.SetCurve(i, editorCurve); } } quaternionCurveTangentCalculation.UpdateTangentsFromMode(curveIndexFromName); } else { CurveUtility.UpdateTangentsFromMode(curve); } }
public static Vector3 GetEulerFromQuaternion(Quaternion q, Vector3 refEuler) { Vector3[] equivalentEulerAngles = QuaternionCurveTangentCalculation.GetEquivalentEulerAngles(q); for (int index = 0; index < equivalentEulerAngles.Length; ++index) { equivalentEulerAngles[index] = new Vector3((float)((double)Mathf.Repeat((float)((double)equivalentEulerAngles[index].x - (double)refEuler.x + 180.0), 360f) + (double)refEuler.x - 180.0), (float)((double)Mathf.Repeat((float)((double)equivalentEulerAngles[index].y - (double)refEuler.y + 180.0), 360f) + (double)refEuler.y - 180.0), (float)((double)Mathf.Repeat((float)((double)equivalentEulerAngles[index].z - (double)refEuler.z + 180.0), 360f) + (double)refEuler.z - 180.0)); float num1 = Mathf.Repeat(equivalentEulerAngles[index].x, 360f); if ((double)Mathf.Abs(num1 - 90f) < 1.0) { float num2 = equivalentEulerAngles[index].z - equivalentEulerAngles[index].y - (refEuler.z - refEuler.y); equivalentEulerAngles[index].z = refEuler.z + num2 * 0.5f; equivalentEulerAngles[index].y = refEuler.y - num2 * 0.5f; } if ((double)Mathf.Abs(num1 - 270f) < 1.0) { float num2 = equivalentEulerAngles[index].z + equivalentEulerAngles[index].y - (refEuler.z + refEuler.y); equivalentEulerAngles[index].z = refEuler.z + num2 * 0.5f; equivalentEulerAngles[index].y = refEuler.y + num2 * 0.5f; } } Vector3 vector3 = equivalentEulerAngles[0]; float num = (equivalentEulerAngles[0] - refEuler).sqrMagnitude; for (int index = 1; index < equivalentEulerAngles.Length; ++index) { float sqrMagnitude = (equivalentEulerAngles[index] - refEuler).sqrMagnitude; if ((double)sqrMagnitude < (double)num) { num = sqrMagnitude; vector3 = equivalentEulerAngles[index]; } } return(vector3); }
public float CalculateLinearTangent(Keyframe from, Keyframe to, int component) { float num = 0.01f; Vector3 vector = this.EvaluateEulerCurvesDirectly(to.time); Vector3 euler = this.EvaluateEulerCurvesDirectly(from.time); Quaternion a = Quaternion.Euler(vector); Quaternion b = Quaternion.Euler(euler); Quaternion q = Quaternion.Slerp(a, b, num); Vector3 eulerFromQuaternion = QuaternionCurveTangentCalculation.GetEulerFromQuaternion(q, vector); switch (component) { case 0: return((eulerFromQuaternion.x - vector.x) / num / -(to.time - from.time)); case 1: return((eulerFromQuaternion.y - vector.y) / num / -(to.time - from.time)); case 2: return((eulerFromQuaternion.z - vector.z) / num / -(to.time - from.time)); default: return(0f); } }
private Vector3 GetValues(float time, bool keyReference) { if (this.quaternionX == null) { Debug.LogError((object)"X curve is null!"); } if (this.quaternionY == null) { Debug.LogError((object)"Y curve is null!"); } if (this.quaternionZ == null) { Debug.LogError((object)"Z curve is null!"); } if (this.quaternionW == null) { Debug.LogError((object)"W curve is null!"); } if (this.quaternionX.length != 0 && this.quaternionY.length != 0 && (this.quaternionZ.length != 0 && this.quaternionW.length != 0)) { Quaternion quaternionCurvesDirectly = this.EvaluateQuaternionCurvesDirectly(time); if (keyReference) { this.refEuler = this.EvaluateEulerCurvesDirectly(time); } this.refEuler = QuaternionCurveTangentCalculation.GetEulerFromQuaternion(quaternionCurvesDirectly, this.refEuler); } else { this.refEuler = this.EvaluateEulerCurvesDirectly(time); } return(this.refEuler); }
private Vector3 GetValues(float time, bool keyReference) { if (this.quaternionX == null) { Debug.LogError("X curve is null!"); } if (this.quaternionY == null) { Debug.LogError("Y curve is null!"); } if (this.quaternionZ == null) { Debug.LogError("Z curve is null!"); } if (this.quaternionW == null) { Debug.LogError("W curve is null!"); } Quaternion q = this.EvaluateQuaternionCurvesDirectly(time); if (keyReference) { this.refEuler = this.EvaluateEulerCurvesDirectly(time); } this.refEuler = QuaternionCurveTangentCalculation.GetEulerFromQuaternion(q, this.refEuler); return this.refEuler; }
public float CalculateSmoothTangent(int index, int component) { AnimationCurve curve = this.GetCurve(component); float result; if (curve.length < 2) { result = 0f; } else if (index <= 0) { result = this.CalculateLinearTangent(curve[0], curve[1], component); } else if (index >= curve.length - 1) { result = this.CalculateLinearTangent(curve[curve.length - 1], curve[curve.length - 2], component); } else { float time = curve[index - 1].time; float time2 = curve[index].time; float time3 = curve[index + 1].time; Vector3 euler = this.EvaluateEulerCurvesDirectly(time); Vector3 vector = this.EvaluateEulerCurvesDirectly(time2); Vector3 euler2 = this.EvaluateEulerCurvesDirectly(time3); Quaternion quaternion = Quaternion.Euler(euler); Quaternion quaternion2 = Quaternion.Euler(vector); Quaternion quaternion3 = Quaternion.Euler(euler2); if (quaternion.x * quaternion2.x + quaternion.y * quaternion2.y + quaternion.z * quaternion2.z + quaternion.w * quaternion2.w < 0f) { quaternion = new Quaternion(-quaternion.x, -quaternion.y, -quaternion.z, -quaternion.w); } if (quaternion3.x * quaternion2.x + quaternion3.y * quaternion2.y + quaternion3.z * quaternion2.z + quaternion3.w * quaternion2.w < 0f) { quaternion3 = new Quaternion(-quaternion3.x, -quaternion3.y, -quaternion3.z, -quaternion3.w); } Quaternion quaternion4 = default(Quaternion); float dx = time2 - time; float dx2 = time3 - time2; for (int i = 0; i < 4; i++) { float dy = quaternion2[i] - quaternion[i]; float dy2 = quaternion3[i] - quaternion2[i]; float num = QuaternionCurveTangentCalculation.SafeDeltaDivide(dy, dx); float num2 = QuaternionCurveTangentCalculation.SafeDeltaDivide(dy2, dx2); quaternion4[i] = 0.5f * num + 0.5f * num2; } float num3 = Mathf.Abs(time3 - time) * 0.01f; Quaternion q = new Quaternion(quaternion2.x - quaternion4.x * num3, quaternion2.y - quaternion4.y * num3, quaternion2.z - quaternion4.z * num3, quaternion2.w - quaternion4.w * num3); Quaternion q2 = new Quaternion(quaternion2.x + quaternion4.x * num3, quaternion2.y + quaternion4.y * num3, quaternion2.z + quaternion4.z * num3, quaternion2.w + quaternion4.w * num3); Vector3 eulerFromQuaternion = QuaternionCurveTangentCalculation.GetEulerFromQuaternion(q, vector); Vector3 eulerFromQuaternion2 = QuaternionCurveTangentCalculation.GetEulerFromQuaternion(q2, vector); result = ((eulerFromQuaternion2 - eulerFromQuaternion) / (num3 * 2f))[component]; } return(result); }
public float CalculateSmoothTangent(int index, int component) { AnimationCurve curve = this.GetCurve(component); if (curve.length < 2) { return(0.0f); } if (index <= 0) { return(this.CalculateLinearTangent(curve[0], curve[1], component)); } if (index >= curve.length - 1) { return(this.CalculateLinearTangent(curve[curve.length - 1], curve[curve.length - 2], component)); } float time1 = curve[index - 1].time; float time2 = curve[index].time; float time3 = curve[index + 1].time; Vector3 eulerCurvesDirectly1 = this.EvaluateEulerCurvesDirectly(time1); Vector3 eulerCurvesDirectly2 = this.EvaluateEulerCurvesDirectly(time2); Vector3 eulerCurvesDirectly3 = this.EvaluateEulerCurvesDirectly(time3); Quaternion quaternion1 = Quaternion.Euler(eulerCurvesDirectly1); Quaternion quaternion2 = Quaternion.Euler(eulerCurvesDirectly2); Quaternion quaternion3 = Quaternion.Euler(eulerCurvesDirectly3); if ((double)quaternion1.x * (double)quaternion2.x + (double)quaternion1.y * (double)quaternion2.y + (double)quaternion1.z * (double)quaternion2.z + (double)quaternion1.w * (double)quaternion2.w < 0.0) { quaternion1 = new Quaternion(-quaternion1.x, -quaternion1.y, -quaternion1.z, -quaternion1.w); } if ((double)quaternion3.x * (double)quaternion2.x + (double)quaternion3.y * (double)quaternion2.y + (double)quaternion3.z * (double)quaternion2.z + (double)quaternion3.w * (double)quaternion2.w < 0.0) { quaternion3 = new Quaternion(-quaternion3.x, -quaternion3.y, -quaternion3.z, -quaternion3.w); } Quaternion quaternion4 = new Quaternion(); float dx1 = time2 - time1; float dx2 = time3 - time2; for (int index1 = 0; index1 < 4; ++index1) { float dy1 = quaternion2[index1] - quaternion1[index1]; float dy2 = quaternion3[index1] - quaternion2[index1]; float num1 = QuaternionCurveTangentCalculation.SafeDeltaDivide(dy1, dx1); float num2 = QuaternionCurveTangentCalculation.SafeDeltaDivide(dy2, dx2); quaternion4[index1] = (float)(0.5 * (double)num1 + 0.5 * (double)num2); } float num = Mathf.Abs(time3 - time1) * 0.01f; Quaternion q1 = new Quaternion(quaternion2.x - quaternion4.x * num, quaternion2.y - quaternion4.y * num, quaternion2.z - quaternion4.z * num, quaternion2.w - quaternion4.w * num); Quaternion q2 = new Quaternion(quaternion2.x + quaternion4.x * num, quaternion2.y + quaternion4.y * num, quaternion2.z + quaternion4.z * num, quaternion2.w + quaternion4.w * num); Vector3 eulerFromQuaternion = QuaternionCurveTangentCalculation.GetEulerFromQuaternion(q1, eulerCurvesDirectly2); return(((QuaternionCurveTangentCalculation.GetEulerFromQuaternion(q2, eulerCurvesDirectly2) - eulerFromQuaternion) / (num * 2f))[component]); }
private Vector3 GetValues(float time, bool keyReference) { if (quaternionX == null) { Debug.LogError("X curve is null!"); } if (quaternionY == null) { Debug.LogError("Y curve is null!"); } if (quaternionZ == null) { Debug.LogError("Z curve is null!"); } if (quaternionW == null) { Debug.LogError("W curve is null!"); } Quaternion q; if (quaternionX.length != 0 && quaternionY.length != 0 && quaternionZ.length != 0 && quaternionW.length != 0) { q = EvaluateQuaternionCurvesDirectly(time); if (keyReference) { refEuler = EvaluateEulerCurvesDirectly(time); } refEuler = QuaternionCurveTangentCalculation.GetEulerFromQuaternion(q, refEuler); } else //euler curves only { refEuler = EvaluateEulerCurvesDirectly(time); } return(refEuler); }
public float CalculateLinearTangent(Keyframe from, Keyframe to, int component) { float t = 0.01f; Vector3 eulerCurvesDirectly1 = this.EvaluateEulerCurvesDirectly(to.time); Vector3 eulerCurvesDirectly2 = this.EvaluateEulerCurvesDirectly(from.time); Vector3 eulerFromQuaternion = QuaternionCurveTangentCalculation.GetEulerFromQuaternion(Quaternion.Slerp(Quaternion.Euler(eulerCurvesDirectly1), Quaternion.Euler(eulerCurvesDirectly2), t), eulerCurvesDirectly1); switch (component) { case 0: return((float)(((double)eulerFromQuaternion.x - (double)eulerCurvesDirectly1.x) / (double)t / -((double)to.time - (double)from.time))); case 1: return((float)(((double)eulerFromQuaternion.y - (double)eulerCurvesDirectly1.y) / (double)t / -((double)to.time - (double)from.time))); case 2: return((float)(((double)eulerFromQuaternion.z - (double)eulerCurvesDirectly1.z) / (double)t / -((double)to.time - (double)from.time))); default: return(0.0f); } }
public static Vector3 GetEulerFromQuaternion(Quaternion q, Vector3 refEuler) { Vector3[] equivalentEulerAngles = QuaternionCurveTangentCalculation.GetEquivalentEulerAngles(q); for (int i = 0; i < equivalentEulerAngles.Length; i++) { equivalentEulerAngles[i] = new Vector3(Mathf.Repeat(equivalentEulerAngles[i].x - refEuler.x + 180f, 360f) + refEuler.x - 180f, Mathf.Repeat(equivalentEulerAngles[i].y - refEuler.y + 180f, 360f) + refEuler.y - 180f, Mathf.Repeat(equivalentEulerAngles[i].z - refEuler.z + 180f, 360f) + refEuler.z - 180f); float num = Mathf.Repeat(equivalentEulerAngles[i].x, 360f); if (Mathf.Abs(num - 90f) < 1f) { float num2 = equivalentEulerAngles[i].z - equivalentEulerAngles[i].y; float num3 = refEuler.z - refEuler.y; float num4 = num2 - num3; equivalentEulerAngles[i].z = refEuler.z + num4 * 0.5f; equivalentEulerAngles[i].y = refEuler.y - num4 * 0.5f; } if (Mathf.Abs(num - 270f) < 1f) { float num5 = equivalentEulerAngles[i].z + equivalentEulerAngles[i].y; float num6 = refEuler.z + refEuler.y; float num7 = num5 - num6; equivalentEulerAngles[i].z = refEuler.z + num7 * 0.5f; equivalentEulerAngles[i].y = refEuler.y + num7 * 0.5f; } } Vector3 result = equivalentEulerAngles[0]; float num8 = (equivalentEulerAngles[0] - refEuler).sqrMagnitude; for (int j = 1; j < equivalentEulerAngles.Length; j++) { float sqrMagnitude = (equivalentEulerAngles[j] - refEuler).sqrMagnitude; if (sqrMagnitude < num8) { num8 = sqrMagnitude; result = equivalentEulerAngles[j]; } } return(result); }
public static void UpdateTangentsFromMode(AnimationCurve curve, AnimationClip clip, EditorCurveBinding curveBinding) { if (RotationCurveInterpolation.GetModeFromCurveData(curveBinding) == RotationCurveInterpolation.Mode.NonBaked) { QuaternionCurveTangentCalculation calculation = new QuaternionCurveTangentCalculation(); int curveIndexFromName = RotationCurveInterpolation.GetCurveIndexFromName(curveBinding.propertyName); for (int i = 0; i < 3; i++) { if (i == curveIndexFromName) { calculation.SetCurve(i, curve); } else { EditorCurveBinding binding = curveBinding; binding.propertyName = "localEulerAngles." + RotationCurveInterpolation.kPostFix[i]; AnimationCurve editorCurve = AnimationUtility.GetEditorCurve(clip, binding); if (editorCurve == null) { return; } calculation.SetCurve(i, editorCurve); } } calculation.UpdateTangentsFromMode(curveIndexFromName); } else { CurveUtility.UpdateTangentsFromMode(curve); } }
public void SaveCurve(AnimationCurve animationCurve) { Undo.RegisterCompleteObjectUndo(this.clip, "Edit Curve"); QuaternionCurveTangentCalculation.UpdateTangentsFromMode(animationCurve, this.clip, this.m_CurveBinding); AnimationUtility.SetEditorCurve(this.clip, this.m_CurveBinding, animationCurve); }