Exemple #1
0
        public glTF RecursivelyAddChilren(glTF gltf, Va3cObject obj, int parentIndex)
        {
            foreach (var child in obj.children)
            {
                glTFNode childNode = new glTFNode();
                childNode.name = child.name;
                foreach (double coord in child.matrix)
                {
                    childNode.matrix.Add((float)coord);
                }

                int childIndex = gltf.AddChildNode(childNode, parentIndex);
                if (child.geometry != null)
                {
                    Va3cGeometry geom = _geometries[child.geometry];
                    // make an accessor, buffer, and bufferView
                    glTFBinaryData dataContainer = gltf.AddGeometryMeta(geom, child.uuid);
                    binaryFileData.Add(dataContainer);

                    // add geometry to meshes array
                    glTFMesh          mesh      = new glTFMesh();
                    glTFMeshPrimitive primative = new glTFMeshPrimitive();
                    primative.attributes.POSITION = dataContainer.vertexAccessorIndex;
                    primative.attributes.NORMAL   = dataContainer.normalsAccessorIndex;
                    primative.indices             = dataContainer.indexAccessorIndex;
                    mesh.primitives = new List <glTFMeshPrimitive>()
                    {
                        primative
                    };
                    int meshIndex = gltf.AddMesh(mesh);
                    gltf.nodes[childIndex].mesh = meshIndex;
                }
                if (child.children != null && child.children.Count > 0)
                {
                    return(RecursivelyAddChilren(gltf, child, childIndex));
                }
            }
            return(gltf);
        }
Exemple #2
0
        public glTFBinaryData AddGeometryMeta(Va3cGeometry geom, string name)
        {
            // add a buffer
            glTFBuffer buffer = new glTFBuffer();

            buffer.uri = name + ".bin";
            this.buffers.Add(buffer);
            int bufferIdx = this.buffers.Count - 1;

            Va3cGeometryData geomData   = geom.data;
            glTFBinaryData   bufferData = new glTFBinaryData();

            bufferData.name = buffer.uri;
            foreach (var coord in geomData.vertices)
            {
                bufferData.vertexBuffer.Add((float)coord);
            }
            foreach (var index in geomData.faces)
            {
                bufferData.indexBuffer.Add(index);
            }
            foreach (var normal in geomData.normals)
            {
                bufferData.normalBuffer.Add((float)normal);
            }

            // Get max and min for vertex data
            float[] vertexMinMax = getVec3MinMax(bufferData.vertexBuffer);

            // Get max and min for normal data
            float[] normalMinMax = getVec3MinMax(bufferData.normalBuffer);

            // Get max and min for index data
            int[] faceMinMax = getScalarMinMax(bufferData.indexBuffer);

            // Add a vec3 buffer view
            int            elementsPerVertex = 3;
            int            bytesPerElement   = 4;
            int            bytesPerVertex    = elementsPerVertex * bytesPerElement;
            int            numVec3           = (geom.data.normals.Count + geom.data.vertices.Count) / elementsPerVertex;
            int            sizeOfVec3View    = numVec3 * bytesPerVertex;
            glTFBufferView vec3View          = new glTFBufferView();

            vec3View.buffer     = bufferIdx;
            vec3View.byteOffset = 0;
            vec3View.byteLength = sizeOfVec3View;
            vec3View.target     = Targets.ARRAY_BUFFER;
            this.bufferViews.Add(vec3View);
            int vec3ViewIdx = this.bufferViews.Count - 1;

            // add a position buffer view
            //int elementsPerVertex = 3;
            //int bytesPerElement = 4;
            //int bytesPerVertex = elementsPerVertex * bytesPerElement;
            //int numVertices = geom.data.vertices.Count / elementsPerVertex;
            //int sizeOfView = numVertices * bytesPerVertex;
            //glTFBufferView positionView = new glTFBufferView();
            //positionView.buffer = bufferIdx;
            //positionView.byteOffset = 0;
            //positionView.byteLength = sizeOfView;
            //positionView.target = Targets.ARRAY_BUFFER;
            //this.bufferViews.Add(positionView);
            //int positionViewIdx = this.bufferViews.Count - 1;

            // Add a faces / indexes buffer view
            int            elementsPerIndex     = 1;
            int            bytesPerIndexElement = 4;
            int            bytesPerIndex        = elementsPerIndex * bytesPerIndexElement;
            int            numIndexes           = geom.data.faces.Count;
            int            sizeOfIndexView      = numIndexes * bytesPerIndex;
            glTFBufferView facesView            = new glTFBufferView();

            facesView.buffer     = bufferIdx;
            facesView.byteOffset = vec3View.byteLength;
            facesView.byteLength = sizeOfIndexView;
            facesView.target     = Targets.ELEMENT_ARRAY_BUFFER;
            this.bufferViews.Add(facesView);
            int facesViewIdx = this.bufferViews.Count - 1;

            this.buffers[bufferIdx].byteLength = vec3View.byteLength + facesView.byteLength;

            // add a position accessor
            glTFAccessor positionAccessor = new glTFAccessor();

            positionAccessor.bufferView    = vec3ViewIdx;
            positionAccessor.byteOffset    = 0;
            positionAccessor.componentType = ComponentType.FLOAT;
            positionAccessor.count         = geom.data.vertices.Count / elementsPerVertex;
            positionAccessor.type          = "VEC3";
            positionAccessor.max           = new List <float>()
            {
                vertexMinMax[1], vertexMinMax[3], vertexMinMax[5]
            };
            positionAccessor.min = new List <float>()
            {
                vertexMinMax[0], vertexMinMax[2], vertexMinMax[4]
            };
            this.accessors.Add(positionAccessor);
            bufferData.vertexAccessorIndex = this.accessors.Count - 1;

            // add a normals accessor
            glTFAccessor normalsAccessor = new glTFAccessor();

            normalsAccessor.bufferView    = vec3ViewIdx;
            normalsAccessor.byteOffset    = (positionAccessor.count) * bytesPerVertex;
            normalsAccessor.componentType = ComponentType.FLOAT;
            normalsAccessor.count         = geom.data.normals.Count / elementsPerVertex;
            normalsAccessor.type          = "VEC3";
            normalsAccessor.max           = new List <float>()
            {
                normalMinMax[1], normalMinMax[3], normalMinMax[5]
            };
            normalsAccessor.min = new List <float>()
            {
                normalMinMax[0], normalMinMax[2], normalMinMax[4]
            };
            this.accessors.Add(normalsAccessor);
            bufferData.normalsAccessorIndex = this.accessors.Count - 1;

            // add a face accessor
            glTFAccessor faceAccessor = new glTFAccessor();

            faceAccessor.bufferView    = facesViewIdx;
            faceAccessor.byteOffset    = 0;
            faceAccessor.componentType = ComponentType.UNSIGNED_INT;
            faceAccessor.count         = numIndexes;
            faceAccessor.type          = "SCALAR";
            faceAccessor.max           = new List <float>()
            {
                faceMinMax[1]
            };
            faceAccessor.min = new List <float>()
            {
                faceMinMax[0]
            };
            this.accessors.Add(faceAccessor);
            bufferData.indexAccessorIndex = this.accessors.Count - 1;

            return(bufferData);
        }