public void WriteObjNode(StreamWriter f, CgfData.ChunkNode chunkNode)  // Pass a node to this to have it write to the Stream
        {
            // Console.WriteLine("\n*** Processing Chunk node {0:X}", chunkNode.id);
            // Console.WriteLine("***     Object ID {0:X}", chunkNode.Object);

            // We are only processing Nodes that have Materials.  The chunkType should never be Helper.  Check for Nodes to not process
            // This is wrong.  We have to process nodes that have helpers as the mesh info for the transform.
            Vector3 transform = new Vector3();

            transform.x = 0;  // initializing the transform vector.
            transform.y = 0;
            transform.z = 0;
            if (cgfData.ChunkDictionary[chunkNode.Object].chunkType == ChunkType.Helper)
            {
                // This needs work.
                transform = cgfData.GetTransform(chunkNode, transform);
                return;
            }
            CgfData.ChunkMesh tmpMesh = (CgfData.ChunkMesh)cgfData.ChunkDictionary[chunkNode.Object];

            // Get the Transform here. It's the node chunk Transform.m(41/42/42) divided by 100, added to the parent transform.
            // The transform of a child has to add the transforms of ALL the parents.  Need to use regression?  Maybe a while loop...

            if (chunkNode.Parent != 0xFFFFFFFF)
            {
                // Not the parent node.  Parent node shouldn't have a transform, so no need to calculate it.
                // add the current node's transform to transform.x, y and z.
                transform = cgfData.GetTransform(chunkNode, transform);
            }
            //transform.WriteVector3();

            if (cgfData.ChunkDictionary[chunkNode.Object].chunkType == ChunkType.Helper)
            {
                // This can still have transform, so need to to the transform before skipping.  We should still write an empty, but..obj.
                Console.WriteLine("*********************Found a node chunk for a Helper (ID: {0:X}).  Skipping...", tmpMesh.id);
                //tmpMesh.WriteChunk();
                //Console.WriteLine("Node Chunk: {0}", chunkNode.Name);
                transform = cgfData.GetTransform(chunkNode, transform);
                return;
            }

            if (tmpMesh.MeshSubsets == 0)   // This is probably wrong.  These may be parents with no geometry, but still have an offset
            {
                Console.WriteLine("*********************Found a Mesh chunk with no Submesh ID (ID: {0:X}).  Skipping...", tmpMesh.id);
                //tmpMesh.WriteChunk();
                //Console.WriteLine("Node Chunk: {0}", chunkNode.Name);
                transform = cgfData.GetTransform(chunkNode, transform);
                return;
            }
            if (tmpMesh.VerticesData == 0 && tmpMesh.VertsUVsData == 0)  // This is probably wrong.  These may be parents with no geometry, but still have an offset
            {
                Console.WriteLine("*********************Found a Mesh chunk with no Vertex info (ID: {0:X}).  Skipping...", tmpMesh.id);
                //tmpMesh.WriteChunk();
                //Console.WriteLine("Node Chunk: {0}", chunkNode.Name);
                transform = cgfData.GetTransform(chunkNode, transform);
                return;
            }
            CgfData.ChunkMtlName     tmpMtlName     = (CgfData.ChunkMtlName)cgfData.ChunkDictionary[chunkNode.MatID];
            CgfData.ChunkMeshSubsets tmpMeshSubsets = (CgfData.ChunkMeshSubsets)cgfData.ChunkDictionary[tmpMesh.MeshSubsets];  // Listed as Object ID for the Node

            // Going to assume that there is only one VerticesData datastream for now.  Need to watch for this.
            // Some 801 types have vertices and not VertsUVs.
            //Console.WriteLine("TEMPMESH WITH NO CurrentIndicesPosition");
            //tmpMesh.WriteChunk();
            CgfData.ChunkDataStream tmpIndices  = (CgfData.ChunkDataStream)cgfData.ChunkDictionary[tmpMesh.IndicesData];
            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 (tmpMesh.VerticesData != 0)
            {
                tmpVertices = (CgfData.ChunkDataStream)cgfData.ChunkDictionary[tmpMesh.VerticesData];
            }
            if (tmpMesh.NormalsData != 0)
            {
                tmpNormals = (CgfData.ChunkDataStream)cgfData.ChunkDictionary[tmpMesh.NormalsData];
            }
            if (tmpMesh.UVsData != 0)
            {
                tmpUVs = (CgfData.ChunkDataStream)cgfData.ChunkDictionary[tmpMesh.UVsData];
            }
            if (tmpMesh.VertsUVsData != 0)
            {
                tmpVertsUVs = (CgfData.ChunkDataStream)cgfData.ChunkDictionary[tmpMesh.VertsUVsData];
            }
            // We only use 3 things in obj files:  vertices, normals and UVs.  No need to process the Tangents.

            uint numChildren = chunkNode.NumChildren;           // use in a for loop to print the mesh for each child

            for (int i = 0; i < tmpMeshSubsets.NumMeshSubset; i++)
            {
                // Write vertices data for each MeshSubSet (v)
                f.WriteLine("g");
                if (tmpMesh.VerticesData == 0)
                {
                    // Probably using VertsUVs (3.7+).  Write those vertices out. Do UVs at same time.
                    for (int j = (int)tmpMeshSubsets.MeshSubsets[i].FirstVertex;
                         j < (int)tmpMeshSubsets.MeshSubsets[i].NumVertices + (int)tmpMeshSubsets.MeshSubsets[i].FirstVertex;
                         j++)
                    {
                        string s4 = String.Format("v {0:F7} {1:F7} {2:F7}",
                                                  tmpVertsUVs.Vertices[j].x + transform.x,
                                                  tmpVertsUVs.Vertices[j].y + transform.y,
                                                  tmpVertsUVs.Vertices[j].z + transform.z);
                        f.WriteLine(s4);
                    }
                    f.WriteLine();
                    for (int j = (int)tmpMeshSubsets.MeshSubsets[i].FirstVertex;
                         j < (int)tmpMeshSubsets.MeshSubsets[i].NumVertices + (int)tmpMeshSubsets.MeshSubsets[i].FirstVertex;
                         j++)
                    {
                        string s4 = String.Format("vt {0:F7} {1:F7} 0",
                                                  tmpVertsUVs.UVs[j].U,
                                                  1 - tmpVertsUVs.UVs[j].V);
                        f.WriteLine(s4);
                    }
                    f.WriteLine();
                }
                else
                {
                    // Using Verts.  Write those vertices out.
                    for (int j = (int)tmpMeshSubsets.MeshSubsets[i].FirstVertex;
                         j < (int)tmpMeshSubsets.MeshSubsets[i].NumVertices + (int)tmpMeshSubsets.MeshSubsets[i].FirstVertex;
                         j++)
                    {
                        string s4 = String.Format("v {0:F7} {1:F7} {2:F7}",
                                                  tmpVertices.Vertices[j].x + transform.x,
                                                  tmpVertices.Vertices[j].y + transform.y,
                                                  tmpVertices.Vertices[j].z + transform.z);
                        f.WriteLine(s4);
                    }
                    f.WriteLine();
                    for (int j = (int)tmpMeshSubsets.MeshSubsets[i].FirstVertex;
                         j < (int)tmpMeshSubsets.MeshSubsets[i].NumVertices + (int)tmpMeshSubsets.MeshSubsets[i].FirstVertex;
                         j++)
                    {
                        string s5 = String.Format("vt {0:F7} {1:F7} 0",
                                                  tmpUVs.UVs[j].U,
                                                  1 - tmpUVs.UVs[j].V);
                        f.WriteLine(s5);
                    }
                    //f.WriteLine();
                }

                // Write Normals block (vn)
                if (tmpMesh.NormalsData != 0)
                {
                    for (int j = (int)tmpMeshSubsets.MeshSubsets[i].FirstVertex;
                         j < (int)tmpMeshSubsets.MeshSubsets[i].NumVertices + (int)tmpMeshSubsets.MeshSubsets[i].FirstVertex;
                         j++)
                    {
                        string s6 = String.Format("vn {0:F7} {1:F7} {2:F7}",
                                                  tmpNormals.Normals[j].x,
                                                  tmpNormals.Normals[j].y,
                                                  tmpNormals.Normals[j].z);
                        f.WriteLine(s6);
                    }
                }

                //f.WriteLine();
                string s7 = String.Format("g {0}", chunkNode.Name);
                f.WriteLine(s7);

                // usemtl <number> refers to the position of this material in the .mtl file.  If it's 0, it's the first entry, etc. MaterialNameArray[]
                if (!cgfData.MatFile.MtlFile.Exists)     // No names in the material file.  use the chunknode name.
                {
                    // The material file doesn't have any elements with the Name of the material.  Use the object name.
                    string s_material = String.Format("usemtl {0}", cgfData.RootNode.Name);
                    f.WriteLine(s_material);
                }
                else
                {
                    string s_material = String.Format("usemtl {0}", cgfData.MatFile.MaterialNameArray[tmpMeshSubsets.MeshSubsets[i].MatID].MaterialName);
                    f.WriteLine(s_material);
                }

                // Now write out the faces info based on the MtlName
                for (int j = (int)tmpMeshSubsets.MeshSubsets[i].FirstIndex;
                     j < (int)tmpMeshSubsets.MeshSubsets[i].NumIndices + (int)tmpMeshSubsets.MeshSubsets[i].FirstIndex;
                     j++)
                {
                    string s9 = String.Format("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}",    // Vertices, UVs, Normals
                                              tmpIndices.Indices[j] + 1 + cgfData.CurrentVertexPosition,
                                              tmpIndices.Indices[j + 1] + 1 + cgfData.CurrentVertexPosition,
                                              tmpIndices.Indices[j + 2] + 1 + cgfData.CurrentVertexPosition);
                    f.WriteLine(s9);
                    j = j + 2;
                }
                //f.WriteLine();
                cgfData.TempVertexPosition  += tmpMeshSubsets.MeshSubsets[i].NumVertices; // add the number of vertices so future objects can start at the right place
                cgfData.TempIndicesPosition += tmpMeshSubsets.MeshSubsets[i].NumIndices;  // Not really used...
            }
            // Extend the current vertex, uv and normal positions by the length of those arrays.
            cgfData.CurrentVertexPosition  = cgfData.TempVertexPosition;
            cgfData.CurrentIndicesPosition = cgfData.TempIndicesPosition;
        }
Exemple #2
0
        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;
        }