Esempio n. 1
0
        public static void EnsureQuaternionContinuityAndRecalculateSlope(BezierAnimationCurve x, BezierAnimationCurve y, BezierAnimationCurve z, BezierAnimationCurve w, Quaternion last)
        {
            var keyCount = x.length;

            if (keyCount < 2)
            {
                return;
            }
            for (var i = 0; i < keyCount; i++)
            {
                var cur = GetValue(x, y, z, w, i);
                if (Quaternion.Dot(cur, last) < 0.0f)
                {
                    cur = new Quaternion(-cur.x, -cur.y, -cur.z, -cur.w);
                }
                last = cur;
                SetValue(x, y, z, w, i, cur);
            }

            // for (int i = 0; i < keyCount; i++)
            // {
            //     RecalculateSplineSlopeT(x, i);
            //     RecalculateSplineSlopeT(y, i);
            //     RecalculateSplineSlopeT(z, i);
            //     RecalculateSplineSlopeT(w, i);
            // }
        }
Esempio n. 2
0
        public IEnumerable EvaluateLinear(TestContext context)
        {
            var curve = new BezierAnimationCurve {
                loop = false
            };

            curve.SetKeyframe(0, 10, CurveTypeValues.Linear);
            curve.SetKeyframe(1, 20, CurveTypeValues.Linear);
            curve.SetKeyframe(2, 30, CurveTypeValues.Linear);

            if (!context.Assert(curve.Evaluate(0.0f), 10f, "Linear/0"))
            {
                yield break;
            }
            if (!context.Assert(curve.Evaluate(0.5f), 15f, "Linear/1"))
            {
                yield break;
            }
            if (!context.Assert(curve.Evaluate(1.0f), 20f, "Linear/2"))
            {
                yield break;
            }
            if (!context.Assert(curve.Evaluate(1.5f), 25f, "Linear/3"))
            {
                yield break;
            }
            if (!context.Assert(curve.Evaluate(2.0f), 30f, "Linear/4"))
            {
                yield break;
            }
        }
Esempio n. 3
0
 private static void SetValue(BezierAnimationCurve x, BezierAnimationCurve y, BezierAnimationCurve z, BezierAnimationCurve w, int key, Quaternion q)
 {
     SetValue(x, key, q.x);
     SetValue(y, key, q.y);
     SetValue(z, key, q.z);
     SetValue(w, key, q.w);
 }
Esempio n. 4
0
        private static void SetValue(BezierAnimationCurve curve, int key, float value)
        {
            var keyframe = curve.GetKeyframeByKey(key);

            keyframe.value = value;
            curve.SetKeyframeByKey(key, keyframe);
        }
Esempio n. 5
0
        public IEnumerable KeyframeBinarySearch(TestContext context)
        {
            var curve = new BezierAnimationCurve();

            curve.SetKeyframe(0, 10, CurveTypeValues.Linear);
            curve.SetKeyframe(1, 20, CurveTypeValues.Linear);
            curve.SetKeyframe(2, 30, CurveTypeValues.Linear);

            if (!context.Assert(curve.KeyframeBinarySearch(0.0f), 0, "0.0f"))
            {
                yield break;
            }
            if (!context.Assert(curve.KeyframeBinarySearch(0.5f, true), 1, "0.5f"))
            {
                yield break;
            }
            if (!context.Assert(curve.KeyframeBinarySearch(1.0f), 1, "1.0f"))
            {
                yield break;
            }
            if (!context.Assert(curve.KeyframeBinarySearch(1.5f, true), 2, "1.5f"))
            {
                yield break;
            }
            if (!context.Assert(curve.KeyframeBinarySearch(2.0f), 2, "2.0f"))
            {
                yield break;
            }
        }
        private static void DeserializeCurveFromClassLegacy(BezierAnimationCurve curve, JSONNode curveJSON)
        {
            var keysJSON = curveJSON["keys"].AsArray;

            if (keysJSON.Count == 0)
            {
                return;
            }

            var last = -1f;

            foreach (JSONNode keyframeJSON in keysJSON)
            {
                var time = DeserializeFloat(keyframeJSON["time"]).Snap();
                if (time == last)
                {
                    continue;
                }
                last = time;
                var value    = DeserializeFloat(keyframeJSON["value"]);
                var keyframe = new BezierKeyframe(
                    time,
                    value,
                    CurveTypeValues.SmoothLocal
                    );
                curve.AddKey(keyframe);
            }
        }
Esempio n. 7
0
        private void BindCurve(BezierAnimationCurve lead, Color color, string label)
        {
            var lines = CreateCurvesLines(_linesContainer, color, label);

            _lines.Add(lines);
            lines.AddCurve(color, lead);
            lines.SetVerticesDirty();
        }
Esempio n. 8
0
        public IEnumerable AddAndRemoveFrames(TestContext context)
        {
            var curve = new BezierAnimationCurve();

            {
                var key = curve.SetKeyframe(0, 123, CurveTypeValues.Linear);
                if (!context.Assert(key, 0, "First key is zero"))
                {
                    yield break;
                }
                if (!context.Assert(curve.keys.Select(k => k.time), new[] { 0f }, "Expected one frame"))
                {
                    yield break;
                }
                context.Assert(curve.GetKeyframeByKey(curve.KeyframeBinarySearch(0)).value, 123, "Set and get at time 0");
            }

            {
                var key = curve.SetKeyframe(0.499999f, 456, CurveTypeValues.Linear);
                if (!context.Assert(key, 1, "Second key is one"))
                {
                    yield break;
                }
                if (!context.Assert(curve.keys.Select(k => k.time), new[] { 0f, 0.5f }, "Expected two frames"))
                {
                    yield break;
                }
                context.Assert(curve.GetKeyframeByKey(curve.KeyframeBinarySearch(0.000001f)).value, 123, "Set and get at time 0.000001");
                context.Assert(curve.GetKeyframeByKey(curve.KeyframeBinarySearch(0.499999f)).value, 456, "Set and get at time 0.499999");
            }

            {
                var key = curve.SetKeyframe(0.250f, 789, CurveTypeValues.Linear);
                if (!context.Assert(key, 1, "Third key is one"))
                {
                    yield break;
                }
                if (!context.Assert(curve.keys.Select(k => k.time), new[] { 0f, 0.250f, 0.5f }, "Expected three frames"))
                {
                    yield break;
                }
                context.Assert(curve.GetKeyframeByKey(curve.KeyframeBinarySearch(0.000001f)).value, 123, "Set and get at time 0.000001");
                context.Assert(curve.GetKeyframeByKey(curve.KeyframeBinarySearch(0.250f)).value, 789, "Set and get at time 0.250f");
                context.Assert(curve.GetKeyframeByKey(curve.KeyframeBinarySearch(0.499999f)).value, 456, "Set and get at time 0.499999");
            }

            {
                curve.RemoveKey(1);
                if (!context.Assert(curve.keys.Select(k => k.time), new[] { 0f, 0.5f }, "Expected two frames after remove"))
                {
                    yield break;
                }
            }

            yield break;
        }
Esempio n. 9
0
        public IEnumerable EvaluateSmoothGlobalNonLooping(TestContext context)
        {
            var curve = new BezierAnimationCurve {
                loop = false
            };

            curve.SetKeyframe(0, 100, CurveTypeValues.SmoothGlobal);
            curve.SetKeyframe(1, 200, CurveTypeValues.SmoothGlobal);
            curve.SetKeyframe(2, 300, CurveTypeValues.SmoothGlobal);
            curve.SetKeyframe(3, 200, CurveTypeValues.SmoothGlobal);
            curve.SetKeyframe(4, 100, CurveTypeValues.SmoothGlobal);
            curve.ComputeCurves();

            if (!context.Assert(curve.Evaluate(0.0f), 100f, "0.0"))
            {
                yield break;
            }
            if (!context.Assert(curve.Evaluate(0.5f).Snap(0.001f), 144.643f, "0.5"))
            {
                yield break;
            }
            if (!context.Assert(curve.Evaluate(1.0f), 200f, "1.0"))
            {
                yield break;
            }
            if (!context.Assert(curve.Evaluate(1.5f).Snap(0.001f), 266.071f, "1.5"))
            {
                yield break;
            }
            if (!context.Assert(curve.Evaluate(2.0f), 300f, "2.0"))
            {
                yield break;
            }
            if (!context.Assert(curve.Evaluate(2.5f).Snap(0.001f), 266.071f, "2.5"))
            {
                yield break;
            }
            if (!context.Assert(curve.Evaluate(3.0f), 200f, "3.0"))
            {
                yield break;
            }
            if (!context.Assert(curve.Evaluate(3.5f).Snap(0.001f), 144.643f, "3.5"))
            {
                yield break;
            }
            if (!context.Assert(curve.Evaluate(4.0f), 100f, "4.0"))
            {
                yield break;
            }
        }
Esempio n. 10
0
 protected void Validate(BezierAnimationCurve curve, float animationLength)
 {
     if (animationLength <= 0)
     {
         SuperController.LogError($"Target {name} has an invalid animation length of {animationLength}");
         return;
     }
     if (curve.length < 2)
     {
         SuperController.LogError($"Target {name} has {curve.length} frames");
         return;
     }
     if (curve.GetFirstFrame().time != 0)
     {
         SuperController.LogError($"Target {name} has no start frame. Frames: {string.Join(", ", curve.keys.Select(k => k.time.ToString(CultureInfo.InvariantCulture)).ToArray())}");
         return;
     }
     if (curve.duration > animationLength + 0.0001f)
     {
         SuperController.LogError($"Target {name} has  duration of {curve.duration:0.0000} but the animation should be {animationLength:0.0000}. Auto-repairing extraneous keys.");
         foreach (var c in GetCurves())
         {
             while (c.GetKeyframeByKey(c.length - 1).time > animationLength && c.length > 2)
             {
                 c.RemoveKey(c.length - 1);
             }
         }
         dirty = true;
     }
     if (curve.duration != animationLength)
     {
         if (Mathf.Abs(curve.duration - animationLength) > 0.0009f)
         {
             SuperController.LogError($"Target {name} ends with frame {curve.duration:0.0000} instead of expected {animationLength:0.0000}. Auto-repairing last frame.");
         }
         foreach (var c in GetCurves())
         {
             var keyframe = c.GetLastFrame();
             if (keyframe.time == animationLength)
             {
                 continue;
             }
             keyframe.time = animationLength;
             c.SetLastFrame(keyframe);
         }
         dirty = true;
     }
 }
 private void DeserializeCurve(BezierAnimationCurve curve, JSONNode curveJSON, ref bool dirty)
 {
     if (curveJSON is JSONArray)
     {
         DeserializeCurveFromArray(curve, (JSONArray)curveJSON, ref dirty);
     }
     if (curveJSON is JSONClass)
     {
         DeserializeCurveFromClassLegacy(curve, curveJSON);
         dirty = true;
     }
     else
     {
         DeserializeCurveFromStringLegacy(curve, curveJSON);
         dirty = true;
     }
 }
        private static void DeserializeCurveFromArray(BezierAnimationCurve curve, JSONArray curveJSON, ref bool dirty)
        {
            if (curveJSON.Count == 0)
            {
                return;
            }

            var last = -1f;

            foreach (JSONClass keyframeJSON in curveJSON)
            {
                try
                {
                    var time = float.Parse(keyframeJSON["t"], CultureInfo.InvariantCulture).Snap();
                    if (time == last)
                    {
                        continue;
                    }
                    last = time;
                    var value    = DeserializeFloat(keyframeJSON["v"]);
                    var keyframe = new BezierKeyframe
                    {
                        time            = time,
                        value           = value,
                        curveType       = int.Parse(keyframeJSON["c"]),
                        controlPointIn  = DeserializeFloat(keyframeJSON["i"]),
                        controlPointOut = DeserializeFloat(keyframeJSON["o"])
                    };
                    // Backward compatibility, tangents are not supported since bezier conversion.
                    if (keyframeJSON.HasKey("ti"))
                    {
                        dirty = true;
                        if (keyframe.curveType == CurveTypeValues.LeaveAsIs)
                        {
                            keyframe.curveType = CurveTypeValues.SmoothLocal;
                        }
                    }
                    curve.AddKey(keyframe);
                }
                catch (IndexOutOfRangeException exc)
                {
                    throw new InvalidOperationException($"Failed to read curve: {keyframeJSON}", exc);
                }
            }
        }
Esempio n. 13
0
        public IEnumerable RepairBrokenCurve(TestContext context)
        {
            var curve = new BezierAnimationCurve();

            curve.SetKeyframe(1, 2, CurveTypeValues.Linear);
            curve.SetKeyframe(2, 3, CurveTypeValues.Linear);
            curve.SetKeyframe(3, 4, CurveTypeValues.Linear);
            if (!context.Assert(curve.keys.Select(k => k.time), new[] { 1f, 2f, 3f }, "Expected broken curve"))
            {
                yield break;
            }

            curve.AddEdgeFramesIfMissing(5f, CurveTypeValues.Linear);
            if (!context.Assert(curve.keys.Select(k => k.time), new[] { 0f, 1f, 2f, 3f, 5f }, "Expected repaired curve"))
            {
                yield break;
            }
        }
        private static void DeserializeCurveFromStringLegacy(BezierAnimationCurve curve, JSONNode curveJSON)
        {
            var strFrames = curveJSON.Value.Split(';').Where(x => x != "").ToList();

            if (strFrames.Count == 0)
            {
                return;
            }

            var last = -1f;

            foreach (var strFrame in strFrames)
            {
                var parts = strFrame.Split(',');
                try
                {
                    var time = float.Parse(parts[0], CultureInfo.InvariantCulture).Snap();
                    if (time == last)
                    {
                        continue;
                    }
                    last = time;
                    var value    = DeserializeFloat(parts[1]);
                    var keyframe = new BezierKeyframe
                    {
                        time      = time,
                        value     = value,
                        curveType = int.Parse(parts[2])
                    };
                    // Backward compatibility, tangents are not supported since bezier conversion.
                    if (keyframe.curveType == CurveTypeValues.LeaveAsIs)
                    {
                        keyframe.curveType = CurveTypeValues.SmoothLocal;
                    }
                    curve.AddKey(keyframe);
                }
                catch (IndexOutOfRangeException exc)
                {
                    throw new InvalidOperationException($"Failed to read curve: {strFrame}", exc);
                }
            }
        }
        private static JSONNode SerializeCurve(BezierAnimationCurve curve)
        {
            var curveJSON = new JSONArray();

            for (var key = 0; key < curve.length; key++)
            {
                var keyframe   = curve.GetKeyframeByKey(key);
                var curveEntry = new JSONClass
                {
                    ["t"] = keyframe.time.ToString(CultureInfo.InvariantCulture),
                    ["v"] = keyframe.value.ToString(CultureInfo.InvariantCulture),
                    ["c"] = keyframe.curveType.ToString(CultureInfo.InvariantCulture),
                    ["i"] = keyframe.controlPointIn.ToString(CultureInfo.InvariantCulture),
                    ["o"] = keyframe.controlPointOut.ToString(CultureInfo.InvariantCulture)
                };
                curveJSON.Add(curveEntry);
            }

            return(curveJSON);
        }
Esempio n. 16
0
        // const float kDefaultWeight = 1.0f / 3.0f;
        // const float kCurveTimeEpsilon = 0.00001f;

        private static Quaternion GetValue(BezierAnimationCurve x, BezierAnimationCurve y, BezierAnimationCurve z, BezierAnimationCurve w, int key)
        {
            return(new Quaternion(x.GetKeyframeByKey(key).value, y.GetKeyframeByKey(key).value, z.GetKeyframeByKey(key).value, w.GetKeyframeByKey(key).value));
        }
Esempio n. 17
0
 public void AddCurve(Color color, BezierAnimationCurve curve)
 {
     _curves.Add(new KeyValuePair <Color, BezierAnimationCurve>(color, curve));
 }