public RhinoMeshGltfConverter(ObjectExportData exportData, int?materialIndex, glTFExportOptions options, bool binary, gltfSchemaDummy dummy, List <byte> binaryBuffer) { this.exportData = exportData; this.materialIndex = materialIndex; this.options = options; this.binary = binary; this.dummy = dummy; this.binaryBuffer = binaryBuffer; }
private void AddRhinoObjectText(ObjectExportData data) { var materialIndex = GetMaterial(data.RenderMaterial, data.Object); var primitives = new List <MeshPrimitive>(); foreach (var rhinoMesh in data.Meshes) { if (options.MapRhinoZToGltfY) { rhinoMesh.Transform(ZtoYUp); } rhinoMesh.TextureCoordinates.ReverseTextureCoordinates(1); rhinoMesh.Faces.ConvertQuadsToTriangles(); var vtxBuffer = CreateVerticesBuffer(rhinoMesh.Vertices, out Point3d vtxMin, out Point3d vtxMax); int vtxBufferIdx = dummy.Buffers.AddAndReturnIndex(vtxBuffer); var idsBuffer = CreateIndicesBuffer(rhinoMesh.Faces, out int indicesCount); int idsBufferIdx = dummy.Buffers.AddAndReturnIndex(idsBuffer); var normalsBuffer = CreateNormalsBuffer(rhinoMesh.Normals, out Vector3f normalsMin, out Vector3f normalsMax); int normalsBufferIdx = dummy.Buffers.AddAndReturnIndex(normalsBuffer); var vtxBufferView = new BufferView() { Buffer = vtxBufferIdx, ByteOffset = 0, ByteLength = vtxBuffer.ByteLength, Target = BufferView.TargetEnum.ARRAY_BUFFER, }; int vtxBufferViewIdx = dummy.BufferViews.AddAndReturnIndex(vtxBufferView); var idsBufferView = new BufferView() { Buffer = idsBufferIdx, ByteOffset = 0, ByteLength = idsBuffer.ByteLength, Target = BufferView.TargetEnum.ELEMENT_ARRAY_BUFFER, }; int idsBufferViewIdx = dummy.BufferViews.AddAndReturnIndex(idsBufferView); BufferView normalsBufferView = new BufferView() { Buffer = normalsBufferIdx, ByteOffset = 0, ByteLength = normalsBuffer.ByteLength, Target = BufferView.TargetEnum.ARRAY_BUFFER, }; int normalsBufferViewIdx = dummy.BufferViews.AddAndReturnIndex(normalsBufferView); // Create accessors Accessor vtxAccessor = new Accessor() { BufferView = vtxBufferViewIdx, Count = rhinoMesh.Vertices.Count, Min = new float[] { (float)vtxMin.X, (float)vtxMin.Y, (float)vtxMin.Z }, Max = new float[] { (float)vtxMax.X, (float)vtxMax.Y, (float)vtxMax.Z }, Type = Accessor.TypeEnum.VEC3, ComponentType = Accessor.ComponentTypeEnum.FLOAT, ByteOffset = 0, }; int vtxAccessorIdx = dummy.Accessors.AddAndReturnIndex(vtxAccessor); Accessor idsAccessor = new Accessor() { BufferView = idsBufferViewIdx, Count = indicesCount, Min = new float[] { 0 }, Max = new float[] { rhinoMesh.Vertices.Count - 1 }, Type = Accessor.TypeEnum.SCALAR, ComponentType = Accessor.ComponentTypeEnum.UNSIGNED_INT, ByteOffset = 0, }; int idsAccessorIdx = dummy.Accessors.AddAndReturnIndex(idsAccessor); Accessor normalsAccessor = new Accessor() { BufferView = normalsBufferViewIdx, Count = rhinoMesh.Normals.Count, Min = new float[] { normalsMin.X, normalsMin.Y, normalsMin.Z }, Max = new float[] { normalsMax.X, normalsMax.Y, normalsMax.Z }, Type = Accessor.TypeEnum.VEC3, ComponentType = Accessor.ComponentTypeEnum.FLOAT, ByteOffset = 0, }; int normalsAccessorIdx = dummy.Accessors.AddAndReturnIndex(normalsAccessor); var primitive = new MeshPrimitive() { Attributes = new Dictionary <string, int>() { { Constants.PositionAttributeTag, vtxAccessorIdx }, { Constants.NormalAttributeTag, normalsAccessorIdx }, }, Indices = idsAccessorIdx, Material = materialIndex, }; if (rhinoMesh.TextureCoordinates.Count > 0) { var texCoordsBuffer = CreateTextureCoordinatesBuffer(rhinoMesh.TextureCoordinates, out Point2f texCoordsMin, out Point2f texCoordsMax); int texCoordsBufferIdx = dummy.Buffers.AddAndReturnIndex(texCoordsBuffer); BufferView texCoordsBufferView = new BufferView() { Buffer = texCoordsBufferIdx, ByteOffset = 0, ByteLength = texCoordsBuffer.ByteLength, Target = BufferView.TargetEnum.ARRAY_BUFFER, }; int texCoordsBufferViewIdx = dummy.BufferViews.AddAndReturnIndex(texCoordsBufferView); Accessor texCoordsAccessor = new Accessor() { BufferView = texCoordsBufferViewIdx, Count = rhinoMesh.TextureCoordinates.Count, Min = new float[] { texCoordsMin.X, texCoordsMin.Y }, Max = new float[] { texCoordsMax.X, texCoordsMax.Y }, Type = Accessor.TypeEnum.VEC2, ComponentType = Accessor.ComponentTypeEnum.FLOAT, ByteOffset = 0, }; int texCoordsAccessorIdx = dummy.Accessors.AddAndReturnIndex(texCoordsAccessor); primitive.Attributes.Add(Constants.TexCoord0AttributeTag, texCoordsAccessorIdx); } // Create mesh primitives.Add(primitive); } var mesh = new glTFLoader.Schema.Mesh() { Primitives = primitives.ToArray(), }; int idxMesh = dummy.Meshes.AddAndReturnIndex(mesh); var node = new Node() { Mesh = idxMesh, Name = string.IsNullOrEmpty(data.Object.Name) ? null : data.Object.Name, }; int idxNode = dummy.Nodes.AddAndReturnIndex(node); dummy.Scenes[dummy.Scene].Nodes.Add(idxNode); }
private void AddRhinoObjectDraco(ObjectExportData data) { var materialIndex = GetMaterial(data.RenderMaterial, data.Object); var primitives = new List <MeshPrimitive>(); // For each rhino mesh, create gl-buffers, gl-meshes, etc. foreach (var rhinoMesh in data.Meshes) { if (options.MapRhinoZToGltfY) { rhinoMesh.Transform(ZtoYUp); } rhinoMesh.TextureCoordinates.ReverseTextureCoordinates(1); var dracoComp = DracoCompression.Compress( rhinoMesh, new DracoCompressionOptions() { CompressionLevel = options.DracoCompressionLevel, IncludeNormals = true, IncludeTextureCoordinates = true, IncludeVertexColors = false, PositionQuantizationBits = options.DracoQuantizationBitsPosition, NormalQuantizationBits = options.DracoQuantizationBitsNormal, TextureCoordintateQuantizationBits = options.DracoQuantizationBitsTexture } ); DracoGeometryInfo dracoGeoInfo = AddDracoGeometry(dracoComp); var compMeshBufferView = new BufferView() { Buffer = dracoGeoInfo.bufferIndex, ByteOffset = dracoGeoInfo.byteOffset, ByteLength = dracoGeoInfo.byteLength, }; int compMeshBufferViewIdx = dummy.BufferViews.AddAndReturnIndex(compMeshBufferView); var vtxAccessor = new Accessor { Type = Accessor.TypeEnum.VEC3, ComponentType = Accessor.ComponentTypeEnum.FLOAT, Count = dracoGeoInfo.verticesNum, Min = dracoGeoInfo.verticesMin, Max = dracoGeoInfo.verticesMax, ByteOffset = 0, }; int vtxAccessorIdx = dummy.Accessors.AddAndReturnIndex(vtxAccessor); // // Accessor Triangles Vertex IDs var idsAccessor = new Accessor { Type = Accessor.TypeEnum.SCALAR, ComponentType = Accessor.ComponentTypeEnum.UNSIGNED_INT, Count = dracoGeoInfo.trianglesNum, Min = new float[] { dracoGeoInfo.trianglesMin }, Max = new float[] { dracoGeoInfo.trianglesMax }, ByteOffset = 0, }; int idsAccessorIdx = dummy.Accessors.AddAndReturnIndex(idsAccessor); // Accessor Normals var normalsAccessor = new Accessor { Type = Accessor.TypeEnum.VEC3, ComponentType = Accessor.ComponentTypeEnum.FLOAT, Count = dracoGeoInfo.normalsNum, Min = dracoGeoInfo.normalsMin, Max = dracoGeoInfo.normalsMax, ByteOffset = 0, }; int normalsAccessorIdx = dummy.Accessors.AddAndReturnIndex(normalsAccessor); var primitive = new MeshPrimitive() { Attributes = new Dictionary <string, int>() { { Constants.PositionAttributeTag, vtxAccessorIdx }, { Constants.NormalAttributeTag, normalsAccessorIdx }, }, Indices = idsAccessorIdx, Material = materialIndex, }; if (dracoGeoInfo.texCoordsNum > 0) { // Accessor TexCoords var texCoordsAccessor = new Accessor { Type = Accessor.TypeEnum.VEC2, ComponentType = Accessor.ComponentTypeEnum.FLOAT, Count = dracoGeoInfo.texCoordsNum, Min = dracoGeoInfo.texCoordsMin, Max = dracoGeoInfo.texCoordsMax, ByteOffset = 0, }; int texCoordsAccessorIdx = dummy.Accessors.AddAndReturnIndex(texCoordsAccessor); primitive.Attributes.Add(Constants.TexCoord0AttributeTag, texCoordsAccessorIdx); primitive.Extensions = new Dictionary <string, object>() { { Constants.DracoMeshCompressionExtensionTag, new { bufferView = compMeshBufferViewIdx, attributes = new { POSITION = 0, NORMAL = 1, TEXCOORD_0 = 2 } } } }; } else { primitive.Extensions = new Dictionary <string, object>() { { Constants.DracoMeshCompressionExtensionTag, new { bufferView = compMeshBufferViewIdx, attributes = new { POSITION = 0, NORMAL = 1, } } } }; } // Create mesh primitives.Add(primitive); } var mesh = new glTFLoader.Schema.Mesh() { Primitives = primitives.ToArray(), }; int meshIndex = dummy.Meshes.AddAndReturnIndex(mesh); var node = new Node() { Mesh = meshIndex, }; int nodeIndex = dummy.Nodes.AddAndReturnIndex(node); dummy.Scenes[dummy.Scene].Nodes.Add(nodeIndex); }