protected override float CalculateLinearTangent(NiKeyframe <float> index, NiKeyframe <float> toIndex) { float num = index.time - toIndex.time; if (Mathf.Approximately(num, 0f)) { return(0); } return((index.value - toIndex.value) / num); }
protected override Vector3 CalculateLinearTangent(NiKeyframe <Vector3> index, NiKeyframe <Vector3> toIndex) { float num = index.time - toIndex.time; if (Mathf.Approximately(num, 0f)) { return(Vector3.zero); } return(new Vector3 ( (index.value.x - toIndex.value.x) / num, (index.value.y - toIndex.value.y) / num, (index.value.z - toIndex.value.z) / num )); }
protected override Quaternion CalculateLinearTangent(NiKeyframe <Quaternion> index, NiKeyframe <Quaternion> toIndex) { float num = index.time - toIndex.time; if (Mathf.Approximately(num, 0f)) { return(Quaternion.identity); } return(new Quaternion ( (index.value.x - toIndex.value.x) / num, (index.value.y - toIndex.value.y) / num, (index.value.z - toIndex.value.z) / num, (index.value.w - toIndex.value.w) / num )); }
protected abstract T CalculateLinearTangent(NiKeyframe <T> index, NiKeyframe <T> toIndex);
public NiKeyframeGroup(int length, KeyType interpolation, System.IO.BinaryReader reader) { this.length = length; this.interpolation = interpolation; this.reader = reader; Keyframes = new NiKeyframe <T> [length]; // Read all the keys for (var i = 0; i < length; i++) { var time = reader.ReadSingle(); var value = GetValue(); switch (interpolation) { case KeyType.Linear: case KeyType.Constant: Keyframes[i] = new NiKeyframe <T>(time, value); break; case KeyType.Quadratic: var forward = GetValue(); var backward = GetValue(); Keyframes[i] = new NiKeyframe <T>(time, value, forward, backward); break; case KeyType.Tbc: var tension = reader.ReadSingle(); var bias = reader.ReadSingle(); var continuity = reader.ReadSingle(); Keyframes[i] = new NiKeyframe <T>(time, value, tension, bias, continuity); break; default: throw new NotImplementedException(interpolation.ToString()); } } // After keys are read, they should be "processed" so tangents for quadratic/tbc can be calculated animationKeyframes = new Keyframe[AnimCurveCount][]; for (var i = 0; i < AnimCurveCount; i++) { animationKeyframes[i] = new Keyframe[Keyframes.Length]; } // Set tangents for first frame // Some animations only have one frame, do this to avoid errors if (Keyframes.Length == 1) { switch (interpolation) { case KeyType.Linear: SetLinearCurves(0, 0, 0); break; case KeyType.Quadratic: SetQuadraticCurves(0); break; case KeyType.Tbc: SetTbcCurves(0, 0, 0); break; case KeyType.Constant: SetConstantCurves(0); break; default: throw new NotImplementedException(interpolation.ToString()); } return; } switch (interpolation) { case KeyType.Linear: SetLinearCurves(0, 0, 1); break; case KeyType.Quadratic: SetQuadraticCurves(0); break; case KeyType.Tbc: SetLinearCurves(0, 0, 1); break; case KeyType.Constant: SetConstantCurves(0); break; default: throw new NotImplementedException(interpolation.ToString()); } // Don't set tangents here for first or last frame for (var i = 1; i < Keyframes.Length - 2; i++) { switch (interpolation) { case KeyType.Linear: SetLinearCurves(i, i - 1, i + 1); break; case KeyType.Quadratic: SetQuadraticCurves(i); break; case KeyType.Tbc: SetTbcCurves(i, i - 1, i + 1); break; case KeyType.Constant: SetConstantCurves(i); break; default: throw new NotImplementedException(interpolation.ToString()); } } // Set tangents for last frame switch (interpolation) { case KeyType.Linear: SetLinearCurves(Keyframes.Length - 1, Keyframes.Length - 2, Keyframes.Length - 1); break; case KeyType.Quadratic: SetQuadraticCurves(Keyframes.Length - 1); break; case KeyType.Tbc: SetTbcCurves(Keyframes.Length - 1, Keyframes.Length - 2, Keyframes.Length - 1); break; case KeyType.Constant: SetConstantCurves(Keyframes.Length - 1); break; default: throw new NotImplementedException(interpolation.ToString()); } }