public static Software.Mesh ParseCollada(String filename) { ColladaDocument doc = new ColladaDocument(filename); ColladaMesh resultMesh = new ColladaMesh(); Dictionary <String, ColladaMesh> geometryMeshes = new Dictionary <string, ColladaMesh>(); foreach (ColladaDocument.Geometry g in doc.geometries) { if (geometryMeshes.ContainsKey(g.id)) { throw new Exception("Duplicate geometry entries"); } geometryMeshes[g.id] = ExtractColladaGeometry(g); } if (doc.visualScenes.Count != 1) { throw new NotImplementedException("There has to be exactly one Visual Scene"); } foreach (ColladaDocument.Node n in doc.visualScenes[0].nodes) { HandleNode(geometryMeshes, ref resultMesh, n, Matrix.Identity); } resultMesh.BuildVertexList(); return(IndexedCollada(resultMesh.Vertices, resultMesh.Indices)); }
public static Software.Mesh ParseCollada(String filename) { ColladaDocument doc = new ColladaDocument(filename); ColladaMesh resultMesh = new ColladaMesh(); Dictionary<String, ColladaMesh> geometryMeshes = new Dictionary<string, ColladaMesh>(); foreach (ColladaDocument.Geometry g in doc.geometries) { if (geometryMeshes.ContainsKey(g.id)) throw new Exception("Duplicate geometry entries"); geometryMeshes[g.id] = ExtractColladaGeometry(g); } if (doc.visualScenes.Count != 1) throw new NotImplementedException("There has to be exactly one Visual Scene"); foreach (ColladaDocument.Node n in doc.visualScenes[0].nodes) HandleNode(geometryMeshes, ref resultMesh, n, Matrix.Identity); resultMesh.BuildVertexList(); return IndexedCollada(resultMesh.Vertices, resultMesh.Indices); }
private static ColladaMesh ExtractColladaGeometry(ColladaDocument.Geometry g) { ColladaMesh mesh = new ColladaMesh(); var m = g.mesh; Vector3[] vertexData = null; Vector3[] normalData = null; Vector3[] texcoordData = null; if (m.primitives.Count != 1) throw new NotImplementedException("m.primitives.Count = " + m.primitives.Count); var p = m.primitives[0]; Dictionary<string, float[]> data = new Dictionary<string, float[]>(); for (int i = 0; i < m.sources.Count; i++) { ColladaDocument.Array<float> inputArr = (ColladaDocument.Array<float>)m.sources[i].array; if (data.ContainsKey(m.sources[i].id)) throw new Exception("A data entry called " + m.sources[i].id + " has already been parsed."); data[m.sources[i].id] = inputArr.arr; } int indlen = p.p.Length / p.stride; int[] vertexIndices = new int[indlen]; int[] normalIndices = new int[indlen]; int[] texcoordIndices = new int[indlen]; foreach (ColladaDocument.Input input in p.Inputs) { switch (input.semantic.ToLower()) { case "vertex": if (!(input.source is ColladaDocument.Vertices)) throw new Exception("VERTEX source should be of type ColladaDocument.Vertices"); ProcessVertex((ColladaDocument.Vertices)input.source, p.p, p.stride, input.offset, data, ref vertexData, ref vertexIndices, ref normalData, ref normalIndices, ref texcoordData, ref texcoordIndices); break; case "normal": if (!(input.source is ColladaDocument.Source)) throw new Exception("NORMAL source should be of type ColladaDocument.Vertices"); var nsource = (ColladaDocument.Source)input.source; // set up indices for (int i = 0; i < indlen; i++) normalIndices[i] = p.p[i * p.stride + input.offset]; // load data normalData = ParseNormalData(data[nsource.id]); break; case "texcoord": if (!(input.source is ColladaDocument.Source)) throw new Exception("TEXCOORD source should be of type ColladaDocument.Vertices"); var tsource = (ColladaDocument.Source)input.source; // set up indices for (int i = 0; i < indlen; i++) texcoordIndices[i] = p.p[i * p.stride + input.offset]; // load data texcoordData = ParseTexcoordData(data[tsource.id], tsource.accessor.stride); break; default: throw new NotImplementedException(); } } if (vertexIndices.Length != normalIndices.Length || normalIndices.Length != texcoordIndices.Length) throw new NotImplementedException("all of them needs to be supplied and of the same amount right now"); mesh.VertexData = new List<Vector3>(vertexData); mesh.VertexIndices = new List<int>(vertexIndices); if (normalData != null) { mesh.NormalData = new List<Vector3>(normalData); mesh.NormalIndices = new List<int>(normalIndices); } if (texcoordData != null) { mesh.TexcoordData = new List<Vector3>(texcoordData); mesh.TexcoordIndices = new List<int>(texcoordIndices); } return mesh; }
private static void ProcessVertex(ColladaDocument.Vertices source, int[] p, int stride, int offset, Dictionary<string, float[]> data, ref Vector3[] vertexData, ref int[] vertexIndices, ref Vector3[] normalData, ref int[] normalIndices, ref Vector3[] texcoordData, ref int[] texcoordIndices) { int length = p.Length / stride; for (int i = 0; i < length; i++) { int value = p[i * stride + offset]; foreach (var input in source.inputs) { switch (input.semantic.ToLower()) { case "position": vertexIndices[i] = value; break; case "normal": normalIndices[i] = value; break; case "texcoord": texcoordIndices[i] = value; break; default: throw new NotImplementedException(); } } } foreach (var input in source.inputs) { if (!(input.source is ColladaDocument.Source)) throw new Exception("CHILD OF VERTEX source should be of type ColladaDocument.Source"); var csource = (ColladaDocument.Source)input.source; switch (input.semantic.ToLower()) { case "position": vertexData = ParseVertexData(data[csource.id]); break; case "normal": normalData = ParseNormalData(data[csource.id]); break; case "texcoord": texcoordData = ParseTexcoordData(data[csource.id], csource.accessor.stride); break; } } }
private static void HandleNode(Dictionary<string, ColladaMesh> geometryMeshes, ref ColladaMesh resultMesh, ColladaDocument.Node node, Matrix world) { if(node.transforms != null) world = ConcatTransforms(node.transforms, world); if (node.instances != null) { if (node.instances.Count != 1) throw new Exception("Nodes need to have exactly one instance right now"); if (!(node.instances[0] is ColladaDocument.InstanceGeometry)) return; // SILENT FAIL ColladaDocument.Instance i = node.instances[0]; ColladaMesh mesh = geometryMeshes[i.url.Fragment]; resultMesh.AppendMesh(mesh, world); if (node.children != null && node.children.Count > 0) throw new Exception("Tell Joakim."); } else if (node.children != null && node.children.Count > 0) { foreach (ColladaDocument.Node n in node.children) HandleNode(geometryMeshes, ref resultMesh, n, world); } else { //throw new Exception("Node has no instance and no child. Keh?"); } }