public static CurveAnimHelper FromCurve(AnimCurve curve, string target, bool useDegrees) { var convCurve = new CurveAnimHelper(); convCurve.KeyFrames = new Dictionary <float, object>(); convCurve.Target = target; convCurve.Scale = curve.Scale; convCurve.Offset = curve.Offset; convCurve.WrapMode = $"{curve.PreWrap}, {curve.PostWrap}"; convCurve.Interpolation = curve.CurveType; convCurve.FrameType = curve.FrameType; convCurve.KeyType = curve.KeyType; float valueScale = curve.Scale > 0 ? curve.Scale : 1; for (int i = 0; i < curve.Frames.Length; i++) { var frame = curve.Frames[i]; switch (curve.CurveType) { case AnimCurveType.Cubic: { var coef0 = curve.Keys[i, 0] * valueScale + curve.Offset; var slopes = GetSlopes(curve, i); if (useDegrees) { coef0 *= Rad2Deg; slopes[0] *= Rad2Deg; slopes[1] *= Rad2Deg; } convCurve.KeyFrames.Add(frame, new HermiteKey() { Value = coef0, In = slopes[0], Out = slopes[1], }); } break; case AnimCurveType.StepBool: convCurve.KeyFrames.Add(frame, new BooleanKey() { Value = curve.KeyStepBoolData[i], }); break; case AnimCurveType.StepInt: convCurve.KeyFrames.Add(frame, new KeyFrame() { Value = (int)curve.Keys[i, 0] + (int)curve.Offset }); break; case AnimCurveType.Linear: { var value = curve.Keys[i, 0] * valueScale + curve.Offset; if (useDegrees) { value *= Rad2Deg; } convCurve.KeyFrames.Add(frame, new LinearKeyFrame() { Value = value, Delta = curve.Keys[i, 1] * valueScale, }); } break; default: { var value = curve.Keys[i, 0] * valueScale + curve.Offset; if (useDegrees) { value *= Rad2Deg; } convCurve.KeyFrames.Add(frame, new KeyFrame() { Value = value }); } break; } } return(convCurve); }
public static AnimCurve GenerateCurve(CurveAnimHelper curveJson, uint target, bool isDegrees) { AnimCurve curve = new AnimCurve(); curve.Offset = curveJson.Offset; curve.Scale = curveJson.Scale; curve.CurveType = curveJson.Interpolation; curve.FrameType = curveJson.FrameType; curve.KeyType = curveJson.KeyType; curve.AnimDataOffset = target; var first = curveJson.KeyFrames.First(); var last = curveJson.KeyFrames.Last(); curve.EndFrame = last.Key; curve.StartFrame = first.Key; var keys = curveJson.KeyFrames.Values.ToList(); var frames = curveJson.KeyFrames.Keys.ToList(); curve.Frames = frames.ToArray(); curve.Keys = new float[keys.Count, 1]; if (curve.CurveType == AnimCurveType.Cubic) { curve.Keys = new float[keys.Count, 4]; } if (curve.CurveType == AnimCurveType.Linear) { curve.Keys = new float[keys.Count, 2]; } for (int i = 0; i < keys.Count; i++) { switch (curve.CurveType) { case AnimCurveType.Cubic: var hermiteKey = ToObject <HermiteKey>(keys[i]); float time = 0; float value = hermiteKey.Value; float outSlope = hermiteKey.Out; float nextValue = 0; float nextInSlope = 0; if (i < keys.Count - 1) { var nextKey = ToObject <HermiteKey>(keys[i + 1]); var nextFrame = frames[i + 1]; nextValue = nextKey.Value; nextInSlope = nextKey.In; time = nextFrame - frames[i]; } if (isDegrees) { value *= Deg2Rad; nextValue *= Deg2Rad; nextInSlope *= Deg2Rad; outSlope *= Deg2Rad; } float[] coefs = HermiteToCubicKey( value, nextValue, outSlope * time, nextInSlope * time); curve.Keys[i, 0] = coefs[0]; if (time != 0) { curve.Keys[i, 1] = coefs[1]; curve.Keys[i, 2] = coefs[2]; curve.Keys[i, 3] = coefs[3]; } break; case AnimCurveType.StepBool: var booleanKey = ToObject <BooleanKey>(keys[i]); curve.KeyStepBoolData[i] = booleanKey.Value; break; case AnimCurveType.Linear: var linearKey = ToObject <LinearKeyFrame>(keys[i]); float linearValue = linearKey.Value; if (isDegrees) { linearValue *= Deg2Rad; } curve.Keys[i, 0] = linearValue; curve.Keys[i, 1] = linearKey.Delta; break; case AnimCurveType.StepInt: var stepKey = ToObject <KeyFrame>(keys[i]); curve.Keys[i, 0] = stepKey.Value; break; } } if (curve.Keys.Length >= 2) { var lastKey = curve.Keys[keys.Count - 1, 0]; var firstKey = curve.Keys[0, 0]; curve.Delta = lastKey - firstKey; } for (int i = 0; i < keys.Count; i++) { curve.Keys[i, 0] -= curve.Offset; //Apply scale for cubic and linear curves only if (curve.CurveType == AnimCurveType.Cubic) { if (curve.Scale != 0) { curve.Keys[i, 0] /= curve.Scale; curve.Keys[i, 1] /= curve.Scale; curve.Keys[i, 2] /= curve.Scale; curve.Keys[i, 3] /= curve.Scale; } } else if (curve.CurveType == AnimCurveType.Linear) { if (curve.Scale != 0) { curve.Keys[i, 0] /= curve.Scale; curve.Keys[i, 1] /= curve.Scale; } } } return(curve); }