Example #1
0
        public void LoadNode(EntryTreeNode node)
        {
            foreach (EntryTreeNode child in node.Nodes)
            {
                DataGridViewRow row = new DataGridViewRow();

                DataGridViewTextBoxCell type = new DataGridViewTextBoxCell
                {
                    Value = Helpers.FormatNicely(child.ResourceIdentifier)
                };
                row.Cells.Add(type);

                DataGridViewTextBoxCell offset = new DataGridViewTextBoxCell
                {
                    Value = child.ResourceOffset
                };
                row.Cells.Add(offset);

                dataGridView.Rows.Add(row);
            }
        }
Example #2
0
        public static Submesh[] ExtractModel(string fileName, EntryTreeNode node, Action completionAction)
        {
            Submesh[] submeshes;

            using (Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                if (stream.Length == 0)
                {
                    return(null);
                }

                using (BinaryReader reader = new BinaryReader(stream))
                {
                    // header
                    DatafileHeader header = new DatafileHeader
                    {
                        ResourceType = reader.ReadInt32(),
                        FileSize     = reader.ReadInt32(),
                        FileNameSize = reader.ReadInt32()
                    };
                    header.FileName = reader.ReadChars(header.FileNameSize);

                    // ignore the 2 bytes, file ID, and resource type
                    reader.BaseStream.Seek(0x1d, SeekOrigin.Current);

                    // block A - 1
                    uint  aCount = reader.ReadUInt32();
                    Block blockA = new Block();
                    blockA.Bytes = new byte[aCount][];
                    for (int i = 0; i < aCount; i++)
                    {
                        blockA.Bytes[i] = reader.ReadBytes(0x51);
                    }

                    // block B - 1-0
                    Block blockB = new Block();
                    blockB.Bytes = new byte[2][];
                    for (int i = 0; i < 2; i++)
                    {
                        blockB.Bytes[i] = reader.ReadBytes(0x10);
                    }

                    // block C - 1-1
                    reader.BaseStream.Seek(1, SeekOrigin.Current);
                    Block blockC = new Block();
                    blockC.Bytes = new byte[2][];
                    for (int i = 0; i < 2; i++)
                    {
                        blockC.Bytes[i] = reader.ReadBytes(0x11);
                    }

                    // block D - 1-2
                    reader.BaseStream.Seek(0x29, SeekOrigin.Current);
                    uint  dCount = reader.ReadUInt32();
                    Block blockD = new Block();
                    blockD.Bytes = new byte[dCount][];
                    for (int i = 0; i < dCount; i++)
                    {
                        blockD.Bytes[i] = reader.ReadBytes(0x18);
                    }

                    // internal/external UVs (block E) - 20
                    uint eCount = reader.ReadUInt32();
                    reader.BaseStream.Seek(eCount, SeekOrigin.Current);

                    // vertices (block F) - 30
                    uint  fCount         = reader.ReadUInt32() / 12;
                    long  verticesOffset = reader.BaseStream.Position;
                    Block blockF         = new Block();
                    blockF.Bytes = new byte[fCount][];
                    for (int i = 0; i < fCount; i++)
                    {
                        blockF.Bytes[i] = reader.ReadBytes(0x0c);
                    }

                    // block G - 40
                    uint  gSize  = reader.ReadUInt32();
                    Block blockG = new Block();
                    blockG.Bytes = new byte[gSize][];
                    reader.BaseStream.Seek(gSize, SeekOrigin.Current);

                    // faces (block) H - 50
                    uint  hCount      = reader.ReadUInt32() / 6;
                    long  facesOffset = reader.BaseStream.Position;
                    Block blockH      = new Block();
                    blockH.Bytes = new byte[hCount][];
                    for (int i = 0; i < hCount; i++)
                    {
                        blockH.Bytes[i] = reader.ReadBytes(0x06);
                    }

                    // block I - 60
                    uint  iSize  = reader.ReadUInt32();
                    Block blockI = new Block();
                    blockI.Bytes = new byte[iSize][];
                    reader.BaseStream.Seek(iSize, SeekOrigin.Current);

                    // block J - 70
                    uint  jSize  = reader.ReadUInt32();
                    Block blockJ = new Block();
                    blockJ.Bytes = new byte[jSize][];
                    reader.BaseStream.Seek(jSize, SeekOrigin.Current);

                    // block K - 80
                    uint  kSize  = reader.ReadUInt32();
                    Block blockK = new Block();
                    blockK.Bytes = new byte[kSize][];
                    reader.BaseStream.Seek(kSize, SeekOrigin.Current);

                    // block L
                    Block blockL = new Block();
                    blockL.Bytes = new byte[1][];
                    for (int i = 0; i < 1; i++)
                    {
                        blockL.Bytes[i] = reader.ReadBytes(0x12);
                    }

                    // block M - 90
                    uint mSize = reader.ReadUInt32(); // number of submeshes

                    // create submeshes
                    submeshes = new Submesh[mSize];
                    for (int i = 0; i < mSize; i++)
                    {
                        submeshes[i] = new Submesh();

                        reader.BaseStream.Seek(0x14, SeekOrigin.Current);
                        submeshes[i].VertexCount = reader.ReadUInt32();
                        reader.BaseStream.Seek(0x04, SeekOrigin.Current);
                        submeshes[i].FaceCount = reader.ReadUInt32();
                        reader.BaseStream.Seek(0x04, SeekOrigin.Current);
                    }

                    /*reader.BaseStream.Seek(0x10, SeekOrigin.Current);
                     *
                     * // block N - 100
                     * uint nSize = reader.ReadUInt32();
                     * Block blockN = new Block();
                     * blockN.Bytes = new byte[nSize][];
                     * for (int i = 0; i < nSize; i++)
                     * {
                     *  blockN.Bytes[i] = reader.ReadBytes(0x1e);
                     * }
                     *
                     * // block O - 110
                     * reader.BaseStream.Seek(0x16, SeekOrigin.Current);
                     * uint oSize = reader.ReadUInt32();
                     * Block blockO = new Block();
                     * blockO.Bytes = new byte[nSize][];
                     * for (int i = 0; i < oSize; i++)
                     * {
                     *  blockO.Bytes[i] = reader.ReadBytes(0x0a);
                     * }*/

                    // get faces
                    reader.BaseStream.Seek(facesOffset, SeekOrigin.Begin);
                    for (int i = 0; i < submeshes.Length; i++)
                    {
                        submeshes[i].Faces = new Face[submeshes[i].FaceCount];
                        for (int j = 0; j < submeshes[i].FaceCount; j++)
                        {
                            submeshes[i].Faces[j] = new Face
                            {
                                X = reader.ReadUInt16(),
                                Y = reader.ReadUInt16(),
                                Z = reader.ReadUInt16()
                            };

                            /*ObjParser.Types.Face f = new ObjParser.Types.Face
                             * {
                             *  X = submeshes[i].Vertices[j].X,
                             *  Y = submeshes[i].Vertices[j].Y,
                             *  Z = submeshes[i].Vertices[j].Z
                             * };
                             * faces.Add(f);*/
                        }
                    }

                    // get vertices
                    reader.BaseStream.Seek(verticesOffset, SeekOrigin.Begin);
                    List <ObjParser.Types.Vertex> verts = new List <ObjParser.Types.Vertex>();
                    for (int i = 0; i < submeshes.Length; i++)
                    {
                        submeshes[i].Vertices = new Vertex[submeshes[i].VertexCount];
                        for (int j = 0; j < submeshes[i].VertexCount; j++)
                        {
                            submeshes[i].Vertices[j] = new Vertex
                            {
                                X     = reader.ReadInt16(),
                                Y     = reader.ReadInt16(),
                                Z     = reader.ReadInt16(),
                                U     = reader.ReadInt16(),
                                V     = reader.ReadInt16(),
                                Dummy = reader.ReadInt16()
                            };

                            ObjParser.Types.Vertex v = new ObjParser.Types.Vertex
                            {
                                X = submeshes[i].Vertices[j].X,
                                Y = submeshes[i].Vertices[j].Y,
                                Z = submeshes[i].Vertices[j].Z
                            };
                            verts.Add(v);
                        }
                    }

                    Obj obj = new Obj();
                    obj.VertexList = verts;
                    obj.WriteObjFile(@"C:\Users\pinea\bag-new.obj", new string[] { "" });

                    completionAction();
                }
            }

            return(submeshes);
        }
Example #3
0
        private void modelButton_Click(object sender, EventArgs e)
        {
            // get the entry node, not subentry node
            node = node.Type == EntryTreeNodeType.SUBENTRY ? (EntryTreeNode)node.Parent : node;

            string item = (string)modelComboBox.SelectedItem;

            saveFileDialog.FileName = node.Text;
            saveFileDialog.Filter   = $"{item}|All Files|*.*";
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                if (combineMeshesCheckBox.Checked)
                {
                    switch (modelComboBox.SelectedIndex)
                    {
                    /*case 0: //dae
                     *  DAE.Export(saveFileDialog.FileName, model, false, false);
                     *  break;*/
                    case 0:     //obj
                        File.WriteAllText(saveFileDialog.FileName, OBJ.Export(model, (NormalExportMode)normalsComboBox.SelectedIndex));
                        break;

                    /*case 2: //smd
                     *  File.WriteAllText(saveFileDialog.FileName, SMD.Export(model, calculateNormals));
                     *  break;
                     * case 3: //stl
                     *  STL.ExportBinary(saveFileDialog.FileName, model, calculateNormals);
                     *  break;*/
                    default:
                        break;
                    }
                    Message.Success("Saved the model into a single file.");
                }
                else
                {
                    for (int i = 0; i < model.Meshes.Count; i++)
                    {
                        string fileName = string.Concat(Path.Combine(Path.GetDirectoryName(saveFileDialog.FileName), Path.GetFileNameWithoutExtension(saveFileDialog.FileName)), "-", i, Path.GetExtension(saveFileDialog.FileName));
                        Model  mdl      = Model.CreateFromMesh(model.Meshes[i]);

                        switch (modelComboBox.SelectedIndex)
                        {
                        /*case 0: //dae
                         *  DAE.Export(fileName, mdl, false, false);
                         *  break;*/
                        case 0:     //obj
                            File.WriteAllText(fileName, OBJ.Export(mdl, (NormalExportMode)normalsComboBox.SelectedIndex, true));
                            break;

                            /*case 2: //smd
                             *  File.WriteAllText(fileName, SMD.Export(mdl, true));
                             *  break;
                             * case 3: //stl
                             *  STL.ExportBinary(fileName, mdl, true);
                             *  break;
                             * default:
                             *  break;*/
                        }
                    }
                    Message.Success("Saved the model into separate files.");
                }
            }
        }
Example #4
0
 public void SetValues(int selectedTab, EntryTreeNode node, Model model = null)
 {
     tabControl1.SelectedIndex = selectedTab;
     this.node  = node;
     this.model = model;
 }
Example #5
0
        public static void ExtractTextureMap(string fileName, EntryTreeNode node, Action <string> completionAction)
        {
            string name = Path.GetFileNameWithoutExtension(fileName);

            using (Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                if (stream.Length == 0)
                {
                    return;
                }

                using (BinaryReader reader = new BinaryReader(stream))
                {
                    DatafileHeader header = new DatafileHeader
                    {
                        ResourceIdentifier = reader.ReadUInt32(),
                        FileSize           = reader.ReadInt32(),
                        FileNameSize       = reader.ReadInt32()
                    };
                    header.FileName = reader.ReadChars(header.FileNameSize);
                    reader.BaseStream.Seek(9, SeekOrigin.Current); // fileID + 1 skipped bytes

                    if (header.ResourceIdentifier != (uint)ResourceIdentifier.TEXTURE_MAP)
                    {
                        Message.Fail("This is not proper Texture Map data.");
                    }

                    /*// mip 0
                     * TextureMap mip0 = new TextureMap
                     * {
                     *  Width = reader.ReadInt32(),
                     *  Height = reader.ReadInt32()
                     * };
                     * reader.BaseStream.Seek(4, SeekOrigin.Current);
                     * mip0.DXT = DXTExtensions.GetDXT(reader.ReadInt32());
                     * reader.BaseStream.Seek(8, SeekOrigin.Current);
                     * mip0.Mipmaps = reader.ReadInt32();
                     *
                     * reader.BaseStream.Seek(39, SeekOrigin.Current); // go to next mip
                     *
                     * // ignore mip 1
                     * reader.BaseStream.Seek(28, SeekOrigin.Current);
                     *
                     * // locate the two mips, if they exist
                     * if (node.GetForge().FileEntries.Where(x => x.NameTable.Name.Contains(Path.GetFileNameWithoutExtension(fileName) + "_Mip")).Count() > 0)
                     * {
                     *  Forge.FileEntry[] mipEntries = node.GetForge().FileEntries.Where(x => x.NameTable.Name == Path.GetFileNameWithoutExtension(fileName) + "_Mip0").ToArray();
                     *  if (mipEntries != null && mipEntries.Length > 0)
                     *  {
                     *      Forge.FileEntry mipEntry = mipEntries[0];
                     *
                     *      // extract, read, and create a DDS image with the first mip
                     *      byte[] rawTopMipData = node.GetForge().GetRawData(mipEntry);
                     *
                     *      // read
                     *      byte[] topMipData = ReadFile(rawTopMipData);
                     *      File.WriteAllBytes(Helpers.GetTempPath(mipEntry.NameTable.Name + "." + Helpers.GameToExtension(node.Game)), topMipData);
                     *
                     *      // extract
                     *      //ExtractTopMip(topMipData, mipEntry.NameTable.Name, mip0, completionAction);
                     *  }
                     * }
                     * else // mips do not exist. fear not! there is still image data found here. let us use that.
                     * {
                     *  reader.BaseStream.Seek(12, SeekOrigin.Current);
                     *
                     *  /*TextureMap map = new TextureMap();
                     *  map.DataSize = reader.ReadInt32();
                     *
                     *  // test if this dataSize is too big
                     *  bool correctSize = true;
                     *  if (map.DataSize > reader.BaseStream.Length || map.DataSize < reader.BaseStream.Length - 300) // if the dataSize lies within a reasonable range
                     *  {
                     *      correctSize = false;
                     *  }
                     *
                     *  // test again, 14 bytes later
                     *  if (!correctSize)
                     *  {
                     *      reader.BaseStream.Seek(14, SeekOrigin.Current);
                     *      map.DataSize = reader.ReadInt32();
                     *  }
                     *
                     *  byte[] mipmapData = reader.ReadBytes(map.DataSize);
                     *
                     *  // write DDS file
                     *  TopMip mip = mip0;
                     *  Helpers.WriteTempDDS(name, mipmapData, mip.Width, mip.Height, mip.Mipmaps, mip.DXTType, () =>
                     *  {
                     *      Helpers.ConvertDDS($"{Helpers.GetTempPath(name)}.dds", fixNormals: name.Contains("NormalMap"), completionAction: (error) => {
                     *          if (error)
                     *              completionAction("FAILED");
                     *          else
                     *              completionAction($"{Helpers.GetTempPath(name)}.png");
                     *      });
                     *  });*
                     * }*/

                    // TextureMap
                    reader.BaseStream.Seek(5, SeekOrigin.Current); // identifier + 1 skipped byte
                    TextureMap textureMap = new TextureMap
                    {
                        Width  = reader.ReadInt32(),
                        Height = reader.ReadInt32()
                    };
                    reader.BaseStream.Seek(4, SeekOrigin.Current);  // 4 skipped bytes
                    textureMap.DXT = (DXT)reader.ReadInt32();
                    reader.BaseStream.Seek(8, SeekOrigin.Current);  // 8 skipped bytes
                    textureMap.Mipmaps = reader.ReadInt32();
                    reader.BaseStream.Seek(12, SeekOrigin.Current); // 3 skipped ints

                    reader.BaseStream.Seek(2, SeekOrigin.Current);

                    // CompiledTopMip
                    CompiledTopMip[] compiledTopMips = new CompiledTopMip[reader.ReadInt32()];
                    reader.BaseStream.Seek(1, SeekOrigin.Current);

                    // read CompiledTopMips
                    for (int i = 0; i < compiledTopMips.Length; i++)
                    {
                        compiledTopMips[i].FileID = reader.ReadInt64();
                        reader.BaseStream.Seek(1, SeekOrigin.Current); // 1 skipped byte
                    }

                    reader.BaseStream.Seek(8, SeekOrigin.Current);

                    // CompiledTextureMap
                    reader.BaseStream.Seek(12, SeekOrigin.Current); // identifier + two skipped ints
                    CompiledTextureMap compiledTextureMap = new CompiledTextureMap
                    {
                        Width  = reader.ReadInt32(),
                        Height = reader.ReadInt32()
                    };
                    reader.BaseStream.Seek(4, SeekOrigin.Current);  // 1 skipped int
                    compiledTextureMap.Mipmaps = reader.ReadInt32();
                    reader.BaseStream.Seek(4, SeekOrigin.Current);  // 1 skipped int
                    compiledTextureMap.DXT = (DXT)reader.ReadInt32();
                    reader.BaseStream.Seek(16, SeekOrigin.Current); // 4 skipped ints

                    // locate the parent forge tree node
                    EntryTreeNode forgeNode = (EntryTreeNode)node.Parent.Parent;
                    if (forgeNode.Type != EntryTreeNodeType.FORGE)
                    {
                        Message.Fail("Failed to locate the forge node.");
                        return;
                    }

                    // check to see if there is a topmip
                    if (compiledTopMips.Select(x => x.FileID).Count() > 0 && compiledTopMips.Select(x => x.FileID).First() != 0)
                    {
                        // search for file IDs from the CompiledTextureMaps
                        if (forgeNode.Nodes.Cast <EntryTreeNode>().Where(x => x.FileID == compiledTopMips[0].FileID).Count() == 0)
                        {
                            if (Message.Show("Failed to locate the Mip0. Would you like to try extracting the TextureMap's internal image data?", "Failed", MessageBoxButtons.YesNo) == DialogResult.Yes)
                            {
                                ExtractInternalTexture(reader, textureMap, name, completionAction);
                                return;
                            }
                            else
                            {
                                return;
                            }
                        }
                        EntryTreeNode mip0Node = forgeNode.Nodes.Cast <EntryTreeNode>().Where(x => x.FileID == compiledTopMips[0].FileID).First();

                        if (node.GetForge().FileEntries.Where(x => x.IndexTable.FileDataID == compiledTopMips[0].FileID).Count() == 0)
                        {
                            Message.Fail("Failed to locate the Mip0 in the forge.");
                            return;
                        }
                        Forge.FileEntry mip0Entry = node.GetForge().FileEntries.Where(x => x.IndexTable.FileDataID == compiledTopMips[0].FileID).First();

                        // read
                        byte[] rawMip0Data = node.GetForge().GetRawData(mip0Entry);
                        byte[] mip0Data    = ReadFile(rawMip0Data);

                        // save for future use
                        File.WriteAllBytes(Helpers.GetTempPath($"{mip0Entry.NameTable.Name}.{Helpers.GameToExtension(node.Game)}"), mip0Data);

                        // extract
                        Odyssey.ExtractTopMip(mip0Data, mip0Entry.NameTable.Name, compiledTextureMap, completionAction);
                    }
                    else
                    {
                        // use the image data within this file
                        ExtractInternalTexture(reader, textureMap, name, completionAction);
                    }
                }
            }
        }
Example #6
0
        public static void ExtractTextureMap(string fileName, EntryTreeNode node, Action <string> completionAction)
        {
            string name = Path.GetFileNameWithoutExtension(fileName);

            using (Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                if (stream.Length == 0)
                {
                    return;
                }

                using (BinaryReader reader = new BinaryReader(stream))
                {
                    DatafileHeader header = new DatafileHeader
                    {
                        ResourceType = reader.ReadInt32(),
                        FileSize     = reader.ReadInt32(),
                        FileNameSize = reader.ReadInt32()
                    };
                    header.FileName = reader.ReadChars(header.FileNameSize);

                    // ignore the 1 byte, file ID, resource type, and 1 extra byte
                    reader.BaseStream.Seek(14, SeekOrigin.Current);

                    // mip 0
                    Mip mip0 = new Mip
                    {
                        Width  = reader.ReadInt32(),
                        Height = reader.ReadInt32()
                    };
                    reader.BaseStream.Seek(8, SeekOrigin.Current);
                    mip0.DXTType = DXTExtensions.GetDXT(reader.ReadInt32());
                    reader.BaseStream.Seek(4, SeekOrigin.Current);
                    mip0.Mipmaps = reader.ReadInt32();

                    reader.BaseStream.Seek(39, SeekOrigin.Current); // go to next mip

                    // mip 1
                    Mip mip1 = new Mip
                    {
                        Width  = reader.ReadInt32(),
                        Height = reader.ReadInt32()
                    };
                    reader.BaseStream.Seek(8, SeekOrigin.Current);
                    mip1.DXTType = DXTExtensions.GetDXT(reader.ReadInt32());
                    reader.BaseStream.Seek(4, SeekOrigin.Current);
                    mip1.Mipmaps = reader.ReadInt32();

                    // locate the two mips, if they exist
                    if (node.GetForge().FileEntries.Where(x => x.NameTable.Name.Contains(Path.GetFileNameWithoutExtension(fileName) + "_Mip")).Count() == 2)
                    {
                        Forge.FileEntry[] mipEntries = node.GetForge().FileEntries.Where(x => x.NameTable.Name == Path.GetFileNameWithoutExtension(fileName) + "_Mip0").ToArray();
                        if (mipEntries.Length > 0)
                        {
                            Forge.FileEntry mipEntry = mipEntries[0];

                            // extract, read, and create a DDS image with the first mip
                            byte[] rawTopMipData = node.GetForge().GetRawData(mipEntry);
                            //Helpers.WriteToFile(mipEntry.NameTable.Name, rawData, true);

                            // read
                            //ReadFile(Helpers.GetTempPath(mipEntry.NameTable.Name));
                            byte[] topMipData = ReadFile(rawTopMipData);

                            // extract
                            //ExtractTopMip(Helpers.GetTempPath(mipEntry.NameTable.Name), mip0, completionAction);
                            ExtractTopMip(topMipData, mipEntry.NameTable.Name, mip0, completionAction);
                        }
                    }
                    else // mips do not exist. fear not! there is still image data found here. let us use that.
                    {
                        reader.BaseStream.Seek(12, SeekOrigin.Current);

                        TextureMap map = new TextureMap
                        {
                            DataSize = reader.ReadInt32()
                        };
                        byte[] mipmapData = reader.ReadBytes(map.DataSize);

                        // write DDS file
                        Helpers.WriteTempDDS(name, mipmapData, mip1.Width, mip1.Height, mip1.Mipmaps, mip1.DXTType, () =>
                        {
                            Helpers.ConvertDDS($"{Helpers.GetTempPath(name)}.dds", (bool error) => {
                                if (error)
                                {
                                    completionAction("FAILED");
                                }
                                else
                                {
                                    completionAction($"{Helpers.GetTempPath(name)}.png");
                                }
                            });
                        });
                    }
                }
            }
        }