private static void AddLines(long id, Vector3[] vertices, Gltf gltf, int material, List <byte> buffer, List <BufferView> bufferViews, List <Accessor> accessors, Transform t = null) { var floatSize = sizeof(float); var ushortSize = sizeof(ushort); var vBuff = new byte[vertices.Length * 3 * floatSize]; var indices = new byte[vertices.Length / 2 * 2 * ushortSize]; var vi = 0; var ii = 0; for (var i = 0; i < vertices.Length; i++) { var v = vertices[i]; System.Buffer.BlockCopy(BitConverter.GetBytes((float)v.X), 0, vBuff, vi, floatSize); System.Buffer.BlockCopy(BitConverter.GetBytes((float)v.Y), 0, vBuff, vi + floatSize, floatSize); System.Buffer.BlockCopy(BitConverter.GetBytes((float)v.Z), 0, vBuff, vi + 2 * floatSize, floatSize); vi += 3 * floatSize; // On every even index, write a line segment. if (i % 2 == 0 && i < vertices.Length - 1) { System.Buffer.BlockCopy(BitConverter.GetBytes((ushort)i), 0, indices, ii, ushortSize); System.Buffer.BlockCopy(BitConverter.GetBytes((ushort)(i + 1)), 0, indices, ii + ushortSize, ushortSize); ii += 2 * ushortSize; } } // Console.WriteLine($"{vBuff.Count / sizeof(float)/3} vertices, {indices.Count / sizeof(ushort)} indices"); var bbox = new BBox3(vertices); gltf.AddLineLoop($"{id}_curve", buffer, bufferViews, accessors, vBuff.ToArray(), indices.ToArray(), bbox.Min.ToArray(), bbox.Max.ToArray(), 0, (ushort)(vertices.Length - 1), material, MeshPrimitive.ModeEnum.LINES, t); }
private void AddLines(long id, Vector3[] vertices, Gltf gltf, int material, Transform t = null) { var vBuff = vertices.ToArray(); var vCount = vertices.Length; var indices = new List <ushort>(); for (ushort i = 0; i < vertices.Length; i += 2) { indices.Add(i); indices.Add((ushort)(i + 1)); } // var indices = Enumerable.Range(0, vCount).Select(i => (ushort)i).ToArray(); var bbox = new BBox3(vertices); gltf.AddLineLoop($"{id}_curve", _buffer, vBuff, indices.ToArray(), bbox.Min.ToArray(), bbox.Max.ToArray(), 0, (ushort)(vCount - 1), material, MeshPrimitive.ModeEnum.LINES, t); }
private void AddArrow(long id, Vector3 origin, Vector3 direction, Gltf gltf, int material, Transform t) { var scale = 0.5; var end = origin + direction * scale; var up = direction.IsParallelTo(Vector3.ZAxis) ? Vector3.YAxis : Vector3.ZAxis; var tr = new Transform(Vector3.Origin, direction.Cross(up), direction); tr.Rotate(up, -45.0); var arrow1 = tr.OfPoint(Vector3.XAxis * 0.1); var pts = new[] { origin, end, end + arrow1 }; var vBuff = pts.ToArray(); var vCount = 3; var indices = Enumerable.Range(0, vCount).Select(i => (ushort)i).ToArray(); var bbox = new BBox3(pts); gltf.AddLineLoop($"{id}_curve", _buffer, vBuff, indices, bbox.Min.ToArray(), bbox.Max.ToArray(), 0, (ushort)(vCount - 1), material, MeshPrimitive.ModeEnum.LINE_STRIP, t); }
private static void AddLines(long id, IList <Vector3> vertices, Gltf gltf, int material, List <byte> buffer, List <BufferView> bufferViews, List <Accessor> accessors, List <glTFLoader.Schema.Mesh> meshes, List <glTFLoader.Schema.Node> nodes, bool lineLoop, Transform t = null) { var floatSize = sizeof(float); var ushortSize = sizeof(ushort); var vBuff = new byte[vertices.Count * 3 * floatSize]; var indices = new byte[vertices.Count * 2 * ushortSize]; var vi = 0; var ii = 0; for (var i = 0; i < vertices.Count; i++) { var v = vertices[i]; System.Buffer.BlockCopy(BitConverter.GetBytes((float)v.X), 0, vBuff, vi, floatSize); System.Buffer.BlockCopy(BitConverter.GetBytes((float)v.Y), 0, vBuff, vi + floatSize, floatSize); System.Buffer.BlockCopy(BitConverter.GetBytes((float)v.Z), 0, vBuff, vi + 2 * floatSize, floatSize); vi += 3 * floatSize; var write = lineLoop ? (i < vertices.Count - 1) : (i % 2 == 0 && i < vertices.Count - 1); if (write) { System.Buffer.BlockCopy(BitConverter.GetBytes((ushort)i), 0, indices, ii, ushortSize); System.Buffer.BlockCopy(BitConverter.GetBytes((ushort)(i + 1)), 0, indices, ii + ushortSize, ushortSize); ii += 2 * ushortSize; } } var bbox = new BBox3(vertices); gltf.AddLineLoop($"{id}_curve", buffer, bufferViews, accessors, vBuff, indices, bbox.Min.ToArray(), bbox.Max.ToArray(), 0, (ushort)(vertices.Count - 1), material, MeshPrimitive.ModeEnum.LINES, meshes, nodes, t); }
private void GetRenderDataForElement(Element e, Gltf gltf, Dictionary <string, int> materials) { if (e is ITessellateMesh) { var mp = e as ITessellateMesh; var mesh = mp.Mesh(); Transform transform = null; if (e.Transform != null) { transform = e.Transform; } gltf.AddTriangleMesh(e.Id + "_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[e.Material.Name], null, transform); } if (e is ITessellateCurves) { var cp = e as ITessellateCurves; var curves = cp.Curves(); var counter = 0; foreach (var c in curves) { var vBuff = c.ToArray(); var indices = Enumerable.Range(0, c.Count).Select(i => (ushort)i).ToArray(); var bbox = new BBox3(c); gltf.AddLineLoop($"{e.Id}_curve_{counter}", _buffer, vBuff, indices, bbox.Min.ToArray(), bbox.Max.ToArray(), 0, (ushort)(c.Count - 1), materials[BuiltInMaterials.Black.Name], e.Transform); } } if (e.SubElements.Count > 0) { foreach (var esub in e.SubElements) { GetRenderDataForElement(esub, gltf, materials); } } }
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); }