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