Exemplo n.º 1
0
        public sealed override void StreamReadData(BinaryReader instream, SectionHeader section)
        {
            this.id   = section.id;
            this.size = section.size;
            uint[] numArray = new uint[9]
            {
                0U,
                4U,
                8U,
                12U,
                16U,
                4U,
                4U,
                8U,
                12U
            };
            this.vert_count   = instream.ReadUInt32();
            this.header_count = instream.ReadUInt32();
            uint num = 0;

            for (int index = 0; (long)index < (long)this.header_count; ++index)
            {
                GeometryHeader geometryHeader = new GeometryHeader();
                geometryHeader.item_size = instream.ReadUInt32();
                geometryHeader.item_type = instream.ReadUInt32();
                num += numArray[(int)geometryHeader.item_size];
                this.headers.Add(geometryHeader);
            }

            this.geometry_size = this.vert_count * num;
            foreach (GeometryHeader header in this.headers)
            {
                if (header.item_type == 1U)
                {
                    for (int index = 0; (long)index < (long)this.vert_count; ++index)
                    {
                        this.verts.Add(new Vector3D()
                        {
                            X = instream.ReadSingle(),
                            Y = instream.ReadSingle(),
                            Z = instream.ReadSingle()
                        });
                    }
                }
                else if (header.item_type == 7U)
                {
                    for (int index = 0; (long)index < (long)this.vert_count; ++index)
                    {
                        this.uvs.Add(new Vector2D()
                        {
                            X = instream.ReadSingle(),
                            Y = -instream.ReadSingle()
                        });
                    }
                }
                else if (header.item_type == 2U)
                {
                    for (int index = 0; (long)index < (long)this.vert_count; ++index)
                    {
                        this.normals.Add(new Vector3D()
                        {
                            X = instream.ReadSingle(),
                            Y = instream.ReadSingle(),
                            Z = instream.ReadSingle()
                        });
                    }
                }
                else if (header.item_type == 8U)
                {
                    for (int index = 0; (long)index < (long)this.vert_count; ++index)
                    {
                        this.pattern_uvs.Add(new Vector2D()
                        {
                            X = instream.ReadSingle(),
                            Y = instream.ReadSingle()
                        });
                    }
                }
                else if (header.item_type == 5U)
                {
                    for (int index = 0; (long)index < (long)this.vert_count; ++index)
                    {
                        this.vertex_colors.Add(new GeometryColor(instream));
                    }
                }
                else if (header.item_type == 20U)
                {
                    for (int index = 0; (long)index < (long)this.vert_count; ++index)
                    {
                        this.unknown20.Add(new Vector3D()
                        {
                            X = instream.ReadSingle(),
                            Y = instream.ReadSingle(),
                            Z = instream.ReadSingle()
                        });
                    }
                }
                else if (header.item_type == 21U)
                {
                    for (int index = 0; (long)index < (long)this.vert_count; ++index)
                    {
                        this.unknown21.Add(new Vector3D()
                        {
                            X = instream.ReadSingle(),
                            Y = instream.ReadSingle(),
                            Z = instream.ReadSingle()
                        });
                    }
                }
                else if (header.item_type == 15U)
                {
                    for (int index = 0; (long)index < (long)this.vert_count; ++index)
                    {
                        this.weight_groups.Add(new GeometryWeightGroups(instream));
                    }
                }
                else if (header.item_type == 17U)
                {
                    for (int index = 0; (long)index < (long)this.vert_count; ++index)
                    {
                        this.weights.Add(new Vector3D()
                        {
                            X = instream.ReadSingle(),
                            Y = instream.ReadSingle(),
                            Z = instream.ReadSingle()
                        });
                    }
                }
                else
                {
                    this.unknown_item_data.Add(
                        instream.ReadBytes((int)numArray[header.item_size] * (int)this.vert_count));
                }
            }

            this.hashname       = instream.ReadUInt64();
            this.remaining_data = (byte[])null;
            if (section.offset + 12L + (long)section.size <= instream.BaseStream.Position)
            {
                return;
            }
            this.remaining_data =
                instream.ReadBytes((int)(section.offset + 12L + (long)section.size - instream.BaseStream.Position));
        }
Exemplo n.º 2
0
        public Geometry(BinaryReader instream, SectionHeader section) : this()
        {
            this.SectionId = section.id;
            // Count of everysingle item in headers (Verts, Normals, UVs, UVs for normalmap, Colors, Unknown 20, Unknown 21, etc)
            this.vert_count = instream.ReadUInt32();
            //Count of all headers for items in this section
            uint   header_count = instream.ReadUInt32();
            UInt32 calc_size    = 0;

            for (int x = 0; x < header_count; x++)
            {
                GeometryHeader header = new GeometryHeader();
                header.ItemSize = instream.ReadUInt32();
                header.ItemType = (GeometryChannelTypes)instream.ReadUInt32();
                calc_size      += header.ItemSizeBytes;
                this.Headers.Add(header);
            }

            foreach (GeometryHeader head in this.Headers)
            {
                //Console.WriteLine("Header type: " + head.item_type + " Size: " + head.item_size);
                if (head.ItemType == GeometryChannelTypes.POSITION)
                {
                    verts.Capacity = (int)vert_count + 1;
                    for (int x = 0; x < this.vert_count; x++)
                    {
                        Vector3 vert = new Vector3();
                        vert.X = instream.ReadSingle();
                        vert.Y = instream.ReadSingle();
                        vert.Z = instream.ReadSingle();

                        this.verts.Add(vert);
                    }
                }
                else if (head.ItemType == GeometryChannelTypes.NORMAL)
                {
                    normals.Capacity = (int)vert_count + 1;
                    for (int x = 0; x < this.vert_count; x++)
                    {
                        Vector3 norm = new Vector3();
                        norm.X = instream.ReadSingle();
                        norm.Y = instream.ReadSingle();
                        norm.Z = instream.ReadSingle();
                        this.normals.Add(norm);
                    }
                }
                else if (head.ItemType == GeometryChannelTypes.COLOR0)
                {
                    vertex_colors.Capacity = (int)vert_count + 1;
                    for (int x = 0; x < this.vert_count; x++)
                    {
                        this.vertex_colors.Add(new GeometryColor(instream));
                    }
                }
                //Below is unknown data

                else if (head.ItemType == GeometryChannelTypes.BINORMAL0)
                {
                    binormals.Capacity = (int)vert_count + 1;
                    for (int x = 0; x < this.vert_count; x++)
                    {
                        Vector3 binormal_entry = new Vector3();
                        binormal_entry.X = instream.ReadSingle();
                        binormal_entry.Y = instream.ReadSingle();
                        binormal_entry.Z = instream.ReadSingle();
                        this.binormals.Add(binormal_entry);
                    }
                }
                else if (head.ItemType == GeometryChannelTypes.TANGENT0)
                {
                    tangents.Capacity = (int)vert_count + 1;
                    for (int x = 0; x < this.vert_count; x++)
                    {
                        Vector3 tangent_entry = new Vector3();
                        tangent_entry.X = instream.ReadSingle();
                        tangent_entry.Y = instream.ReadSingle();
                        tangent_entry.Z = instream.ReadSingle();
                        this.tangents.Add(tangent_entry);
                    }
                }

                //Weight Groups
                else if (head.ItemType == GeometryChannelTypes.BLENDINDICES0)
                {
                    weight_groups.Capacity = (int)vert_count + 1;
                    for (int x = 0; x < this.vert_count; x++)
                    {
                        GeometryWeightGroups unknown_15_entry = new GeometryWeightGroups(instream);
                        this.weight_groups.Add(unknown_15_entry);
                    }
                }

                //Weights
                else if (head.ItemType == GeometryChannelTypes.BLENDWEIGHT0)
                {
                    if (head.ItemSize == 4)
                    {
                        Log.Default.Warn("Section {0} has four weights", this.SectionId);
                    }

                    weights.Capacity = (int)vert_count + 1;
                    for (int x = 0; x < this.vert_count; x++)
                    {
                        Vector3 unknown_17_entry = new Vector3();
                        unknown_17_entry.X = instream.ReadSingle();
                        unknown_17_entry.Y = instream.ReadSingle();
                        if (head.ItemSize == 3)
                        {
                            unknown_17_entry.Z = instream.ReadSingle();
                        }
                        else if (head.ItemSize == 4)
                        {
                            unknown_17_entry.Z = instream.ReadSingle();
                            var tmp = instream.ReadSingle();
                            if (tmp != 0)
                            {
                                Log.Default.Warn("Nonzero fourth weight in {0} vtx {1} (is {2})", this.SectionId, x, tmp);
                            }
                        }
                        else if (head.ItemSize != 2)
                        {
                            throw new Exception("Bad BLENDWEIGHT0 item size " + head.ItemSize);
                        }
                        this.weights.Add(unknown_17_entry);
                    }
                }
                else if (head.ItemType >= GeometryChannelTypes.TEXCOORD0 &&
                         head.ItemType <= GeometryChannelTypes.TEXCOORD7)
                {
                    int idx = head.ItemType - GeometryChannelTypes.TEXCOORD0;
                    for (int x = 0; x < vert_count; x++)
                    {
                        // Previously, the Y was only inverted on the TEXCOORD0 channel, and
                        // not on the TEXCOORD1 channel. I assume that was incorrect, TODO check?
                        Vector2 uv = new Vector2 {
                            X = instream.ReadSingle(), Y = -instream.ReadSingle()
                        };
                        UVs[idx].Add(uv);
                    }
                }
                else
                {
                    this.unknown_item_data.Add(
                        instream.ReadBytes((int)(head.ItemSizeBytes * this.vert_count)));
                }
            }

            this.HashName = new HashName(instream.ReadUInt64());

            this.remaining_data = null;
            long sect_end = section.offset + 12 + section.size;

            if (sect_end > instream.BaseStream.Position)
            {
                // If exists, this contains hashed name for this geometry (see hashlist.txt)
                remaining_data = instream.ReadBytes((int)(sect_end - instream.BaseStream.Position));
            }
        }