private void AddComponentsToMesh(gltf.Mesh targetMesh, ShapeComponentIds osgGeom, int materialIndex) { gltf.MeshPrimitive thisPrimitive = new gltf.MeshPrimitive(); Dictionary <string, int> att = new Dictionary <string, int>(); att.Add("NORMAL", osgGeom.NormalsAccessorId); att.Add("POSITION", osgGeom.VerticesAccessorId); thisPrimitive.Attributes = att; thisPrimitive.Indices = osgGeom.IndicesAccessorId; thisPrimitive.Material = materialIndex; thisPrimitive.Mode = gltf.MeshPrimitive.ModeEnum.TRIANGLES; int initSize = targetMesh.Primitives != null ? targetMesh.Primitives.Length : 0; if (initSize == 0) { targetMesh.Primitives = new gltf.MeshPrimitive[] { thisPrimitive }; } else { var concat = targetMesh.Primitives.ToList(); concat.Add(thisPrimitive); targetMesh.Primitives = concat.ToArray(); } }
private static RenderData ProcessPrimitive(ILogger logger, glTFLoader.Schema.MeshPrimitive primitive, Gltf gltf, byte[][] buffers, DisplayStyle displayStyle, Outline outline, Transform transform) { if (primitive.Mode != MeshPrimitive.ModeEnum.TRIANGLES) { logger.Debug("The selected primitive mode is not supported."); return(null); } var indexAccessor = gltf.Accessors[(int)primitive.Indices]; var positionAccessor = gltf.Accessors[primitive.Attributes["POSITION"]]; var normalAccessor = gltf.Accessors[primitive.Attributes["NORMAL"]]; var hasColor = primitive.Attributes.ContainsKey("COLOR_0"); var indexBufferView = gltf.BufferViews[(int)indexAccessor.BufferView]; var positionBufferView = gltf.BufferViews[(int)positionAccessor.BufferView]; var normalBufferView = gltf.BufferViews[(int)normalAccessor.BufferView]; var indices = new List <int>(); for (var i = indexBufferView.ByteOffset; i < indexBufferView.ByteOffset + indexBufferView.ByteLength; i += indexBufferView.ByteStride ?? sizeof(ushort)) { var index = BitConverter.ToUInt16(buffers[indexBufferView.Buffer], i); indices.Add(index); } var floatSize = sizeof(float); var positions = new List <XYZ>(); for (var i = positionBufferView.ByteOffset; i < positionBufferView.ByteOffset + positionBufferView.ByteLength; i += positionBufferView.ByteStride ?? (floatSize * 3)) { // Read x, y, z values var x = BitConverter.ToSingle(buffers[positionBufferView.Buffer], i); var y = BitConverter.ToSingle(buffers[positionBufferView.Buffer], i + floatSize); var z = BitConverter.ToSingle(buffers[positionBufferView.Buffer], i + floatSize * 2); var pt = new XYZ(Elements.Units.MetersToFeet(x), Elements.Units.MetersToFeet(y), Elements.Units.MetersToFeet(z)); if (transform != null) { pt = transform.OfPoint(pt); } outline.AddPoint(pt); positions.Add(pt); } var normals = new List <XYZ>(); for (var i = normalBufferView.ByteOffset; i < normalBufferView.ByteOffset + normalBufferView.ByteLength; i += normalBufferView.ByteStride ?? (floatSize * 3)) { // Read x, y, z values var x = BitConverter.ToSingle(buffers[normalBufferView.Buffer], i); var y = BitConverter.ToSingle(buffers[normalBufferView.Buffer], i + floatSize); var z = BitConverter.ToSingle(buffers[normalBufferView.Buffer], i + floatSize * 2); var n = new XYZ(x, y, z); if (transform != null) { n = transform.OfVector(n); } normals.Add(n); } var colors = new List <ColorWithTransparency>(); if (hasColor) { var colorAccessor = gltf.Accessors[primitive.Attributes["COLOR_0"]]; var colorBufferView = gltf.BufferViews[(int)colorAccessor.BufferView]; for (var i = colorBufferView.ByteOffset; i < colorBufferView.ByteOffset + colorBufferView.ByteLength; i += colorBufferView.ByteStride ?? (floatSize * 3)) { // Read x, y, z values var r = BitConverter.ToSingle(buffers[colorBufferView.Buffer], i); var g = BitConverter.ToSingle(buffers[colorBufferView.Buffer], i + floatSize); var b = BitConverter.ToSingle(buffers[colorBufferView.Buffer], i + floatSize * 2); colors.Add(displayStyle == DisplayStyle.HLR ? new ColorWithTransparency(255, 255, 255, 0) : new ColorWithTransparency((uint)(r * 255), (uint)(g * 255), (uint)(b * 255), 0)); } } // The number of vertices will be the same as the length of the indices // because we'll duplicate vertices at every position. var numVertices = indices.Count; var pType = PrimitiveType.TriangleList; var numPrimitives = indices.Count / 3; var numIndices = GetPrimitiveSize(pType) * numPrimitives; VertexFormatBits vertexFormatBits; switch (displayStyle) { case DisplayStyle.HLR: case DisplayStyle.FlatColors: vertexFormatBits = VertexFormatBits.PositionColored; break; default: vertexFormatBits = VertexFormatBits.PositionNormalColored; break; } var vertexFormat = new VertexFormat(vertexFormatBits); var vBuffer = new VertexBuffer(GetVertexSize(vertexFormatBits) * numVertices); var iBuffer = new IndexBuffer(numIndices); vBuffer.Map(GetVertexSize(vertexFormatBits) * numVertices); iBuffer.Map(numIndices); var verticesFlat = new List <VertexPositionColored>(); var vertices = new List <VertexPositionNormalColored>(); var triangles = new List <IndexTriangle>(); ColorWithTransparency color = null; if (displayStyle == DisplayStyle.HLR) { color = new ColorWithTransparency(255, 255, 255, 0); } else if (primitive.Material != null) { var material = gltf.Materials[(int)primitive.Material]; var r = (uint)(material.PbrMetallicRoughness.BaseColorFactor[0] * 255); var g = (uint)(material.PbrMetallicRoughness.BaseColorFactor[1] * 255); var b = (uint)(material.PbrMetallicRoughness.BaseColorFactor[2] * 255); var a = (uint)(material.PbrMetallicRoughness.BaseColorFactor[3] * 255); color = new ColorWithTransparency(r, g, b, a); } for (var i = 0; i < indices.Count; i += 3) { var ia = indices[i]; var ib = indices[i + 1]; var ic = indices[i + 2]; var a = positions[ia]; var b = positions[ib]; var c = positions[ic]; var na = normals[ia]; var nb = normals[ib]; var nc = normals[ic]; switch (vertexFormatBits) { case VertexFormatBits.PositionColored: if (hasColor) { color = colors[ia]; } verticesFlat.Add(new VertexPositionColored(a, hasColor ? colors[ia] : color)); verticesFlat.Add(new VertexPositionColored(b, hasColor ? colors[ib] : color)); verticesFlat.Add(new VertexPositionColored(c, hasColor ? colors[ic] : color)); break; default: if (hasColor) { color = colors[ia]; } vertices.Add(new VertexPositionNormalColored(a, na, hasColor ? colors[ia] : color)); vertices.Add(new VertexPositionNormalColored(b, nb, hasColor ? colors[ib] : color)); vertices.Add(new VertexPositionNormalColored(c, nc, hasColor ? colors[ic] : color)); break; } triangles.Add(new IndexTriangle(i, i + 1, i + 2)); } switch (displayStyle) { case DisplayStyle.HLR: case DisplayStyle.FlatColors: var pc = vBuffer.GetVertexStreamPositionColored(); pc.AddVertices(verticesFlat); break; default: var pnc = vBuffer.GetVertexStreamPositionNormalColored(); pnc.AddVertices(vertices); break; } var iPos = iBuffer.GetIndexStreamTriangle(); iPos.AddTriangles(triangles); vBuffer.Unmap(); iBuffer.Unmap(); var effect = new EffectInstance(vertexFormatBits); var renderData = new RenderData() { VertexBuffer = vBuffer, VertexCount = numVertices, IndexBuffer = iBuffer, IndexCount = numIndices, VertexFormat = vertexFormat, Effect = effect, PrimitiveType = pType, PrimitiveCount = numPrimitives }; if (displayStyle != DisplayStyle.Wireframe && numPrimitives > 0) { DrawContext.FlushBuffer(vBuffer, numVertices, iBuffer, numIndices, vertexFormat, effect, pType, 0, numPrimitives); } return(renderData); }