/// <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])); } } }
/// <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])); } }