/// <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); } }
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; }