public void TestAffineTransformIdentity()
        {
            var asMatrix     = new AffineTransform(Matrix4x4.Identity);
            var asDecomposed = new AffineTransform(null, null, null);

            NumericsAssert.AreEqual(Matrix4x4.Identity, asMatrix.Matrix);
            NumericsAssert.AreEqual(Matrix4x4.Identity, asDecomposed.Matrix);

            Assert.IsTrue(asMatrix.IsIdentity);
            Assert.IsTrue(asDecomposed.IsIdentity);
        }
        public void TestMatrixNormalization()
        {
            void testMatrix(Matrix4x4 m, float tolerance = 0)
            {
                var o = m;

                Matrix4x4Factory.NormalizeMatrix(ref m);

                NumericsAssert.AreEqual(o, m, tolerance);

                Assert.IsTrue(Matrix4x4.Decompose(m, out _, out _, out _));
                Assert.IsTrue(Matrix4x4.Invert(m, out _));
            }

            void testSkewed(Func <Matrix4x4, Matrix4x4> mf, float tolerance = 0)
            {
                var m = Matrix4x4.Identity;

                var o = m = mf(m);

                Assert.IsFalse(Matrix4x4.Decompose(m, out _, out _, out _));

                Matrix4x4Factory.NormalizeMatrix(ref m);

                NumericsAssert.AreEqual(o, m, tolerance);

                Assert.IsTrue(Matrix4x4.Decompose(m, out _, out _, out _));
                Assert.IsTrue(Matrix4x4.Invert(m, out _));
            }

            testSkewed(m => { m.M12 += 0.34f; return(m); }, 0.34f);
            testSkewed(m => { m.M13 += 0.34f; return(m); }, 0.34f);
            testSkewed(m => { m.M21 += 0.34f; return(m); }, 0.34f);
            testSkewed(m => { m.M23 += 0.34f; return(m); }, 0.34f);
            testSkewed(m => { m.M31 += 0.34f; return(m); }, 0.34f);
            testSkewed(m => { m.M32 += 0.34f; return(m); }, 0.34f);

            testSkewed(m => { m.M12 += 0.1f; m.M23 -= 0.1f; m.M31 += 0.05f; return(m); }, 0.20f);

            // test normalization with uneven scaling

            testMatrix(Matrix4x4.CreateScale(0.0001f) * Matrix4x4.CreateFromYawPitchRoll(1, 2, 3), 0.0001f);
            testMatrix(Matrix4x4.CreateScale(1000) * Matrix4x4.CreateFromYawPitchRoll(1, 2, 3), 0.0001f);

            var SxR = Matrix4x4.CreateScale(5, 1, 1) * Matrix4x4.CreateFromYawPitchRoll(1, 2, 3);   // Decomposable
            var RxS = Matrix4x4.CreateFromYawPitchRoll(1, 2, 3) * Matrix4x4.CreateScale(5, 1, 1);   // Not Decomposable

            Assert.IsTrue(Matrix4x4.Decompose(SxR, out _, out _, out _));
            testMatrix(SxR, 0.0001f);

            Assert.IsFalse(Matrix4x4.Decompose(RxS, out _, out _, out _));
            testMatrix(RxS, 100);
        }
Пример #3
0
        public void TestAffineTransformMult()
        {
            var a = Matrix4x4.CreateScale(1, 2, 4) * Matrix4x4.CreateFromYawPitchRoll(1, 2, 3);
            var b = Matrix4x4.CreateFromYawPitchRoll(1, 0, 2) * Matrix4x4.CreateTranslation(3, -4, 2);
            var r = Matrix4x4.Multiply(a, b);

            var aa = new AffineTransform(a);
            var bb = new AffineTransform(b);
            var rr = AffineTransform.Multiply(aa, bb);

            NumericsAssert.AreEqual(r, rr.Matrix, 0.0001f);
        }
Пример #4
0
        public void CreateRotationCurve1()
        {
            // Create a Quaternion curve

            var curve = CurveFactory.CreateCurveBuilder <Quaternion>();

            curve
            .WithPoint(0, Quaternion.Identity);

            curve
            .WithPoint(1, Quaternion.CreateFromAxisAngle(Vector3.UnitX, 1))
            .WithOutgoingTangent(1, Quaternion.CreateFromAxisAngle(Vector3.UnitX, 1));

            curve
            .WithPoint(2, Quaternion.CreateFromAxisAngle(Vector3.UnitX, 1))
            .WithIncomingTangent(2, Quaternion.CreateFromAxisAngle(Vector3.UnitX, -1));

            // convert and resample the curve to a linear and cubic curves.

            var convertible = curve as IConvertibleCurve <Quaternion>;

            Assert.NotNull(convertible);

            var linear = convertible.ToLinearCurve().Select(kvp => (kvp.Key, kvp.Value)).CreateSampler();
            var spline = convertible.ToSplineCurve().Select(kvp => (kvp.Key, kvp.Value)).CreateSampler();

            // check if both curves are roughly the same.

            for (float t = 0; t < 2; t += 0.01f)
            {
                var cc = curve.GetPoint(t);
                var ls = linear.GetPoint(t);
                var ss = spline.GetPoint(t);

                NumericsAssert.AreEqual(cc, ss, 0.05f);
                NumericsAssert.AreEqual(cc, ls, 0.05f);
                NumericsAssert.AreEqual(ls, ss, 0.05f);
            }

            // plot the curve.

            convertible
            .ToLinearCurve()
            .Select(kvp => new Vector2(kvp.Key, kvp.Value.W))
            .ToPointSeries()
            .WithLineType(Plotting.LineType.Continuous)
            .AttachToCurrentTest("plot.png");
        }
Пример #5
0
        public void CreateTranslationCurve1()
        {
            // Create a Vector3 curve

            var curve = CurveFactory.CreateCurveBuilder <Vector3>();

            curve
            .WithPoint(0, 0, 0, 0);

            curve
            .WithPoint(1, 1, 1, 1)
            .WithOutgoingTangent(1, 0, 4, 0);

            curve
            .WithPoint(2, 2, 1, 1)
            .WithIncomingTangent(2, 0, -4, 0);

            // convert and resample the curve to a linear and cubic curves.

            var convertible = curve as IConvertibleCurve <Vector3>;

            Assert.NotNull(convertible);

            var linear = convertible.ToLinearCurve().Select(kvp => (kvp.Key, kvp.Value)).CreateSampler();
            var spline = convertible.ToSplineCurve().Select(kvp => (kvp.Key, kvp.Value)).CreateSampler();

            // check if both curves are roughly the same.

            for (float t = 0; t < 2; t += 0.01f)
            {
                var cc = curve.GetPoint(t);
                var ls = linear.GetPoint(t);
                var ss = spline.GetPoint(t);

                NumericsAssert.AreEqual(cc, ls, 0.002f);
                NumericsAssert.AreEqual(cc, ss, 0.002f);
                NumericsAssert.AreEqual(ls, ss, 0.002f);
            }

            // plot the curve.

            convertible
            .ToLinearCurve()
            .Select(kvp => new Vector2(kvp.Value.X, kvp.Value.Y))
            .ToPointSeries()
            .WithLineType(Plotting.LineType.Continuous)
            .AttachToCurrentTest("plot.png");
        }
Пример #6
0
        public void CalculateInverseBindMatrix(float mx, float my, float mz, float jx, float jy, float jz)
        {
            var model = Matrix4x4.CreateFromYawPitchRoll(mx, my, mz);
            var joint = Matrix4x4.CreateFromYawPitchRoll(jx, jy, jz);

            joint.Translation = new Vector3(jx, jy, jz);

            var invBindMatrix = SkinTransform.CalculateInverseBinding(model, joint);

            Matrix4x4.Invert(model, out Matrix4x4 xform);
            Matrix4x4.Invert(joint * xform, out Matrix4x4 result);
            NumericsAssert.AreEqual(result, invBindMatrix, 0.000001f);

            Matrix4x4.Invert(joint, out Matrix4x4 invJoint);
            result = model * invJoint;
            NumericsAssert.AreEqual(result, invBindMatrix, 0.000001f);
        }
Пример #7
0
        public void TestFloatingArrayEncoding2()
        {
            var v1 = new Vector4(0.1f, 0.2f, 0.6f, 0.8f);
            var v2 = new Vector4(1, 2, 3, 4);

            var bytes = new Byte[256];

            var v4n = new Vector4Array(bytes, 0, 5, 8, Schema2.EncodingType.UNSIGNED_BYTE, true);
            var v4u = new Vector4Array(bytes, 4, 5, 8, Schema2.EncodingType.UNSIGNED_BYTE, false);

            v4n[1] = v1;
            NumericsAssert.AreEqual(v4n[1], v1, 0.1f);


            v4u[1] = v2;
            NumericsAssert.AreEqual(v4u[1], v2);
        }
Пример #8
0
        public void CreateMeshInSanitizedMode()
        {
            var mesh = VERTEX2.CreateCompatibleMesh();

            mesh.VertexPreprocessor.SetSanitizerPreprocessors();

            var prim = mesh.UsePrimitive(Materials.MaterialBuilder.CreateDefault(), 1);

            var p = new VertexPositionNormal(Vector3.UnitX, new Vector3(float.NaN));
            var m = new VertexColor1Texture1(Vector4.One * 7, new Vector2(float.NaN));
            var s = new VertexJoints4((0, 2), (1, 7), (2, 6), (3, 5));

            var v1Idx = prim.AddPoint(new VERTEX2(p, m, s));
            var v1Bis = prim.Vertices[v1Idx];

            NumericsAssert.AreEqual(v1Bis.Geometry.Position, Vector3.UnitX);
            NumericsAssert.AreEqual(v1Bis.Geometry.Normal, Vector3.UnitX);
            NumericsAssert.AreEqual(v1Bis.Material.Color, Vector4.One);
            NumericsAssert.AreEqual(v1Bis.Material.TexCoord, Vector2.Zero);
            NumericsAssert.AreEqual(v1Bis.Skinning.Joints, new Vector4(1, 2, 3, 0));
            NumericsAssert.AreEqual(v1Bis.Skinning.Weights, new Vector4(7, 6, 5, 2) / (7f + 6f + 5f + 2f));
        }
        public void TestAffineTransformMult()
        {
            var s_a = new Vector3(1, 2, 4);
            var r_a = Quaternion.CreateFromYawPitchRoll(1, 2, 3);
            var t_a = Vector3.Zero;

            var s_b = new Vector3(1, 1, 1);
            var r_b = Quaternion.CreateFromYawPitchRoll(1, 0, 2);
            var t_b = new Vector3(3, -4, 2);

            var mat_a  = Matrix4x4.CreateScale(s_a) * Matrix4x4.CreateFromQuaternion(r_a) * Matrix4x4.CreateTranslation(t_a);
            var mat_b  = Matrix4x4.CreateScale(s_b) * Matrix4x4.CreateFromQuaternion(r_b) * Matrix4x4.CreateTranslation(t_b);
            var mat_ab = Matrix4x4.Multiply(mat_a, mat_b);
            var mat_ba = Matrix4x4.Multiply(mat_b, mat_a);

            var srt_a  = new AffineTransform(s_a, r_a, t_a);
            var srt_b  = new AffineTransform(s_b, r_b, t_b);
            var srt_ab = AffineTransform.Multiply(srt_a, srt_b);
            var srt_ba = AffineTransform.Multiply(srt_b, srt_a);

            NumericsAssert.AreEqual(mat_ab, srt_ab.Matrix, 0.0001f);
            NumericsAssert.AreEqual(mat_ba, srt_ba.Matrix, 0.0001f);
        }
Пример #10
0
        public void TestRoundTrip(string path)
        {
            TestContext.CurrentContext.AttachGltfValidatorLinks();

            path = TestFiles
                   .GetSampleModelsPaths()
                   .FirstOrDefault(item => item.Contains(path));

            var srcModel = Schema2.ModelRoot.Load(path, Validation.ValidationMode.TryFix);

            Assert.NotNull(srcModel);

            // perform roundtrip

            var srcScene = Toolkit.ToSceneBuilder(srcModel.DefaultScene);

            var rowModel = srcScene.ToGltf2();

            var settings = SceneBuilderSchema2Settings.Default;

            settings.UseStridedBuffers = false;
            var colModel = srcScene.ToGltf2(settings);

            var rowScene = Toolkit.ToSceneBuilder(rowModel.DefaultScene);
            var colScene = Toolkit.ToSceneBuilder(colModel.DefaultScene);

            // compare files

            var srcTris = srcModel.DefaultScene.EvaluateTriangles().ToList();
            var rowTris = rowModel.DefaultScene.EvaluateTriangles().ToList();
            var colTris = colModel.DefaultScene.EvaluateTriangles().ToList();

            Assert.AreEqual(srcTris.Count, rowTris.Count);
            Assert.AreEqual(srcTris.Count, colTris.Count);

            var srcRep = Reporting.ModelReport.CreateReportFrom(srcModel);
            var rowRep = Reporting.ModelReport.CreateReportFrom(rowModel);
            var colRep = Reporting.ModelReport.CreateReportFrom(colModel);

            Assert.AreEqual(srcRep.NumTriangles, rowRep.NumTriangles);
            NumericsAssert.AreEqual(srcRep.Bounds.Min, rowRep.Bounds.Min, 0.0001f);
            NumericsAssert.AreEqual(srcRep.Bounds.Max, rowRep.Bounds.Max, 0.0001f);

            // save file

            path = System.IO.Path.GetFileNameWithoutExtension(path);

            srcModel.AttachToCurrentTest(path + "_src" + ".plotly");

            srcModel.AttachToCurrentTest(path + "_src" + ".glb");
            rowModel.AttachToCurrentTest(path + "_row" + ".glb");
            colModel.AttachToCurrentTest(path + "_col" + ".glb");

            srcModel.AttachToCurrentTest(path + "_src" + ".gltf");
            rowModel.AttachToCurrentTest(path + "_row" + ".gltf");
            colModel.AttachToCurrentTest(path + "_col" + ".gltf");

            srcModel.AttachToCurrentTest(path + "_src" + ".obj");
            rowModel.AttachToCurrentTest(path + "_row" + ".obj");
            colModel.AttachToCurrentTest(path + "_col" + ".obj");

            if (srcModel.LogicalAnimations.Count > 0)
            {
                srcModel.AttachToCurrentTest(path + "_src_at01" + ".obj", srcModel.LogicalAnimations[0], 0.1f);

                if (rowModel.LogicalAnimations.Count > 0)
                {
                    rowModel.AttachToCurrentTest(path + "_row_at01" + ".obj", rowModel.LogicalAnimations[0], 0.1f);
                }
            }
        }