private static void UpdateGEOS(BinaryReader br, BinaryWriter bw, int size) { Console.WriteLine("'Fixing' GEOS"); // write the header and record the chunk size offset bw.Write((uint)Chunks.GEOS); long offset = bw.BaseStream.Position; bw.Write(0); long end = br.BaseStream.Position + size; while (br.BaseStream.Position < end) { using (var substream = new SubStream()) { long sectionEnd = br.BaseStream.Position + br.ReadInt32(); substream.Write(0); // inclusive size int vertexCount = 0; long gndxOffset = 0; int noOf = 0; if (br.HasTag("VRTX")) { vertexCount = noOf = br.ReadInt32(); br.BaseStream.Position -= 8; substream.Write(br.ReadBytes(8 + 12 * noOf)); } if (br.HasTag("NRMS")) { noOf = br.ReadInt32(); br.BaseStream.Position -= 8; substream.Write(br.ReadBytes(8 + 12 * noOf)); } if (br.HasTag("PTYP")) { noOf = br.ReadInt32(); br.BaseStream.Position -= 8; substream.Write(br.ReadBytes(8 + 4 * noOf)); } if (br.HasTag("PCNT")) { noOf = br.ReadInt32(); br.BaseStream.Position -= 8; substream.Write(br.ReadBytes(8 + 4 * noOf)); } if (br.HasTag("PVTX")) { noOf = br.ReadInt32() / 3; br.BaseStream.Position -= 8; substream.Write(br.ReadBytes(8 + 6 * noOf)); } if (br.HasTag("GNDX")) { noOf = br.ReadInt32(); substream.Write((int)Chunks.GNDX); if (noOf == 0) // this has been moved to the SKIN section { substream.Write(vertexCount); gndxOffset = substream.Position; substream.Write(new byte[vertexCount]); } else { substream.Write(noOf); substream.Write(br.ReadBytes(noOf)); } } if (br.HasTag("MTGC")) { noOf = br.ReadInt32(); br.BaseStream.Position -= 8; substream.Write(br.ReadBytes(8 + 4 * noOf)); } if (br.HasTag("MATS")) { noOf = br.ReadInt32(); br.BaseStream.Position -= 8; substream.Write(br.ReadBytes(8 + 4 * noOf)); } substream.Write(br.ReadBytes(12)); // MaterialId, SelectionGroup, Unselectable br.BaseStream.Position += 4 + SizeName; // skip LevelOfDetail, FilePath substream.Write(br.ReadBytes(28)); // Bounds noOf = br.ReadInt32(); // Extents br.BaseStream.Position -= 4; substream.Write(br.ReadBytes(4 + noOf * 28)); if (br.HasTag("TANG")) { noOf = br.ReadInt32(); br.BaseStream.Position += noOf * 16; // skip Tangents } if (br.HasTag("SKIN")) { noOf = br.ReadInt32(); // rebuild the GNDX from the SKIN section // this is (uint32 index, uint32 weight) // casting the indicies to bytes is "enough" for this if (gndxOffset > 0) { byte[] buffer = br.ReadBytes(noOf); substream.Position = gndxOffset; for (int i = 0; i < buffer.Length; i += 8) { substream.WriteByte(buffer[i]); } substream.Position = substream.Length; } else { br.BaseStream.Position += noOf; } } // copy anything else the chunk contains int remaining = (int)(sectionEnd - br.BaseStream.Position); if (remaining > 0) { substream.Write(br.ReadBytes(remaining)); } // update the inclusive size and write to the filestream substream.Position = 0; substream.Write((int)substream.Length); substream.WriteTo(bw.BaseStream); } } // update the chunk size bw.BaseStream.Position = offset; bw.Write((int)(bw.BaseStream.Length - offset - 4)); bw.BaseStream.Position = bw.BaseStream.Length; }