Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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);
        }