Exemple #1
0
        /// <summary>
        /// Reads JMP from a data stream.
        /// </summary>
        /// <param name="stream">The stream containing the JMP data.</param>
        public JMP(Stream stream)
        {
            // Define a binary reader to read with.
            DhBinaryReader br = new DhBinaryReader(stream, DhEndian.Big);

            // Read JMP's Header
            uint entryCount = br.ReadU32();
            uint fieldCount = br.ReadU32();

            EntryOffset = br.ReadU32();
            EntrySize   = br.ReadU32();

            // Read JMP's Fields
            Fields = new List <JField>();
            for (int i = 0; i < fieldCount; i++)
            {
                Fields.Add(new JField(br));
            }

            // Seek to beginning of file.
            br.Goto(0);

            // Read JMP's Entries
            Entries = new List <JEntry>();
            for (int i = 0; i < entryCount; i++)
            {
                br.Goto(EntryOffset + (i * EntrySize));
                Entries.Add(new JEntry(br, Fields));
            }
        }
Exemple #2
0
        /// <summary>
        /// Read a single texture from BIN.
        /// </summary>
        /// <param name="br">Binary Reader to use.</param>
        /// <param name="texturesOffset">Offset to textures.</param>
        public BinTexture(DhBinaryReader br, long texturesOffset)
        {
            // Read texture width.
            Width = br.ReadU16();

            // Read texture height.
            Height = br.ReadU16();

            // Read texture format.
            Format = br.ReadU8();

            // Read texture unknown 1. (Flags?)
            Unknown1 = br.ReadU8();

            // Read texture unknown 2. (Padding)
            Unknown2 = br.ReadU16();

            // Read texture data offset.
            DataOffset = br.ReadU32();

            // Save the current position.
            long currentPosition = br.Position();

            // Go to the bin textures offset.
            br.Goto(texturesOffset);

            // Sail to the texture's data offset.
            br.Sail(DataOffset);

            // Read the texture's raw data.
            Data = br.Read((Width * Height) / 2);

            // Go to the previously saved offset.
            br.Goto(currentPosition);
        }
Exemple #3
0
        /// <summary>
        /// Read a single batch from BIN.
        /// </summary>
        /// <param name="br">The binaryreader to write with.</param>
        /// <param name="batchesOffset">Offset to batches.</param>
        public Batch(DhBinaryReader br, long batchesOffset)
        {
            // Read face count.
            FaceCount = br.ReadU16();

            // Read primitive list size.
            ListSize = br.ReadS16();

            // Read vertex attributes.
            VertexAttributes = (Attributes)br.ReadU32();

            // Read UseNormals flag.
            UseNormals = br.ReadBool8();

            // Read Position Winding.
            Positions = br.Read();

            // Read UV Count.
            UvCount = br.Read();

            // Read UseNBT flag.
            UseNBT = br.ReadBool8();

            // Read Primitive offset.
            PrimitiveOffset = br.ReadU32();

            // Read Unknown 1. (Padding?)
            Unknown1 = br.ReadS32s(2);

            // Save the current position.
            long currentPosition = br.Position();

            // Go to the batch's primitive offset offset.
            br.Goto(batchesOffset + PrimitiveOffset);

            // Define list to hold batch's primitives.
            Primitives = new List <Primitive>();

            // Define int to keep track of the amount of faces read.
            int readFaces = 0;

            // Read primitives until batch's face count has been reached.
            while ((readFaces < FaceCount) && (br.Position() < (batchesOffset + PrimitiveOffset + (ListSize << 5))))
            {
                // Read primitive.
                Primitive binPrimitive = new Primitive(br, VertexAttributes, UseNBT);

                // Add the primitive to the batch's primitives.
                Primitives.Add(binPrimitive);

                // Add primitive's face count to the read faces counter.
                readFaces += binPrimitive.FaceCount;
            }

            // Go to the previously saved offset.
            br.Goto(currentPosition);
        }
Exemple #4
0
        public TXPEntry(DhBinaryReader br, ushort frameCount)
        {
            //Ensure that Uknown 1 is 1
            if (br.ReadU16() != 1)
            {
                throw new Exception("Unknown1 wasn't 1!");
            }

            //Read material index
            MaterialIndex = br.ReadS16();

            if (br.ReadU32() != 0)
            {
                throw new Exception("Unknown2 wasn't 0!");
            }

            //Read the frame data offset for this
            uint frameDataOffset = br.ReadU32();

            TexObjIndicies = new short[frameCount];

            //Save reader's current position and seek to the frame data
            br.SaveOffset(0);
            br.Goto(frameDataOffset);

            //Fill TexObjIndicies for each frame
            for (int frame = 0; frame < frameCount; frame++)
            {
                TexObjIndicies[frame] = br.ReadS16();
            }

            br.LoadOffset(0);
        }
Exemple #5
0
        /// <summary>
        /// Read a single entry from JMP.
        /// </summary>
        /// <param name="br">Binary Reader to use.</param>
        /// <param name="fields">List of fields in JMP.</param>
        public JEntry(DhBinaryReader br, List <JField> fields)
        {
            long currentPosition = br.Position();

            Values = new Dictionary <string, object>();
            for (int i = 0; i < fields.Count; i++)
            {
                br.Sail(fields[i].Offset);

                object value;
                switch (fields[i].Type)
                {
                case JFieldType.INTEGER:
                    value = ((br.ReadS32() & fields[i].Bitmask) >> fields[i].Shift);
                    break;

                case JFieldType.STRING:
                    value = br.ReadFixedStr(32);
                    break;

                case JFieldType.FLOAT:
                    value = br.ReadF32();
                    break;

                default:
                    throw new InvalidDataException($"{fields[i].Type} is not a valid jmp entry type!");
                }

                Values.Add(fields[i].Name, value);

                br.Goto(currentPosition);
            }
        }
Exemple #6
0
        /// <summary>
        /// Reads TMB from a byte array.
        /// </summary>
        /// <param name="data">The byte array containing the TMB data.</param>
        public TMB(byte[] data)
        {
            // Define a new binary reader to read with.
            DhBinaryReader br = new DhBinaryReader(data, DhEndian.Big);

            // Read sequence count.
            SequenceCount = br.ReadU16();

            // Read timing duration.
            Duration = br.ReadU16();

            // Read sequence data offset.
            SequenceDataOffset = br.ReadU32();

            // Define a new list to hold our sequences.
            Sequences = new List <TMBSequence>();

            // Goto sequence data offset.
            br.Goto(SequenceDataOffset);

            // Loop through sequences within this bank.
            for (int i = 0; i < SequenceCount; i++)
            {
                // Read a sequence and add it to the list of sequences.
                Sequences.Add(new TMBSequence(br));
            }

            // Loop through sequences within this bank.
            for (int i = 0; i < SequenceCount; i++)
            {
                // Go to this sequence's keyframe data.
                br.Goto(8 + ((Sequences[i].StartIndex * 4)));

                // Loop through keyframe's within this sequence.
                for (int y = 0; y < Sequences[i].KeyFrameCount; y++)
                {
                    // Read this keyframe and add it to the sequence's list of the keyframes.
                    Sequences[i].KeyFrames.Add(new TIMKeyFrame(br, Sequences[i].KeyFrameSize));
                }
            }
        }
Exemple #7
0
        public List <GraphObject> GetGraphObjects(DhBinaryReader br, int index)
        {
            // Save current offset.
            long currentPosition = br.Position();

            // Goto a specific graph object offset based on it's index.
            br.Goto(Offsets[12] + (0x8C * index));

            // Initialize the graph object at specific index.
            GraphObject graphObject = new GraphObject(br, Offsets[12]);

            // Goto previously saved offset.
            br.Goto(currentPosition);

            // Initialize a list to hold all graph objects.
            List <GraphObject> graphObjects = new List <GraphObject>();

            // Add first graph object to list of graph objects.
            graphObjects.Add(graphObject);

            // Check if graph object specifies a child graph object.
            if (graphObject.ChildIndex >= 0)
            {
                // Add the child graph object (And it's child/next graph objects.)
                graphObjects.AddRange(GetGraphObjects(br, graphObject.ChildIndex));
            }

            // Check if graph object specifies the next graph object.
            if (graphObject.NextIndex >= 0)
            {
                // Add the next graph object (And it's child/next graph objects.)
                graphObjects.AddRange(GetGraphObjects(br, graphObject.NextIndex));
            }

            // Return the list of graph objects.
            return(graphObjects);
        }
Exemple #8
0
        /// <summary>
        /// Reads JMP from a byte array.
        /// </summary>
        /// <param name="stream">The byte array containing the JMP data.</param>
        public JMP(byte[] data)
        {
            DhBinaryReader br = new DhBinaryReader(data, DhEndian.Big);

            uint entryCount  = br.ReadU32();
            uint fieldCount  = br.ReadU32();
            uint entryOffset = br.ReadU32();
            uint entrySize   = br.ReadU32();

            Fields = new List <JField>();
            for (int i = 0; i < fieldCount; i++)
            {
                Fields.Add(new JField(br));
            }

            br.Goto(0);

            Entries = new List <JEntry>();
            for (int i = 0; i < entryCount; i++)
            {
                br.Goto(entryOffset + (i * entrySize));
                Entries.Add(new JEntry(br, Fields));
            }
        }
Exemple #9
0
        /// <summary>
        /// Read a single entry from JMP.
        /// </summary>
        /// <param name="br">Binary Reader to use.</param>
        /// <param name="fields">List of fields in JMP.</param>
        public JEntry(DhBinaryReader br, List <JField> fields)
        {
            // Save the current position.
            long currentPosition = br.Position();

            // Define a new object array to hold entry's values.
            Values = new object[fields.Count];

            // Loop through each field in the JMP.
            for (int i = 0; i < fields.Count; i++)
            {
                // Seek from the current position to value's offset in the entry.
                br.Sail(fields[i].Offset);

                // Define a new object to hold our data.
                object value;

                // Check which type the current value is.
                switch (fields[i].Type)
                {
                case JFieldType.INTEGER:
                    // Read the data as a integer.
                    value = ((br.ReadS32() & fields[i].Bitmask) >> fields[i].Shift);
                    break;

                case JFieldType.STRING:
                    // Read the data as a 32-byte long string.
                    value = br.ReadStr32();
                    break;

                case JFieldType.FLOAT:
                    // Read the data as a float32.
                    value = br.ReadF32();
                    break;

                default:
                    // Something went horribly wrong.
                    throw new InvalidDataException();
                }
                // Set the value of this entry's value's data to the value we just read.
                Values[i] = value;

                // Seek back to the position we saved earlier.
                br.Goto(currentPosition);
            }
        }
Exemple #10
0
        /// <summary>
        /// Reads BIN from a byte array.
        /// </summary>
        /// <param name="data">The byte array containing the BIN data.</param>
        public BIN(byte[] data)
        {
            // Define a binary reader to read with.
            DhBinaryReader br = new DhBinaryReader(data, DhEndian.Big);

            // Read bin version.
            Version = br.Read();

            // Make sure the bin version is either 0x01 or 0x02.
            if (Version == 0x00 || Version > 0x02)
            {
                throw new Exception($"[BIN] {Version} is not a valid version!");
            }

            // Read bin model name.
            ModelName = br.ReadFixedStr(11);

            // Define a new list to hold the bin's offsets.
            Offsets = br.ReadU32s(21);

            // Go to the bin graph object offset.
            br.Goto(Offsets[12]);

            // Get first graph object, then all of it's attached graph objects.
            GraphObjects = GetGraphObjects(br, 0);


            // Make sure bin batches has a offset.
            if (Offsets[11] != 0)
            {
                // Go to the bin batches offset.
                br.Goto(Offsets[11]);

                // Define a new list to hold the bin's batches.
                Batches = new List <Batch>();

                // Loop through batches.
                for (int i = 0; i < GetBatchCount(); i++)
                {
                    // Read a batch and add it to the batch list.
                    Batches.Add(new Batch(br, Offsets[11]));
                }
            }


            // Make sure bin shaders has a offset.
            if (Offsets[10] != 0)
            {
                // Go to the bin shaders offset.
                br.Goto(Offsets[10]);

                // Define a new list to hold the bin's shaders.
                Shaders = new List <Shader>();

                // Loop through shaders.
                for (int i = 0; i < GetShaderCount(); i++)
                {
                    // Read a shader and add it to the shader list.
                    Shaders.Add(new Shader(br));
                }
            }


            // Make sure bin texture coordinates 1 has a offset.
            if (Offsets[7] != 0)
            {
                // Go to the bin texture coordinates 1 offset.
                br.Goto(Offsets[7]);

                // Define a new list to hold the bin's texture coordinates 1.
                TextureCoordinates1 = new List <Vec2>();

                // Loop through texture coordinates 1.
                for (int i = 0; i < GetTexCoordinate1Count(); i++)
                {
                    // Read a bin texture coordinates and add it to the texture coordinates 1 list.
                    TextureCoordinates1.Add(br.ReadVec2());
                }
            }


            // Make sure bin texture coordinates 0 has a offset.
            if (Offsets[6] != 0)
            {
                // Go to the bin texture coordinates 0 offset.
                br.Goto(Offsets[6]);

                // Define a new list to hold the bin's texture coordinates 0.
                TextureCoordinates0 = new List <Vec2>();

                // Loop through texture coordinates 0.
                for (int i = 0; i < GetTexCoordinate0Count(); i++)
                {
                    // Read a bin texture coordinates 0 and add it to the texture coordinates 0 list.
                    TextureCoordinates0.Add(br.ReadVec2());
                }
            }


            // WE'RE SKIPPING COLOR0 AND COLOR1! (Offset5 and Offset4)


            // Make sure bin normals has a offset.
            if (Offsets[3] != 0)
            {
                // Go to the bin normals offset.
                br.Goto(Offsets[3]);

                // Define a new list to hold the bin's normals.
                Normals = new List <Vec3>();

                // Loop through normals.
                for (int i = 0; i < GetNormalCount(); i++)
                {
                    // Read a bin normal and add it to the normals list.
                    Normals.Add(br.ReadVec3());
                }
            }


            // Make sure bin positions has a offset.
            if (Offsets[2] != 0)
            {
                // Go to the bin positions offset.
                br.Goto(Offsets[2]);

                // Define a new list to hold the bin's positions.
                Positions = new List <Vec3>();

                // Loop through positions.
                for (int i = 0; i < GetPositionCount(); i++)
                {
                    // Read a bin position and add it to the positions list.
                    Positions.Add(new Vec3(br.ReadF16() / 256.0f, br.ReadF16() / 256.0f, br.ReadF16() / 256.0f));
                }
            }


            // Make sure bin materials has a offset.
            if (Offsets[1] != 0)
            {
                // Go to the bin materials offset.
                br.Goto(Offsets[1]);

                // Define a new list to hold the bin's materials.
                Materials = new List <Material>();

                // Loop through materials.
                for (int i = 0; i < GetMaterialCount(); i++)
                {
                    // Read a bin material and add it to the materials list.
                    Materials.Add(new Material(br));
                }
            }


            // Make sure bin textures has a offset.
            if (Offsets[0] != 0)
            {
                // Go to the bin textures offset.
                br.Goto(Offsets[0]);

                // Define a new list to hold the bin's textures.
                Textures = new List <BTI>();

                // Loop through textures.
                for (int i = 0; i < GetTextureCount(); i++)
                {
                    // Read a bin textures and add it to the textures list.
                    Textures.Add(new BTI(br, Offsets[0]));
                }
            }
        }
Exemple #11
0
        /// <summary>
        /// Read a single batch from BIN.
        /// </summary>
        /// <param name="br">Binary Reader to use.</param>
        /// <param name="batchesOffset">Offset to batches.</param>
        public BinBatch(DhBinaryReader br, long batchesOffset)
        {
            // Read face count.
            FaceCount = br.ReadU16();

            // Read primitive list size.
            ListSize = (ushort)(br.ReadS16() << 5);

            // Read vertex attributes.
            VertexAttributes = (BinBatchAttributes)br.ReadU32();

            // Read UseNormals flag.
            UseNormals = br.Read();

            // Read Position Winding.
            Positions = br.Read();

            // Read UV Count.
            UvCount = br.Read();

            // Read UseNBT flag.
            UseNBT = br.Read();

            // Read Primitive offset.
            PrimitiveOffset = br.ReadU32();

            // Define array to hold Unknown 1 values.
            Unknown1 = new int[2];

            // Loop through Unknown 1 values.
            for (int i = 0; i < 2; i++)
            {
                // Read current Unknown 1 value.
                Unknown1[i] = br.ReadS32();
            }

            // Save the current position.
            long currentPosition = br.Position();

            // Go to the bin batches offset.
            br.Goto(batchesOffset);

            // Sail to the batches's primitive offset.
            br.Sail(PrimitiveOffset);

            // Define list to hold batch's primitives.
            Primitives = new List <BinPrimitive>();

            // Define int to hold amount of faces read.
            int readFaces = 0;

            // Read primitives until batch's face count has been reached.
            while (readFaces < FaceCount && br.Position() < (batchesOffset + PrimitiveOffset + ListSize))
            {
                // Read primitive.
                BinPrimitive binPrimitive = new BinPrimitive(br, UseNBT, UvCount, VertexAttributes);

                // Add the primitive to the batch's primitives.
                Primitives.Add(binPrimitive);

                // Add primitive's face count to the read faces counter.
                readFaces += binPrimitive.FaceCount;
            }

            // Go to the previously saved offset.
            br.Goto(currentPosition);
        }
Exemple #12
0
        public static VirtDirectory LoadRarc(byte[] data)
        {
            if (Yay0.IsCompressed(data))
            {
                data = Yay0.Decompress(data);
            }

            DhBinaryReader br = new DhBinaryReader(data, DhEndian.Big);

            if (br.ReadStr(4) != "RARC")
            {
                throw new InvalidDataException("No valid RARC signature was found!");
            }

            List <RarcNode>  nodes   = new List <RarcNode>();
            List <RarcEntry> entries = new List <RarcEntry>();

            // read header
            // RARC here
            br.Skip(4);
            br.Skip(4);
            var dataOffset = br.ReadU32() + 0x20;

            br.Skip(4);
            br.Skip(4);
            br.Skip(4);
            br.Skip(4);

            // read infoblock
            var NodeCount   = br.ReadU32();
            var NodeOffset  = br.ReadU32() + 0x20;
            var EntryCount  = br.ReadU32();
            var EntryOffset = br.ReadU32() + 0x20;

            br.Skip(4);
            var StringTableOffset = br.ReadU32() + 0x20;

            br.Skip(2);
            br.Skip(2);
            br.Skip(4);

            br.Goto(EntryOffset);

            // read entries
            for (int i = 0; i < EntryCount; i++)
            {
                RarcEntry entry = new RarcEntry()
                {
                    Id         = br.ReadU16(),
                    NameHash   = br.ReadU16(),
                    Type       = br.ReadU16(),
                    NameOffset = br.ReadU16(),
                    DataOffset = br.ReadU32(),
                    DataLength = br.ReadU32()
                };

                if (entry.Type == 0x1100)
                {
                    entry.Data = br.ReadAt(dataOffset + entry.DataOffset, (int)entry.DataLength);
                }
                entry.MemoryPointer = br.ReadU32();
                entry.Name          = br.ReadStrAt(StringTableOffset + entry.NameOffset);

                entries.Add(entry);
            }

            br.Goto(NodeOffset);

            // read nodes
            for (int i = 0; i < NodeCount; i++)
            {
                RarcNode rarcNode = new RarcNode()
                {
                    Id              = br.ReadStr(4),
                    NameOffset      = br.ReadU32(),
                    NameHash        = br.ReadU16(),
                    EntryCount      = br.ReadU16(),
                    FirstEntryIndex = br.ReadU32()
                };

                rarcNode.Name    = br.ReadStrAt(StringTableOffset + rarcNode.NameOffset);
                rarcNode.Entries = entries.GetRange((int)rarcNode.FirstEntryIndex, (int)rarcNode.EntryCount);

                nodes.Add(rarcNode);
            }

            List <VirtDirectory> virtDirectories = new List <VirtDirectory>(nodes.Count);

            foreach (RarcNode rarcNode in nodes)
            {
                virtDirectories.Add(new VirtDirectory(rarcNode.Name, Guid.Empty));
            }

            for (int i = 0; i < nodes.Count; i++)
            {
                RarcNode rarcNode = nodes[i];

                for (int y = 0; y < nodes[i].Entries.Count; y++)
                {
                    if (rarcNode.Entries[y].Name == "." || rarcNode.Entries[y].Name == "..")
                    {
                        continue;
                    }

                    if (rarcNode.Entries[y].Type == (ushort)NodeType.Directory)
                    {
                        var virtDirectory = virtDirectories[(int)rarcNode.Entries[y].DataOffset];
                        virtDirectory.ParentGuid = virtDirectories[i].Guid;
                        virtDirectory.Name       = rarcNode.Entries[y].Name;

                        virtDirectories[i].Children.Add(virtDirectory);
                    }
                    else
                    {
                        VirtFile virtFile = new VirtFile(rarcNode.Entries[y].Name, virtDirectories[i].Guid, rarcNode.Entries[y].Data);
                        virtDirectories[i].Children.Add(virtFile);
                    }
                }
            }

            return(virtDirectories.Count > 0 ? virtDirectories[0] : null);
        }
Exemple #13
0
        /// <summary>
        /// Reads BIN from a stream.
        /// </summary>
        /// <param name="stream">The stream containing the BIN data.</param>
        public BIN(Stream stream)
        {
            // Define a binary reader to read with.
            DhBinaryReader br = new DhBinaryReader(stream, DhEndian.Big);

            // Read bin version.
            Version = br.Read();

            // Make sure the bin version is either 0x01 or 0x02.
            if (Version == 0x00 || Version > 0x02)
            {
                throw new Exception(string.Format("{0} is not a valid bin version!", Version.ToString()));
            }

            // Read bin model name.
            ModelName = br.ReadStr(11).Trim('\0');

            // Define a new list to hold the bin's offsets.
            Offsets = new List <uint>();

            // Loop through the bin's offsets.
            for (int i = 0; i < 21; i++)
            {
                // Read offset and add it to the offsets list.
                Offsets.Add(br.ReadU32());
            }


            // Go to the bin textures offset.
            br.Goto(Offsets[0]);

            // Define a new list to hold the bin's textures.
            Textures = new List <BinTexture>();

            // Loop through bin's textures. TODO: This is static for now, add automatic texture count.
            for (int i = 0; i < 3; i++)
            {
                // Read texture and add it to the textures list.
                Textures.Add(new BinTexture(br, Offsets[0]));
            }


            // Go to the bin materials offset.
            br.Goto(Offsets[1]);

            // Define a new list to hold the bin's materials.
            Materials = new List <BinMaterial>();

            // Loop through bin's materials. TODO: This is static for now, add automatic material count.
            for (int i = 0; i < 3; i++)
            {
                // Read texture and add it to the materials list.
                Materials.Add(new BinMaterial(br));
            }


            // Go to the bin positions offset.
            br.Goto(Offsets[2]);

            // Define a new list to hold the bin's positions.
            Positions = new List <Vector3>();

            // Loop through bin's positions. TODO: Fix this; This is a pretty shitty way to calculate amount of bin positions ...
            for (int i = 0; i < ((Math.Floor((decimal)(Offsets[3] - Offsets[2])) / 6) - 1); i++)
            {
                // Skip 6 bytes to "simulate" reading a bin position.
                br.Skip(6);

                // Make sure the currenet position has not passed the normals offset.
                if (!(br.Position() > Offsets[3]))
                {
                    // Go back 6 bytes as we just "simulated" to read a bin position.
                    br.Goto(br.Position() - 6);

                    // Read a position and add it to the positions list.
                    Positions.Add(new Vector3(br.ReadF16(), br.ReadF16(), br.ReadF16()));
                }
            }


            // Go to the bin normals offset.
            br.Goto(Offsets[3]);

            // Define a new list to hold the bin's normals.
            Normals = new List <Vector3>();

            // Loop through bin's normals. TODO: This is static for now, add automatic normal count.
            for (int i = 0; i < 69; i++)
            {
                // Read a normal and add it to the normals list.
                Normals.Add(new Vector3(br.ReadF32(), br.ReadF32(), br.ReadF32()));
            }


            // Go to the bin texture coordinates offset.
            br.Goto(Offsets[6]);

            // Define a new list to hold the bin's texture coordinates.
            TextureCoordinates = new List <BinTextureCoordinate>();

            // Loop through bin's texture coordinates. TODO: This is static for now, add automatic texture coordinates count.
            for (int i = 0; i < 72; i++)
            {
                // Read a bin texture coordinates and add it to the texture coordinates list.
                TextureCoordinates.Add(new BinTextureCoordinate(br));
            }


            // Go to the bin shaders offset.
            br.Goto(Offsets[10]);

            // Define a new list to hold the bin's shaders.
            Shaders = new List <BinShader>();

            // Loop through bin's shaders. TODO: This is static for now, add automatic shader count.
            for (int i = 0; i < 3; i++)
            {
                // Read a bin shader and add it to the shaders list.
                Shaders.Add(new BinShader(br));
            }


            // Go to the bin batches offset.
            br.Goto(Offsets[11]);

            // Define a new list to hold the bin's batches.
            Batches = new List <BinBatch>();

            // Loop through bin's batches. TODO: This is static for now, add automatic batch count.
            for (int i = 0; i < 2; i++)
            {
                // Read a bin batch and add it to the batches list.
                Batches.Add(new BinBatch(br, Offsets[11]));
            }
        }
Exemple #14
0
        /// <summary>
        /// Read a single graph object from BIN.
        /// </summary>
        /// <param name="br">Binary Reader to use.</param>
        /// <param name="graphObjectOffset">Offset to the graph objects.</param>
        public GraphObject(DhBinaryReader br, uint graphObjectOffset) // 112 bytes long
        {
            // Read Parent Index.
            ParentIndex = br.ReadS16();

            // Read Child Index.
            ChildIndex = br.ReadS16();

            // Read Next Index.
            NextIndex = br.ReadS16();

            // Read Previous Index.
            PreviousIndex = br.ReadS16();

            // Read Render Flags.
            RenderFlags = (GraphObjectRenderFlags)br.ReadU16();

            // Unknown 1. (Padding?)
            Unknown1 = br.ReadU16();

            // Read Scale.
            Scale = br.ReadVec3();

            // Read Rotation.
            Rotation = br.ReadVec3();

            // Read Position
            Position = br.ReadVec3();

            // Read Bounding Box Minimum.
            BoundingBoxMinimum = br.ReadVec3();

            // Read Bounding Box Maximum.
            BoundingBoxMaximum = br.ReadVec3();

            // Read Bounding Sphere Radius.
            BoundingSphereRadius = br.ReadF32();

            // Read Parent Index.
            PartCount = br.ReadS16();

            // Unknown 3. (Padding?)
            Unknown3 = br.ReadU16();

            // Read Parent Index.
            PartOffset = br.ReadS32();

            // Unknown 4. (Padding?)
            Unknown4 = br.ReadU32s(7);

            // Initialize a new list to hold parts.
            Parts = new List <BinGraphObjectPart>();

            // Offset to continue reading from.
            long currentPosition = br.Position();

            // Goto graphobject's parts.
            br.Goto(graphObjectOffset + PartOffset);

            // Loop through parts.
            for (int i = 0; i < PartCount; i++)
            {
                // Read part and add it to the list of parts.
                Parts.Add(new BinGraphObjectPart(br));
            }

            // Go back to return offset we saved earlier.
            br.Goto(currentPosition);
        }
Exemple #15
0
        public MDL(byte[] data)
        {
            // Define a binary reader to read with.
            DhBinaryReader br = new DhBinaryReader(data, DhEndian.Big);

            Header = new MDLHeader(br);

            br.Goto(Header.MatricesOffset);
            Matrices = new Mat4[Header.JointCount + Header.WeightCount];
            for (int i = 0; i < Matrices.Length; i++)
            {
                Matrices[i] = Mat4.Identity;
            }

            for (int i = 0; i < Header.JointCount; i++)
            {
                float[] matrix = br.ReadF32s(12);

                Matrices[i] = new Mat4()
                {
                    Row1 = new Vec4(matrix[0], matrix[1], matrix[2], matrix[3]),
                    Row2 = new Vec4(matrix[4], matrix[5], matrix[6], matrix[7]),
                    Row3 = new Vec4(matrix[8], matrix[9], matrix[10], matrix[11]),
                    Row4 = new Vec4(0, 0, 0, 1),
                };
            }

            br.Goto(Header.PositionOffset);
            Positions = br.ReadVec3s(Header.PositionCount).ToList();

            br.Goto(Header.NormalOffset);
            Normals = br.ReadVec3s(Header.NormalCount).ToList();

            br.Goto(Header.ColorOffset);
            Colors = br.ReadClr4s(Header.ColorCount).ToList();

            br.Goto(Header.TextureCoordinateOffset);
            TextureCoordinates = br.ReadVec2s(Header.TextureCoordinateCount).ToList();

            br.Goto(Header.PacketOffset);
            Packets = new List <MDLShapePacket>();
            for (int i = 0; i < Header.PacketCount; i++)
            {
                Packets.Add(new MDLShapePacket(br));
            }

            br.Goto(Header.ShapeOffset);
            Shapes = new List <MDLShape>();
            for (int i = 0; i < Header.ShapeCount; i++)
            {
                Shapes.Add(new MDLShape(br, Packets));
            }

            foreach (MDLShape shape in Shapes)
            {
                ushort[] matrixIndices = new ushort[10];

                foreach (MDLShapePacket packet in shape.Packets)
                {
                    for (int m = 0; m < packet.MatrixCount; m++)
                    {
                        if (packet.MatrixIndices[m] == ushort.MaxValue)
                        {
                            continue;
                        }
                        matrixIndices[m] = packet.MatrixIndices[m];
                    }

                    DhBinaryReader reader = new DhBinaryReader(packet.Data, DhEndian.Big);

                    while (reader.Position() < packet.DataSize)
                    {
                        ShapePacketData packetData = new ShapePacketData();
                        packetData.PrimitiveType = reader.ReadU8();

                        if (packetData.PrimitiveType == 0x00)
                        {
                            continue;
                        }

                        packetData.VertexCount = reader.ReadU16();
                        for (int i = 0; i < packetData.VertexCount; i++)
                        {
                            MDLVertex vertex = new MDLVertex(reader, Header, shape.UseNbt);
                            if (vertex.MatrixIndex != -1)
                            {
                                vertex.MatrixDataIndex = matrixIndices[(vertex.MatrixIndex / 3)];
                            }
                            packetData.Vertices.Add(vertex);
                        }
                        packet.PacketData.Add(packetData);
                    }
                }
            }

            br.Goto(Header.TextureLocationOffset);
            Textures = new List <BTI>();
            for (int i = 0; i < Header.TextureCount; i++)
            {
                uint offset          = br.ReadU32();
                long currentPosition = br.Position();
                br.Goto(offset);
                BTI bti = new BTI(br, offset, Header.TextureLocationOffset);
                Textures.Add(bti);
                br.Goto(currentPosition);
            }

            br.Goto(Header.SamplerOffset);
            Samplers = new List <MDLSampler>();
            for (int i = 0; i < Header.SamplerCount; i++)
            {
                Samplers.Add(new MDLSampler(br));
            }

            br.Goto(Header.MaterialOffset);
            Materials = new List <MDLMaterial>();
            for (int i = 0; i < Header.MaterialCount; i++)
            {
                Materials.Add(new MDLMaterial(br, Samplers));
            }

            br.Goto(Header.DrawElementOffset);
            DrawElements = new List <MDLDrawElement>();
            for (int i = 0; i < Header.DrawElementCount; i++)
            {
                DrawElements.Add(new MDLDrawElement(br, Materials, Shapes));
            }

            br.Goto(Header.NodeOffset);
            Nodes = new List <MDLNode>();
            for (int i = 0; i < Header.NodeCount; i++)
            {
                Nodes.Add(new MDLNode(br, DrawElements));
            }
        }
Exemple #16
0
        /// <summary>
        /// Reads MP from a stream.
        /// </summary>
        /// <param name="stream">The stream containing the MP data.</param>
        public MP(Stream stream)
        {
            // Define a binary reader to read with.
            DhBinaryReader br = new DhBinaryReader(stream, DhEndian.Big);

            // Read Grid Scale.
            GridScale = new Vector3(br.ReadF32(), br.ReadF32(), br.ReadF32());

            // Read Minimum Bounds.
            MinimumBounds = new Vector3(br.ReadF32(), br.ReadF32(), br.ReadF32());

            // Read Axis Lengths.
            AxisLengths = new Vector3(br.ReadF32(), br.ReadF32(), br.ReadF32());

            // Define new array to hold offsets.
            Offsets = new int[7];

            // Loop through our offsets.
            for (int i = 0; i < 7; i++)
            {
                // Read offset and store it to the offsets array.
                Offsets[i] = br.ReadS32();
            }


            // Go to mp's vertex data offset.
            br.Goto(Offsets[0]);

            // Calculate amount of vertices.
            int verticeCount = (Offsets[1] - Offsets[0]) / 12;

            // Define new list to hold vertices.
            Vertices = new List <Vector3>();

            // Loop through vertices.
            for (int i = 0; i < verticeCount; i++)
            {
                // Read vertex and add it to the vertice list.
                Vertices.Add(new Vector3(br.ReadF32(), br.ReadF32(), br.ReadF32()));
            }


            // Go to mp's normals offset.
            br.Goto(Offsets[1]);

            // Calculate amount of normals.
            int normalCount = (Offsets[2] - Offsets[1]) / 12;

            // Define new list to hold normals.
            Normals = new List <Vector3>();

            // Loop through normals.
            for (int i = 0; i < verticeCount; i++)
            {
                // Read normal and add it to the normal list.
                Normals.Add(new Vector3(br.ReadF32(), br.ReadF32(), br.ReadF32()));
            }


            // Go to mp's triangle data offset.
            br.Goto(Offsets[2]);

            // Calculate amount of normals.
            int triangleDataCount = (Offsets[3] - Offsets[2]) / 24;

            // Define new list to hold normals.
            TriangleData = new List <MpTriangleData>();

            // Loop through normals.
            for (int i = 0; i < triangleDataCount; i++)
            {
                // Read normal and add it to the normal list.
                TriangleData.Add(new MpTriangleData(br));
            }


            // Go to mp's triangle group offset.
            br.Goto(Offsets[3]);

            // TODO: Implement reading Triangle Group data.


            // Go to mp's grid index offset.
            br.Goto(Offsets[4]);

            // Calculate amount of grid index entries.
            int gridIndexCount = (Offsets[4] - Offsets[3]) / 8;

            // Define new list to hold grid indices.
            GridIndices = new List <MpGridIndex>();

            // Loop through grid indices.
            for (int i = 0; i < gridIndexCount; i++)
            {
                // Read grid index and add it to the grid indices list.
                GridIndices.Add(new MpGridIndex(br));
            }


            // Go to mp's unknown offset.
            br.Goto(Offsets[5]);

            // TODO: Implement reading Unknown data.
        }
Exemple #17
0
        /// <summary>
        /// Reads MP from a byte array.
        /// </summary>
        /// <param name="data">The byte array containing the MP data.</param>
        public MP(byte[] data)
        {
            // Define a binary reader to read with.
            DhBinaryReader br = new DhBinaryReader(data, DhEndian.Big);

            // Read Grid Scale.
            GridScale = br.ReadVec3();

            // Read Minimum Bounds.
            MinimumBounds = br.ReadVec3();

            // Read Axis Lengths.
            AxisLengths = br.ReadVec3();

            // Define new array to hold offsets.
            Offsets = new int[7];

            // Loop through our offsets.
            for (int i = 0; i < 7; i++)
            {
                // Read offset and store it to the offsets array.
                Offsets[i] = br.ReadS32();
            }


            // Go to mp's vertex data offset.
            br.Goto(Offsets[0]);

            // Calculate amount of vertices.
            int verticeCount = (Offsets[1] - Offsets[0]) / 12;

            // Define new list to hold vertices.
            Vertices = new List <Vec3>();

            // Loop through vertices.
            for (int i = 0; i < verticeCount; i++)
            {
                // Read vertex and add it to the list of vertices.
                Vertices.Add(br.ReadVec3());
            }


            // Go to mp's normals offset.
            br.Goto(Offsets[1]);

            // Calculate amount of normals.
            int normalCount = (Offsets[2] - Offsets[1]) / 12;

            // Define new list to hold normals.
            Normals = new List <Vec3>();

            // Loop through normals.
            for (int i = 0; i < normalCount; i++)
            {
                // Read normal and add it to the normal list.
                Normals.Add(br.ReadVec3());
            }


            // Go to mp's triangle data offset.
            br.Goto(Offsets[2]);

            // Calculate amount of triangles.
            int triangleDataCount = (Offsets[3] - Offsets[2]) / 24;

            // Define new list to hold triangle data.
            TriangleData = new List <TriangleData>();

            // Loop through triangles.
            for (int i = 0; i < triangleDataCount; i++)
            {
                // Read triangle and add it to the triangle data list.
                TriangleData.Add(new TriangleData(br));
            }


            // Go to mp's triangle group offset.
            br.Goto(Offsets[3]);

            // Define new list to hold triangle groups.
            TriangleGroups = new List <TriangleGroup>();

            // Make sure first ushort is 0xFFFF.
            if (br.ReadU16() != 0xFFFF)
            {
                throw new FormatException("Start of triangle groups section was not 0xFFFF!");
            }

            // We'll read triangle groups as long as we're not entering the next section.
            while (br.Position() < Offsets[4] - 2)
            {
                // Read group and add it to the groups list.
                TriangleGroups.Add(new TriangleGroup(br));
            }

            // Make sure last ushort is 0xFFFF.
            if (br.ReadU16() != 0xFFFF)
            {
                throw new FormatException("End of triangle groups section was not 0xFFFF!");
            }

            // Go to mp's grid index offset.
            br.Goto(Offsets[4]);

            // Calculate amount of grid index entries. (Offset 5 is a duplicate of offset 4)
            int gridIndexCount = (Offsets[6] - Offsets[4]) / 8;

            // Define new list to hold grid indices.
            GridIndices = new List <GridIndex>();

            // Loop through grid indices.
            for (int i = 0; i < gridIndexCount; i++)
            {
                GridIndices.Add(new GridIndex(br));
            }


            // Go to mp's unknown offset.
            br.Goto(Offsets[6]);

            // Define new list to hold unknown data.
            Unknowns = new List <Unknown>();

            // We'll read unknowns as long as we're not reading padding EOF.
            while (br.Position() < br.GetStream().Length)
            {
                // Check if next byte is 0xFF. (More data)
                if (br.Read() == 0xFF)
                {
                    // Jump back a byte, since we checked for data.
                    br.Sail(-1);

                    // Read unknown and add it to the unknowns list.
                    Unknowns.Add(new Unknown(br));
                }
                else
                {
                    // We've reached padding, stop reading.
                    break;
                }
            }
        }