/// <summary> /// 设置当前材质 /// </summary> /// <param name="uidMaterial"></param> void SetCurrentMaterial(string uidMaterial, MaterialNode node) { if (!_materials.ContainsKey(uidMaterial)) { RMaterial material = CurrentDocument.GetElement(uidMaterial) as RMaterial; Color c = material.Color; MaterialBuilder m = null; try { if (material.Transparency != 0) { m = new MaterialBuilder() .WithAlpha(SharpGLTF.Materials.AlphaMode.BLEND) .WithDoubleSide(true) .WithMetallicRoughnessShader() .WithChannelParam(KnownChannel.BaseColor, new Vector4(c.Red / 256f, c.Green / 256f, c.Blue / 256f, 1 - (material.Transparency / 128f))); } else { m = new MaterialBuilder() .WithDoubleSide(true) .WithMetallicRoughnessShader() .WithChannelParam(KnownChannel.BaseColor, new Vector4(c.Red / 256f, c.Green / 256f, c.Blue / 256f, 1)); } Autodesk.Revit.DB.Visual.Asset currentAsset; if (node.HasOverriddenAppearance) { currentAsset = node.GetAppearanceOverride(); } else { currentAsset = node.GetAppearance(); } try { //取得Asset中贴图信息 Autodesk.Revit.DB.Visual.Asset findAssert = FindTextureAsset(currentAsset as AssetProperty); if (findAssert != null) { string textureFile = (findAssert["unifiedbitmap_Bitmap"] as AssetPropertyString).Value.Split('|')[0]; //用Asset中贴图信息和注册表里的材质库地址得到贴图文件所在位置 string textureName = textureFile.Replace("/", "\\"); string texturePath = Path.Combine(_textureFolder, textureName); m.WithChannelImage(KnownChannel.BaseColor, texturePath); } } catch (Exception e) { } } catch (Exception e) { } _materials.Add(uidMaterial, m); } _currentMaterial = _materials[uidMaterial]; }
static void Main(string[] args) { Texture texture = null; Skybox skybox = null; VertexBuffer vertexBuffer = null; IndexBuffer indexBuffer = null; Material material = null; MaterialInstance materialInstance = null; Camera camera = null; int cameraEntity = -1; int renderable = -1; var app = new Application( new WindowConfig() { Title = "texturedquad" }, new ApplicationConfig() ); app.Setup = (engine, view, scene) => { var path = Path.Combine(app.RootAssetPath, "textures/Moss_01/Moss_01_Color.png"); if (!File.Exists(path)) { Console.WriteLine("The texture {0} does not exist", path); Environment.Exit(1); } using (var stream = File.OpenRead(path)) { var imageResult = ImageResult.FromStream(stream, ColorComponents.RedGreenBlueAlpha); Console.WriteLine("Loaded texture: {0}x{1}", imageResult.Width, imageResult.Height); var pixelBuffer = new PixelBufferDescriptor(imageResult.Data, PixelDataFormat.Rgba, PixelDataType.UByte); texture = TextureBuilder.Create() .WithWidth(imageResult.Width) .WithHeight(imageResult.Height) .WithLevels(1) .WithSampler(TextureSamplerType.Texture2d) .WithFormat(TextureFormat.Rgba8) .Build(engine); texture.SetImage(engine, 0, pixelBuffer); } // Set up view skybox = SkyboxBuilder.Create() .WithColor(new Color(0.1f, 0.125f, 0.25f, 1.0f)) .Build(engine); scene.Skybox = skybox; cameraEntity = EntityManager.Create(); camera = engine.CreateCamera(cameraEntity); view.PostProcessingEnabled = false; view.Camera = camera; // Create quad renderable var vbo = new VertexBufferObject(); vbo.Write(new Vector2(-1, -1)); vbo.Write(new Vector2(0, 0)); vbo.Write(new Vector2(1, -1)); vbo.Write(new Vector2(1, 0)); vbo.Write(new Vector2(-1, 1)); vbo.Write(new Vector2(0, 1)); vbo.Write(new Vector2(1, 1)); vbo.Write(new Vector2(1, 1)); vertexBuffer = VertexBufferBuilder.Create() .WithVertexCount(4) .WithBufferCount(1) .WithAttribute(VertexAttribute.Position, 0, ElementType.Float2, 0, 16) .WithAttribute(VertexAttribute.Uv0, 0, ElementType.Float2, 8, 16) .Build(engine); vertexBuffer.SetBufferAt(engine, 0, vbo); var sampleData = new SampleDataLoader(); indexBuffer = IndexBufferBuilder.Create() .WithIndexCount(6) .WithBufferType(IndexType.UShort) .Build(engine); indexBuffer.SetBuffer(engine, QUAD_INDICES); material = MaterialBuilder.Create() .WithPackage(sampleData.LoadBakedTexture()) .Build(engine); var sampler = new TextureSampler(SamplerMinFilter.Linear, SamplerMagFilter.Linear); materialInstance = material.CreateInstance(); materialInstance.SetParameter("albedo", texture, sampler); renderable = EntityManager.Create(); RenderableBuilder.Create() .WithBoundingBox( new Box( new Vector3(-1, -1, -1), new Vector3(1, 1, 1) ) ) .WithMaterial(0, materialInstance) .WithGeometry(0, PrimitiveType.Triangles, vertexBuffer, indexBuffer, 0, 6) .WithCulling(false) .WithReceiveShadows(false) .WithCastShadows(false) .Build(engine, renderable); scene.AddEntity(renderable); }; app.Cleanup = (engine, view, scene) => { engine.Destroy(skybox); engine.Destroy(renderable); engine.Destroy(materialInstance); engine.Destroy(material); engine.Destroy(texture); engine.Destroy(vertexBuffer); engine.Destroy(indexBuffer); engine.DestroyCameraComponent(cameraEntity); EntityManager.Destroy(cameraEntity); }; app.Animate = (engine, view, now) => { var zoom = 2.0f + 2.0f * MathF.Sin(now); var width = view.Viewport.Width; var height = view.Viewport.Height; var aspect = (float)width / (float)height; camera.SetProjection(Projection.Ortho, -aspect * zoom, aspect * zoom, -zoom, zoom, -1, 1 ); }; app.Run(); }
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(KnownChannels.BaseColor, new Vector4(1, 0, 1, 1)) .WithDoubleSide(true); var yellow = new MaterialBuilder("material2") .WithChannelParam(KnownChannels.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 void CreateSceneWithSharedBuffers() { TestContext.CurrentContext.AttachShowDirLink(); TestContext.CurrentContext.AttachGltfValidatorLinks(); // create materials var material1 = new MaterialBuilder("material1") .WithChannelParam(KnownChannels.BaseColor, new Vector4(1, 1, 0, 1)); var material2 = new MaterialBuilder("material1") .WithChannelParam(KnownChannels.BaseColor, new Vector4(1, 0, 1, 1)); // create several meshes var meshBuilder1 = new MeshBuilder <VPOSNRM>("mesh1"); meshBuilder1.VertexPreprocessor.SetDebugPreprocessors(); var meshBuilder2 = new MeshBuilder <VPOSNRM>("mesh2"); meshBuilder2.VertexPreprocessor.SetDebugPreprocessors(); var meshBuilder3 = new MeshBuilder <VPOSNRM>("mesh3"); meshBuilder3.VertexPreprocessor.SetDebugPreprocessors(); var meshBuilder4 = new MeshBuilder <VPOSNRM>("mesh4"); meshBuilder4.VertexPreprocessor.SetDebugPreprocessors(); meshBuilder1.AddCube(material1, Matrix4x4.Identity); meshBuilder2.AddCube(material2, Matrix4x4.Identity); meshBuilder3.AddSphere(material1, 0.5f, Matrix4x4.Identity); meshBuilder4.AddSphere(material2, 0.5f, Matrix4x4.Identity); meshBuilder1.Validate(); meshBuilder2.Validate(); meshBuilder3.Validate(); meshBuilder4.Validate(); // create the gltf model var model = ModelRoot.CreateModel(); // create gltf meshes, by doing so in a single call, we ensure a single, shared vertex and index buffer will be used. var meshes = model.CreateMeshes(meshBuilder1, meshBuilder2, meshBuilder3, meshBuilder4); // create scene nodes model.UseScene("Default").CreateNode("Cube1").WithMesh(meshes[0]).WithLocalTranslation(new Vector3(-5, 0, 0)); model.UseScene("Default").CreateNode("Cube2").WithMesh(meshes[1]).WithLocalTranslation(new Vector3(0, 5, 0)); model.UseScene("Default").CreateNode("Sphere1").WithMesh(meshes[2]).WithLocalTranslation(new Vector3(+5, 0, 0)); model.UseScene("Default").CreateNode("Sphere2").WithMesh(meshes[3]).WithLocalTranslation(new Vector3(0, -5, 0)); // manuall merge all the buffers model.MergeBuffers(); // checks Assert.AreEqual(1, model.LogicalBuffers.Count); Assert.AreEqual(2, model.LogicalBufferViews.Count); Assert.AreEqual(BufferMode.ARRAY_BUFFER, model.LogicalBufferViews[0].DeviceBufferTarget); Assert.AreEqual(BufferMode.ELEMENT_ARRAY_BUFFER, model.LogicalBufferViews[1].DeviceBufferTarget); Assert.AreEqual(2, model.LogicalMaterials.Count); model.AttachToCurrentTest("result.glb"); model.AttachToCurrentTest("result.gltf"); }
private static void _CopyMetallicRoughnessTo(Material srcMaterial, MaterialBuilder dstMaterial) { dstMaterial.WithMetallicRoughnessShader(); srcMaterial.CopyChannelsTo(dstMaterial, "BaseColor", "MetallicRoughness"); srcMaterial.CopyChannelsTo(dstMaterial, "ClearCoat", "ClearCoatRoughness", "ClearCoatNormal"); }
public void CreateSceneWithSharedBuffers() { TestContext.CurrentContext.AttachGltfValidatorLinks(); // create materials var material1 = new MaterialBuilder("material1") .WithChannelParam(KnownChannel.BaseColor, KnownProperty.RGBA, new Vector4(1, 1, 0, 1)); var material2 = new MaterialBuilder("material1") .WithChannelParam(KnownChannel.BaseColor, KnownProperty.RGBA, new Vector4(1, 0, 1, 1)); // create several meshes var meshBuilder1 = new MeshBuilder <VPOSNRM>("mesh1"); meshBuilder1.VertexPreprocessor.SetValidationPreprocessors(); var meshBuilder2 = new MeshBuilder <VPOSNRM>("mesh2"); meshBuilder2.VertexPreprocessor.SetValidationPreprocessors(); var meshBuilder3 = new MeshBuilder <VPOSNRM>("mesh3"); meshBuilder3.VertexPreprocessor.SetValidationPreprocessors(); var meshBuilder4 = new MeshBuilder <VPOSNRM>("mesh4"); meshBuilder4.VertexPreprocessor.SetValidationPreprocessors(); meshBuilder1.AddCube(material1, Matrix4x4.Identity); meshBuilder2.AddCube(material2, Matrix4x4.Identity); meshBuilder3.AddSphere(material1, 0.5f, Matrix4x4.Identity); meshBuilder4.AddSphere(material2, 0.5f, Matrix4x4.Identity); meshBuilder1.Validate(); meshBuilder2.Validate(); meshBuilder3.Validate(); meshBuilder4.Validate(); // create scene nodes var pivot1 = new NodeBuilder("Cube1").WithLocalTranslation(new Vector3(-5, 0, 0)); var pivot2 = new NodeBuilder("Cube2").WithLocalTranslation(new Vector3(0, 5, 0)); var pivot3 = new NodeBuilder("SPhere1").WithLocalTranslation(new Vector3(+5, 0, 0)); var pivot4 = new NodeBuilder("SPhere2").WithLocalTranslation(new Vector3(0, -5, 0)); // create the scene: var scene = new SceneBuilder(); scene.AddRigidMesh(meshBuilder1, pivot1); scene.AddRigidMesh(meshBuilder2, pivot2); scene.AddRigidMesh(meshBuilder3, pivot3); scene.AddRigidMesh(meshBuilder4, pivot4); // convert to gltf2 var model = scene.ToGltf2(); model.MergeBuffers(); // checks Assert.AreEqual(1, model.LogicalBuffers.Count); Assert.AreEqual(2, model.LogicalBufferViews.Count); Assert.IsTrue(model.LogicalBufferViews[0].IsVertexBuffer); Assert.IsTrue(model.LogicalBufferViews[1].IsIndexBuffer); Assert.AreEqual(2, model.LogicalMaterials.Count); model.AttachToCurrentTest("result.glb"); model.AttachToCurrentTest("result.gltf"); scene.AttachToCurrentTest("result.plotly"); }
private static IMeshBuilder <MaterialBuilder> BuildMesh(PapaMeshBinding meshBinding) { var meshBuilder = VERTEX.CreateCompatibleMesh(); foreach (PapaMaterialGroup materialGroup in meshBinding.Mesh.MaterialGroups) { // Skip empty materials if (materialGroup.PrimitiveCount == 0) { continue; } MaterialBuilder materialBuiler = new MaterialBuilder(materialGroup.Name).WithSpecularGlossinessShader(); var materialPrimitive = meshBuilder.UsePrimitive(materialBuiler); // Check for DiffuseColor material parameter if (materialGroup.Material.VectorParameters.Any(x => x.Name == "DiffuseColor")) { PapaVectorParameter diffuseColor = materialGroup.Material.VectorParameters.FirstOrDefault(x => x.Name == "DiffuseColor"); materialBuiler.UseChannel(KnownChannel.Diffuse).Parameter = diffuseColor.Value; } int minVertex = int.MaxValue; int maxVertex = int.MinValue; for (uint i = materialGroup.FirstIndex; i < materialGroup.PrimitiveCount * 3; i++) { uint index = meshBinding.Mesh.Indices[(int)i]; if (index < minVertex) { minVertex = (int)index; } if (index > maxVertex) { maxVertex = (int)index; } } int vertexCount = maxVertex - minVertex + 1; List <VERTEX> vertices = new(vertexCount); for (int i = minVertex; i < maxVertex + 1; i++) { PapaVertex papaVertex = meshBinding.Mesh.Vertices[i]; VERTEX vertex = new VERTEX(); vertex.Geometry = new VertexPositionNormal() { Position = papaVertex.Position.Value, Normal = papaVertex.Normal.HasValue ? papaVertex.Normal.Value : new Vector3() }; vertex.Material = new VertexColor2Texture2() { Color0 = papaVertex.Color1.HasValue ? papaVertex.Color1.Value : new Color(), Color1 = papaVertex.Color2.HasValue ? papaVertex.Color2.Value : new Color(), TexCoord0 = papaVertex.TexCoord1.HasValue ? papaVertex.TexCoord1.Value : new Vector2(), TexCoord1 = papaVertex.TexCoord2.HasValue ? papaVertex.TexCoord2.Value : new Vector2(), }; vertices.Add(vertex); } for (uint i = materialGroup.FirstIndex; i < materialGroup.PrimitiveCount * 3; i += 3) { int index0 = (int)meshBinding.Mesh.Indices[(int)i + 0] - minVertex; int index1 = (int)meshBinding.Mesh.Indices[(int)i + 1] - minVertex; int index2 = (int)meshBinding.Mesh.Indices[(int)i + 2] - minVertex; VERTEX vertex0 = vertices[index0]; VERTEX vertex1 = vertices[index1]; VERTEX vertex2 = vertices[index2]; materialPrimitive.AddTriangle(vertex0, vertex1, vertex2); } } return(meshBuilder); }
protected record PrimitiveData(PssgNode Node, MaterialBuilder Material, bool CreatedNewMaterial, RenderDataSourceReader Rds);
static void Main(string[] args) { Material material = null; MaterialInstance materialInstance = null; Texture normal = null; Texture albedo = null; Texture ao = null; Texture metallic = null; Texture roughness = null; Mesh mesh = null; Matrix4x4 transform; var app = new Application( new WindowConfig() { Title = "suzanne", }, new ApplicationConfig() { IblDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), IBL_FOLDER) } ); app.Setup = (engine, view, scene) => { var tcm = engine.TransformManager; var rcm = engine.RenderableManager; var monkeyData = new MonkeyDataLoader(); // Create textures. The KTX bundles are freed by KtxUtility. var albedoBundle = new KtxBundle(monkeyData.LoadAlbedoS3tc()); var aoBundle = new KtxBundle(monkeyData.LoadAo()); var metallicBundle = new KtxBundle(monkeyData.LoadMetallic()); var roughnessBundle = new KtxBundle(monkeyData.LoadRougness()); albedo = KtxUtility.CreateTexture(engine, albedoBundle, true); ao = KtxUtility.CreateTexture(engine, aoBundle, false); metallic = KtxUtility.CreateTexture(engine, metallicBundle, false); roughness = KtxUtility.CreateTexture(engine, roughnessBundle, false); normal = LoadNormalMap(engine, monkeyData.LoadNormal()); var resourceData = new SampleDataLoader(); var sampler = new TextureSampler(SamplerMinFilter.LinearMipmapLinear, SamplerMagFilter.Linear); // Instantiate material. material = MaterialBuilder.Create() .WithPackage(resourceData.LoadTexturedLit()) .Build(engine); materialInstance = material.CreateInstance(); materialInstance.SetParameter("albedo", albedo, sampler); materialInstance.SetParameter("ao", ao, sampler); materialInstance.SetParameter("metallic", metallic, sampler); materialInstance.SetParameter("normal", normal, sampler); materialInstance.SetParameter("roughness", roughness, sampler); var indirectLight = app.Ibl.IndirectLight; indirectLight.Intensity = 100000; indirectLight.Rotation = Matrix4x4.CreateFromAxisAngle(Vector3.UnitY, 0.5f); // Add geometry into the scene. mesh = MeshReader.LoadFromBuffer(engine, monkeyData.LoadSuzanne(), materialInstance); var ti = tcm.GetInstance(mesh.Renderable); transform = tcm.GetWorldTransform(ti) * Matrix4x4.CreateTranslation(0, 0, -4); rcm.SetCastShadows(rcm.GetInstance(mesh.Renderable), false); scene.AddEntity(mesh.Renderable); tcm.SetTransform(ti, transform); }; app.Cleanup = (engine, view, scene) => { engine.Destroy(materialInstance); engine.Destroy(mesh.Renderable); engine.Destroy(material); engine.Destroy(albedo); engine.Destroy(normal); engine.Destroy(roughness); engine.Destroy(metallic); engine.Destroy(ao); }; app.Run(); }
static void Main(string[] args) { Texture offscreenColorTexture = null; Texture offscreenDepthTexture = null; Filament.RenderTarget offscreenRenderTarget = null; View offscreenView = null; Scene offscreenScene = null; Camera offscreenCamera = null; int lightEntity = -1; Material meshMaterial = null; MaterialInstance meshMatInstance = null; Mesh monkeyMesh = null; int reflectedMonkey = -1; Matrix4x4 transform = Matrix4x4.Identity; int quadEntity = -1; Vector3 quadCenter = Vector3.Zero; Vector3 quadNormal = Vector3.Zero; VertexBuffer quadVb = null; IndexBuffer quadIb = null; Material quadMaterial = null; MaterialInstance quadMatInstance = null; ReflectionMode mode = ReflectionMode.Camera; var app = new Application( new WindowConfig() { Title = "rendertarget", }, new ApplicationConfig() ); app.Setup = (engine, view, scene) => { var tcm = engine.TransformManager; var rcm = engine.RenderableManager; var vp = view.Viewport; var resourceData = new SampleDataLoader(); var monkeyData = new MonkeyDataLoader(); // Instantiate offscreen render target. offscreenScene = engine.CreateScene(); offscreenView = engine.CreateView(); offscreenView.Scene = offscreenScene; offscreenView.PostProcessingEnabled = false; offscreenColorTexture = TextureBuilder.Create() .WithWidth(vp.Width) .WithHeight(vp.Height) .WithLevels(1) .WithUsage(TextureUsage.ColorAttachment | TextureUsage.Sampleable) .WithFormat(TextureFormat.Rgba8) .Build(engine); offscreenDepthTexture = TextureBuilder.Create() .WithWidth(vp.Width) .WithHeight(vp.Height) .WithLevels(1) .WithUsage(TextureUsage.DepthAttachment) .WithFormat(TextureFormat.Depth24) .Build(engine); offscreenRenderTarget = RenderTargetBuilder.Create() .WithTexture(AttachmentPoint.Color, offscreenColorTexture) .WithTexture(AttachmentPoint.Depth, offscreenDepthTexture) .Build(engine); offscreenView.RenderTarget = offscreenRenderTarget; offscreenView.Viewport = new Viewport(0, 0, vp.Width, vp.Height); offscreenCamera = engine.CreateCamera(EntityManager.Create()); offscreenView.Camera = offscreenCamera; app.AddOffscreenView(offscreenView); // Position and orient the mirror in an interesting way. var c = quadCenter = new Vector3(-2, 0, -5); var n = quadNormal = Vector3.Normalize(new Vector3(1, 0, 2)); var u = Vector3.Normalize(Vector3.Cross(quadNormal, new Vector3(0, 1, 0))); var v = Vector3.Cross(n, u); u = 1.5f * u; v = 1.5f * v; Vertex[] kQuadVertices = { new() { Position = c - u - v, Uv = new Vector2(1, 0) }, new() { Position = c + u - v, Uv = new Vector2(0, 0) }, new() { Position = c - u + v, Uv = new Vector2(1, 1) }, new() { Position = c + u + v, Uv = new Vector2(0, 1) }, }; var vbo = new byte[20 * 4]; MemoryStream vboStream = new MemoryStream(vbo); BinaryWriter vboWriter = new BinaryWriter(vboStream); vboWriter.Write(kQuadVertices[0].Position.X); vboWriter.Write(kQuadVertices[0].Position.Y); vboWriter.Write(kQuadVertices[0].Position.Z); vboWriter.Write(kQuadVertices[0].Uv.X); vboWriter.Write(kQuadVertices[0].Uv.Y); vboWriter.Write(kQuadVertices[1].Position.X); vboWriter.Write(kQuadVertices[1].Position.Y); vboWriter.Write(kQuadVertices[1].Position.Z); vboWriter.Write(kQuadVertices[1].Uv.X); vboWriter.Write(kQuadVertices[1].Uv.Y); vboWriter.Write(kQuadVertices[2].Position.X); vboWriter.Write(kQuadVertices[2].Position.Y); vboWriter.Write(kQuadVertices[2].Position.Z); vboWriter.Write(kQuadVertices[2].Uv.X); vboWriter.Write(kQuadVertices[2].Uv.Y); vboWriter.Write(kQuadVertices[3].Position.X); vboWriter.Write(kQuadVertices[3].Position.Y); vboWriter.Write(kQuadVertices[3].Position.Z); vboWriter.Write(kQuadVertices[3].Uv.X); vboWriter.Write(kQuadVertices[3].Uv.Y); // Create quad vertex buffer. quadVb = VertexBufferBuilder.Create() .WithVertexCount(4) .WithBufferCount(1) .WithAttribute(VertexAttribute.Position, 0, ElementType.Float3, 0, 20) .WithAttribute(VertexAttribute.Uv0, 0, ElementType.Float2, 12, 20) .Build(engine); quadVb.SetBufferAt(engine, 0, vbo); // Create quad index buffer. var kQuadIndices = new ushort[] { 0, 1, 2, 3, 2, 1 }; quadIb = IndexBufferBuilder.Create() .WithIndexCount(6) .WithBufferType(IndexType.UShort) .Build(engine); quadIb.SetBuffer(engine, kQuadIndices); // Create quad material and renderable. quadMaterial = MaterialBuilder.Create() .WithPackage(resourceData.LoadMirror()) .Build(engine); quadMatInstance = quadMaterial.CreateInstance(); var sampler = new TextureSampler(SamplerMinFilter.Linear, SamplerMagFilter.Linear); quadMatInstance.SetParameter("albedo", offscreenColorTexture, sampler); quadEntity = EntityManager.Create(); RenderableBuilder.Create() .WithBoundingBox( new Box( new Vector3(-1, -1, -1), new Vector3(1, 1, 1) ) ) .WithMaterial(0, quadMatInstance) .WithGeometry(0, PrimitiveType.Triangles, quadVb, quadIb, 0, 6) .WithCulling(false) .WithReceiveShadows(false) .WithCastShadows(false) .Build(engine, quadEntity); scene.AddEntity(quadEntity); // Instantiate mesh material. meshMaterial = MaterialBuilder.Create() .WithPackage(resourceData.LoadAiDefaultMat()) .Build(engine); var mi = meshMatInstance = meshMaterial.CreateInstance(); mi.SetParameter("baseColor", RgbType.Linear, new Color(0.8f, 1.0f, 1.0f)); mi.SetParameter("metallic", 0.0f); mi.SetParameter("roughness", 0.4f); mi.SetParameter("reflectance", 0.5f); // Add monkey into the scene. monkeyMesh = MeshReader.LoadFromBuffer(engine, monkeyData.LoadSuzanne(), mi); var ti = tcm.GetInstance(monkeyMesh.Renderable); transform = Matrix4x4.CreateTranslation(0, 0, -4) * tcm.GetWorldTransform(ti); rcm.SetCastShadows(rcm.GetInstance(monkeyMesh.Renderable), false); scene.AddEntity(monkeyMesh.Renderable); // Create a reflected monkey, which is used only for ReflectionMode::RENDERABLES. reflectedMonkey = EntityManager.Create(); RenderableBuilder.Create() .WithBoundingBox( new Box( new Vector3(-2, -2, -2), new Vector3(2, 2, 2) ) ) .WithMaterial(0, mi) .WithGeometry(0, PrimitiveType.Triangles, monkeyMesh.VertexBuffer, monkeyMesh.IndexBuffer) .WithReceiveShadows(true) .WithCastShadows(false) .Build(engine, reflectedMonkey); mode = SetReflectionMode(offscreenScene, offscreenView, reflectedMonkey, monkeyMesh, ReflectionMode.Camera); // Add light source to both scenes. // NOTE: this is slightly wrong when the reflection mode is RENDERABLES. lightEntity = EntityManager.Create(); LightBuilder.Create(LightType.Sun) .WithColor(Color.ToLinearAccurate(new sRGBColor(0.98f, 0.92f, 0.89f))) .WithIntensity(110000) .WithDirection(new Vector3(0.7f, -1, -0.8f)) .WithSunAngularRadius(1.9f) .WithCastShadows(false) .Build(engine, lightEntity); scene.AddEntity(lightEntity); offscreenScene.AddEntity(lightEntity); };
public ModelRoot SceneGroup( List <Vitaboy.Mesh> meshes, List <Vitaboy.Animation> animations, List <Microsoft.Xna.Framework.Graphics.Texture2D> textures, Vitaboy.Skeleton skel ) { var builder = new SharpGLTF.Scenes.SceneBuilder(); var framerate = 1 / 36f; var nodes = new Dictionary <Vitaboy.Bone, NodeBuilder>(); var transforms = new List <Matrix4x4>(); skel.ComputeBonePositions(skel.RootBone, Microsoft.Xna.Framework.Matrix.Identity); ConvertBone(nodes, skel.RootBone, new NodeBuilder(skel.RootBone.Name)); //animations must be uploaded as part of the bone. add them as animation tracks to the existing nodes var timeprops = new Dictionary <string, float>(); var useAnimID = animations.Count > 1; foreach (var anim in animations) { var name = anim.XSkillName ?? anim.Name; foreach (var motion in anim.Motions) { //find the bone we're creating a curve for var bone = nodes.Values.FirstOrDefault(x => x.Name == motion.BoneName); if (bone == null) { continue; //cannot add this curve to a bone } var root = bone.Name == "ROOT"; var scale = RecursiveScale(bone.Parent); if (motion.TimeProperties != null) { foreach (var tps in motion.TimeProperties) { foreach (var tp in tps.Items) { foreach (var prop in tp.Properties.Items) { foreach (var keyPair in prop.KeyPairs) { var tpname = name + "/" + tp.ID.ToString() + "/" + keyPair.Key; float value = 1; if (!float.TryParse(keyPair.Value, out value)) { value = 1; tpname += "=" + keyPair.Value; } timeprops[tpname] = value; } } } } } //create curves for rotation and translation CurveBuilder <Vector3> transCurve = null; CurveBuilder <Quaternion> rotCurve = null; if (motion.HasTranslation) { transCurve = bone.Translation.UseTrackBuilder(name); } if (motion.HasRotation) { rotCurve = bone.Rotation.UseTrackBuilder(name); } for (int i = 0; i < motion.FrameCount; i++) { var quat = new Quaternion(); Vector3 trans = new Vector3(); if (rotCurve != null) { quat = QuatConvert(anim.Rotations[i + motion.FirstRotationIndex]); } if (transCurve != null) { trans = Vec3Convert(anim.Translations[i + motion.FirstTranslationIndex]) / scale; } if (root) { quat = RotateQ * quat; trans = Vector3.Transform(trans, RotateM); } rotCurve?.SetPoint(i * framerate, quat, true); transCurve?.SetPoint(i * framerate, trans, true); } if (bone.Name == "R_LEG") { } } } var resultMeshes = new List <MeshBuilder <VertexPositionNormal, VertexTexture1, VertexJoints8x4> >(); var orderedBones = skel.Bones.Select(x => nodes[x]).ToArray(); var world = Matrix4x4.Identity; //Matrix4x4.CreateFromAxisAngle(new Vector3(0, 1, 0), (float)Math.PI / 2f); var outMesh = new MeshBuilder <VertexPositionNormal, VertexTexture1, VertexJoints8x4>("Avatar"); var meshi = 0; foreach (var mesh in meshes) { var tex = textures[meshi++]; var data = TextureToPng(tex); var material = new MaterialBuilder(mesh.SkinName ?? ("mesh_" + meshi)); var mtex = material.UseChannel(KnownChannels.BaseColor).UseTexture().WithPrimaryImage(new ArraySegment <byte>(data)); var prim = outMesh.UsePrimitive(material, 3); //todo: blend verts var previous = new List <VertexBuilder <VertexPositionNormal, VertexTexture1, VertexJoints8x4> >(); for (int i = 0; i < mesh.IndexBuffer.Length; i++) { var point = mesh.IndexBuffer[(i / 3) * 3 + (2 - (i % 3))]; //flip triangles var vert = mesh.VertexBuffer[point]; var texc = new Vector2(vert.TextureCoordinate.X, vert.TextureCoordinate.Y); var boneInd = (int)vert.Parameters.X; var blendInd = (int)vert.Parameters.Y; var mat = skel.Bones[boneInd].AbsoluteMatrix * RotateMX; var bmat = skel.Bones[blendInd].AbsoluteMatrix * RotateMX; VertexBuilder <VertexPositionNormal, VertexTexture1, VertexJoints8x4> nvert = ( new VertexPositionNormal( Vector3.Lerp(Vec3Convert(Microsoft.Xna.Framework.Vector3.Transform(vert.Position, mat)), Vec3Convert(Microsoft.Xna.Framework.Vector3.Transform(vert.BvPosition, bmat)), vert.Parameters.Z), Vector3.Lerp(Vec3Convert(Microsoft.Xna.Framework.Vector3.TransformNormal(vert.Normal, mat)), Vec3Convert(Microsoft.Xna.Framework.Vector3.TransformNormal(vert.BvNormal, bmat)), vert.Parameters.Z) ), new VertexTexture1(texc), new VertexJoints8x4(new SharpGLTF.Transforms.SparseWeight8(new Vector4(boneInd, blendInd, 0, 0), new Vector4(1 - vert.Parameters.Z, vert.Parameters.Z, 0, 0))) ); if (previous.Count == 2) { prim.AddTriangle(previous[0], previous[1], nvert); previous.Clear(); } else { previous.Add(nvert); } } } var skin = builder.AddSkinnedMesh(outMesh, world, orderedBones); skin.Name = "Skeleton"; var schema = builder.ToSchema2(); /* * var children = schema.LogicalScenes.FirstOrDefault().VisualChildren; * foreach (var child in children) * { * if (child.Skin == null) { //armature * var extras = child.TryUseExtrasAsDictionary(true); * foreach (var tp in timeprops) * { * extras.Add(tp.Key, tp.Value); * } * } * } */ //var extras = schema.LogicalNodes.FirstOrDefault(x => x.Name == "ROOT").TryUseExtrasAsDictionary(true); var extras = schema.LogicalScenes.FirstOrDefault().TryUseExtrasAsDictionary(true); foreach (var tp in timeprops) { extras.Add(tp.Key, tp.Value); } return(schema); }
public void OnBodyBegin(IBody2 body, MaterialBuilder docMatBuilder, Matrix4x4 postion) { _sceneBuilder.AddRigidMesh(body.GetBodyMeshBuilder(docMatBuilder), postion); }
public GeometryModelProcessor() { this.MaterialBuilder = new MaterialBuilder(new MaterialLookup(this.FallbackAlbedo, this.FallbackMetalicness, this.FallbackNormal, this.FallbackRoughness, this.FallbackAmbientOcclusion)); }
public void CreateDoubleSkinnedScene() { TestContext.CurrentContext.AttachShowDirLink(); TestContext.CurrentContext.AttachGltfValidatorLinks(); // 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 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"); }
private MeshBuilder <VPOS /*, VTEX*/> BuildCaseMesh( string meshName, float length, float width, float height, Color[] colorFaces, float filet, Color colorFilet, float tapeWidth, Color colorTape ) { var mesh = new MeshBuilder <VPOS /*, VTEX*/>(meshName); // // 7--------------- 6 T { 3,0,4,7 } // Left // /| /| | K { 1,2,6,5 } // Right // / | / | |/ { 0,1,5,4 } // Front // / 3-------------/- 2 L---- | ----R { 2,3,7,6 } // Rear // 4--/------------ 5 / /| { 0,3,2,1 } // Bottom // | / | / F | { 4,5,6,7 } // Top // |/ |/ B // 0----------------1 // VPOS[] vertices = new VPOS[] { // 0 new VPOS(0.0f, 0.0f, 0.0f), // 0 new VPOS(0.0f + filet, 0.0f + filet, 0.0f), // B // 1 new VPOS(0.0f + filet, 0.0f, 0.0f + filet), // F // 2 new VPOS(0.0f, 0.0f + filet, 0.0f + filet), // L // 3 // 1 new VPOS(length, 0.0f, 0.0f), // 4 new VPOS(length - filet, 0.0f + filet, 0.0f), // B // 5 new VPOS(length - filet, 0.0f, 0.0f + filet), // F // 6 new VPOS(length, 0.0f + filet, 0.0f + filet), // R // 7 // 2 new VPOS(length, width, 0.0f), // 8 new VPOS(length - filet, width - filet, 0.0f), // B // 9 new VPOS(length - filet, width, 0.0f + filet), // K // 10 new VPOS(length, width - filet, 0.0f + filet), // R // 11 // 3 new VPOS(0.0f, width, 0.0f), // 12 new VPOS(0.0f + filet, width - filet, 0.0f), // B // 13 new VPOS(0.0f + filet, width, 0.0f + filet), // K // 14 new VPOS(0.0f, width - filet, 0.0f + filet), // L // 15 // 4 new VPOS(0.0f, 0.0f, height), // 16 new VPOS(0.0f + filet, 0.0f + filet, height), // T // 17 new VPOS(0.0f + filet, 0.0f, height - filet), // F // 18 new VPOS(0.0f, 0.0f + filet, height - filet), // L // 19 // 5 new VPOS(length, 0.0f, height), // 20 new VPOS(length - filet, 0.0f + filet, height), // T // 21 new VPOS(length - filet, 0.0f, height - filet), // F // 22 new VPOS(length, 0.0f + filet, height - filet), // R // 23 // 6 new VPOS(length, width, height), // 24 new VPOS(length - filet, width - filet, height), // T // 25 new VPOS(length - filet, width, height - filet), // K // 26 new VPOS(length, width - filet, height - filet), // R // 27 // 7 new VPOS(0.0f, width, height), // 28 new VPOS(0.0f + filet, width - filet, height), // T // 29 new VPOS(0.0f + filet, width, height - filet), // K // 30 new VPOS(0.0f, width - filet, height - filet), // L // 31 // 8 new VPOS(0.0f + filet, 0.5f * (width - tapeWidth), height), // 32 new VPOS(length - filet, 0.5f * (width - tapeWidth), height), // 33 new VPOS(length - filet, 0.5f * (width + tapeWidth), height), // 34 new VPOS(0.0f + filet, 0.5f * (width + tapeWidth), height) //35 }; Vector3[] vectors = { // 0 new Vector3(0.0f, 0.0f, 0.0f), // 0 new Vector3(0.0f + filet, 0.0f + filet, 0.0f), // B // 1 new Vector3(0.0f + filet, 0.0f, 0.0f + filet), // F // 2 new Vector3(0.0f, 0.0f + filet, 0.0f + filet), // L // 3 // 1 new Vector3(length, 0.0f, 0.0f), // 4 new Vector3(length - filet, 0.0f + filet, 0.0f), // B // 5 new Vector3(length - filet, 0.0f, 0.0f + filet), // F // 6 new Vector3(length, 0.0f + filet, 0.0f + filet), // R // 7 // 2 new Vector3(length, width, 0.0f), // 8 new Vector3(length - filet, width - filet, 0.0f), // B // 9 new Vector3(length - filet, width, 0.0f + filet), // K // 10 new Vector3(length, width - filet, 0.0f + filet), // R // 11 // 3 new Vector3(0.0f, width, 0.0f), // 12 new Vector3(0.0f + filet, width - filet, 0.0f), // B // 13 new Vector3(0.0f + filet, width, 0.0f + filet), // K // 14 new Vector3(0.0f, width - filet, 0.0f + filet), // L // 15 // 4 new Vector3(0.0f, 0.0f, height), // 16 new Vector3(0.0f + filet, 0.0f + filet, height), // T // 17 new Vector3(0.0f + filet, 0.0f, height - filet), // F // 18 new Vector3(0.0f, 0.0f + filet, height - filet), // L // 19 // 5 new Vector3(length, 0.0f, height), // 20 new Vector3(length - filet, 0.0f + filet, height), // T // 21 new Vector3(length - filet, 0.0f, height - filet), // F // 22 new Vector3(length, 0.0f + filet, height - filet), // R // 23 // 6 new Vector3(length, width, height), // 24 new Vector3(length - filet, width - filet, height), // T // 25 new Vector3(length - filet, width, height - filet), // K // 26 new Vector3(length, width - filet, height - filet), // R // 27 // 7 new Vector3(0.0f, width, height), // 28 new Vector3(0.0f + filet, width - filet, height), // T // 29 new Vector3(0.0f + filet, width, height - filet), // K // 30 new Vector3(0.0f, width - filet, height - filet), // L // 31 // 8 new Vector3(0.0f + filet, 0.5f * (width - tapeWidth), height), // 32 new Vector3(length - filet, 0.5f * (width - tapeWidth), height), // 33 new Vector3(length - filet, 0.5f * (width + tapeWidth), height), // 34 new Vector3(0.0f + filet, 0.5f * (width + tapeWidth), height) //35 }; int[,] qFace = new int[, ] { { 15, 3, 19, 31 }, // left { 7, 11, 27, 23 }, // right { 2, 6, 22, 18 }, // front { 10, 14, 30, 26 }, // rear { 1, 13, 9, 5 }, // bottom { 17, 21, 33, 32 }, // top1 { 35, 34, 25, 29 }, // top2 { 32, 33, 34, 35 } // tape }; int[,] qFaceFilet = new int[, ] { { 1, 5, 6, 2 }, { 5, 9, 11, 7 }, { 9, 13, 14, 10 }, { 13, 1, 3, 15 }, { 18, 22, 21, 17 }, { 23, 27, 25, 21 }, { 26, 30, 29, 25 }, { 31, 19, 17, 29 }, { 3, 2, 18, 19 }, { 6, 7, 23, 22 }, { 11, 10, 26, 27 }, { 14, 15, 31, 30 } }; int[,] edges = new int[, ] { { 0, 4 }, // 0 { 4, 8 }, // 1 { 8, 12 }, // 2 { 12, 0 }, // 3 { 16, 20 }, // 4 { 20, 24 }, // 5 { 24, 28 }, // 6 { 28, 16 }, // 7 { 0, 16 }, // 8 { 4, 20 }, // 9 { 8, 24 }, // 10 { 12, 28 } // 11 }; var materialBlack = new MaterialBuilder() .WithUnlitShader() .WithChannelParam(KnownChannel.BaseColor, ColorToVector4(Color.Black)); for (int i = 0; i < 7; ++i) { MaterialBuilder materialColor = new MaterialBuilder() .WithDoubleSide(true) .WithMetallicRoughnessShader() .WithChannelParam(KnownChannel.BaseColor, ColorToVector4(colorFaces[i < 6 ? i : 5])); /* * if (i == 1) * { * materialColor = new MaterialBuilder().WithChannelImage(KnownChannel.BaseColor, @"D:\\testImage.png"); * materialColor.GetChannel(KnownChannel.BaseColor).UseTexture().WithTransform(1.0f, 1.0f, 1.0f, 1.0f); * } */ var primFace = mesh.UsePrimitive(materialColor); // 1 2 6 5 /* * Vector2 v3 = new Vector2(0.0f, 0.0f); * Vector2 v2 = new Vector2(1.0f, 0.0f); * Vector2 v1 = new Vector2(1.0f, 1.0f); * Vector2 v0 = new Vector2(0.0f, 1.0f); * if (i == 1) * primFace.AddQuadrangle( * (vectors[qFace[i, 0]], v0 ), * (vectors[qFace[i, 1]], v1 ), * (vectors[qFace[i, 2]], v2 ), * (vectors[qFace[i, 3]], v3 ) * ); * else */ primFace.AddQuadrangle(vertices[qFace[i, 0]], vertices[qFace[i, 1]], vertices[qFace[i, 2]], vertices[qFace[i, 3]]); } if (tapeWidth > 0.0f) { var materialTape = new MaterialBuilder() .WithDoubleSide(true) .WithMetallicRoughnessShader() .WithChannelParam(KnownChannel.BaseColor, ColorToVector4(colorTape)); var primFace = mesh.UsePrimitive(materialTape); primFace.AddQuadrangle(vertices[qFace[7, 0]], vertices[qFace[7, 1]], vertices[qFace[7, 2]], vertices[qFace[7, 3]]); if (filet == 0) { var primTapeBorder = mesh.UsePrimitive(materialBlack, 2); primTapeBorder.AddLine(vertices[qFace[7, 0]], vertices[qFace[7, 1]]); primTapeBorder.AddLine(vertices[qFace[7, 1]], vertices[qFace[7, 2]]); primTapeBorder.AddLine(vertices[qFace[7, 2]], vertices[qFace[7, 3]]); primTapeBorder.AddLine(vertices[qFace[7, 3]], vertices[qFace[7, 0]]); } } if (filet > 0) { var materialFilet = new MaterialBuilder() .WithDoubleSide(true) .WithMetallicRoughnessShader() .WithChannelParam(KnownChannel.BaseColor, ColorToVector4(colorFilet)); var prim = mesh.UsePrimitive(materialFilet); for (int i = 0; i < 12; ++i) { prim.AddQuadrangle( vertices[qFaceFilet[i, 0]], vertices[qFaceFilet[i, 1]], vertices[qFaceFilet[i, 2]], vertices[qFaceFilet[i, 3]] ); } } else { var prim = mesh.UsePrimitive(materialBlack, 2); for (int i = 0; i < 12; ++i) { prim.AddLine(vertices[edges[i, 0]], vertices[edges[i, 1]]); } } return(mesh); }
public void SaveToGltf2(string path, string texturePath) { var textures = new List <(string, Texture)>(); var converter = new ImageConverter(texturePath); var scene = new SceneBuilder(); // var materials = new DictionaryEntry(); var materials = new MaterialBuilder[Materials.Length]; var skin = CreateSkin(); int meshId = 0; foreach (var mesh in Meshes) { // Console.WriteLine("Process mesh " + meshId); int counter = 0; foreach (var submesh in mesh.Submeshes) { var mat = materials[submesh.Material.Id] ?? InitializeMaterial(submesh.Material, materials, converter); materials[submesh.Material.Id] = mat; if (submesh.Vertices.FirstOrDefault().BoneIndices != null) { var glbMesh = new MeshBuilder <VertexPositionNormal, VertexTexture1, VertexJoints4>($"{submesh.Name}"); var primitive = glbMesh.UsePrimitive(mat); var vertices = submesh.Vertices .Select(v => new VertexBuilder <VertexPositionNormal, VertexTexture1, VertexJoints4>( new VertexPositionNormal(v.Position, v.Normal), new VertexTexture1(new Vector2(v.Uv0.X, 1 - v.Uv0.Y)), new VertexJoints4( (v.BoneIndices[0], v.BoneWeights[0]), (v.BoneIndices[1], v.BoneWeights[1]), (v.BoneIndices[2], v.BoneWeights[2]), (v.BoneIndices[3], v.BoneWeights[3]) ) )).ToArray(); var t = submesh.Triangles; for (int i = 0; i < t.GetLength(0); i++) { primitive.AddTriangle(vertices[t[i, 0]], vertices[t[i, 1]], vertices[t[i, 2]]); } scene.AddSkinnedMesh(glbMesh, null, Matrix4x4.Identity, skin); } else { var glbMesh = new MeshBuilder <VertexPositionNormal, VertexTexture1, VertexEmpty>($"{submesh.Name}"); var primitive = glbMesh.UsePrimitive(mat); var vertices = submesh.Vertices .Select(v => new VertexBuilder <VertexPositionNormal, VertexTexture1, VertexEmpty>( new VertexPositionNormal(v.Position, v.Normal), new VertexTexture1(new Vector2(v.Uv0.X, 1 - v.Uv0.Y)) )).ToArray(); var t = submesh.Triangles; for (int i = 0; i < t.GetLength(0); i++) { primitive.AddTriangle(vertices[t[i, 0]], vertices[t[i, 1]], vertices[t[i, 2]]); } scene.AddRigidMesh(glbMesh, null, submesh.Transform); } } meshId++; } // Console.WriteLine("Save..."); var gltf2 = scene.ToGltf2(); // Fix skin var firstSkin = gltf2.LogicalSkins.FirstOrDefault(); foreach (var node in gltf2.LogicalNodes) { if (node.Skin != null) { node.Skin = firstSkin; } } // Fix texture naming (sadl, very inefficient...) foreach (var tex in gltf2.LogicalTextures) { var name = converter.GetName(tex.PrimaryImage.Content.Content.ToArray()); if (name != null) { tex.Name = name; tex.PrimaryImage.Name = name; } else { Console.WriteLine("Texture not found."); } } gltf2.Save(Path.GetFullPath(path), new WriteSettings() { ImageWriting = ResourceWriteMode.Default, Validation = ValidationMode.Strict }); }
private MeshBuilder <VPOS /*, VTEX*/> BuildPalletCapMesh( float length, float width, float height, float innerLength, float innerWidth, float innerHeight, Color color) { VPOS[] vertices = new VPOS[] { new VPOS(0.0f, 0.0f, 0.0f), new VPOS(length, 0.0f, 0.0f), new VPOS(length, width, 0.0f), new VPOS(0.0f, width, 0.0f), new VPOS(0.0f, 0.0f, height), new VPOS(length, 0.0f, height), new VPOS(length, width, height), new VPOS(0.0f, width, height) }; int[,] faces = { { 3, 0, 4, 7 }, // left { 1, 2, 6, 5 }, // Right { 0, 1, 5, 4 }, // Front { 2, 3, 7, 6 }, // Rear { 4, 5, 6, 7 } // Top }; int[,] edges = { { 0, 1 }, // bottom { 1, 2 }, { 2, 3 }, { 3, 0 }, { 4, 5 }, // top { 5, 6 }, { 6, 7 }, { 7, 4 }, { 0, 4 }, // side edges { 1, 5 }, { 2, 6 }, { 3, 7 } }; // mesh var mesh = new MeshBuilder <VPOS /*, VTEX*/>("PalletCap"); // faces var materialColor = new MaterialBuilder() .WithDoubleSide(true) .WithMetallicRoughnessShader() .WithChannelParam(KnownChannel.BaseColor, ColorToVector4(color)); var primFaces = mesh.UsePrimitive(materialColor); for (int i = 0; i < 5; ++i) { primFaces.AddQuadrangle(vertices[faces[i, 0]], vertices[faces[i, 1]], vertices[faces[i, 2]], vertices[faces[i, 3]]); } // edges var materialBlack = new MaterialBuilder() .WithUnlitShader() .WithChannelParam(KnownChannel.BaseColor, ColorToVector4(Color.Black)); var primEdges = mesh.UsePrimitive(materialBlack, 2); for (int i = 0; i < 12; ++i) { primEdges.AddLine(vertices[edges[i, 0]], vertices[edges[i, 1]]); } return(mesh); }
void SetDefaultMaterial() { _material = _materials["Default"]; }
public static void CopyTo(this MaterialBuilder srcMaterial, Material dstMaterial) { Guard.NotNull(srcMaterial, nameof(srcMaterial)); Guard.NotNull(dstMaterial, nameof(dstMaterial)); srcMaterial.ValidateForSchema2(); srcMaterial.TryCopyNameAndExtrasTo(dstMaterial); dstMaterial.Alpha = srcMaterial.AlphaMode.ToSchema2(); dstMaterial.AlphaCutoff = srcMaterial.AlphaCutoff; dstMaterial.DoubleSided = srcMaterial.DoubleSided; dstMaterial.IndexOfRefraction = srcMaterial.IndexOfRefraction; var hasClearCoat = srcMaterial.GetChannel("ClearCoat") != null || srcMaterial.GetChannel("ClearCoatRoughness") != null || srcMaterial.GetChannel("ClearCoatNormal") != null; var hasTransmission = srcMaterial.GetChannel("Transmission") != null; var hasSheen = srcMaterial.GetChannel("SheenColor") != null || srcMaterial.GetChannel("SheenRoughness") != null; var hasSpecular = srcMaterial.GetChannel("SpecularColor") != null || srcMaterial.GetChannel("SpecularFactor") != null; var hasVolume = srcMaterial.GetChannel("VolumeThickness") != null || srcMaterial.GetChannel("VolumeAttenuation") != null; srcMaterial.CopyChannelsTo(dstMaterial, "Normal", "Occlusion", "Emissive"); MaterialBuilder defMaterial = null; if (srcMaterial.ShaderStyle == "Unlit") { dstMaterial.InitializeUnlit(); srcMaterial.CopyChannelsTo(dstMaterial, "BaseColor"); return; } if (srcMaterial.ShaderStyle == "PBRMetallicRoughness") { dstMaterial.InitializePBRMetallicRoughness ( hasClearCoat ? "ClearCoat" : null, hasTransmission ? "Transmission" : null, hasSheen ? "Sheen" : null, hasSpecular ? "Specular" : null, hasVolume ? "Volume" : null); 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)); } defMaterial.CopyChannelsTo(dstMaterial, "BaseColor", "MetallicRoughness"); defMaterial.CopyChannelsTo(dstMaterial, "ClearCoat", "ClearCoatRoughness", "ClearCoatNormal"); defMaterial.CopyChannelsTo(dstMaterial, "Transmission"); defMaterial.CopyChannelsTo(dstMaterial, "SheenColor", "SheenRoughness"); defMaterial.CopyChannelsTo(dstMaterial, "SpecularColor", "SpecularFactor"); defMaterial.CopyChannelsTo(dstMaterial, "VolumeThickness", "VolumeAttenuation"); } }