public static MeshBuilder <Materials.MaterialBuilder, TvG, TvM, VertexEmpty> ToStaticMeshBuilder <TvG, TvM>(this Scene srcScene, Runtime.RuntimeOptions options, Animation animation, float time) where TvG : struct, IVertexGeometry where TvM : struct, IVertexMaterial { var materials = new Dictionary <Material, Materials.MaterialBuilder>(); Materials.MaterialBuilder convertMaterial(Material srcMaterial) { if (materials.TryGetValue(srcMaterial, out Materials.MaterialBuilder dstMaterial)) { return(dstMaterial); } dstMaterial = new Materials.MaterialBuilder(); srcMaterial.CopyTo(dstMaterial); // if we find an exiting match, we will use it instead. var oldMaterial = materials.Values.FirstOrDefault(item => Materials.MaterialBuilder.AreEqualByContent(dstMaterial, item)); if (oldMaterial != null) { dstMaterial = oldMaterial; } return(materials[srcMaterial] = dstMaterial); } return(srcScene.ToStaticMeshBuilder <Materials.MaterialBuilder, TvG, TvM>(convertMaterial, options, animation, time)); }
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 static void CopyTo(this Materials.MaterialBuilder srcMaterial, Material dstMaterial) { // dstMaterial.Name = srcMaterial.Name; dstMaterial.Alpha = srcMaterial.AlphaMode; dstMaterial.AlphaCutoff = srcMaterial.AlphaCutoff; dstMaterial.DoubleSided = srcMaterial.DoubleSided; srcMaterial.GetChannel("Normal").CopyTo(dstMaterial.FindChannel("Normal")); srcMaterial.GetChannel("Occlusion").CopyTo(dstMaterial.FindChannel("Occlusion")); srcMaterial.GetChannel("Emissive").CopyTo(dstMaterial.FindChannel("Emissive")); if (srcMaterial.Style == "PBRMetallicRoughness") { dstMaterial.InitializePBRMetallicRoughness(); srcMaterial.GetChannel("BaseColor").CopyTo(dstMaterial.FindChannel("BaseColor")); srcMaterial.GetChannel("Metallic").CopyTo(dstMaterial.FindChannel("Metallic")); srcMaterial.GetChannel("Roughness").CopyTo(dstMaterial.FindChannel("Roughness")); } else if (srcMaterial.Style == "PBRSpecularGlossiness") { dstMaterial.InitializePBRSpecularGlossiness(); srcMaterial.GetChannel("Diffuse").CopyTo(dstMaterial.FindChannel("Diffuse")); srcMaterial.GetChannel("Specular").CopyTo(dstMaterial.FindChannel("Specular")); srcMaterial.GetChannel("Glossiness").CopyTo(dstMaterial.FindChannel("Glossiness")); } }
public static Material CreateMaterial(this ModelRoot root, Materials.MaterialBuilder mb) { var m = root.CreateMaterial(mb.Name); mb.CopyTo(m); return(m); }
public static void CopyTo(this Materials.MaterialBuilder srcMaterial, Material dstMaterial) { Guard.NotNull(srcMaterial, nameof(srcMaterial)); Guard.NotNull(dstMaterial, nameof(dstMaterial)); srcMaterial.ValidateForSchema2(); dstMaterial.Alpha = srcMaterial.AlphaMode.ToSchema2(); dstMaterial.AlphaCutoff = srcMaterial.AlphaCutoff; dstMaterial.DoubleSided = srcMaterial.DoubleSided; var hasClearCoat = srcMaterial.GetChannel("ClearCoat") != null || srcMaterial.GetChannel("ClearCoatRoughness") != null || srcMaterial.GetChannel("ClearCoatNormal") != null; srcMaterial.CopyChannelsTo(dstMaterial, "Normal", "Occlusion", "Emissive"); Materials.MaterialBuilder defMaterial = null; if (srcMaterial.ShaderStyle == "Unlit") { dstMaterial.InitializePBRMetallicRoughness(); srcMaterial.CopyChannelsTo(dstMaterial, "BaseColor"); return; } if (srcMaterial.ShaderStyle == "PBRMetallicRoughness") { if (hasClearCoat) { dstMaterial.InitializePBRMetallicRoughnessClearCoat(); } else { dstMaterial.InitializePBRMetallicRoughness(); } defMaterial = srcMaterial; } if (srcMaterial.ShaderStyle == "PBRSpecularGlossiness") { dstMaterial.InitializePBRSpecularGlossiness(srcMaterial.CompatibilityFallback != null); srcMaterial.CopyChannelsTo(dstMaterial, "Diffuse", "SpecularGlossiness"); defMaterial = srcMaterial.CompatibilityFallback; } if (defMaterial != null) { if (defMaterial.ShaderStyle != "PBRMetallicRoughness") { throw new ArgumentException(nameof(srcMaterial.CompatibilityFallback.ShaderStyle)); } srcMaterial.CopyChannelsTo(dstMaterial, "BaseColor", "MetallicRoughness"); srcMaterial.CopyChannelsTo(dstMaterial, "ClearCoat", "ClearCoatRoughness", "ClearCoatNormal"); } }
public static Material CreateMaterial(this ModelRoot root, Materials.MaterialBuilder mb) { Guard.NotNull(root, nameof(root)); Guard.NotNull(mb, nameof(mb)); var m = root.CreateMaterial(mb.Name); mb.CopyTo(m); return(m); }
public static MaterialBuilder ToMaterialBuilder(this Material srcMaterial) { if (srcMaterial == null) { return(Materials.MaterialBuilder.CreateDefault()); } var dstMaterial = new Materials.MaterialBuilder(srcMaterial.Name); srcMaterial.CopyTo(dstMaterial); return(dstMaterial); }
public static void CopyTo(this Material srcMaterial, Materials.MaterialBuilder mb) { mb.Name = srcMaterial.Name; mb.Unlit = srcMaterial.Unlit; mb.AlphaMode = srcMaterial.Alpha; mb.AlphaCutoff = srcMaterial.AlphaCutoff; mb.DoubleSided = srcMaterial.DoubleSided; foreach (var channel in srcMaterial.Channels) { var ch = mb.UseChannel(channel.Key); channel.CopyTo(ch); } }
public static MeshBuilder <VertexPosition, VertexTexture1> CreateTerrainMesh(int width, int length, Func <int, int, float> heightFunction, string terrainColorImagePath) { // we create a new material to use with the terrain mesh var material = new Materials.MaterialBuilder("TerrainMaterial") .WithChannelImage(Materials.KnownChannel.BaseColor, terrainColorImagePath); // we create a MeshBuilder var terrainMesh = new MeshBuilder <VertexPosition, VertexTexture1>("terrain"); var texScale = new Vector2(width, length); // fill the MeshBuilder with quads using the heightFunction. for (int y = 1; y < length; ++y) { for (int x = 1; x < width; ++x) { // quad vertex positions var a = new Vector3(x - 1, heightFunction(x - 1, y + 0), y + 0); var b = new Vector3(x + 0, heightFunction(x + 0, y + 0), y + 0); var c = new Vector3(x + 0, heightFunction(x + 0, y - 1), y - 1); var d = new Vector3(x - 1, heightFunction(x - 1, y - 1), y - 1); // quad UV coordinates var at = new Vector2(a.X, a.Z) / texScale; var bt = new Vector2(b.X, b.Z) / texScale; var ct = new Vector2(c.X, c.Z) / texScale; var dt = new Vector2(d.X, d.Z) / texScale; terrainMesh .UsePrimitive(material) .AddQuadrangle ( (a, at), (b, bt), (c, ct), (d, dt) ); } } terrainMesh.Validate(); return(terrainMesh); }
public static void CopyChannelsTo(this Material srcMaterial, Materials.MaterialBuilder dstMaterial, params string[] channelKeys) { Guard.NotNull(srcMaterial, nameof(srcMaterial)); Guard.NotNull(dstMaterial, nameof(dstMaterial)); foreach (var k in channelKeys) { var src = srcMaterial.FindChannel(k); if (src == null) { continue; } var dst = dstMaterial.UseChannel(k); src.Value.CopyTo(dst); } }
public void CreateSceneWithsSheenExtension() { TestContext.CurrentContext.AttachShowDirLink(); TestContext.CurrentContext.AttachGltfValidatorLinks(); var basePath = System.IO.Path.Combine(TestFiles.RootDirectory, "glTF-Sample-Models", "2.0", "SpecGlossVsMetalRough", "glTF"); var material = new Materials.MaterialBuilder("material") .WithMetallicRoughnessShader() .WithChannelImage(Materials.KnownChannel.Normal, System.IO.Path.Combine(basePath, "WaterBottle_normal.png")) .WithChannelImage(Materials.KnownChannel.Emissive, System.IO.Path.Combine(basePath, "WaterBottle_emissive.png")) .WithChannelImage(Materials.KnownChannel.Occlusion, System.IO.Path.Combine(basePath, "WaterBottle_occlusion.png")) .WithChannelImage(Materials.KnownChannel.BaseColor, System.IO.Path.Combine(basePath, "WaterBottle_baseColor.png")) .WithChannelImage(Materials.KnownChannel.MetallicRoughness, System.IO.Path.Combine(basePath, "WaterBottle_roughnessMetallic.png")) .WithChannelImage(Materials.KnownChannel.SheenColor, System.IO.Path.Combine(basePath, "WaterBottle_emissive.png")) .WithChannelParam(Materials.KnownChannel.SheenColor, new Vector4(1, 1, 1, 0)) .WithChannelImage(Materials.KnownChannel.SheenRoughness, System.IO.Path.Combine(basePath, "WaterBottle_occlusion.png")) .WithChannelParam(Materials.KnownChannel.SheenRoughness, new Vector4(0.5f, 0, 0, 0)); var mesh = new Geometry.MeshBuilder <VPOS, VTEX>("mesh1"); mesh.UsePrimitive(material).AddQuadrangle ((new Vector3(-10, 10, 0), new Vector2(1, 0)) , (new Vector3(10, 10, 0), new Vector2(0, 0)) , (new Vector3(10, -10, 0), new Vector2(0, 1)) , (new Vector3(-10, -10, 0), new Vector2(1, 1)) ); var scene = new Scenes.SceneBuilder(); scene.AddRigidMesh(mesh, Matrix4x4.Identity); var gltf2 = scene.ToGltf2(); var sheenColorFactor = gltf2.LogicalMaterials[0].FindChannel("SheenColor").Value.Parameter; Assert.AreEqual(new Vector4(1, 1, 1, 0), sheenColorFactor); var sheenRoughnessFactor = gltf2.LogicalMaterials[0].FindChannel("SheenRoughness").Value.Parameter; Assert.AreEqual(new Vector4(0.5f, 0, 0, 0), sheenRoughnessFactor); scene.AttachToCurrentTest("result.glb"); scene.AttachToCurrentTest("result.gltf"); }
public void CreateFallbackMaterialScene() { TestContext.CurrentContext.AttachShowDirLink(); TestContext.CurrentContext.AttachGltfValidatorLink(); var basePath = System.IO.Path.Combine(TestContext.CurrentContext.WorkDirectory, "glTF-Sample-Models", "2.0", "SpecGlossVsMetalRough", "glTF"); // first, create a default material var material = new Materials.MaterialBuilder("material1 fallback") .WithMetallicRoughnessShader() .WithChannelImage(Materials.KnownChannels.Normal, System.IO.Path.Combine(basePath, "WaterBottle_normal.png")) .WithChannelImage(Materials.KnownChannels.Emissive, System.IO.Path.Combine(basePath, "WaterBottle_emissive.png")) .WithChannelImage(Materials.KnownChannels.Occlusion, System.IO.Path.Combine(basePath, "WaterBottle_occlusion.png")) .WithChannelImage(Materials.KnownChannels.BaseColor, System.IO.Path.Combine(basePath, "WaterBottle_baseColor.png")) .WithChannelImage(Materials.KnownChannels.MetallicRoughness, System.IO.Path.Combine(basePath, "WaterBottle_roughnessMetallic.png")); // wrap the fallback material with a PBR Specular Glossiness material. material = new Materials.MaterialBuilder("material1") .WithFallback(material) .WithSpecularGlossinessShader() .WithChannelImage(Materials.KnownChannels.Normal, System.IO.Path.Combine(basePath, "WaterBottle_normal.png")) .WithChannelImage(Materials.KnownChannels.Emissive, System.IO.Path.Combine(basePath, "WaterBottle_emissive.png")) .WithChannelImage(Materials.KnownChannels.Occlusion, System.IO.Path.Combine(basePath, "WaterBottle_occlusion.png")) .WithChannelImage(Materials.KnownChannels.Diffuse, System.IO.Path.Combine(basePath, "WaterBottle_diffuse.png")) .WithChannelImage(Materials.KnownChannels.SpecularGlossiness, System.IO.Path.Combine(basePath, "WaterBottle_specularGlossiness.png")); var mesh = new Geometry.MeshBuilder <VPOS, VTEX>("mesh1"); mesh.UsePrimitive(material).AddPolygon ((new Vector3(-10, 10, 0), new Vector2(1, 0)) , (new Vector3(10, 10, 0), new Vector2(0, 0)) , (new Vector3(10, -10, 0), new Vector2(0, 1)) , (new Vector3(-10, -10, 0), new Vector2(1, 1)) ); var model = ModelRoot.CreateModel(); var scene = model.UseScene("Default"); var rnode = scene.CreateNode("RootNode").WithMesh(model.CreateMesh(mesh)); model.AttachToCurrentTest("result.glb"); model.AttachToCurrentTest("result.gltf"); }
public void CreateSceneWithSpecularGlossinessExtension() { TestContext.CurrentContext.AttachShowDirLink(); TestContext.CurrentContext.AttachGltfValidatorLinks(); var basePath = System.IO.Path.Combine(TestFiles.RootDirectory, "glTF-Sample-Models", "2.0", "SpecGlossVsMetalRough", "glTF"); // first, create a default material var material = new Materials.MaterialBuilder("material1 fallback") .WithMetallicRoughnessShader() .WithChannelImage(Materials.KnownChannel.Normal, System.IO.Path.Combine(basePath, "WaterBottle_normal.png")) .WithChannelImage(Materials.KnownChannel.Emissive, System.IO.Path.Combine(basePath, "WaterBottle_emissive.png")) .WithChannelImage(Materials.KnownChannel.Occlusion, System.IO.Path.Combine(basePath, "WaterBottle_occlusion.png")) .WithChannelImage(Materials.KnownChannel.BaseColor, System.IO.Path.Combine(basePath, "WaterBottle_baseColor.png")) .WithChannelImage(Materials.KnownChannel.MetallicRoughness, System.IO.Path.Combine(basePath, "WaterBottle_roughnessMetallic.png")); // wrap the fallback material with a PBR Specular Glossiness material. material = new Materials.MaterialBuilder("material1") .WithFallback(material) .WithSpecularGlossinessShader() .WithChannelImage(Materials.KnownChannel.Normal, System.IO.Path.Combine(basePath, "WaterBottle_normal.png")) .WithChannelImage(Materials.KnownChannel.Emissive, System.IO.Path.Combine(basePath, "WaterBottle_emissive.png")) .WithChannelImage(Materials.KnownChannel.Occlusion, System.IO.Path.Combine(basePath, "WaterBottle_occlusion.png")) .WithChannelImage(Materials.KnownChannel.Diffuse, System.IO.Path.Combine(basePath, "WaterBottle_diffuse.png")) .WithChannelImage(Materials.KnownChannel.SpecularGlossiness, System.IO.Path.Combine(basePath, "WaterBottle_specularGlossiness.png")); var mesh = new Geometry.MeshBuilder <VPOS, VTEX>("mesh1"); mesh.UsePrimitive(material).AddQuadrangle ((new Vector3(-10, 10, 0), new Vector2(1, 0)) , (new Vector3(10, 10, 0), new Vector2(0, 0)) , (new Vector3(10, -10, 0), new Vector2(0, 1)) , (new Vector3(-10, -10, 0), new Vector2(1, 1)) ); var scene = new Scenes.SceneBuilder(); scene.AddMesh(mesh, Matrix4x4.Identity); scene.AttachToCurrentTest("result.glb"); scene.AttachToCurrentTest("result.gltf"); }
public void CreateSceneWithClearCoatExtension() { TestContext.CurrentContext.AttachGltfValidatorLinks(); var basePath = System.IO.Path.Combine(TestFiles.KhronosSampleModelsDirectory, "2.0", "SpecGlossVsMetalRough", "glTF"); // first, create a default material var material = new Materials.MaterialBuilder("material") .WithMetallicRoughnessShader() .WithChannelImage(Materials.KnownChannel.Normal, System.IO.Path.Combine(basePath, "WaterBottle_normal.png")) .WithChannelImage(Materials.KnownChannel.Emissive, System.IO.Path.Combine(basePath, "WaterBottle_emissive.png")) .WithChannelImage(Materials.KnownChannel.Occlusion, System.IO.Path.Combine(basePath, "WaterBottle_occlusion.png")) .WithChannelImage(Materials.KnownChannel.BaseColor, System.IO.Path.Combine(basePath, "WaterBottle_baseColor.png")) .WithChannelImage(Materials.KnownChannel.MetallicRoughness, System.IO.Path.Combine(basePath, "WaterBottle_roughnessMetallic.png")) .WithChannelImage(Materials.KnownChannel.ClearCoat, System.IO.Path.Combine(basePath, "WaterBottle_emissive.png")) .WithChannelParam(Materials.KnownChannel.ClearCoat, Materials.KnownProperty.ClearCoatFactor, 0.5f) .WithChannelImage(Materials.KnownChannel.ClearCoatRoughness, System.IO.Path.Combine(basePath, "WaterBottle_roughnessMetallic.png")) .WithChannelImage(Materials.KnownChannel.ClearCoatNormal, System.IO.Path.Combine(basePath, "WaterBottle_normal.png")); var mesh = new Geometry.MeshBuilder <VPOS, VTEX>("mesh1"); mesh.UsePrimitive(material).AddQuadrangle ((new Vector3(-10, 10, 0), new Vector2(1, 0)) , (new Vector3(10, 10, 0), new Vector2(0, 0)) , (new Vector3(10, -10, 0), new Vector2(0, 1)) , (new Vector3(-10, -10, 0), new Vector2(1, 1)) ); var scene = new Scenes.SceneBuilder(); scene.AddRigidMesh(mesh, Matrix4x4.Identity); var gltf2 = scene.ToGltf2(); var clearCoatFactor = gltf2.LogicalMaterials[0].FindChannel("ClearCoat").Value.GetFactor("ClearCoatFactor"); Assert.AreEqual(0.5f, clearCoatFactor); scene.AttachToCurrentTest("result.glb"); scene.AttachToCurrentTest("result.gltf"); }
public void CreateSceneWithTextureImageExtension(string textureFileName) { TestContext.CurrentContext.AttachShowDirLink(); TestContext.CurrentContext.AttachGltfValidatorLinks(); var basePath = System.IO.Path.Combine(TestContext.CurrentContext.WorkDirectory, "Assets"); // first, create a default material var material = new Materials.MaterialBuilder("material1") .WithDoubleSide(true) .WithMetallicRoughnessShader() .WithChannelImage ( Materials.KnownChannel.BaseColor, System.IO.Path.Combine(basePath, textureFileName) ); var mesh = new Geometry.MeshBuilder <VPOS, VTEX>("mesh1"); mesh .UsePrimitive(material) .AddQuadrangle ((new Vector3(-10, 10, 0), new Vector2(1, 0)) , (new Vector3(10, 10, 0), new Vector2(0, 0)) , (new Vector3(10, -10, 0), new Vector2(0, 1)) , (new Vector3(-10, -10, 0), new Vector2(1, 1)) ); var model = ModelRoot.CreateModel(); model.CreateMeshes(mesh); model.UseScene("Default") .CreateNode("RootNode") .WithMesh(model.LogicalMeshes[0]); model.AttachToCurrentTest("result_wf.obj"); model.AttachToCurrentTest("result_glb.glb"); model.AttachToCurrentTest("result_gltf.gltf"); }
public static void CopyTo(this Material srcMaterial, Materials.MaterialBuilder dstMaterial) { Guard.NotNull(srcMaterial, nameof(srcMaterial)); Guard.NotNull(dstMaterial, nameof(dstMaterial)); dstMaterial.Name = srcMaterial.Name; dstMaterial.AlphaMode = srcMaterial.Alpha.ToToolkit(); dstMaterial.AlphaCutoff = srcMaterial.AlphaCutoff; dstMaterial.DoubleSided = srcMaterial.DoubleSided; srcMaterial.CopyChannelsTo(dstMaterial, "Normal", "Occlusion", "Emissive"); if (srcMaterial.Unlit) { dstMaterial.WithUnlitShader(); } if (srcMaterial.FindChannel("BaseColor") != null || srcMaterial.FindChannel("MetallicRoughness") != null) { dstMaterial.WithMetallicRoughnessShader(); srcMaterial.CopyChannelsTo(dstMaterial, "BaseColor", "MetallicRoughness"); srcMaterial.CopyChannelsTo(dstMaterial, "ClearCoat", "ClearCoatRoughness", "ClearCoatNormal"); } if (srcMaterial.FindChannel("Diffuse") != null || srcMaterial.FindChannel("SpecularGlossiness") != null) { dstMaterial = new Materials.MaterialBuilder(srcMaterial.Name).WithFallback(dstMaterial); dstMaterial.Name = srcMaterial.Name; dstMaterial.AlphaMode = srcMaterial.Alpha.ToToolkit(); dstMaterial.AlphaCutoff = srcMaterial.AlphaCutoff; dstMaterial.DoubleSided = srcMaterial.DoubleSided; srcMaterial.CopyChannelsTo(dstMaterial, "Normal", "Occlusion", "Emissive"); dstMaterial.WithSpecularGlossinessShader(); srcMaterial.CopyChannelsTo(dstMaterial, "Diffuse", "SpecularGlossiness"); } }
public static IMeshBuilder <Materials.MaterialBuilder> ToMeshBuilder(this Mesh srcMesh) { if (srcMesh == null) { return(null); } var vertexAttributes = srcMesh.Primitives .SelectMany(item => item.VertexAccessors.Keys) .Distinct() .ToArray(); var dstMesh = MeshBuilderToolkit.CreateMeshBuilderFromVertexAttributes <Materials.MaterialBuilder>(vertexAttributes); dstMesh.Name = srcMesh.Name; dstMesh.Extras = srcMesh.Extras.DeepClone(); Materials.MaterialBuilder defMat = null; var dstMaterials = new Dictionary <Material, Materials.MaterialBuilder>(); IPrimitiveBuilder GetPrimitive(Material srcMaterial, int vcount) { IPrimitiveBuilder dstPrim = null; if (srcMaterial == null) { if (defMat == null) { defMat = Materials.MaterialBuilder.CreateDefault(); } dstPrim = dstMesh.UsePrimitive(defMat, vcount); } else { if (!dstMaterials.TryGetValue(srcMaterial, out Materials.MaterialBuilder dstMat)) { dstMat = new Materials.MaterialBuilder(); srcMaterial.CopyTo(dstMat); dstMaterials[srcMaterial] = dstMat; } dstPrim = dstMesh.UsePrimitive(dstMat, vcount); } return(dstPrim); } foreach (var srcPrim in srcMesh.Primitives) { int vcount = 0; if (srcPrim.GetPointIndices().Any()) { vcount = 1; } if (srcPrim.GetLineIndices().Any()) { vcount = 2; } if (srcPrim.GetTriangleIndices().Any()) { vcount = 3; } var dstPrim = GetPrimitive(srcPrim.Material, vcount); dstPrim.AddPrimitiveGeometry(srcPrim); } return(dstMesh); }
public void CreateInvalidTriangles() { var m = new Materials.MaterialBuilder(); var mb = VERTEX2.CreateCompatibleMesh(); // replaces default preprocessor with a debug preprocessor that throws exceptions at the slightest issue. mb.VertexPreprocessor.SetDebugPreprocessors(); int TriangleCounter() { return(mb.Primitives.Sum(item => item.Triangles.Count())); } var prim = mb.UsePrimitive(m); var a = VERTEX2 .Create(Vector3.Zero, Vector3.UnitX) .WithMaterial(Vector4.One, Vector2.Zero) .WithSkinning((0, 1)); var b = VERTEX2 .Create(Vector3.UnitX, Vector3.UnitX) .WithMaterial(Vector4.One, Vector2.Zero) .WithSkinning((0, 1)); var c = VERTEX2 .Create(Vector3.UnitY, Vector3.UnitX) .WithMaterial(Vector4.One, Vector2.Zero) .WithSkinning((0, 1)); prim.AddTriangle(a, b, c); Assert.AreEqual(1, TriangleCounter()); var v2nan = new Vector2(float.NaN, float.NaN); var v3nan = new Vector3(float.NaN, float.NaN, float.NaN); var v4nan = new Vector4(float.NaN, float.NaN, float.NaN, float.NaN); Assert.Throws(typeof(ArgumentException), () => prim.AddTriangle(a.WithGeometry(v3nan), b, c)); Assert.AreEqual(1, TriangleCounter()); Assert.Throws(typeof(ArgumentException), () => prim.AddTriangle(a.WithGeometry(Vector3.Zero, v3nan), b, c)); Assert.AreEqual(1, TriangleCounter()); Assert.Throws(typeof(ArgumentOutOfRangeException), () => prim.AddTriangle(a.WithGeometry(Vector3.Zero, Vector3.Zero), b, c)); Assert.AreEqual(1, TriangleCounter()); Assert.Throws(typeof(ArgumentOutOfRangeException), () => prim.AddTriangle(a.WithGeometry(Vector3.Zero, Vector3.UnitX * 0.8f), b, c)); Assert.AreEqual(1, TriangleCounter()); Assert.Throws(typeof(ArgumentException), () => prim.AddTriangle(a.WithMaterial(v2nan), b, c)); Assert.AreEqual(1, TriangleCounter()); Assert.Throws(typeof(ArgumentException), () => prim.AddTriangle(a.WithMaterial(v4nan), b, c)); Assert.AreEqual(1, TriangleCounter()); Assert.Throws(typeof(ArgumentOutOfRangeException), () => prim.AddTriangle(a.WithMaterial(Vector4.One * 2), b, c)); Assert.AreEqual(1, TriangleCounter()); Assert.Throws(typeof(ArgumentOutOfRangeException), () => prim.AddTriangle(a.WithMaterial(-Vector4.One), b, c)); Assert.AreEqual(1, TriangleCounter()); Assert.Throws(typeof(ArgumentOutOfRangeException), () => prim.AddTriangle(a.WithSkinning((0, 0)), b, c)); Assert.AreEqual(1, TriangleCounter()); }
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); }