Example #1
0
            public DataSet(PakFile Pak, PakFile.PakTag Item)
            {
                var reader = Pak.Reader;

                var count = reader.ReadInt32();
                if (count == 0) return;

                for (int i = 0; i < count; i++)
                    unkS0.Add(new struct0(Pak, Item));

                unk0 = reader.ReadInt32(); //total faces

                MinBound = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

                unkf0 = reader.ReadSingle();
                DataLength = reader.ReadInt32();

                reader.ReadBytes(DataLength); //unmapped
            }
Example #2
0
        public VertexValue(XmlNode Node, EndianReader reader)
        {
            if (Convert.ToInt32(Node.Attributes["stream"].Value) > 0) throw new NotSupportedException("Multi-streamed vertices not supported");
            Type = (ValueType)Enum.Parse(typeof(ValueType), Node.Attributes["type"].Value);
            Usage = Node.Attributes["usage"].Value;
            UsageIndex = Convert.ToInt32(Node.Attributes["usageIndex"].Value);
            
            switch (Type)
            {
                case ValueType.Float32_2:
                    Data = new Vector(reader.ReadSingle(), reader.ReadSingle());
                    break;

                case ValueType.Float32_3:
                    Data = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                    break;

                case ValueType.Float32_4:
                    Data = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                    break;

                case ValueType.Int8_N4:
                    Data = new Vector((float)reader.ReadByte() / (float)0x7F, (float)reader.ReadByte() / (float)0x7F, (float)reader.ReadByte() / (float)0x7F, (float)reader.ReadByte() / (float)0x7F);
                    break;

                case ValueType.UInt8_2:
                    Data = new Vector(reader.ReadByte(), reader.ReadByte(), 0, 0);
                    break;

                case ValueType.UInt8_3:
                    Data = new Vector(reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), 0);
                    break;

                case ValueType.UInt8_4:
                    Data = Vector.FromUByte4(reader.ReadUInt32());
                    break;

                case ValueType.UInt8_N2:
                    Data = new Vector((float)reader.ReadByte() / (float)0xFF, (float)reader.ReadByte() / (float)0xFF, 0, 0);
                    break;

                case ValueType.UInt8_N3:
                    Data = new Vector((float)reader.ReadByte() / (float)0xFF, (float)reader.ReadByte() / (float)0xFF, (float)reader.ReadByte() / (float)0xFF, 0);
                    break;

                case ValueType.UInt8_N4:
                    Data = Vector.FromUByteN4(reader.ReadUInt32());
                    break;

                case ValueType.Int16_N3:
                    Data = new Vector(((float)reader.ReadInt16() + (float)0x7FFF) / (float)0xFFFF, ((float)reader.ReadInt16() + (float)0x7FFF) / (float)0xFFFF, ((float)reader.ReadInt16() + (float)0x7FFF) / (float)0xFFFF, 0);
                    break;

                case ValueType.Int16_N4:
                    Data = new Vector(((float)reader.ReadInt16() + (float)0x7FFF) / (float)0xFFFF, ((float)reader.ReadInt16() + (float)0x7FFF) / (float)0xFFFF, ((float)reader.ReadInt16() + (float)0x7FFF) / (float)0xFFFF, ((float)reader.ReadInt16() + (float)0x7FFF) / (float)0xFFFF);
                    break;

                case ValueType.UInt16_2:
                    Data = new Vector(reader.ReadUInt16(), reader.ReadUInt16());
                    break;

                case ValueType.UInt16_4:
                    Data = new Vector(reader.ReadUInt16(), reader.ReadUInt16(), reader.ReadUInt16(), reader.ReadUInt16());
                    break;

                case ValueType.UInt16_N2:
                    Data = new Vector((float)reader.ReadUInt16() / (float)0xFFFF, (float)reader.ReadUInt16() / (float)0xFFFF);
                    break;

                case ValueType.UInt16_N4:
                    Data = new Vector((float)reader.ReadUInt16() / (float)0xFFFF, (float)reader.ReadUInt16() / (float)0xFFFF, (float)reader.ReadUInt16() / (float)0xFFFF, (float)reader.ReadUInt16() / (float)0xFFFF);
                    break;

                case ValueType.DecN4:
                    Data = Vector.FromDecN4(reader.ReadUInt32());
                    break;

                case ValueType.UDecN4:
                    Data = Vector.FromUDecN4(reader.ReadUInt32());
                    break;

                case ValueType.DHenN3:
                    Data = Vector.FromDHenN3(reader.ReadUInt32());
                    break;

                case ValueType.UDHenN3:
                    Data = Vector.FromUDHenN3(reader.ReadUInt32());
                    break;

                case ValueType.HenDN3:
                    Data = Vector.FromHenDN3(reader.ReadUInt32());
                    break;

                case ValueType.UHenDN3:
                    Data = Vector.FromUHenDN3(reader.ReadUInt32());
                    break;

                case ValueType.Float16_2:
                    Data = new Vector(Half.ToHalf(reader.ReadUInt16()), Half.ToHalf(reader.ReadUInt16()));
                    break;

                case ValueType.Float16_4:
                    Data = new Vector(Half.ToHalf(reader.ReadUInt16()), Half.ToHalf(reader.ReadUInt16()), Half.ToHalf(reader.ReadUInt16()), Half.ToHalf(reader.ReadUInt16()));
                    break;

                case ValueType.D3DColour:
                    reader.ReadUInt32();
                    break;
            }
        }
Example #3
0
 public VertexValue(Vector Data, ValueType Type, string Usage, int UsageIndex)
 {
     this.Data = Data;
     this.Type = Type;
     this.Usage = Usage;
     this.UsageIndex = UsageIndex;
 }
Example #4
0
                public Sprite(CacheBase Cache, int Address)
                {
                    EndianReader Reader = Cache.Reader;
                    Reader.SeekTo(Address);

                    SubmapIndex = Reader.ReadInt16();
                    Reader.ReadInt16();
                    Reader.ReadInt32();
                    Left = Reader.ReadSingle();
                    Right = Reader.ReadSingle();
                    Top = Reader.ReadSingle();
                    Bottom = Reader.ReadSingle();
                    RegPoint = new Vector(
                        Reader.ReadSingle(),
                        Reader.ReadSingle());
                }
Example #5
0
            public Node(CacheBase Cache, int Address)
            {
                EndianReader Reader = Cache.Reader;
                Reader.SeekTo(Address);

                Name = Cache.Strings.GetItemByID(Reader.ReadInt32());
                ParentIndex = Reader.ReadInt16();
                FirstChildIndex = Reader.ReadInt16();
                NextSiblingIndex = Reader.ReadInt16();
                Reader.ReadInt16();
                Position = new Vector(
                    Reader.ReadSingle(),
                    Reader.ReadSingle(),
                    Reader.ReadSingle());
                Rotation = new Vector(
                    Reader.ReadSingle(),
                    Reader.ReadSingle(),
                    Reader.ReadSingle(),
                    Reader.ReadSingle());

                TransformScale = Reader.ReadSingle();

                TransformMatrix = Matrix4x3.Read(Reader);

                DistanceFromParent = Reader.ReadSingle();
            }
Example #6
0
        public override void LoadRaw()
        {
            if (RawLoaded) return;

            var bb = BoundingBoxes[0];
            var IH = (Halo1PC.CacheFile.CacheIndexHeader)cache.IndexHeader;
            var reader = cache.Reader;

            for (int i = 0; i < ModelSections.Count; i++)
            {
                var section = ModelSections[i];

                List<int> tIndices = new List<int>();
                List<Vertex> tVertices = new List<Vertex>();

                for (int j = 0; j < section.Submeshes.Count; j++)
                {
                    var submesh = (Halo1PC.gbxmodel.ModelSection.Submesh)section.Submeshes[j];

                    #region Read Indices
                    submesh.FaceIndex = tIndices.Count;
                    var strip = new List<int>();

                    reader.SeekTo(submesh.FaceOffset + IH.vertDataOffset + IH.indexDataOffset);
                    for (int k = 0; k < submesh.FaceCount; k++)
                        strip.Add(reader.ReadUInt16() + tVertices.Count);

                    strip = ModelFunctions.GetTriangleList(strip.ToArray(), 0, strip.Count, 5);
                    strip.Reverse();
                    submesh.FaceCount = strip.Count;
                    tIndices.AddRange(strip);
                    #endregion

                    #region Read Vertices
                    reader.SeekTo(submesh.VertOffset + IH.vertDataOffset);
                    for (int k = 0; k < submesh.VertexCount; k++)
                    {
                        var v = new Vertex() { FormatName = "Halo1PC_Skinned" };
                        var position = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        var normal = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        var binormal = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        var tangent = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        var texcoord = new Vector(reader.ReadSingle() * uScale, 1f - reader.ReadSingle() * vScale);
                        var nodes = (Flags.Values[1]) ?
                            new Vector(submesh.LocalNodes[reader.ReadInt16()], submesh.LocalNodes[reader.ReadInt16()], 0, 0) :
                            new Vector(reader.ReadInt16(), reader.ReadInt16(), 0, 0);
                        var weights = new Vector(reader.ReadSingle(), reader.ReadSingle(), 0, 0);

                        v.Values.Add(new VertexValue(position, VertexValue.ValueType.Float32_3, "position", 0));
                        v.Values.Add(new VertexValue(normal, VertexValue.ValueType.Float32_3, "normal", 0));
                        v.Values.Add(new VertexValue(binormal, VertexValue.ValueType.Float32_3, "binormal", 0));
                        v.Values.Add(new VertexValue(tangent, VertexValue.ValueType.Float32_3, "tangent", 0));
                        v.Values.Add(new VertexValue(texcoord, VertexValue.ValueType.Float32_2, "texcoords", 0));
                        v.Values.Add(new VertexValue(nodes, VertexValue.ValueType.Int16_N2, "blendindices", 0));
                        v.Values.Add(new VertexValue(weights, VertexValue.ValueType.Float32_2, "blendweight", 0));

                        tVertices.Add(v);

                        bb.XBounds = new Range<float>(
                            Math.Min(bb.XBounds.Min, position.X),
                            Math.Max(bb.XBounds.Max, position.X));

                        bb.YBounds = new Range<float>(
                            Math.Min(bb.YBounds.Min, position.Y),
                            Math.Max(bb.YBounds.Max, position.Y));

                        bb.ZBounds = new Range<float>(
                            Math.Min(bb.ZBounds.Min, position.Z),
                            Math.Max(bb.ZBounds.Max, position.Z));
                    }
                    #endregion
                }

                section.Indices = tIndices.ToArray();
                section.Vertices = tVertices.ToArray();

                IndexInfoList.Add(new IndexBufferInfo() { FaceFormat = 3 });
                VertInfoList.Add(new VertexBufferInfo() { VertexCount = section.TotalVertexCount });
            }

            RawLoaded = true;
        }
Example #7
0
            public Node(CacheBase Cache, int Address)
            {
                EndianReader Reader = Cache.Reader;
                Reader.SeekTo(Address);

                Name = Reader.ReadNullTerminatedString(32);
                NextSiblingIndex = Reader.ReadInt16();
                FirstChildIndex = Reader.ReadInt16();
                ParentIndex = Reader.ReadInt16();
                Reader.ReadInt16();
                Position = new Vector(
                    Reader.ReadSingle(),
                    Reader.ReadSingle(),
                    Reader.ReadSingle());
                Rotation = new Vector(
                    -Reader.ReadSingle(),
                    -Reader.ReadSingle(),
                    -Reader.ReadSingle(),
                    Reader.ReadSingle());

                DistanceFromParent = Reader.ReadSingle();
            }
Example #8
0
                public Marker(CacheBase Cache, int Address)
                {
                    EndianReader Reader = Cache.Reader;
                    Reader.SeekTo(Address);

                    RegionIndex = Reader.ReadByte();
                    PermutationIndex = Reader.ReadByte();
                    NodeIndex = Reader.ReadByte();
                    Reader.ReadByte();
                    Position = new Vector(
                        Reader.ReadSingle(),
                        Reader.ReadSingle(),
                        Reader.ReadSingle());
                    Rotation = new Vector(
                        -Reader.ReadSingle(),
                        -Reader.ReadSingle(),
                        -Reader.ReadSingle(),
                        Reader.ReadSingle());
                }
Example #9
0
        public static Matrix4x3 FromBounds(Vector min, Vector max)
        {
            var bbXLength = max.X - min.X;
            var bbYLength = max.Y - min.Y;
            var bbZLength = max.Z - min.Z;

            return new Matrix4x3(
                bbXLength != 0.0f ? bbXLength : 1.0f, 0.0f, 0.0f,
                0.0f, bbYLength != 0.0f ? bbYLength : 1.0f, 0.0f,
                0.0f, 0.0f, bbZLength != 0.0f ? bbZLength : 1.0f,
                bbXLength, bbYLength, bbZLength);
        }
        public override void LoadRaw()
        {
            if (RawLoaded) return;

            var reader = cache.Reader;

            #region Read Indices
            int[] indices = new int[indexCount];
            reader.SeekTo(indexOffset);
            for (int i = 0; i < indexCount; i++)
                indices[i] = reader.ReadUInt16();
            #endregion

            for (int i = 0; i < ModelSections.Count; i++)
            {
                var section = ModelSections[i];
                var tempVerts = new List<Vertex>();

                if (section.Submeshes.Count == 0) continue;

                #region Read Vertices
                for (int j = 0; j < section.Submeshes.Count; j++)
                {
                    var mesh = (Lightmap.Material)section.Submeshes[j];

                    reader.SeekTo(mesh.vertsOffset);
                    for (int k = 0; k < mesh.VertexCount; k++)
                    {
                        var v = new Vertex() { FormatName = "Halo1PC_World" };
                        var position = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        var normal = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        var binormal = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        var tangent = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        var texcoord = new Vector(reader.ReadSingle(), 1f - reader.ReadSingle());

                        v.Values.Add(new VertexValue(position, VertexValue.ValueType.Float32_3, "position", 0));
                        v.Values.Add(new VertexValue(normal, VertexValue.ValueType.Float32_3, "normal", 0));
                        v.Values.Add(new VertexValue(binormal, VertexValue.ValueType.Float32_3, "binormal", 0));
                        v.Values.Add(new VertexValue(tangent, VertexValue.ValueType.Float32_3, "tangent", 0));
                        v.Values.Add(new VertexValue(texcoord, VertexValue.ValueType.Float32_2, "texcoords", 0));

                        tempVerts.Add(v);
                    }
                }
                #endregion

                #region Copy & Translate Indices
                int offset = section.Submeshes[0].FaceIndex;
                section.Indices = new int[section.TotalFaceCount];
                Array.Copy(indices, offset, section.Indices, 0, section.TotalFaceCount);
                section.Vertices = tempVerts.ToArray();

                int pos = 0;
                for (int j = 0; j < section.Submeshes.Count; j++)
                {
                    var mesh = section.Submeshes[j];
                    mesh.FaceIndex -= offset;

                    for (int k = 0; k < mesh.FaceCount; k++)
                        section.Indices[k + mesh.FaceIndex] += pos;

                    Array.Reverse(section.Indices, mesh.FaceIndex, mesh.FaceCount);
                    pos += mesh.VertexCount;
                }
                #endregion

                IndexInfoList.Add(new mode.IndexBufferInfo() { FaceFormat = 3 });
                VertInfoList.Add(new mode.VertexBufferInfo() { VertexCount = section.TotalVertexCount });
            }

            RawLoaded = true;
        }
Example #11
0
        public UVDataBlock_3001(EndianReader reader, bool loadMesh, Vertex[] Vertices)
            : base(reader, 0x3001)
        {
            DataCount = reader.ReadInt32(); //vCount

            x2E00 = reader.ReadInt16(); //2E00
            reader.Format = EndianFormat.Big;

            unkUV0 = reader.ReadInt16(); //flags? 0x1C00 when world
            unkUV1 = reader.ReadByte();
            unkUV2 = reader.ReadByte();
            unkUV3 = reader.ReadByte();
            unkUV4 = reader.ReadByte(); //0x00 when world, else 0x20
            DataSize = reader.ReadByte();

            if (!loadMesh) reader.SeekTo(EOBOffset);
            else for (int i = 0; i < DataCount; i++)
            {
                Vector tex0 = new Vector();

                #region switch
                switch (DataSize)
                {
                    case 8:
                        tex0 = Vector.FromUByteN4(reader.ReadUInt32());
                        reader.Skip(0);
                        break;
                    case 12:
                        reader.Skip(4);
                        break;
                    case 16:
                        reader.Skip(12);
                        break;
                    case 20:
                        reader.Skip(16);
                        break;
                    case 24:
                        reader.Skip(16);
                        break;
                    case 28:
                        reader.Skip(20);
                        break;
                    case 32:
                        reader.Skip(16);
                        break;
                    case 36:
                        reader.Skip(24);
                        break;
                    case 44:
                        reader.Skip(28);
                        break;
                }
                #endregion

                int u = reader.ReadInt16();
                int v = reader.ReadInt16();

                //var tex0 = new RealQuat(((float)a + (float)0) / (float)0xFFFF, ((float)b + (float)0) / (float)0xFFFF);
                var tex1 = new Vector((float)u / (float)(0x7FFF), (float)v / (float)(0x7FFF));

                #region switch
                switch (DataSize)
                {
                    case 8:
                        reader.Skip(0);
                        break;
                    case 12:
                        reader.Skip(4);
                        break;
                    case 16:
                        reader.Skip(0);
                        break;
                    case 20:
                        reader.Skip(0);
                        break;
                    case 24:
                        reader.Skip(4);
                        break;
                    case 28:
                        reader.Skip(4);
                        break;
                    case 32:
                        reader.Skip(12);
                        break;
                    case 36:
                        reader.Skip(8);
                        break;
                    case 44:
                        reader.Skip(12);
                        break;
                }
                #endregion

                //Vertices[i].Values.Add(new VertexValue(tex0, 0, "normal", 0));
                Vertices[i].Values.Add(new VertexValue(tex1, VertexValue.ValueType.Int16_N2, "texcoords", 0));
            }

            reader.Format = EndianFormat.Little;
        }
Example #12
0
        public Vector Data; //relative position coords

        #endregion Fields

        #region Constructors

        public PosBlock_FA02(EndianReader reader)
            : base(reader, 0xFA02)
        {
            Data = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
        }
Example #13
0
        public int DataCount; //always 1

        #endregion Fields

        #region Constructors

        public BoundsBlock_1D01(EndianReader reader)
            : base(reader, 0x1D01)
        {
            DataCount = reader.ReadInt32();
            var min = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
            var max = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

            Data.XBounds = new Range<float>(min.X, max.X);
            Data.YBounds = new Range<float>(min.Y, max.Y);
            Data.ZBounds = new Range<float>(min.Z, max.Z);
        }
Example #14
0
        public Block_2002(EndianReader reader)
            : base(reader, 0x2002)
        {
            unk0 = reader.ReadInt32(); // ]
            unk1 = reader.ReadInt32(); // ] unknown purpose, often all 60
            unk2 = reader.ReadInt32(); // ]

            var min = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
            var max = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
            Bounds = new BoundingBox()
            {
                XBounds = new Range<float>(min.X, max.X),
                YBounds = new Range<float>(min.Y, max.Y),
                ZBounds = new Range<float>(min.Z, max.Z),
            };
            unkPos0 = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
        }
Example #15
0
        public VertexBlock_F100(EndianReader reader, bool loadMesh, int geomUnk01)
            : base(reader, 0xF100)
        {
            DataCount = reader.ReadInt32();
            Data = new Vertex[DataCount];
            if (DataCount == 0) return;

            if (geomUnk01 != 134 && geomUnk01 != 142)
            {
                CentreX = reader.ReadInt16();
                CentreY = reader.ReadInt16();
                CentreZ = reader.ReadInt16();
                RadiusX = reader.ReadInt16();
                RadiusY = reader.ReadInt16();
                RadiusZ = reader.ReadInt16();
            }

            if (!loadMesh) reader.SeekTo(EOBOffset);
            else for (int i = 0; i < DataCount; i++)
            {
                Vertex v;

                if (geomUnk01 == 134 || geomUnk01 == 142)
                {
                    v = new Vertex() { FormatName = "S3D_World" };
                    var data = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                    v.Values.Add(new VertexValue(data, VertexValue.ValueType.Float32_3, "position", 0));
                }
                else
                {
                    v = new Vertex() { FormatName = "S3D_Compressed" };
                    var data = new Vector(reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16());
                    v.Values.Add(new VertexValue(data, VertexValue.ValueType.Int16_N4, "position", 0));
                }
                Data[i] = v;
            }
        }
Example #16
0
        public Template(PakFile Pak, PakFile.PakTag Item, bool loadMesh)
        {
            var reader = Pak.Reader;
            reader.Format = EndianFormat.Little;
            reader.Origin = Item.Offset;
            reader.SeekTo(0);

            reader.ReadInt16(); //E402
            reader.ReadInt32(); //filesize (EOB offset?)

            #region Block E502
            reader.ReadInt16(); //E502
            reader.ReadInt32(); //EOB offset
            reader.ReadInt32(); //LPTA (probs part of the string)
            Name = reader.ReadNullTerminatedString();
            reader.ReadByte(); //00
            #endregion

            #region Block 1603
            reader.ReadInt16(); //1603
            reader.ReadInt32(); //EOB offset
            reader.ReadBytes(3); //02 01 01
            #endregion

            #region Block 5501
            reader.ReadInt16(); //5501
            reader.ReadInt32(); //address

            int count = reader.ReadInt32();
            Materials = new List<MatRefBlock_5601>();
            for (int i = 0; i < count; i++)
                Materials.Add(new MatRefBlock_5601(reader));
            #endregion

            reader.ReadInt16(); //0100
            reader.ReadInt32(); //address

            #region Block F000
            xF000 = reader.ReadInt16();
            reader.ReadInt32(); //EOB offset
            x2C01 = reader.ReadInt16();
            reader.ReadInt32(); //EOB offset

            count = reader.ReadInt32();
            Objects = new List<Node>();
            for (int i = 0; i < count; i++)
                Objects.Add(new Node(reader, loadMesh));

            foreach (var obj in Objects)
                if (obj.isInheritor)
                    Objects[obj._2901.InheritID].isInherited = true;
            #endregion

            reader.ReadInt16(); //0100
            reader.ReadInt32(); //address

            #region Block E802
            reader.ReadInt16(); //E802
            reader.ReadInt32(); //address

            count = reader.ReadInt32();
            for (int i = 0; i < count; i++)
                Bones.Add(new BoneBlock_E902(reader));
            #endregion

            //havent mapped this block, assumed anim/sound related
            _E602 = new unkBlock_XXXX(reader, 0xE602);

            reader.ReadInt16(); //0100
            reader.ReadInt32(); //address

            if (reader.PeekUInt16() == 0xBA01)
                unkStrBlk = new StringBlock_BA01(reader);

            //contains data count, havent seen used
            _1D02 = new unkBlock_XXXX(reader, 0x1D02);

            //int16 count, [int16, int16] * count
            if (reader.PeekUInt16() == 0x1103)
                _1103 = new unkBlock_XXXX(reader, 0x1103);

            //contains null term string, used on IGA models
            _0403 = new unkBlock_XXXX(reader, 0x0403);

            if (reader.PeekUInt16() == 0x0503)
                _0503 = new Block_0503(reader);

            #region Block 0803
            reader.ReadInt16(); //0803
            reader.ReadInt32(); //address to end of bounds values
            reader.ReadInt32(); //bounds count?
            var min = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
            var max = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

            RenderBounds = new BoundingBox();
            RenderBounds.XBounds = new Range<float>(min.X, max.X);
            RenderBounds.YBounds = new Range<float>(min.Y, max.Y);
            RenderBounds.ZBounds = new Range<float>(min.Z, max.Z);
            #endregion

            _0E03 = new Block_0E03(reader);

            //contains length prefixed string
            if (reader.PeekUInt16() == 0x1203)
                _1203 = new unkBlock_XXXX(reader, 0x1203);

            reader.ReadInt16(); //0100
            reader.ReadInt32(); //address to EOF

            reader.Origin = 0;
        }