Beispiel #1
0
        public void DumpToOBJ(string file_name)
        {
            using (FileStream strm = new FileStream(file_name, FileMode.Create))
            {
                EndianBinaryWriter writer = new EndianBinaryWriter(strm, Endian.Big);

                List <Vector3> master_list = new List <Vector3>();

                for (int i = 0; i < m_Meshes.Count; i++)
                {
                    Mesh cur_mesh = m_Meshes[i];

                    for (int j = 0; j < cur_mesh.VertexData.Position.Count; j++)
                    {
                        if (!master_list.Contains(cur_mesh.VertexData.Position[j]))
                        {
                            master_list.Add(cur_mesh.VertexData.Position[j]);
                        }
                    }
                }

                for (int i = 0; i < master_list.Count; i++)
                {
                    writer.Write($"v { master_list[i].X } { master_list[i].Y } { master_list[i].Z }\n".ToCharArray());
                    writer.Flush();
                }

                for (int i = 0; i < m_Meshes.Count; i++)
                {
                    writer.Write($"o { m_Meshes[i].Name }\n".ToCharArray());

                    for (int j = 0; j < m_Meshes[i].Vertices.Count; j += 3)
                    {
                        MeshVertexIndex index_1 = m_Meshes[i].Vertices[j];
                        MeshVertexIndex index_2 = m_Meshes[i].Vertices[j + 1];
                        MeshVertexIndex index_3 = m_Meshes[i].Vertices[j + 2];

                        if (index_1.Position >= m_Meshes[i].VertexData.Position.Count)
                        {
                            continue;
                        }
                        if (index_2.Position >= m_Meshes[i].VertexData.Position.Count)
                        {
                            continue;
                        }
                        if (index_3.Position >= m_Meshes[i].VertexData.Position.Count)
                        {
                            continue;
                        }

                        Vector3 vec_1 = m_Meshes[i].VertexData.Position[index_1.Position];
                        Vector3 vec_2 = m_Meshes[i].VertexData.Position[index_2.Position];
                        Vector3 vec_3 = m_Meshes[i].VertexData.Position[index_3.Position];

                        writer.Write($"f { master_list.IndexOf(vec_1) + 1 } { master_list.IndexOf(vec_2) + 1 } { master_list.IndexOf(vec_3) + 1 }\n".ToCharArray());
                        writer.Flush();
                    }
                }
            }
        }
Beispiel #2
0
        private List <MeshVertexIndex> ConvertTopologyToTriangles(int fromType, List <MeshVertexIndex> indexes)
        {
            List <MeshVertexIndex> sortedIndexes = new List <MeshVertexIndex>();

            if (fromType == 4)
            {
                for (int v = 2; v < indexes.Count; v++)
                {
                    bool isEven = v % 2 != 0;
                    MeshVertexIndex[] newTri = new MeshVertexIndex[3];

                    newTri[0] = indexes[v - 2];
                    newTri[1] = isEven ? indexes[v] : indexes[v - 1];
                    newTri[2] = isEven ? indexes[v - 1] : indexes[v];

                    // Check against degenerate triangles (a triangle which shares indexes)
                    if (newTri[0] != newTri[1] && newTri[1] != newTri[2] && newTri[2] != newTri[0])
                    {
                        sortedIndexes.AddRange(newTri);
                    }
                    else
                    {
                        System.Console.WriteLine("Degenerate triangle detected, skipping TriangleStrip conversion to triangle.");
                    }
                }
            }
            else if (fromType == 1)
            {
                for (int v = 1; v < indexes.Count - 1; v++)
                {
                    // Triangle is always, v, v+1, and index[0]?
                    MeshVertexIndex[] newTri = new MeshVertexIndex[3];
                    newTri[0] = indexes[v];
                    newTri[1] = indexes[v + 1];
                    newTri[2] = indexes[0];

                    // Check against degenerate triangles (a triangle which shares indexes)
                    if (newTri[0] != newTri[1] && newTri[1] != newTri[2] && newTri[2] != newTri[0])
                    {
                        sortedIndexes.AddRange(newTri);
                    }
                    else
                    {
                        System.Console.WriteLine("Degenerate triangle detected, skipping TriangleFan conversion to triangle.");
                    }
                }
            }
            else if (fromType == 2)
            {
                // The good news is, Triangles just go straight though!
                sortedIndexes.AddRange(indexes);
            }
            else if (fromType == 3)
            {
            }
            else
            {
                System.Console.WriteLine("Unsupported GXPrimitiveType: {0} in conversion to Triangle List.", fromType);
            }

            return(sortedIndexes);
        }
Beispiel #3
0
        private void ReadPrimitiveData(EndianBinaryReader reader, EndianBinaryReader string_table)
        {
            reader.Skip(0x38);

            int prim_offset = reader.ReadInt32();
            int prim_count  = reader.ReadInt32();

            int data_base_offset = prim_offset + (prim_count * 12);

            reader.BaseStream.Seek(prim_offset, SeekOrigin.Begin);

            for (int i = 0; i < prim_count; i++)
            {
                int name_offset = reader.ReadInt32();
                int vec_count   = reader.ReadInt32();
                int data_offset = reader.ReadInt32();

                string_table.BaseStream.Seek(name_offset, SeekOrigin.Begin);
                string mesh_name = string_table.ReadStringUntil('\0');
                Mesh   mesh      = m_Meshes.Find(x => x.Name == mesh_name);

                long cur_pos = reader.BaseStream.Position;
                reader.BaseStream.Seek(data_base_offset + data_offset, SeekOrigin.Begin);

                for (int v = 0; v < vec_count; v++)
                {
                    ushort unk_1 = reader.ReadUInt16();
                    byte   unk_a = reader.ReadByte();
                    byte   unk_2 = reader.ReadByte();

                    List <MeshVertexIndex> vert_indices = new List <MeshVertexIndex>();

                    for (int a = 0; a < 3; a++)
                    {
                        MeshVertexIndex index = new MeshVertexIndex();

                        index.Position = reader.ReadInt16();
                        index.Normal   = reader.ReadInt16();
                        index.Color0   = reader.ReadInt16();
                        index.Tex0     = reader.ReadInt16();

                        vert_indices.Add(index);
                    }

                    // quad
                    if (unk_1 == 3)
                    {
                        MeshVertexIndex index = new MeshVertexIndex();

                        index.Position = reader.ReadInt16();
                        index.Normal   = reader.ReadInt16();
                        index.Color0   = reader.ReadInt16();
                        index.Tex0     = reader.ReadInt16();

                        vert_indices.Add(index);

                        mesh.Vertices.AddRange(new MeshVertexIndex[] { vert_indices[0], vert_indices[1], vert_indices[2] });
                        mesh.Vertices.AddRange(new MeshVertexIndex[] { vert_indices[1], vert_indices[3], vert_indices[2] });
                    }
                    else if (unk_1 == 2)
                    {
                        mesh.Vertices.AddRange(new MeshVertexIndex[] { vert_indices[0], vert_indices[1], vert_indices[2] });

                        reader.SkipInt32();
                        reader.SkipInt32();
                    }

                    // tristrip
                    else if (unk_1 == 4)
                    {
                        int tri_count = reader.ReadInt32();
                        int unk_value = reader.ReadInt32();

                        List <MeshVertexIndex> strip = new List <MeshVertexIndex>();

                        strip.AddRange(new MeshVertexIndex[] { vert_indices[0], vert_indices[1], vert_indices[2] });

                        for (int t = 0; t < tri_count - 1; t++)
                        {
                            MeshVertexIndex orig     = strip[strip.Count - 2];
                            MeshVertexIndex new_vert = new MeshVertexIndex();
                            new_vert.Position = orig.Position + 3;

                            strip.Add(new_vert);
                        }

                        //mesh.Vertices.AddRange(ConvertTopologyToTriangles(4, strip).ToArray());
                    }

                    Vector3 unk_3 = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                }

                reader.BaseStream.Seek(cur_pos, SeekOrigin.Begin);
            }

            reader.BaseStream.Seek(8, SeekOrigin.Begin);
        }