/// <summary> /// Convert a list of Grendgine_Collada_Float_Array to an array of Vectors /// </summary> private List <Vector3D> FloatToVectorArray(Grendgine_Collada_Float_Array colArray) { List <Vector3D> vecArray = new List <Vector3D>(colArray.Count / 3); float[] array = colArray.Value(); for (int i = 0; i < colArray.Count / 3; i++) { vecArray.Add(new Vector3D( array[i * 3], array[i * 3 + 2], array[i * 3 + 1])); } return(vecArray); }
public void Import(string fileName) { // Only need to Update the HEADER, and Animation.Duration, ASETHEADER is auto handled this.File = new BrgFile(); BrgFile model = this.File; // just ref here so I don't have to rename model to this.File Grendgine_Collada cModel = Grendgine_Collada.Grendgine_Load_File(fileName); //Materials BrgMaterial mat = new BrgMaterial(model); model.Materials.Add(mat); mat.AmbientColor = new Color3D(); mat.DiffuseColor = new Color3D(); mat.SpecularColor = new Color3D(0.5f); mat.SpecularExponent = 5; mat.Id = 100; mat.Opacity = 1f; mat.Flags |= BrgMatFlag.HasTexture | BrgMatFlag.SpecularExponent; model.Header.NumMaterials = model.Materials.Count(); //Meshes foreach (Grendgine_Collada_Geometry geo in cModel.Library_Geometries.Geometry) { BrgMesh mesh = new BrgMesh(model); model.Meshes.Add(mesh); mesh.Header.Flags |= BrgMeshFlag.MATERIAL; mesh.Header.Flags |= model.Meshes.Count == 1 ? 0 : BrgMeshFlag.SECONDARYMESH; mesh.Header.AnimationType |= BrgMeshAnimType.KeyFrame; mesh.Header.Format |= 0; mesh.ExtendedHeader.NumMaterials = (byte)model.Header.NumMaterials; mesh.ExtendedHeader.AnimationLength = 30; mesh.ExtendedHeader.NumUniqueMaterials = 0; string polyVertSourceID; string polyNormalsSourceID; string materialID; int[] vertCountPerPoly; int[] vertLinkPerPoly; int[] vertNormalBindings; //Locate the vertices and convert them string vertexPosSourceID = geo.Mesh.Vertices.Input.First <Grendgine_Collada_Input_Unshared>(x => x.Semantic == Grendgine_Collada_Input_Semantic.POSITION).source; Grendgine_Collada_Float_Array vertsArray = FindSourceByID(geo.Mesh, vertexPosSourceID).Float_Array; mesh.Vertices = FloatToVectorArray(vertsArray); mesh.Header.NumVertices = (short)mesh.Vertices.Count; //Check for polygons otherwise skip mesh if (geo.Mesh.Polylist != null || geo.Mesh.Polylist.Length > 0) { mesh.Header.NumFaces = (short)geo.Mesh.Polylist[0].Count; polyVertSourceID = geo.Mesh.Polylist[0].Input.First <Grendgine_Collada_Input_Unshared>(x => x.Semantic == Grendgine_Collada_Input_Semantic.VERTEX).source; polyNormalsSourceID = geo.Mesh.Polylist[0].Input.First <Grendgine_Collada_Input_Unshared>(x => x.Semantic == Grendgine_Collada_Input_Semantic.NORMAL).source; vertCountPerPoly = geo.Mesh.Polylist[0].VCount.Value(); materialID = geo.Mesh.Polylist[0].Material; vertLinkPerPoly = geo.Mesh.Polylist[0].P.Value(); mesh.Faces = new List <Face>(mesh.Header.NumFaces); vertNormalBindings = new int[mesh.Header.NumVertices]; int polyindex = 0; Face ff; foreach (int count in vertCountPerPoly) { if (count == 3) //If triangle { ff = new Face(); ff.Indices = new List <short>(3); ff.Indices.Add((short)vertLinkPerPoly[polyindex]); ff.Indices.Add((short)vertLinkPerPoly[polyindex + 4]); ff.Indices.Add((short)vertLinkPerPoly[polyindex + 2]); //List correct normal bindings vertNormalBindings[ff.Indices[0]] = vertLinkPerPoly[polyindex + 1]; vertNormalBindings[ff.Indices[1]] = vertLinkPerPoly[polyindex + 5]; vertNormalBindings[ff.Indices[2]] = vertLinkPerPoly[polyindex + 3]; //Bind materials if (mesh.Header.Flags.HasFlag(BrgMeshFlag.MATERIAL)) { ff.MaterialIndex = (short)mat.Id; } mesh.Faces.Add(ff); } polyindex += count * 2; //Including face normal bindings } } else { break; } //Locate the vertex normals Grendgine_Collada_Float_Array normalsArray = FindSourceByID(geo.Mesh, polyNormalsSourceID).Float_Array; if (normalsArray.Count != vertsArray.Count) { System.Windows.Forms.MessageBox.Show("The mesh hash only face normals instead of vertex normals. Be sure to export only smooth shaded models.", "Model Import Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning); } List <Vector3D> unsortedNormals = FloatToVectorArray(normalsArray); mesh.Normals = new List <Vector3D>(mesh.Header.NumVertices); for (int i = 0; i < mesh.Header.NumVertices; i++) { mesh.Normals.Add(unsortedNormals[vertNormalBindings[i]]); } mesh.VertexMaterials = new List <short>(mesh.Header.NumVertices); for (int i = 0; i < mesh.Header.NumVertices; i++) { mesh.VertexMaterials.Add((short)mat.Id); } } model.Header.NumMeshes = model.Meshes.Count(); }
public void WriteLibrary_Geometries() { // Geometry library. this is going to be fun... Grendgine_Collada_Library_Geometries libraryGeometries = new Grendgine_Collada_Library_Geometries(); libraryGeometries.ID = cgfData.RootNode.Name; // Make a list for all the geometries objects we will need. Will convert to array at end. Define the array here as well List <Grendgine_Collada_Geometry> geometryList = new List <Grendgine_Collada_Geometry>(); // For each of the nodes, we need to write the geometry. // Need to figure out how to assign the right material to the node as well. // Use a foreach statement to get all the node chunks. This will get us the meshes, which will contain the vertex, UV and normal info. foreach (CgfData.ChunkNode nodeChunk in cgfData.CgfChunks.Where(a => a.chunkType == ChunkType.Node)) { // Create a geometry object. Use the chunk ID for the geometry ID // Will have to be careful with this, since with .cga/.cgam pairs will need to match by Name. Grendgine_Collada_Geometry tmpGeo = new Grendgine_Collada_Geometry(); tmpGeo.Name = nodeChunk.Name; tmpGeo.ID = nodeChunk.id.ToString(); // Now make the mesh object. This will have 3 sources, 1 vertices, and 1 triangles (with material ID) // If the Object ID of Node chunk points to a Helper or a Controller though, place an empty. // Will have to figure out transforms here too. Grendgine_Collada_Mesh tmpMesh = new Grendgine_Collada_Mesh(); // need to make a list of the sources and triangles to add to tmpGeo.Mesh List <Grendgine_Collada_Source> sourceList = new List <Grendgine_Collada_Source>(); List <Grendgine_Collada_Triangles> triList = new List <Grendgine_Collada_Triangles>(); CgfData.ChunkDataStream tmpNormals = new CgfData.ChunkDataStream(); CgfData.ChunkDataStream tmpUVs = new CgfData.ChunkDataStream(); CgfData.ChunkDataStream tmpVertices = new CgfData.ChunkDataStream(); CgfData.ChunkDataStream tmpVertsUVs = new CgfData.ChunkDataStream(); if (cgfData.ChunkDictionary[nodeChunk.Object].chunkType == ChunkType.Mesh) { // Get the mesh chunk and submesh chunk for this node. CgfData.ChunkMesh tmpMeshChunk = (CgfData.ChunkMesh)cgfData.ChunkDictionary[nodeChunk.Object]; CgfData.ChunkMeshSubsets tmpMeshSubsets = tmpMeshSubsets = (CgfData.ChunkMeshSubsets)cgfData.ChunkDictionary[tmpMeshChunk.MeshSubsets]; // Listed as Object ID for the Node // Get pointers to the vertices data if (tmpMeshChunk.VerticesData != 0) { tmpVertices = (CgfData.ChunkDataStream)cgfData.ChunkDictionary[tmpMeshChunk.VerticesData]; } if (tmpMeshChunk.NormalsData != 0) { tmpNormals = (CgfData.ChunkDataStream)cgfData.ChunkDictionary[tmpMeshChunk.NormalsData]; } if (tmpMeshChunk.UVsData != 0) { tmpUVs = (CgfData.ChunkDataStream)cgfData.ChunkDictionary[tmpMeshChunk.UVsData]; } if (tmpMeshChunk.VertsUVsData != 0) { tmpVertsUVs = (CgfData.ChunkDataStream)cgfData.ChunkDictionary[tmpMeshChunk.VertsUVsData]; } // need a collada_source for position, normal, UV and color, what the source is (verts), and the tri index Grendgine_Collada_Source posSource = new Grendgine_Collada_Source(); Grendgine_Collada_Source normSource = new Grendgine_Collada_Source(); Grendgine_Collada_Source uvSource = new Grendgine_Collada_Source(); Grendgine_Collada_Vertices verts = new Grendgine_Collada_Vertices(); Grendgine_Collada_Triangles tris = new Grendgine_Collada_Triangles(); posSource.ID = nodeChunk.Name + "_pos"; // I want to use the chunk ID, but that may be daunting. posSource.Name = nodeChunk.Name + "_pos"; normSource.ID = nodeChunk.Name + "_norm"; normSource.Name = nodeChunk.Name + "_norm"; uvSource.Name = nodeChunk.Name + "_UV"; uvSource.ID = nodeChunk.Name + "_UV"; // Create a float_array object to store all the data Grendgine_Collada_Float_Array floatArray = new Grendgine_Collada_Float_Array(); floatArray.ID = posSource.Name + "_array"; floatArray.Count = (int)tmpVertices.NumElements; // Build the string of vertices with a stringbuilder StringBuilder vertString = new StringBuilder(); for (int i = 0; i < floatArray.Count; i++) { // this is an array of Vector3s? } //floatArray = normSource.ID = nodeChunk.Name + "_pos"; normSource.Name = nodeChunk.Name + "_pos"; uvSource.ID = nodeChunk.Name + "_UV"; uvSource.Name = nodeChunk.Name + "_UV"; // make a vertices eliment. Only one, so no list needed. // tris are easy. Just the index of faces } else if (cgfData.ChunkDictionary[nodeChunk.Object].chunkType == ChunkType.Helper) { } else if (cgfData.ChunkDictionary[nodeChunk.Object].chunkType == ChunkType.Controller) { } tmpGeo.Mesh = tmpMesh; // Add the tmpGeo geometry to the list geometryList.Add(tmpGeo); } libraryGeometries.Geometry = geometryList.ToArray(); daeObject.Library_Geometries = libraryGeometries; }