public static void CreateWithDegeneratedTriangle() { var validTriangle = ( new Vector3(4373.192624189425f, 5522.678275192156f, -359.8238015332605f), new Vector3(4370.978060142137f, 5522.723320999183f, -359.89184701762827f), new Vector3(4364.615741107147f, 5511.510615546256f, -359.08922455413233f) ); var degeneratedTriangle = ( new Vector3(4374.713581837248f, 5519.741978117265f, -360.87014389818034f), new Vector3(4373.187151107471f, 5521.493282925338f, -355.70835120644153f), new Vector3(4373.187151107471f, 5521.493282925338f, -355.70835120644153f) ); var material1 = new Materials.MaterialBuilder() .WithMetallicRoughnessShader() .WithChannelParam("BaseColor", Vector4.One * 0.5f); var material2 = new Materials.MaterialBuilder() .WithMetallicRoughnessShader() .WithChannelParam("BaseColor", Vector4.One * 0.7f); var mesh = new MeshBuilder <VertexPosition>("mesh"); mesh.VertexPreprocessor.SetDebugPreprocessors(); var validIndices = mesh.UsePrimitive(material1) .AddTriangle ( new VertexPosition(validTriangle.Item1), new VertexPosition(validTriangle.Item2), new VertexPosition(validTriangle.Item3) ); Assert.GreaterOrEqual(validIndices.A, 0); Assert.GreaterOrEqual(validIndices.B, 0); Assert.GreaterOrEqual(validIndices.C, 0); var degenIndices = mesh.UsePrimitive(material2) .AddTriangle ( new VertexPosition(degeneratedTriangle.Item1), new VertexPosition(degeneratedTriangle.Item2), new VertexPosition(degeneratedTriangle.Item3) ); Assert.Less(degenIndices.A, 0); Assert.Less(degenIndices.B, 0); Assert.Less(degenIndices.C, 0); // create meshes: var model = ModelRoot.CreateModel(); var dstMeshes = model.CreateMeshes(mesh); Assert.AreEqual(1, dstMeshes[0].Primitives.Count); }
public void CreateSceneWithPointCloud() { TestContext.CurrentContext.AttachShowDirLink(); TestContext.CurrentContext.AttachGltfValidatorLinks(); var material = new MaterialBuilder("material1").WithUnlitShader(); var mesh = new MeshBuilder <VPOS, Geometry.VertexTypes.VertexColor1>("points"); mesh.VertexPreprocessor.SetDebugPreprocessors(); // create a point cloud primitive var pointCloud = mesh.UsePrimitive(material, 1); var rnd = new Random(178); for (int i = 0; i < 1000000; ++i) { var x = (float)(rnd.NextDouble() * 2 - 1); var y = (float)(rnd.NextDouble() * 2 - 1); var z = (float)(rnd.NextDouble() * 2 - 1); var opacity = Math.Max(Math.Max(Math.Abs(x), Math.Abs(y)), Math.Abs(z)); opacity = opacity * opacity * opacity * opacity; var r = (float)rnd.NextDouble() * opacity; var g = (float)rnd.NextDouble() * opacity; var b = (float)rnd.NextDouble() * opacity; x *= 50; y *= 50; z *= 50; pointCloud.AddPoint((new Vector3(x, y + 60, z), new Vector4(r, g, b, 1))); } // adds 4 lines as the base of the points mesh.UsePrimitive(material, 2).AddLine((new Vector3(-50, 0, -50), Vector4.One), (new Vector3(+50, 0, -50), Vector4.UnitW)); mesh.UsePrimitive(material, 2).AddLine((new Vector3(+50, 0, -50), Vector4.One), (new Vector3(+50, 0, +50), Vector4.UnitW)); mesh.UsePrimitive(material, 2).AddLine((new Vector3(+50, 0, +50), Vector4.One), (new Vector3(-50, 0, +50), Vector4.UnitW)); mesh.UsePrimitive(material, 2).AddLine((new Vector3(-50, 0, +50), Vector4.One), (new Vector3(-50, 0, -50), Vector4.UnitW)); // create a new gltf model var model = ModelRoot.CreateModel(); // add all meshes (just one in this case) to the model model.CreateMeshes(mesh); // create a scene, a node, and assign the first mesh (the terrain) model.UseScene("Default") .CreateNode().WithMesh(model.LogicalMeshes[0]); // save the model as GLB model.AttachToCurrentTest("PointCloud.glb"); }
public void CreateSceneWithMeshBuilder() { TestContext.CurrentContext.AttachShowDirLink(); TestContext.CurrentContext.AttachGltfValidatorLinks(); // create a material var material1 = new MaterialBuilder("material1") .WithChannelParam(KnownChannel.BaseColor, Vector4.One); // create model var meshBuilder = new MeshBuilder <VPOSNRM>("mesh1"); meshBuilder.VertexPreprocessor.SetDebugPreprocessors(); // define 4 vertices var v1 = new VPOSNRM(-10, 10, 0, 0, 0, 1); var v2 = new VPOSNRM(10, 10, 0, 0, 0, 1); var v3 = new VPOSNRM(10, -10, 0, 0, 0, 1); var v4 = new VPOSNRM(-10, -10, 0, 0, 0, 1); // add a polygon to the primitive that uses material1 as key. meshBuilder.UsePrimitive(material1).AddQuadrangle(v1, v2, v3, v4); // create a scene var scene = new SceneBuilder(); scene.AddRigidMesh(meshBuilder, Matrix4x4.Identity); scene.AttachToCurrentTest("result.glb"); scene.AttachToCurrentTest("result.gltf"); }
public static void CreateWithMutableSharedMaterial() { var material1 = Materials.MaterialBuilder.CreateDefault(); var material2 = Materials.MaterialBuilder.CreateDefault(); var material3 = Materials.MaterialBuilder.CreateDefault(); Assert.IsTrue(Materials.MaterialBuilder.AreEqualByContent(material1, material2)); Assert.IsTrue(Materials.MaterialBuilder.AreEqualByContent(material1, material3)); Assert.AreNotEqual(material1, material2); Assert.AreNotEqual(material1, material3); // MeshBuilder should split primitives by material reference, // because in general, materials will not be immutable. var mesh = new MeshBuilder <VertexPosition>(); mesh.UsePrimitive(material1, 1).AddPoint(default);
public void CreateSceneWithSkinnedAnimatedMeshBuilder() { TestContext.CurrentContext.AttachShowDirLink(); TestContext.CurrentContext.AttachGltfValidatorLinks(); // create animation sequence with 4 frames var keyframes = new Dictionary <Single, Quaternion> { [1] = Quaternion.Identity, [2] = Quaternion.CreateFromYawPitchRoll(0, 1, 0), [3] = Quaternion.CreateFromYawPitchRoll(0, 0, 1), [4] = Quaternion.Identity, }; // create two materials var pink = new MaterialBuilder("material1") .WithChannelParam(KnownChannel.BaseColor, new Vector4(1, 0, 1, 1)) .WithDoubleSide(true); var yellow = new MaterialBuilder("material2") .WithChannelParam(KnownChannel.BaseColor, new Vector4(1, 1, 0, 1)) .WithDoubleSide(true); // create the mesh var meshBuilder = new MeshBuilder <VPOS, VEMPTY, VSKIN4>("mesh1"); #if DEBUG meshBuilder.VertexPreprocessor.SetDebugPreprocessors(); #else meshBuilder.VertexPreprocessor.SetSanitizerPreprocessors(); #endif const int jointIdx0 = 0; const int jointIdx1 = 1; const int jointIdx2 = 2; var v1 = (new VPOS(-10, 0, +10), new VSKIN4(jointIdx0)); var v2 = (new VPOS(+10, 0, +10), new VSKIN4(jointIdx0)); var v3 = (new VPOS(+10, 0, -10), new VSKIN4(jointIdx0)); var v4 = (new VPOS(-10, 0, -10), new VSKIN4(jointIdx0)); var v5 = (new VPOS(-10, 40, +10), new VSKIN4((jointIdx0, 0.5f), (jointIdx1, 0.5f))); var v6 = (new VPOS(+10, 40, +10), new VSKIN4((jointIdx0, 0.5f), (jointIdx1, 0.5f))); var v7 = (new VPOS(+10, 40, -10), new VSKIN4((jointIdx0, 0.5f), (jointIdx1, 0.5f))); var v8 = (new VPOS(-10, 40, -10), new VSKIN4((jointIdx0, 0.5f), (jointIdx1, 0.5f))); var v9 = (new VPOS(-5, 80, +5), new VSKIN4(jointIdx2)); var v10 = (new VPOS(+5, 80, +5), new VSKIN4(jointIdx2)); var v11 = (new VPOS(+5, 80, -5), new VSKIN4(jointIdx2)); var v12 = (new VPOS(-5, 80, -5), new VSKIN4(jointIdx2)); meshBuilder.UsePrimitive(pink).AddQuadrangle(v1, v2, v6, v5); meshBuilder.UsePrimitive(pink).AddQuadrangle(v2, v3, v7, v6); meshBuilder.UsePrimitive(pink).AddQuadrangle(v3, v4, v8, v7); meshBuilder.UsePrimitive(pink).AddQuadrangle(v4, v1, v5, v8); meshBuilder.UsePrimitive(yellow).AddQuadrangle(v5, v6, v10, v9); meshBuilder.UsePrimitive(yellow).AddQuadrangle(v6, v7, v11, v10); meshBuilder.UsePrimitive(yellow).AddQuadrangle(v7, v8, v12, v11); meshBuilder.UsePrimitive(yellow).AddQuadrangle(v8, v5, v9, v12); meshBuilder.Validate(); // create base model var model = ModelRoot.CreateModel(); var scene = model.UseScene("Default"); // create the three joints that will affect the mesh var skelet = scene.CreateNode("Skeleton"); var joint0 = skelet.CreateNode("Joint 0").WithLocalTranslation(new Vector3(0, 0, 0)); var joint1 = joint0.CreateNode("Joint 1").WithLocalTranslation(new Vector3(0, 40, 0)).WithRotationAnimation("Base Track", keyframes); var joint2 = joint1.CreateNode("Joint 2").WithLocalTranslation(new Vector3(0, 40, 0)); // setup skin var snode = scene.CreateNode("Skeleton Node"); snode.Skin = model.CreateSkin(); snode.Skin.BindJoints(joint0, joint1, joint2); snode.WithMesh(model.CreateMesh(meshBuilder)); model.AttachToCurrentTest("result.glb"); model.AttachToCurrentTest("result.gltf"); }
public static void CreateWithDegeneratedTriangle() { // create materials var material1 = new Materials.MaterialBuilder() .WithMetallicRoughnessShader() .WithChannelParam(Materials.KnownChannel.BaseColor, Materials.KnownProperty.RGBA, Vector4.One * 0.5f); var material2 = new Materials.MaterialBuilder() .WithMetallicRoughnessShader() .WithChannelParam(Materials.KnownChannel.BaseColor, Materials.KnownProperty.RGBA, Vector4.One * 0.7f); // create a mesh with degenerated triangles var validTriangle = ( new Vector3(4373.192624189425f, 5522.678275192156f, -359.8238015332605f), new Vector3(4370.978060142137f, 5522.723320999183f, -359.89184701762827f), new Vector3(4364.615741107147f, 5511.510615546256f, -359.08922455413233f) ); var degeneratedTriangle = ( new Vector3(4374.713581837248f, 5519.741978117265f, -360.87014389818034f), new Vector3(4373.187151107471f, 5521.493282925338f, -355.70835120644153f), new Vector3(4373.187151107471f, 5521.493282925338f, -355.70835120644153f) ); var mesh = new MeshBuilder <VertexPosition>("mesh"); mesh.VertexPreprocessor.SetValidationPreprocessors(); var validIndices = mesh.UsePrimitive(material1) .AddTriangle ( new VertexPosition(validTriangle.Item1), new VertexPosition(validTriangle.Item2), new VertexPosition(validTriangle.Item3) ); Assert.GreaterOrEqual(validIndices.A, 0); Assert.GreaterOrEqual(validIndices.B, 0); Assert.GreaterOrEqual(validIndices.C, 0); var degenIndices = mesh.UsePrimitive(material2) .AddTriangle ( new VertexPosition(degeneratedTriangle.Item1), new VertexPosition(degeneratedTriangle.Item2), new VertexPosition(degeneratedTriangle.Item3) ); Assert.Less(degenIndices.A, 0); Assert.Less(degenIndices.B, 0); Assert.Less(degenIndices.C, 0); // create scene: var scene = new SceneBuilder(); scene.AddRigidMesh(mesh, Matrix4x4.Identity); // check gltf2 var model = scene.ToGltf2(); Assert.AreEqual(1, model.LogicalMeshes[0].Primitives.Count); }