Пример #1
0
        public static byte[] WriteTfrags(Terrain terrain, int fileOffset, GameType game)
        {
            List <TerrainFragment> tFrags = terrain.fragments;

            List <List <byte> > vertBytes = new List <List <byte> >()
            {
                new List <byte>(), new List <byte>(), new List <byte>(), new List <byte>()
            };
            List <List <byte> > rgbaBytes = new List <List <byte> >()
            {
                new List <byte>(), new List <byte>(), new List <byte>(), new List <byte>()
            };
            List <List <byte> > uvBytes = new List <List <byte> >()
            {
                new List <byte>(), new List <byte>(), new List <byte>(), new List <byte>()
            };
            List <List <byte> > indexBytes = new List <List <byte> >()
            {
                new List <byte>(), new List <byte>(), new List <byte>(), new List <byte>()
            };

            List <byte> textureBytes = new List <byte>();

            byte[] tfragHeads = new byte[0x30 * tFrags.Count];

            int headerSize = (game.num == 4) ? 0x70 : 0x60;

            ushort chunk = 0;

            for (int i = 0; i < tFrags.Count; i++)
            {
                TerrainModel mod = (TerrainModel)(tFrags[i].model);

                int offset = i * 0x30;
                tFrags[i].ToByteArray().CopyTo(tfragHeads, offset);

                WriteInt(tfragHeads, offset + 0x10, fileOffset + headerSize + tfragHeads.Length + textureBytes.Count);
                WriteInt(tfragHeads, offset + 0x14, tFrags[i].model.textureConfig.Count);

                byte[] modelVertBytes = mod.SerializeVerts();
                if (((vertBytes[chunk].Count + modelVertBytes.Length) / 0x1c) > 0xffff)
                {
                    chunk++;
                }

                WriteUshort(tfragHeads, offset + 0x18, (ushort)(vertBytes[chunk].Count / 0x1c));
                WriteUshort(tfragHeads, offset + 0x1a, (ushort)(tFrags[i].model.vertexBuffer.Length / 8));

                WriteUshort(tfragHeads, offset + 0x22, chunk);

                foreach (var texConf in tFrags[i].model.textureConfig)
                {
                    byte[] texBytes = new byte[0x10];
                    WriteInt(texBytes, 0x00, texConf.id);
                    WriteInt(texBytes, 0x04, texConf.start + indexBytes[chunk].Count / 2);
                    WriteInt(texBytes, 0x08, texConf.size);
                    WriteInt(texBytes, 0x0C, texConf.mode);
                    textureBytes.AddRange(texBytes);
                }

                indexBytes[chunk].AddRange(tFrags[i].model.GetFaceBytes((ushort)(vertBytes[chunk].Count / 0x1C)));
                vertBytes[chunk].AddRange(modelVertBytes);
                rgbaBytes[chunk].AddRange(tFrags[i].model.rgbas);
                uvBytes[chunk].AddRange(tFrags[i].model.SerializeUVs());
            }

            List <byte> outBytes = new List <byte>();

            byte[] head = new byte[headerSize];
            WriteInt(head, 0, fileOffset + headerSize);
            WriteUshort(head, 0x4, terrain.levelNumber);
            WriteUshort(head, 0x6, (ushort)tFrags.Count);

            outBytes.AddRange(head);
            outBytes.AddRange(tfragHeads);
            outBytes.AddRange(textureBytes);

            int[] vertOffsets  = { 0, 0, 0, 0 };
            int[] rgbaOffsets  = { 0, 0, 0, 0 };
            int[] uvOffsets    = { 0, 0, 0, 0 };
            int[] indexOffsets = { 0, 0, 0, 0 };
            int[] unkOffsets   = { 0, 0, 0, 0 };

            for (int i = 0; i < 4; i++)
            {
                if (vertBytes[i].Count == 0)
                {
                    continue;
                }
                Pad(outBytes);
                vertOffsets[i] = fileOffset + outBytes.Count;
                outBytes.AddRange(vertBytes[i]);
                Pad(outBytes);
                rgbaOffsets[i] = fileOffset + outBytes.Count;
                outBytes.AddRange(rgbaBytes[i]);
                Pad(outBytes);
                uvOffsets[i] = fileOffset + outBytes.Count;
                outBytes.AddRange(uvBytes[i]);
                Pad(outBytes);
                indexOffsets[i] = fileOffset + outBytes.Count;
                outBytes.AddRange(indexBytes[i]);
                Pad(outBytes);
                unkOffsets[i] = fileOffset + outBytes.Count;
            }


            byte[] outByteArr = outBytes.ToArray();

            for (int i = 0; i < 4; i++)
            {
                WriteInt(outByteArr, 0x08 + i * 4, vertOffsets[i]);
                WriteInt(outByteArr, 0x18 + i * 4, rgbaOffsets[i]);
                WriteInt(outByteArr, 0x28 + i * 4, uvOffsets[i]);
                WriteInt(outByteArr, 0x38 + i * 4, indexOffsets[i]);
                if (game.num == 4)
                {
                    WriteInt(outByteArr, 0x48 + i * 4, unkOffsets[i]);
                }
            }

            return(outByteArr);
        }
Пример #2
0
        private byte[] WriteTfrags(List <TerrainFragment> tFrags, int fileOffset)
        {
            List <List <byte> > vertBytes = new List <List <byte> >()
            {
                new List <byte>(), new List <byte>(), new List <byte>(), new List <byte>()
            };
            List <List <byte> > rgbaBytes = new List <List <byte> >()
            {
                new List <byte>(), new List <byte>(), new List <byte>(), new List <byte>()
            };
            List <List <byte> > uvBytes = new List <List <byte> >()
            {
                new List <byte>(), new List <byte>(), new List <byte>(), new List <byte>()
            };
            List <List <byte> > indexBytes = new List <List <byte> >()
            {
                new List <byte>(), new List <byte>(), new List <byte>(), new List <byte>()
            };

            List <byte> textureBytes = new List <byte>();

            byte[] tfragHeads = new byte[0x30 * tFrags.Count];

            ushort chunk = 0;

            for (int i = 0; i < tFrags.Count; i++)
            {
                TerrainModel mod = (TerrainModel)(tFrags[i].model);

                int offset = i * 0x30;
                WriteFloat(tfragHeads, offset + 0x00, tFrags[i].off_00);
                WriteFloat(tfragHeads, offset + 0x04, tFrags[i].off_04);
                WriteFloat(tfragHeads, offset + 0x08, tFrags[i].off_08);
                WriteFloat(tfragHeads, offset + 0x0C, tFrags[i].off_0C);

                WriteInt(tfragHeads, offset + 0x10, fileOffset + 0x60 + tfragHeads.Length + textureBytes.Count);
                WriteInt(tfragHeads, offset + 0x14, tFrags[i].model.textureConfig.Count);

                byte[] modelVertBytes = mod.SerializeVerts();
                if (((vertBytes[chunk].Count + modelVertBytes.Length) / 0x1c) > 0xffff)
                {
                    chunk++;
                }

                WriteUshort(tfragHeads, offset + 0x18, (ushort)(vertBytes[chunk].Count / 0x1c));
                WriteUshort(tfragHeads, offset + 0x1a, (ushort)(tFrags[i].model.vertexBuffer.Length / 8));

                WriteUshort(tfragHeads, offset + 0x1C, tFrags[i].off_1C);
                WriteUshort(tfragHeads, offset + 0x1E, tFrags[i].off_1E);
                WriteUshort(tfragHeads, offset + 0x20, tFrags[i].off_20);
                WriteUshort(tfragHeads, offset + 0x22, chunk);
                WriteUint(tfragHeads, offset + 0x24, tFrags[i].off_24);
                WriteUint(tfragHeads, offset + 0x28, tFrags[i].off_28);
                WriteUint(tfragHeads, offset + 0x2C, tFrags[i].off_2C);

                foreach (var texConf in tFrags[i].model.textureConfig)
                {
                    byte[] texBytes = new byte[0x10];
                    WriteInt(texBytes, 0x00, texConf.ID);
                    WriteInt(texBytes, 0x04, texConf.start + indexBytes[chunk].Count / 2);
                    WriteInt(texBytes, 0x08, texConf.size);
                    WriteInt(texBytes, 0x0C, texConf.mode);
                    textureBytes.AddRange(texBytes);
                }

                indexBytes[chunk].AddRange(tFrags[i].model.GetFaceBytes((ushort)(vertBytes[chunk].Count / 0x1C)));
                vertBytes[chunk].AddRange(modelVertBytes);
                rgbaBytes[chunk].AddRange(tFrags[i].model.rgbas);
                uvBytes[chunk].AddRange(tFrags[i].model.SerializeUVs());
            }

            List <byte> outBytes = new List <byte>();

            byte[] head = new byte[0x60];
            WriteInt(head, 0, fileOffset + 0x60);
            WriteUshort(head, 0x4, (ushort)tFrags.Count);
            WriteUshort(head, 0x6, (ushort)tFrags.Count);

            outBytes.AddRange(head);
            outBytes.AddRange(tfragHeads);
            outBytes.AddRange(textureBytes);

            int[] vertOffsets  = { 0, 0, 0, 0 };
            int[] rgbaOffsets  = { 0, 0, 0, 0 };
            int[] uvOffsets    = { 0, 0, 0, 0 };
            int[] indexOffsets = { 0, 0, 0, 0 };

            for (int i = 0; i < 4; i++)
            {
                if (vertBytes[i].Count == 0)
                {
                    continue;
                }
                Pad(outBytes);
                vertOffsets[i] = fileOffset + outBytes.Count;
                outBytes.AddRange(vertBytes[i]);
                Pad(outBytes);
                rgbaOffsets[i] = fileOffset + outBytes.Count;
                outBytes.AddRange(rgbaBytes[i]);
                Pad(outBytes);
                uvOffsets[i] = fileOffset + outBytes.Count;
                outBytes.AddRange(uvBytes[i]);
                Pad(outBytes);
                indexOffsets[i] = fileOffset + outBytes.Count;
                outBytes.AddRange(indexBytes[i]);
                Pad(outBytes);
            }


            byte[] outByteArr = outBytes.ToArray();

            for (int i = 0; i < 4; i++)
            {
                WriteInt(outByteArr, 0x08 + i * 4, vertOffsets[i]);
                WriteInt(outByteArr, 0x18 + i * 4, rgbaOffsets[i]);
                WriteInt(outByteArr, 0x28 + i * 4, uvOffsets[i]);
                WriteInt(outByteArr, 0x38 + i * 4, indexOffsets[i]);
            }

            return(outByteArr);
        }