Пример #1
0
        public void CreateAnimatedCubeScene()
        {
            TestContext.CurrentContext.AttachGltfValidatorLinks();

            var material = MaterialBuilder.CreateDefault();

            var mesh = new Cube <MaterialBuilder>(material)
                       .ToMesh(Matrix4x4.Identity);

            var pivot = new NodeBuilder();

            pivot.UseTranslation("track1")
            .WithPoint(0, Vector3.Zero)
            .WithPoint(1, Vector3.One);

            pivot.UseRotation("track1")
            .WithPoint(0, Quaternion.Identity)
            .WithPoint(1, Quaternion.CreateFromAxisAngle(Vector3.UnitY, 1.5f));

            pivot.UseScale("track1")
            .WithPoint(0, Vector3.One)
            .WithPoint(1, new Vector3(0.5f));

            var scene = new SceneBuilder();

            scene.AddRigidMesh(mesh, pivot);

            scene.AttachToCurrentTest("animated.glb");
            scene.AttachToCurrentTest("animated.gltf");
        }
Пример #2
0
        public void CreateSharedNodeInstanceScene()
        {
            // SceneBuilder API supports reusing a NodeBuilder in multiple instances with different content.
            // but glTF nodes can only hold one mesh per node, so if we find this case we need to internally
            // add an additional child node to give room to the the extra mesh.

            TestContext.CurrentContext.AttachGltfValidatorLinks();

            var m = MaterialBuilder.CreateDefault();

            var cube   = new Cube <MaterialBuilder>(m, 1.7f, 1.7f, 1.7f).ToMesh(Matrix4x4.Identity);
            var sphere = new IcoSphere <MaterialBuilder>(m).ToMesh(Matrix4x4.Identity);

            var armature1 = new NodeBuilder("Skeleton1");
            var joint0    = armature1
                            .CreateNode("Joint 0")
                            .WithLocalTranslation(new Vector3(0, 1, 0));

            var scene = new SceneBuilder();

            scene.AddRigidMesh(cube, joint0);
            scene.AddRigidMesh(sphere, joint0);

            scene.AttachToCurrentTest("instanced.glb");
            scene.AttachToCurrentTest("instanced.gltf");
        }
Пример #3
0
        public void CreateCubeSceneWithExtras()
        {
            TestContext.CurrentContext.AttachShowDirLink();
            TestContext.CurrentContext.AttachGltfValidatorLinks();

            var material = MaterialBuilder.CreateDefault();

            material.Name   = "hello name";
            material.Extras = IO.JsonContent.Serialize(new KeyValuePair <string, int>("hello", 16));

            var mesh = new Cube <MaterialBuilder>(material).ToMesh(Matrix4x4.Identity);

            mesh.Name   = "world name";
            mesh.Extras = "world extras";

            var scene = new SceneBuilder();

            scene.AddRigidMesh(mesh, Matrix4x4.Identity)
            .WithName("Cube")
            .WithExtras(17);

            scene.AttachToCurrentTest("cube.glb");
            scene.AttachToCurrentTest("cube.gltf");
            scene.AttachToCurrentTest("cube.plotly");
        }
Пример #4
0
        public void CreateSceneWithRandomShapes()
        {
            TestContext.CurrentContext.AttachShowDirLink();
            TestContext.CurrentContext.AttachGltfValidatorLinks();

            var rnd = new Random(177);

            // create materials
            var materials = Enumerable
                            .Range(0, 10)
                            .Select(idx => new Materials.MaterialBuilder()
                                    .WithChannelParam("BaseColor", new Vector4(rnd.NextVector3(), 1)))
                            .ToList();

            // create scene

            var scene = new SceneBuilder();

            for (int i = 0; i < 100; ++i)
            {
                // create mesh
                var mat  = materials[rnd.Next(0, 10)];
                var mesh = VPOSNRM.CreateCompatibleMesh("shape");

                #if DEBUG
                mesh.VertexPreprocessor.SetValidationPreprocessors();
                #else
                mesh.VertexPreprocessor.SetSanitizerPreprocessors();
                #endif

                if ((i & 1) == 0)
                {
                    mesh.AddCube(mat, Matrix4x4.Identity);
                }
                else
                {
                    mesh.AddSphere(mat, 0.5f, Matrix4x4.Identity);
                }

                mesh.Validate();

                // create random transform
                var r     = rnd.NextVector3() * 5;
                var xform = Matrix4x4.CreateFromYawPitchRoll(r.X, r.Y, r.Z) * Matrix4x4.CreateTranslation(rnd.NextVector3() * 25);

                scene.AddRigidMesh(mesh, xform);
            }

            // save the model as GLB

            scene.AttachToCurrentTest("shapes.glb");
            scene.AttachToCurrentTest("shapes.plotly");
        }
Пример #5
0
        public void CreateAllAnimationTypesScene()
        {
            // 3D View 7.1908.9012.0 has an issue displaying off-center meshes with animated morph targets.

            TestContext.CurrentContext.AttachShowDirLink();
            TestContext.CurrentContext.AttachGltfValidatorLinks();

            // create two materials

            var pink = new MaterialBuilder("material1")
                       .WithChannelParam(KnownChannel.BaseColor, new Vector4(1, 0, 1, 1));

            var yellow = new MaterialBuilder("material2")
                         .WithChannelParam(KnownChannel.BaseColor, new Vector4(1, 1, 0, 1));

            var scene = new SceneBuilder();

            var mesh1 = VPOSNRM.CreateCompatibleMesh("shape1");

            mesh1.AddCube(MaterialBuilder.CreateDefault(), Matrix4x4.Identity);
            var inst1 = scene.AddRigidMesh(mesh1, Matrix4x4.Identity);

            var mesh2 = VPOSNRM.CreateCompatibleMesh("shape2");

            mesh2.AddCube(pink, Matrix4x4.Identity);
            var inst2 = scene.AddRigidMesh(mesh2, Matrix4x4.CreateTranslation(2, 0, 0));

            scene.AttachToCurrentTest("static.glb");
            scene.AttachToCurrentTest("static.gltf");

            var morphBuilder = mesh2.UseMorphTarget(0);

            morphBuilder.SetVertexDelta(morphBuilder.Positions.ElementAt(0), (Vector3.UnitY, Vector3.Zero));
            morphBuilder.SetVertexDelta(morphBuilder.Positions.ElementAt(1), (Vector3.UnitY, Vector3.Zero));
            morphBuilder.SetVertexDelta(morphBuilder.Positions.ElementAt(2), (Vector3.UnitY, Vector3.Zero));
            morphBuilder.SetVertexDelta(morphBuilder.Positions.ElementAt(3), (Vector3.UnitY, Vector3.Zero));

            inst2.Content.UseMorphing().Value = Transforms.SparseWeight8.Create(1);

            var curve = inst2.Content.UseMorphing().UseTrackBuilder("Default");

            curve.SetPoint(0, Transforms.SparseWeight8.Create(0));
            curve.SetPoint(1, Transforms.SparseWeight8.Create(1));
            curve.SetPoint(2, Transforms.SparseWeight8.Create(0));

            var gltf = scene.ToGltf2();

            // Assert.AreEqual(1, gltf.LogicalMeshes[1].MorphWeights[0]);

            scene.AttachToCurrentTest("mopth.glb");
            scene.AttachToCurrentTest("mopth.gltf");
        }
Пример #6
0
        public void ExportMeshes(string path)
        {
            TestContext.CurrentContext.AttachGltfValidatorLinks();

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

            // load the glTF model
            var srcModel = ModelRoot.Load(path, Validation.ValidationMode.TryFix);

            Assert.NotNull(srcModel);

            srcModel.AttachToCurrentTest("GearBoxAssy.plotly");

            // convert it to a SceneBuilder so we can manipulate it:
            var srcScene = srcModel.DefaultScene.ToSceneBuilder();

            // export all the individual meshes to OBJ:
            for (int i = 0; i < srcScene.Instances.Count; ++i)
            {
                var inst = srcScene.Instances[i].Content;

                // scan for meshes:
                if (inst.Content is MeshContent mesh)
                {
                    var newScene = new SceneBuilder();

                    newScene.AddRigidMesh(mesh.Mesh, inst.GetPoseWorldMatrix());

                    newScene.AttachToCurrentTest($"result_{i}.obj");
                }
            }
        }
Пример #7
0
        public void CreateCubeScene()
        {
            TestContext.CurrentContext.AttachGltfValidatorLinks();

            var material = MaterialBuilder.CreateDefault();

            var mesh = new Cube <MaterialBuilder>(material).ToMesh(Matrix4x4.Identity);

            var scene = new SceneBuilder();

            scene.AddRigidMesh(mesh, Matrix4x4.Identity);

            scene.AttachToCurrentTest("cube.glb");
            scene.AttachToCurrentTest("cube.gltf");
            scene.AttachToCurrentTest("cube.plotly");
        }
Пример #8
0
        public void CreateNonConvexQuadsScene()
        {
            TestContext.CurrentContext.AttachShowDirLink();
            TestContext.CurrentContext.AttachGltfValidatorLinks();

            var mesh = new MeshBuilder <VertexPosition>();
            var prim = mesh.UsePrimitive(MaterialBuilder.CreateDefault());

            var idx = prim.AddQuadrangle(new VertexPosition(0, -1, 0), new VertexPosition(1, 0, 0), new VertexPosition(0, 1, 0), new VertexPosition(-1, 0, 0));

            Assert.AreEqual((0, 1, 2, 3), idx);

            idx = prim.AddQuadrangle(new VertexPosition(0, -1, 1), new VertexPosition(1, 0, 1), new VertexPosition(0, 1, 1), new VertexPosition(0.5f, 0, 1));
            Assert.AreEqual((4, 5, 6, 7), idx);

            idx = prim.AddQuadrangle(new VertexPosition(0, 0.5f, 2), new VertexPosition(1, 0, 2), new VertexPosition(0, 1, 2), new VertexPosition(-1, 0, 2));
            Assert.AreEqual((8, 9, 10, 11), idx);

            idx = prim.AddQuadrangle(new VertexPosition(1, 0, 3), new VertexPosition(0, 1, 3), new VertexPosition(0.5f, 0, 3), new VertexPosition(0, -1, 3));
            Assert.AreEqual((12, 13, 14, 15), idx);

            idx = prim.AddQuadrangle(new VertexPosition(1, 0, 4), new VertexPosition(1, 0, 4), new VertexPosition(0, 1, 4), new VertexPosition(-1, 0, 4));
            Assert.AreEqual((-1, 16, 17, 18), idx);

            idx = prim.AddQuadrangle(new VertexPosition(1, 0, 4), new VertexPosition(1, 0, 4), new VertexPosition(0, 1, 4), new VertexPosition(0, 1, 4));
            Assert.AreEqual((-1, -1, -1, -1), idx);

            idx = prim.AddQuadrangle(new VertexPosition(0, 0, 5), new VertexPosition(10, -1, 5), new VertexPosition(9, 0, 5), new VertexPosition(10, 1, 5));
            Assert.AreEqual((19, 20, 21, 22), idx);

            idx = prim.AddQuadrangle(new VertexPosition(10, -1, 6), new VertexPosition(9, 0, 6), new VertexPosition(10, 1, 6), new VertexPosition(0, 0, 6));
            Assert.AreEqual((23, 24, 25, 26), idx);

            var scene = new SceneBuilder();

            scene.AddRigidMesh(mesh, Matrix4x4.Identity);

            scene.AttachToCurrentTest("NonConvexQuads.glb");
            scene.AttachToCurrentTest("NonConvexQuads.gltf");
        }
Пример #9
0
        public void CreateSceneWithMixedVertexFormats()
        {
            TestContext.CurrentContext.AttachGltfValidatorLinks();

            var scene = new SceneBuilder();

            var mesh1 = new MeshBuilder <VertexPosition, VertexEmpty, VertexEmpty>();
            var mesh2 = new MeshBuilder <VertexPositionNormal, VertexEmpty, VertexEmpty>();

            mesh1.AddCube(MaterialBuilder.CreateDefault(), Matrix4x4.Identity);
            mesh2.AddCube(MaterialBuilder.CreateDefault(), Matrix4x4.Identity);

            scene.AddRigidMesh(mesh1, Matrix4x4.CreateTranslation(-2, 0, 0));
            scene.AddRigidMesh(mesh2, Matrix4x4.CreateTranslation(2, 0, 0));

            scene.AttachToCurrentTest("scene.glb");
        }
Пример #10
0
        public void CreateAllAnimationTypesScene()
        {
            // 3D View 7.1908.9012.0 has an issue displaying off-center meshes with animated morph targets.

            TestContext.CurrentContext.AttachGltfValidatorLinks();

            // create two materials

            var pink = new MaterialBuilder("material1")
                       .WithChannelParam(KnownChannel.BaseColor, KnownProperty.RGBA, new Vector4(1, 0, 1, 1));

            var yellow = new MaterialBuilder("material2")
                         .WithChannelParam(KnownChannel.BaseColor, KnownProperty.RGBA, new Vector4(1, 1, 0, 1));

            var mesh1 = VPOSNRM.CreateCompatibleMesh("shape1");

            mesh1.AddCube(pink, Matrix4x4.Identity);

            var mesh2 = VPOSNRM.CreateCompatibleMesh("shape2");

            mesh2.AddCube(yellow, Matrix4x4.Identity);

            var scene = new SceneBuilder();

            var inst1 = scene.AddRigidMesh(mesh1, Matrix4x4.Identity);

            // meshes intended to support animation must be created using an armature
            var armature = new NodeBuilder();

            armature.LocalTransform = Matrix4x4.CreateTranslation(2, 0, 0);
            var inst2 = scene.AddRigidMesh(mesh2, armature);

            scene.AttachToCurrentTest("static.glb");
            scene.AttachToCurrentTest("static.gltf");

            // up to this point, the scene has two plain unanimated cubes.

            var morphBuilder = mesh2.UseMorphTarget(0);

            morphBuilder.SetVertexDelta(morphBuilder.Positions.ElementAt(0), (Vector3.UnitY, Vector3.Zero));
            morphBuilder.SetVertexDelta(morphBuilder.Positions.ElementAt(1), (Vector3.UnitY, Vector3.Zero));
            morphBuilder.SetVertexDelta(morphBuilder.Positions.ElementAt(2), (Vector3.UnitY, Vector3.Zero));
            morphBuilder.SetVertexDelta(morphBuilder.Positions.ElementAt(3), (Vector3.UnitY, Vector3.Zero));

            // set default value.
            inst2.Content.UseMorphing().SetValue(1);

            // ser animation curve.
            var curve = inst2.Content.UseMorphing().UseTrackBuilder("Default");

            curve.SetPoint(0, true, 0);
            curve.SetPoint(1, true, 1);
            curve.SetPoint(2, true, 0);

            var gltf = scene.ToGltf2();

            TestContext.WriteLine(gltf.GetJsonPreview());

            var meshIdx = 1;

            Assert.AreEqual(1, gltf.LogicalMeshes[meshIdx].Primitives[0].MorphTargetsCount);
            Assert.AreEqual(1, gltf.LogicalMeshes[meshIdx].MorphWeights[0]);
            Assert.AreEqual(1, gltf.LogicalAnimations.Count);

            scene.AttachToCurrentTest("mopth.glb");
            scene.AttachToCurrentTest("mopth.gltf");
        }
Пример #11
0
        public void CreateDoubleSkinnedScene()
        {
            TestContext.CurrentContext.AttachGltfValidatorLinks();

            // create two materials

            var pink = new MaterialBuilder("material1")
                       .WithChannelParam(KnownChannel.BaseColor, KnownProperty.RGBA, new Vector4(1, 0, 1, 1))
                       .WithDoubleSide(true);

            var yellow = new MaterialBuilder("material2")
                         .WithChannelParam(KnownChannel.BaseColor, KnownProperty.RGBA, new Vector4(1, 1, 0, 1))
                         .WithDoubleSide(true);

            // create the mesh

            const int jointIdx0 = 0; // index of joint node 0
            const int jointIdx1 = 1; // index of joint node 1
            const int jointIdx2 = 2; // index of joint node 2

            var v1 = new SKINNEDVERTEX4(new Vector3(-10, 0, +10), (jointIdx0, 1));
            var v2 = new SKINNEDVERTEX4(new Vector3(+10, 0, +10), (jointIdx0, 1));
            var v3 = new SKINNEDVERTEX4(new Vector3(+10, 0, -10), (jointIdx0, 1));
            var v4 = new SKINNEDVERTEX4(new Vector3(-10, 0, -10), (jointIdx0, 1));

            var v5 = new SKINNEDVERTEX4(new Vector3(-10, 40, +10), (jointIdx0, 0.5f), (jointIdx1, 0.5f));
            var v6 = new SKINNEDVERTEX4(new Vector3(+10, 40, +10), (jointIdx0, 0.5f), (jointIdx1, 0.5f));
            var v7 = new SKINNEDVERTEX4(new Vector3(+10, 40, -10), (jointIdx0, 0.5f), (jointIdx1, 0.5f));
            var v8 = new SKINNEDVERTEX4(new Vector3(-10, 40, -10), (jointIdx0, 0.5f), (jointIdx1, 0.5f));

            var v9  = new SKINNEDVERTEX4(new Vector3(-5, 80, +5), (jointIdx2, 1));
            var v10 = new SKINNEDVERTEX4(new Vector3(+5, 80, +5), (jointIdx2, 1));
            var v11 = new SKINNEDVERTEX4(new Vector3(+5, 80, -5), (jointIdx2, 1));
            var v12 = new SKINNEDVERTEX4(new Vector3(-5, 80, -5), (jointIdx2, 1));

            var mesh = SKINNEDVERTEX4.CreateCompatibleMesh("mesh1");

            #if DEBUG
            mesh.VertexPreprocessor.SetValidationPreprocessors();
            #else
            mesh.VertexPreprocessor.SetSanitizerPreprocessors();
            #endif

            mesh.UsePrimitive(pink).AddQuadrangle(v1, v2, v6, v5);
            mesh.UsePrimitive(pink).AddQuadrangle(v2, v3, v7, v6);
            mesh.UsePrimitive(pink).AddQuadrangle(v3, v4, v8, v7);
            mesh.UsePrimitive(pink).AddQuadrangle(v4, v1, v5, v8);

            mesh.UsePrimitive(yellow).AddQuadrangle(v5, v6, v10, v9);
            mesh.UsePrimitive(yellow).AddQuadrangle(v6, v7, v11, v10);
            mesh.UsePrimitive(yellow).AddQuadrangle(v7, v8, v12, v11);
            mesh.UsePrimitive(yellow).AddQuadrangle(v8, v5, v9, v12);

            mesh.Validate();

            // create the skeleton armature 1 for the skinned mesh.

            var armature1 = new NodeBuilder("Skeleton1");
            var joint0    = armature1.CreateNode("Joint 0").WithLocalTranslation(new Vector3(0, 0, 0)); // jointIdx0
            var joint1    = joint0.CreateNode("Joint 1").WithLocalTranslation(new Vector3(0, 40, 0));   // jointIdx1
            var joint2    = joint1.CreateNode("Joint 2").WithLocalTranslation(new Vector3(0, 40, 0));   // jointIdx2

            joint1.UseRotation("Base Track")
            .WithPoint(1, Quaternion.Identity)
            .WithPoint(2, Quaternion.CreateFromYawPitchRoll(0, 1, 0))
            .WithPoint(3, Quaternion.CreateFromYawPitchRoll(0, 0, 1))
            .WithPoint(4, Quaternion.Identity);

            // create the skeleton armature 2 for the skinned mesh.

            var armature2 = new NodeBuilder("Skeleton2").WithLocalTranslation(new Vector3(100, 0, 0));
            var joint3    = armature2.CreateNode("Joint 3").WithLocalTranslation(new Vector3(0, 0, 0)); // jointIdx0
            var joint4    = joint3.CreateNode("Joint 4").WithLocalTranslation(new Vector3(0, 40, 0));   // jointIdx1
            var joint5    = joint4.CreateNode("Joint 5").WithLocalTranslation(new Vector3(0, 40, 0));   // jointIdx2

            joint4.UseRotation("Base Track")
            .WithPoint(1, Quaternion.Identity)
            .WithPoint(2, Quaternion.CreateFromYawPitchRoll(0, 1, 0))
            .WithPoint(3, Quaternion.CreateFromYawPitchRoll(0, 0, 1))
            .WithPoint(4, Quaternion.Identity);

            // create scene

            var scene = new SceneBuilder();

            scene.AddSkinnedMesh
            (
                mesh,
                armature1.WorldMatrix,
                joint0, // joint used for skinning joint index 0
                joint1, // joint used for skinning joint index 1
                joint2  // joint used for skinning joint index 2
            );

            scene.AddSkinnedMesh
            (
                mesh,
                armature2.WorldMatrix,
                joint3, // joint used for skinning joint index 0
                joint4, // joint used for skinning joint index 1
                joint5  // joint used for skinning joint index 2
            );

            scene.AttachToCurrentTest("skinned.glb");
            scene.AttachToCurrentTest("skinned.gltf");
        }
Пример #12
0
        public void CreateSceneWithRandomShapes(bool useGpuInstancing)
        {
            TestContext.CurrentContext.AttachGltfValidatorLinks();

            var rnd = new Random(177);

            // create materials

            var materials = Enumerable
                            .Range(0, 10)
                            .Select(idx => new MaterialBuilder()
                                    .WithChannelParam(KnownChannel.BaseColor, KnownProperty.RGBA, new Vector4(rnd.NextVector3(), 1)))
                            .ToList();

            // create meshes

            var sphereMeshes = Enumerable
                               .Range(0, 10)
                               .Select(idx => materials[idx])
                               .Select(mat =>
            {
                var mesh = VPOSNRM.CreateCompatibleMesh("shape");
                    #if DEBUG
                mesh.VertexPreprocessor.SetValidationPreprocessors();
                    #else
                mesh.VertexPreprocessor.SetSanitizerPreprocessors();
                    #endif
                mesh.AddSphere(mat, 0.5f, Matrix4x4.Identity);
                mesh.Validate();
                return(mesh);
            });

            var cubeMeshes = Enumerable
                             .Range(0, 10)
                             .Select(idx => materials[idx])
                             .Select(mat =>
            {
                var mesh = VPOSNRM.CreateCompatibleMesh("shape");
                    #if DEBUG
                mesh.VertexPreprocessor.SetValidationPreprocessors();
                    #else
                mesh.VertexPreprocessor.SetSanitizerPreprocessors();
                    #endif
                mesh.AddCube(mat, Matrix4x4.Identity);
                mesh.Validate();
                return(mesh);
            });

            var meshes = sphereMeshes.Concat(cubeMeshes).ToArray();

            // create scene

            var scene = new SceneBuilder();

            for (int i = 0; i < 100; ++i)
            {
                var mesh = meshes[rnd.Next(0, 20)];

                // create random transform
                var r = rnd.NextQuaternion();
                var t = rnd.NextVector3() * 25;

                scene.AddRigidMesh(mesh, (r, t));
            }

            // collapse to glTF


            var gltf = scene.ToGltf2(useGpuInstancing ? SceneBuilderSchema2Settings.WithGpuInstancing : SceneBuilderSchema2Settings.Default);

            var bounds = Runtime.MeshDecoder.EvaluateBoundingBox(gltf.DefaultScene);

            // Assert.AreEqual(defaultBounds,instancedBounds);

            // save the model as GLB

            gltf.AttachToCurrentTest("shapes.glb");
            scene.AttachToCurrentTest("shapes.plotly");
        }