public void MultiplyTest()
        {
            var traits = SrtTransformTraits.Instance;
            var value  = NextRandomValue();

            Assert.IsTrue(SrtTransform.AreNumericallyEqual(SrtTransform.Identity, traits.Multiply(value, 0)));
            Assert.IsTrue(SrtTransform.AreNumericallyEqual(value, traits.Multiply(value, 1)));
            Assert.IsTrue(SrtTransform.AreNumericallyEqual(value * value, traits.Multiply(value, 2)));
            Assert.IsTrue(SrtTransform.AreNumericallyEqual(value * value * value, traits.Multiply(value, 3)));
            Assert.IsTrue(SrtTransform.AreNumericallyEqual(value.Inverse, traits.Multiply(value, -1)));
            Assert.IsTrue(SrtTransform.AreNumericallyEqual(value.Inverse * value.Inverse, traits.Multiply(value, -2)));
            Assert.IsTrue(SrtTransform.AreNumericallyEqual(value.Inverse * value.Inverse * value.Inverse, traits.Multiply(value, -3)));
        }
        public void FromByTest()
        {
            // IAnimationValueTraits<T> is used in a from-by animation to a add a relative offset to
            // the start value.

            var traits = SrtTransformTraits.Instance;
            var from   = NextRandomValue();
            var by     = NextRandomValue();

            var to = traits.Add(from, by);

            Assert.IsTrue(SrtTransform.AreNumericallyEqual(by * from, to));

            Assert.IsTrue(SrtTransform.AreNumericallyEqual(from, traits.Add(to, traits.Inverse(by))));
            Assert.IsTrue(SrtTransform.AreNumericallyEqual(by, traits.Add(traits.Inverse(from), to)));
        }
        public void CycleOffsetTest()
        {
            // IAnimationValueTraits<T> is used in a cyclic animation to a add the cycle offset in
            // each iteration.

            var traits      = SrtTransformTraits.Instance;
            var first       = NextRandomValue(); // Animation value of first key frame.
            var last        = NextRandomValue(); // Animation value of last key frame.
            var cycleOffset = traits.Add(traits.Inverse(first), last);

            // Cycle offset should be the difference between last and first key frame.
            Assert.IsTrue(SrtTransform.AreNumericallyEqual(last, traits.Add(first, cycleOffset)));
            Assert.IsTrue(SrtTransform.AreNumericallyEqual(last, cycleOffset * first));

            // Check multiple cycles (post-loop).
            Assert.IsTrue(SrtTransform.AreNumericallyEqual(last, traits.Add(first, traits.Multiply(cycleOffset, 1))));
            Assert.IsTrue(SrtTransform.AreNumericallyEqual(cycleOffset * cycleOffset * last, traits.Add(first, traits.Multiply(cycleOffset, 3))));

            // Check multiple cycles (pre-loop).
            Assert.IsTrue(SrtTransform.AreNumericallyEqual(first, traits.Add(last, traits.Multiply(cycleOffset, -1))));
            Assert.IsTrue(SrtTransform.AreNumericallyEqual(cycleOffset.Inverse * cycleOffset.Inverse * first, traits.Add(last, traits.Multiply(cycleOffset, -3))));
        }
Пример #4
0
        public void InverseTest()
        {
            var identity = SrtTransform.Identity;
            var a        = new SrtTransform(new Vector3F(-2, -2, -2), new QuaternionF(1, 2, 3, 4).Normalized, new Vector3F(4, -5, 6));
            var aInverse = a.Inverse;

            var aa = a * aInverse;

            Assert.IsTrue(SrtTransform.AreNumericallyEqual(identity, aa));

            aa = aInverse * a;
            Assert.IsTrue(SrtTransform.AreNumericallyEqual(identity, aa));


            a        = new SrtTransform(new Vector3F(-3, 7, -4), QuaternionF.Identity, new Vector3F(4, -5, 6));
            aInverse = a.Inverse;

            aa = a * aInverse;
            Assert.IsTrue(SrtTransform.AreNumericallyEqual(identity, aa));

            aa = aInverse * a;
            Assert.IsTrue(SrtTransform.AreNumericallyEqual(identity, aa));
        }
Пример #5
0
        public void CompressSrtKeyFrameAnimation()
        {
            var random = new Random(12345);

            float scaleThreshold       = 0.1f;
            float rotationThreshold    = 2; // [°]
            float translationThreshold = 0.2f;

            var srtKeyFrameAnimation = new SrtKeyFrameAnimation();

            // Define a view important keyframes.
            var time0  = TimeSpan.FromTicks(100000);
            var value0 = new SrtTransform(Vector3F.One, QuaternionF.Identity, Vector3F.Zero);

            var time1  = TimeSpan.FromTicks(200000);
            var value1 = new SrtTransform(new Vector3F(2, 2, 2), QuaternionF.CreateRotationX(MathHelper.ToRadians(10)), new Vector3F(1, 1, 1));

            var time2  = TimeSpan.FromTicks(400000);
            var value2 = new SrtTransform(new Vector3F(-1, -1, -1), QuaternionF.CreateRotationX(MathHelper.ToRadians(80)), new Vector3F(10, 10, 10));

            var time3  = TimeSpan.FromTicks(500000);
            var value3 = new SrtTransform(new Vector3F(3, 3, 3), QuaternionF.CreateRotationX(MathHelper.ToRadians(-10)), new Vector3F(-2, -2, -2));

            srtKeyFrameAnimation.KeyFrames.Add(new KeyFrame <SrtTransform>(time0, value0));
            srtKeyFrameAnimation.KeyFrames.Add(new KeyFrame <SrtTransform>(time1, value1));
            srtKeyFrameAnimation.KeyFrames.Add(new KeyFrame <SrtTransform>(time2, value2));
            srtKeyFrameAnimation.KeyFrames.Add(new KeyFrame <SrtTransform>(time3, value3));

            // Add random keyframes within tolerance.
            InsertRandomKeyFrames(random, srtKeyFrameAnimation, time0, time1, scaleThreshold, rotationThreshold, translationThreshold);
            InsertRandomKeyFrames(random, srtKeyFrameAnimation, time1, time2, scaleThreshold, rotationThreshold, translationThreshold);
            InsertRandomKeyFrames(random, srtKeyFrameAnimation, time2, time3, scaleThreshold, rotationThreshold, translationThreshold);

            // ---- Compress animation with tolerance.
            var srtAnimation = AnimationHelper.Compress(srtKeyFrameAnimation, scaleThreshold, rotationThreshold, translationThreshold);

            Assert.IsNotNull(srtAnimation);
            Assert.AreEqual(srtKeyFrameAnimation.GetTotalDuration(), srtAnimation.GetTotalDuration());
            Assert.IsNotNull(srtAnimation.Scale);

            Assert.AreEqual(4, ((KeyFrameAnimation <Vector3F>)srtAnimation.Scale).KeyFrames.Count);
            Assert.AreEqual(4, ((KeyFrameAnimation <QuaternionF>)srtAnimation.Rotation).KeyFrames.Count);
            Assert.AreEqual(4, ((KeyFrameAnimation <Vector3F>)srtAnimation.Translation).KeyFrames.Count);

            var defaultSource = SrtTransform.Identity;
            var defaultTarget = SrtTransform.Identity;
            var result        = new SrtTransform();

            srtAnimation.GetValue(time0, ref defaultSource, ref defaultTarget, ref result);
            Assert.AreEqual(value0, result);

            srtAnimation.GetValue(time1, ref defaultSource, ref defaultTarget, ref result);
            Assert.AreEqual(value1, result);

            srtAnimation.GetValue(time2, ref defaultSource, ref defaultTarget, ref result);
            Assert.AreEqual(value2, result);

            srtAnimation.GetValue(time3, ref defaultSource, ref defaultTarget, ref result);
            Assert.AreEqual(value3, result);

            // Take a view samples.
            const int numberOfSamples = 10;
            long      tickIncrement   = (time3 - time0).Ticks / (numberOfSamples + 1);

            for (int i = 0; i < numberOfSamples; i++)
            {
                var time = TimeSpan.FromTicks(time0.Ticks + (i + 1) * tickIncrement);

                var valueRef = new SrtTransform();
                srtKeyFrameAnimation.GetValue(time, ref defaultSource, ref defaultTarget, ref valueRef);

                var valueNew = new SrtTransform();
                srtAnimation.GetValue(time, ref defaultSource, ref defaultTarget, ref valueNew);

                Assert.IsTrue((valueRef.Scale - valueNew.Scale).Length <= scaleThreshold);
                Assert.IsTrue(QuaternionF.GetAngle(valueRef.Rotation, valueNew.Rotation) <= MathHelper.ToRadians(rotationThreshold));
                Assert.IsTrue((valueRef.Translation - valueNew.Translation).Length <= translationThreshold);
            }

            // ----- Compress animation with zero tolerance.
            srtAnimation = AnimationHelper.Compress(srtKeyFrameAnimation, 0, 0, 0);

            Assert.IsNotNull(srtAnimation);
            Assert.AreEqual(srtKeyFrameAnimation.GetTotalDuration(), srtAnimation.GetTotalDuration());
            Assert.IsNotNull(srtAnimation.Scale);

            Assert.AreEqual(srtKeyFrameAnimation.KeyFrames.Count, ((KeyFrameAnimation <Vector3F>)srtAnimation.Scale).KeyFrames.Count);
            Assert.AreEqual(srtKeyFrameAnimation.KeyFrames.Count, ((KeyFrameAnimation <QuaternionF>)srtAnimation.Rotation).KeyFrames.Count);
            Assert.AreEqual(srtKeyFrameAnimation.KeyFrames.Count, ((KeyFrameAnimation <Vector3F>)srtAnimation.Translation).KeyFrames.Count);

            // Take a view samples.
            for (int i = 0; i < numberOfSamples; i++)
            {
                var time = TimeSpan.FromTicks(time0.Ticks + (i + 1) * tickIncrement);

                var valueRef = new SrtTransform();
                srtKeyFrameAnimation.GetValue(time, ref defaultSource, ref defaultTarget, ref valueRef);

                var valueNew = new SrtTransform();
                srtAnimation.GetValue(time, ref defaultSource, ref defaultTarget, ref valueNew);

                Assert.IsTrue(SrtTransform.AreNumericallyEqual(valueRef, valueNew));
            }
        }