/// <summary>
        /// Runs at the end of an element being processed, after all other calls for that element.
        /// Here we compile all the "_current" variables (geometry and vertices) onto glTF buffers.
        /// We do this at OnElementEnd because it signals no more meshes or materials are
        /// coming for this element.
        /// </summary>
        /// <param name="elementId"></param>
        public void OnElementEnd(ElementId elementId)
        {
            Debug.WriteLine("  OnElementEnd");
            if (_skipElementFlag)
            {
                // Duplicate element, skip.
                _skipElementFlag = false;
                return;
            }

            if (_currentVertices.List.Count == 0)
            {
                return;
            }

            Element e = _doc.GetElement(elementId);

            // create a new mesh for the node (we're assuming 1 mesh per node w/ multiple primatives on mesh)
            glTFMesh newMesh = new glTFMesh();

            newMesh.primitives = new List <glTFMeshPrimitive>();
            Meshes.AddOrUpdateCurrent(e.UniqueId, newMesh);

            // add the index of this mesh to the current node.
            Nodes.CurrentItem.mesh = Meshes.CurrentIndex;

            // Add vertex data to _currentGeometry for each geometry/material pairing
            foreach (KeyValuePair <string, VertexLookupInt> kvp in _currentVertices.Dict)
            {
                string vertex_key = kvp.Key;
                foreach (KeyValuePair <PointInt, int> p in kvp.Value)
                {
                    _currentGeometry.GetElement(vertex_key).vertices.Add(p.Key.X);
                    _currentGeometry.GetElement(vertex_key).vertices.Add(p.Key.Y);
                    _currentGeometry.GetElement(vertex_key).vertices.Add(p.Key.Z);
                }
            }

            // Convert _currentGeometry objects into glTFMeshPrimitives
            foreach (KeyValuePair <string, GeometryData> kvp in _currentGeometry.Dict)
            {
                glTFBinaryData elementBinary = AddGeometryMeta(kvp.Value, kvp.Key);
                binaryFileData.Add(elementBinary);

                string material_key = kvp.Key.Split('_')[1];

                glTFMeshPrimitive primative = new glTFMeshPrimitive();
                primative.attributes.POSITION = elementBinary.vertexAccessorIndex;
                primative.indices             = elementBinary.indexAccessorIndex;
                primative.material            = Materials.GetIndexFromUUID(material_key);
                // TODO: Add normal here

                Meshes.CurrentItem.primitives.Add(primative);
            }
        }
Exemple #2
0
        public void CloseGeometry()
        {
            Debug.WriteLine(String.Format("{0}  Closing Geometry", formatDebugHeirarchy));
            // Create the new mesh and populate the primitives with GeometryData
            glTFMesh mesh = new glTFMesh();

            mesh.primitives = new List <glTFMeshPrimitive>();

            // transfer ordered vertices from vertex dictionary to vertices list
            foreach (KeyValuePair <string, GeometryData> key_geom in currentGeom)
            {
                string       key  = key_geom.Key;
                GeometryData geom = key_geom.Value;
                foreach (KeyValuePair <PointInt, int> point_index in geom.vertDictionary)
                {
                    PointInt point = point_index.Key;
                    geom.vertices.Add(point.X);
                    geom.vertices.Add(point.Y);
                    geom.vertices.Add(point.Z);
                }

                // convert GeometryData objects into glTFMeshPrimitive
                string material_key = key.Split('_')[1];

                glTFBinaryData bufferMeta = processGeometry(geom, key);
                if (bufferMeta.hashcode != null)
                {
                    binaryFileData.Add(bufferMeta);
                }

                glTFMeshPrimitive primative = new glTFMeshPrimitive();

                primative.attributes.POSITION = bufferMeta.vertexAccessorIndex;
                primative.indices             = bufferMeta.indexAccessorIndex;
                primative.material            = materialDict.GetIndexFromUUID(material_key);
                // TODO: Add normal attribute accessor index here

                mesh.primitives.Add(primative);
            }

            // glTF entity can not be empty
            if (mesh.primitives.Count() > 0)
            {
                // Prevent mesh duplication by hash checking
                string meshHash            = ManagerUtils.GenerateSHA256Hash(mesh);
                ManagerUtils.HashSearch hs = new ManagerUtils.HashSearch(meshHash);
                int idx = meshContainers.FindIndex(hs.EqualTo);

                if (idx != -1)
                {
                    // set the current nodes mesh index to the already
                    // created mesh location.
                    nodeDict[currentNodeId].mesh = idx;
                }
                else
                {
                    // create new mesh and add it's index to the current node.
                    MeshContainer mc = new MeshContainer();
                    mc.hashcode = meshHash;
                    mc.contents = mesh;
                    meshContainers.Add(mc);
                    nodeDict[currentNodeId].mesh = meshContainers.Count - 1;
                }
            }

            geometryStack.Pop();
            return;
        }