示例#1
0
 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;
 }
示例#2
0
        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);
        }
示例#3
0
        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);
        }