private Gltf InitializeGlTF() { var gltf = new Gltf(); var asset = new Asset(); asset.Version = "2.0"; asset.Generator = "hypar-gltf"; gltf.Asset = asset; var root = new Node(); root.Translation = new[] { 0.0f, 0.0f, 0.0f }; root.Scale = new[] { 1.0f, 1.0f, 1.0f }; // Set Z up by rotating -90d around the X Axis var q = new Quaternion(new Vector3(1, 0, 0), -Math.PI / 2); root.Rotation = new[] { (float)q.X, (float)q.Y, (float)q.Z, (float)q.W }; gltf.Nodes = new[] { root }; gltf.Scene = 0; var scene = new Scene(); scene.Nodes = new[] { 0 }; gltf.Scenes = new[] { scene }; gltf.ExtensionsUsed = new[] { "KHR_materials_pbrSpecularGlossiness" }; var materialsToAdd = this._materials.Values.ToList(); materialsToAdd.Add(BuiltInMaterials.XAxis); materialsToAdd.Add(BuiltInMaterials.YAxis); materialsToAdd.Add(BuiltInMaterials.ZAxis); materialsToAdd.Add(BuiltInMaterials.Edges); materialsToAdd.Add(BuiltInMaterials.EdgesHighlighted); var materials = gltf.AddMaterials(materialsToAdd); var lines = new List <Vector3>(); foreach (var kvp in this._elements) { var e = kvp.Value; GetRenderDataForElement(e, gltf, materials, lines); } AddLines(100000, lines.ToArray(), gltf, materials[BuiltInMaterials.Edges.Name], null); var buff = new glTFLoader.Schema.Buffer(); buff.ByteLength = _buffer.Count(); gltf.Buffers = new[] { buff }; return(gltf); }
internal static void ToGlb(this Solid solid, string path) { var gltf = new Gltf(); var asset = new Asset(); asset.Version = "2.0"; asset.Generator = "hypar-gltf"; gltf.Asset = asset; var root = new Node(); root.Translation = new[] { 0.0f, 0.0f, 0.0f }; root.Scale = new[] { 1.0f, 1.0f, 1.0f }; // Set Z up by rotating -90d around the X Axis var q = new Quaternion(new Vector3(1, 0, 0), -Math.PI / 2); root.Rotation = new[] { (float)q.X, (float)q.Y, (float)q.Z, (float)q.W }; gltf.Nodes = new[] { root }; gltf.Scene = 0; var scene = new Scene(); scene.Nodes = new[] { 0 }; gltf.Scenes = new[] { scene }; gltf.ExtensionsUsed = new[] { "KHR_materials_pbrSpecularGlossiness" }; var materials = gltf.AddMaterials(new[] { BuiltInMaterials.Default, BuiltInMaterials.Edges, BuiltInMaterials.EdgesHighlighted }); var buffer = new List <byte>(); var mesh = new Elements.Geometry.Mesh(); solid.Tessellate(ref mesh); gltf.AddTriangleMesh("mesh", buffer, mesh.Vertices.ToArray(), mesh.Normals.ToArray(), mesh.Indices.ToArray(), mesh.VertexColors.ToArray(), mesh.VMin, mesh.VMax, mesh.NMin, mesh.NMax, mesh.CMin, mesh.CMax, mesh.IMin, mesh.IMax, materials[BuiltInMaterials.Default.Name], null, null); var edgeCount = 0; var vertices = new List <Vector3>(); var verticesHighlighted = new List <Vector3>(); foreach (var e in solid.Edges.Values) { if (e.Left.Loop == null || e.Right.Loop == null) { verticesHighlighted.AddRange(new[] { e.Left.Vertex.Point, e.Right.Vertex.Point }); } else { vertices.AddRange(new[] { e.Left.Vertex.Point, e.Right.Vertex.Point }); } edgeCount++; } if (vertices.Count > 0) { // Draw standard edges var vBuff = vertices.ToArray().ToArray(); var vCount = vertices.Count; // var indices = Enumerable.Range(0, vCount).Select(i => (ushort)i).ToArray(); var indices = new List <ushort>(); for (var i = 0; i < vertices.Count; i += 2) { indices.Add((ushort)i); indices.Add((ushort)(i + 1)); } var bbox = new BBox3(vertices.ToArray()); gltf.AddLineLoop($"edge_{edgeCount}", buffer, vBuff, indices.ToArray(), bbox.Min.ToArray(), bbox.Max.ToArray(), 0, (ushort)(vCount - 1), materials[BuiltInMaterials.Edges.Name], MeshPrimitive.ModeEnum.LINES, null); } if (verticesHighlighted.Count > 0) { // Draw highlighted edges var vBuff = vertices.ToArray().ToArray(); var vCount = vertices.Count; var indices = new List <ushort>(); for (var i = 0; i < vertices.Count; i += 2) { indices.Add((ushort)i); indices.Add((ushort)(i + 1)); } var bbox = new BBox3(vertices.ToArray()); gltf.AddLineLoop($"edge_{edgeCount}", buffer, vBuff, indices.ToArray(), bbox.Min.ToArray(), bbox.Max.ToArray(), 0, (ushort)(vCount - 1), materials[BuiltInMaterials.EdgesHighlighted.Name], MeshPrimitive.ModeEnum.LINES, null); } var buff = new glTFLoader.Schema.Buffer(); buff.ByteLength = buffer.Count; gltf.Buffers = new[] { buff }; if (File.Exists(path)) { File.Delete(path); } gltf.SaveBinaryModel(buffer.ToArray(), path); }
private static Gltf InitializeGlTF(Model model, List <byte> buffer) { var sw = new Stopwatch(); sw.Start(); var gltf = new Gltf(); var asset = new Asset(); asset.Version = "2.0"; asset.Generator = "hypar-gltf"; gltf.Asset = asset; var root = new Node(); root.Translation = new[] { 0.0f, 0.0f, 0.0f }; root.Scale = new[] { 1.0f, 1.0f, 1.0f }; // Set Z up by rotating -90d around the X Axis var q = new Quaternion(new Vector3(1, 0, 0), -Math.PI / 2); root.Rotation = new[] { (float)q.X, (float)q.Y, (float)q.Z, (float)q.W }; gltf.Nodes = new[] { root }; gltf.Scene = 0; var scene = new Scene(); scene.Nodes = new[] { 0 }; gltf.Scenes = new[] { scene }; gltf.ExtensionsUsed = new[] { "KHR_materials_pbrSpecularGlossiness" }; sw.Stop(); Console.WriteLine($"glTF: {sw.Elapsed} elapsed for writing root node."); sw.Reset(); sw.Start(); var materialsToAdd = model.Materials.Values.ToList(); materialsToAdd.Add(BuiltInMaterials.XAxis); materialsToAdd.Add(BuiltInMaterials.YAxis); materialsToAdd.Add(BuiltInMaterials.ZAxis); materialsToAdd.Add(BuiltInMaterials.Edges); materialsToAdd.Add(BuiltInMaterials.EdgesHighlighted); var materials = gltf.AddMaterials(materialsToAdd); sw.Stop(); Console.WriteLine($"glTF: {sw.Elapsed} elapsed for writing materials."); sw.Reset(); sw.Start(); // Lines are stored in a list of lists // according to the max available index size of ushort. var lines = new List <List <Vector3> >() { new List <Vector3>() }; var bufferViews = new List <BufferView>(); var accessors = new List <Accessor>(); var elements = model.Elements.Values.ToArray(); for (var i = 0; i < elements.Length; i++) { var e = elements[i]; GetRenderDataForElement(e, gltf, materials, lines, buffer, bufferViews, accessors); } sw.Stop(); Console.WriteLine($"glTF: {sw.Elapsed} elapsed for getting render data for nodes."); sw.Reset(); sw.Start(); if (lines.Count > 0) { foreach (var lineSet in lines) { if (lineSet.Count > 0) { AddLines(100000, lineSet.ToArray(), gltf, materials[BuiltInMaterials.Edges.Name], buffer, bufferViews, accessors); } } } sw.Stop(); Console.WriteLine($"glTF: {sw.Elapsed} elapsed for writing edges."); sw.Reset(); sw.Start(); var buff = new glTFLoader.Schema.Buffer(); buff.ByteLength = buffer.Count(); gltf.Buffers = new[] { buff }; sw.Stop(); Console.WriteLine($"glTF: {sw.Elapsed} elapsed for assigning buffer."); sw.Reset(); gltf.BufferViews = bufferViews.ToArray(); gltf.Accessors = accessors.ToArray(); return(gltf); }
internal static void ToGlb(this Solid solid, string path) { var gltf = new Gltf(); var asset = new Asset(); asset.Version = "2.0"; asset.Generator = "hypar-gltf"; gltf.Asset = asset; var root = new Node(); root.Translation = new[] { 0.0f, 0.0f, 0.0f }; root.Scale = new[] { 1.0f, 1.0f, 1.0f }; // Set Z up by rotating -90d around the X Axis var q = new Quaternion(new Vector3(1, 0, 0), -Math.PI / 2); root.Rotation = new[] { (float)q.X, (float)q.Y, (float)q.Z, (float)q.W }; gltf.Nodes = new[] { root }; gltf.Scene = 0; var scene = new Scene(); scene.Nodes = new[] { 0 }; gltf.Scenes = new[] { scene }; gltf.ExtensionsUsed = new[] { "KHR_materials_pbrSpecularGlossiness" }; var materials = gltf.AddMaterials(new[] { BuiltInMaterials.Default, BuiltInMaterials.Edges, BuiltInMaterials.EdgesHighlighted }); var buffer = new List <byte>(); var mesh = new Elements.Geometry.Mesh(); solid.Tessellate(ref mesh); byte[] vertexBuffer; byte[] normalBuffer; byte[] indexBuffer; byte[] colorBuffer; double[] vmin; double[] vmax; double[] nmin; double[] nmax; float[] cmin; float[] cmax; ushort imin; ushort imax; mesh.GetBuffers(out vertexBuffer, out indexBuffer, out normalBuffer, out colorBuffer, out vmax, out vmin, out nmin, out nmax, out cmin, out cmax, out imin, out imax); var bufferViews = new List <BufferView>(); var accessors = new List <Accessor>(); gltf.AddTriangleMesh("mesh", buffer, bufferViews, accessors, vertexBuffer, normalBuffer, indexBuffer, colorBuffer, vmin, vmax, nmin, nmax, imin, imax, materials[BuiltInMaterials.Default.Name], cmin, cmax, null, null); var edgeCount = 0; var vertices = new List <Vector3>(); var verticesHighlighted = new List <Vector3>(); foreach (var e in solid.Edges.Values) { if (e.Left.Loop == null || e.Right.Loop == null) { verticesHighlighted.AddRange(new[] { e.Left.Vertex.Point, e.Right.Vertex.Point }); } else { vertices.AddRange(new[] { e.Left.Vertex.Point, e.Right.Vertex.Point }); } edgeCount++; } if (vertices.Count > 0) { // Draw standard edges AddLines(100000, vertices.ToArray(), gltf, materials[BuiltInMaterials.Edges.Name], buffer, bufferViews, accessors); } if (verticesHighlighted.Count > 0) { // Draw highlighted edges AddLines(100001, verticesHighlighted.ToArray(), gltf, materials[BuiltInMaterials.EdgesHighlighted.Name], buffer, bufferViews, accessors); } var buff = new glTFLoader.Schema.Buffer(); buff.ByteLength = buffer.Count; gltf.Buffers = new[] { buff }; gltf.BufferViews = bufferViews.ToArray(); gltf.Accessors = accessors.ToArray(); if (File.Exists(path)) { File.Delete(path); } gltf.SaveBinaryModel(buffer.ToArray(), path); }
private static Gltf InitializeGlTF(Model model, List <byte> buffer, bool drawEdges = false) { var gltf = new Gltf(); var asset = new Asset(); asset.Version = "2.0"; asset.Generator = "hypar-gltf"; gltf.Asset = asset; var root = new Node(); var rootTransform = new Transform(model.Transform); // Rotate the transform for +Z up. rootTransform.Rotate(new Vector3(1, 0, 0), -90.0); var m = rootTransform.Matrix; root.Matrix = new float[] { (float)m.m11, (float)m.m12, (float)m.m13, 0f, (float)m.m21, (float)m.m22, (float)m.m23, 0f, (float)m.m31, (float)m.m32, (float)m.m33, 0f, (float)m.tx, (float)m.ty, (float)m.tz, 1f }; var nodes = new List <glTFLoader.Schema.Node> { root }; var meshes = new List <glTFLoader.Schema.Mesh>(); gltf.Scene = 0; var scene = new Scene(); scene.Nodes = new[] { 0 }; gltf.Scenes = new[] { scene }; gltf.ExtensionsUsed = new[] { "KHR_materials_pbrSpecularGlossiness", "KHR_materials_unlit", "KHR_lights_punctual" }; var bufferViews = new List <BufferView>(); var accessors = new List <Accessor>(); var materialsToAdd = model.AllElementsOfType <Material>().ToList(); if (drawEdges) { materialsToAdd.Add(BuiltInMaterials.Edges); } var materials = gltf.AddMaterials(materialsToAdd, buffer, bufferViews); var elements = model.Elements.Where(e => { return(e.Value is GeometricElement || e.Value is ElementInstance); }).Select(e => e.Value).ToList(); var lights = model.AllElementsOfType <DirectionalLight>().ToList(); gltf.AddLights(lights, nodes); // Lines are stored in a list of lists // according to the max available index size. var lines = new List <List <Vector3> >(); var currLines = new List <Vector3>(); lines.Add(currLines); var meshElementMap = new Dictionary <Guid, List <int> >(); foreach (var e in elements) { // Check if we'll overrun the index size // for the current line array. If so, // create a new line array. if (currLines.Count * 2 > ushort.MaxValue) { currLines = new List <Vector3>(); lines.Add(currLines); } GetRenderDataForElement(e, gltf, materials, buffer, bufferViews, accessors, meshes, nodes, meshElementMap, currLines, drawEdges); } if (buffer.Count == 0 && lights.Count == 0) { return(null); } if (drawEdges && lines.Count() > 0) { foreach (var lineSet in lines) { if (lineSet.Count == 0) { continue; } AddLines(GetNextId(), lineSet, gltf, materials[BuiltInMaterials.Edges.Name], buffer, bufferViews, accessors, meshes, nodes, false); } } var buff = new glTFLoader.Schema.Buffer(); buff.ByteLength = buffer.Count; gltf.Buffers = new[] { buff }; gltf.BufferViews = bufferViews.ToArray(); gltf.Accessors = accessors.ToArray(); gltf.Nodes = nodes.ToArray(); if (meshes.Count > 0) { gltf.Meshes = meshes.ToArray(); } return(gltf); }