Пример #1
0
            public void Read(FileData d)
            {
                destone.Clear();
                d.skip(8);// magic and section size
                int count = d.readInt();
                int start = d.pos();

                for (int i = 0; i < count; i++)
                {
                    int offset = d.readInt();
                    int size   = d.readInt();

                    int temp = d.pos();
                    d.seek(start + offset);
                    TONE_DES des = new TONE_DES();
                    des.Read(d);
                    destone.Add(des);

                    d.seek(temp);
                }
            }
Пример #2
0
            public void Read(FileData d)
            {
                d.skip(8);// magic and section size
                int count = d.readInt();

                int start = d.pos();

                for (int i = 0; i < count; i++)
                {
                    int offset = d.readInt();
                    int size   = d.readInt();

                    int temp = d.pos();
                    d.seek(offset + start);

                    TONE_META meta = new TONE_META();
                    meta.Read(d);
                    tones.Add(meta);

                    d.seek(temp);
                }
            }
Пример #3
0
        public void Read(FileData f)
        {
            f.Endian = endianess;
            if (f.size() < 4)
            {
                return;
            }
            int entryCount       = f.readInt();
            int otherCount       = f.readInt();
            int startOffset      = f.readInt();
            int unk              = f.readInt(); //0x20 - Entry size?
            int unk2             = f.readInt(); //0x8? - values per entry?
            int unk3             = f.readInt(); //0x30? - start offset again?
            int otherStartOffset = f.readInt();

            if (unk != 0x20 || unk2 != 0x8 || unk3 != 0x30)
            {
                throw new Exception("Unexpected Unkowns Please Report to Jam");
            }

            f.seek(startOffset);
            for (int i = 0; i < entryCount; i++)
            {
                Entry temp = new Entry();
                temp.values = new int[8];
                for (int j = 0; j < 8; j++)
                {
                    temp.values[j] = f.readInt();
                }

                int returnOffset = f.pos();
                f.seek(temp.values[0]);
                temp.name = f.readString();
                f.seek(returnOffset);
                entries.Add(temp);
            }

            f.seek(otherStartOffset);
            for (int i = 0; i < otherCount; i++)
            {
                Entry temp = new Entry();
                temp.values = new int[2];
                for (int j = 0; j < 2; j++)
                {
                    temp.values[j] = f.readInt();
                }

                int returnOffset = f.pos();
                f.seek(temp.values[0]);
                temp.name = f.readString();
                f.seek(returnOffset);
                otherEntries.Add(temp);
            }
        }
Пример #4
0
        public void read(FileData f)
        {
            int nameOffset = f.readInt();

            matHash = f.readInt();
            int propertyCount = f.readInt();
            int propertyPos   = f.readInt();

            hasPat = (0 != f.readByte());
            f.skip(3);
            int patOffset     = f.readInt();
            int secondNameOff = f.readInt();

            matHash2 = f.readInt();

            f.seek(nameOffset);
            name = f.readString();

            if (secondNameOff != 0)
            {
                f.seek(secondNameOff);
                name2 = f.readString();
            }

            if (hasPat)
            {
                f.seek(patOffset);
                int patDataPos = f.readInt();
                if (patDataPos != 0)
                {
                    f.seek(patDataPos);
                    pat0.read(f);
                }
            }
            f.seek(propertyPos);
            for (int i = 0; i < propertyCount; i++)
            {
                int propOffset = f.readInt();
                int returnPos  = f.pos();
                f.seek(propOffset);
                MatData temp = new MatData();
                temp.read(f);
                properties.Add(temp);
                f.seek(returnPos);
            }
        }
Пример #5
0
        public DDS(FileData d)
        {
            d.Endian = System.IO.Endianness.Little;
            d.seek(0);

            header               = new Header();
            header.magic         = new char[4];
            header.magic [0]     = (char)d.readByte();
            header.magic [1]     = (char)d.readByte();
            header.magic [2]     = (char)d.readByte();
            header.magic [3]     = (char)d.readByte();
            header.size          = d.readInt();
            header.flags         = d.readInt();
            header.height        = d.readInt();
            header.width         = d.readInt();
            header.pitchOrLinear = d.readInt();
            header.depth         = d.readInt();
            header.mipmapCount   = d.readInt();
            header.reserved      = new int[11];
            for (int i = 0; i < 11; i++)
            {
                header.reserved [i] = d.readInt();
            }
            header.dwSize    = d.readInt();
            header.dwFlags   = d.readInt();
            header.dwFourCC  = d.readInt();
            header.dwBitmask = d.readInt();
            header.dwCaps    = (uint)d.readInt();
            header.dwCaps2   = (uint)d.readInt();
            header.dwCaps3   = (uint)d.readInt();
            header.dwCaps4   = (uint)d.readInt();
            header.reserve   = d.readInt();

            d.skip(16);             // not needed another header

            data = new byte[d.size() - d.pos()];
            for (int i = 0; i < data.Length; i++)
            {
                data [i] = (byte)d.readByte();
            }
        }
Пример #6
0
 public override void Read(string filename)
 {
     {
         {
             FileData d     = new FileData(filename);
             var      size1 = d.readShort();
             if (size1 > 255)
             {
                 d.seek(0);
                 d.Endian = Endianness.Little;
                 size1    = d.readShort();
             }
             if (d.size() < 4)
             {
                 return;
             }
             var          size2  = d.readShort();
             List <short> Table1 = new List <short>();
             for (int i = 0; i < size1; i++)
             {
                 if (d.pos() + 2 > d.size())
                 {
                     break;
                 }
                 Table1.Add((short)d.readShort());
             }
             List <short> Table2 = new List <short>();
             for (int i = 0; i < size2; i++)
             {
                 if (d.pos() + 2 > d.size())
                 {
                     break;
                 }
                 Table2.Add((short)d.readShort());
             }
             Tables = new List <List <short> >();
             Tables.Add(Table1);
             Tables.Add(Table2);
         }
     }
 }
Пример #7
0
        public void read(FileData f)
        {
            keyframe temp;

            defaultTexId = f.readInt();
            int keyframeCount  = f.readInt();
            int keyframeOffset = f.readInt();

            frameCount = f.readInt() + 1;
            unknown    = f.readInt();
            if (keyframeOffset != f.eof())
            {
                f.seek(keyframeOffset);
                for (int i = 0; i < keyframeCount; i++)
                {
                    temp.texId    = f.readInt();
                    temp.frameNum = f.readInt();
                    keyframes.Add(temp);
                }
            }
        }
Пример #8
0
        public void read(FileData f)
        {
            f.Endian = Endian;
            if (f.size() < 4)
            {
                return;
            }

            f.seek(4);
            unknown    = f.readUInt();
            frameCount = f.readUInt();
            startFrame = f.readUInt();
            endFrame   = f.readUInt();
            frameRate  = f.readUInt();
            int matCount  = f.readInt();
            int matOffset = f.readInt();
            int visCount  = f.readInt();
            int visOffset = f.readInt();
            int returnPos;

            f.seek(matOffset);
            for (int i = 0; i < matCount; i++)
            {
                returnPos = f.pos() + 4;
                f.seek(f.readInt());
                MatEntry tempMatEntry = new MatEntry();
                tempMatEntry.read(f);
                matEntries.Add(tempMatEntry);
                f.seek(returnPos);
            }
            f.seek(visOffset);
            for (int i = 0; i < visCount; i++)
            {
                returnPos = f.pos() + 4;
                f.seek(f.readInt());
                VisEntry tempVisEntry = new VisEntry();
                tempVisEntry.read(f);
                visEntries.Add(tempVisEntry);
                f.seek(returnPos);
            }
        }
Пример #9
0
        public void read(FileData f)
        {
            f.Endian = Endian;
            if (f.size() < 4)
            {
                throw new EndOfStreamException("Blank/Broken MTA");
            }
            f.seek(4);
            unknown   = (uint)f.readInt();
            numFrames = (uint)f.readInt();
            f.skip(8);
            frameRate = (uint)f.readInt();
            int matCount  = f.readInt();
            int matOffset = f.readInt();
            int visCount  = f.readInt();
            int visOffset = f.readInt();
            int returnPos;

            f.seek(matOffset);
            for (int i = 0; i < matCount; i++)
            {
                returnPos = f.pos() + 4;
                f.seek(f.readInt());
                MatEntry tempMatEntry = new MatEntry();
                tempMatEntry.read(f);
                matEntries.Add(tempMatEntry);
                f.seek(returnPos);
            }
            f.seek(visOffset);
            for (int i = 0; i < visCount; i++)
            {
                returnPos = f.pos() + 4;
                f.seek(f.readInt());
                VisEntry tempVisEntry = new VisEntry();
                tempVisEntry.read(f);
                visEntries.Add(tempVisEntry);
                f.seek(returnPos);
            }
        }
Пример #10
0
        public override void Read(string filename)
        {
            var offsets = new List <int>();
            var strings = new List <string>();
            var sizes   = new List <int>();

            Files = new Dictionary <string, byte[]>();
            FileData data = new FileData(filename);

            data.Endian = Endianness.Big;

            if (data != null)
            {
                var magic = data.readString();
                if (magic == "PACK")
                {
                    data.Endian = Endianness.Little;
                }
                data.seek(0x08);
                var count = data.readInt();

                for (int i = 0; i < count; i++)
                {
                    data.seek(0x10 + (i * 4));
                    var strOffset = data.readInt();
                    data.seek(strOffset);
                    strings.Add(data.readString());

                    data.seek(0x10 + (count * 4) + (i * 4));
                    offsets.Add(data.readInt());

                    data.seek((count * 4) + (count * 4) + (i * 4) + 0x10);
                    sizes.Add(data.readInt());

                    data.seek(offsets[i]);
                    var b = data.read(sizes[i]);
                    Files.Add(strings[i], b);
                }
            }
        }
Пример #11
0
        public BRTI(FileData f) //Docs thanks to gdkchan!!
        {
            ImageKey         = "texture";
            SelectedImageKey = "texture";

            f.skip(4);

            int  BRTISize1 = f.readInt();
            long BRTISize2 = (f.readInt() | f.readInt() << 32);

            surf = new Swizzle.Surface();

            surf.tileMode = (sbyte)f.readByte();
            surf.dim      = (sbyte)f.readByte();
            ushort Flags = (ushort)f.readShort();

            surf.swizzle = (ushort)f.readShort();
            surf.numMips = (ushort)f.readShort();
            uint unk18 = (uint)f.readInt();

            surf.format = (uint)f.readInt();
            DataType    = (byte)(surf.format & 0xFF);
            uint unk20 = (uint)f.readInt();

            surf.width  = f.readInt();
            surf.height = f.readInt();
            surf.depth  = f.readInt();
            int FaceCount = f.readInt();

            surf.sizeRange = f.readInt();
            uint unk38 = (uint)f.readInt();
            uint unk3C = (uint)f.readInt();
            uint unk40 = (uint)f.readInt();
            uint unk44 = (uint)f.readInt();
            uint unk48 = (uint)f.readInt();
            uint unk4C = (uint)f.readInt();

            surf.imageSize = f.readInt();
            surf.alignment = f.readInt();
            int ChannelType = f.readInt();
            int TextureType = f.readInt();

            Text = f.readString((f.readInt() | f.readInt() << 32) + BNTX.temp + 2, -1);
            long ParentOffset = f.readInt() | f.readInt() << 32;
            long PtrsOffset   = f.readInt() | f.readInt() << 32;

            format = surf.format;

            f.seek((int)PtrsOffset + BNTX.temp);
            long dataOff = f.readInt() | f.readInt() << 32;

            surf.data = f.getSection((int)dataOff + BNTX.temp, surf.imageSize);
            //Console.WriteLine(surf.data.Length + " " + dataOff.ToString("x") + " " + surf.imageSize);

            uint blk_dim   = Formats.blk_dims(surf.format >> 8);
            uint blkWidth  = blk_dim >> 4;
            uint blkHeight = blk_dim & 0xF;

            uint bpp = Formats.bpps(surf.format >> 8);

            //     Console.WriteLine($"{Name} Height {surf.height}wdith = {surf.width}allignment = {surf.alignment}blkwidth = {blkWidth}blkheight = {blkHeight}blkdims = {blk_dim} format = {surf.format} datatype = {DataType} dataoffset = {dataOff}");


            // byte[] result = surf.data;



            byte[] result = Swizzle.deswizzle((uint)surf.width, (uint)surf.height, blkWidth, blkHeight, bpp, (uint)surf.tileMode, (uint)surf.alignment, surf.sizeRange, surf.data, 0);


            uint width  = Swizzle.DIV_ROUND_UP((uint)surf.width, blkWidth);
            uint height = Swizzle.DIV_ROUND_UP((uint)surf.height, blkHeight);

            result_ = new byte[width * height * bpp];

            Array.Copy(result, 0, result_, 0, width * height * bpp);

            texture.data   = result_;
            texture.width  = surf.width;
            texture.height = surf.height;

            Width  = surf.width;
            Height = surf.height;

            texture.mipmaps.Add(result_);

            switch (surf.format >> 8)
            {
            case ((uint)Formats.BNTXImageFormat.IMAGE_FORMAT_BC1):
                if (DataType == (byte)Formats.BNTXImageTypes.UNORM)
                {
                    texture.type = PixelInternalFormat.CompressedRgbaS3tcDxt1Ext;
                }
                else if (DataType == (byte)Formats.BNTXImageTypes.SRGB)
                {
                    texture.type = PixelInternalFormat.CompressedSrgbAlphaS3tcDxt1Ext;
                }
                else
                {
                    throw new Exception("Unsupported data type for BC1");
                }

                break;

            case ((uint)Formats.BNTXImageFormat.IMAGE_FORMAT_BC2):
                if (DataType == (byte)Formats.BNTXImageTypes.UNORM)
                {
                    texture.type = PixelInternalFormat.CompressedRgbaS3tcDxt3Ext;
                }
                else if (DataType == (byte)Formats.BNTXImageTypes.SRGB)
                {
                    texture.type = PixelInternalFormat.CompressedSrgbAlphaS3tcDxt3Ext;
                }
                else
                {
                    throw new Exception("Unsupported data type for BC2");
                }
                break;

            case ((uint)Formats.BNTXImageFormat.IMAGE_FORMAT_BC3):
                if (DataType == (byte)Formats.BNTXImageTypes.UNORM)
                {
                    texture.type = PixelInternalFormat.CompressedRgbaS3tcDxt5Ext;
                }
                else if (DataType == (byte)Formats.BNTXImageTypes.SRGB)
                {
                    texture.type = PixelInternalFormat.CompressedSrgbAlphaS3tcDxt5Ext;
                }
                else
                {
                    throw new Exception("Unsupported data type for BC3");
                }
                break;

            case ((uint)Formats.BNTXImageFormat.IMAGE_FORMAT_BC4):
                if (DataType == (byte)Formats.BNTXImageTypes.UNORM)
                {
                    texture.type = PixelInternalFormat.CompressedRedRgtc1;

                    /*    byte[] fixBC4 = DecompressBC4(texture.data, texture.width, texture.height, false);
                     *  texture.data = fixBC4;
                     *  texture.type = PixelInternalFormat.Rgba;
                     *  texture.utype = OpenTK.Graphics.OpenGL.PixelFormat.Rgba;*/
                }
                else if (DataType == (byte)Formats.BNTXImageTypes.SNORM)
                {
                    texture.type = PixelInternalFormat.CompressedSignedRedRgtc1;

                    /*     byte[] fixBC4 = DecompressBC4(texture.data, texture.width, texture.height, true);
                     *   texture.data = fixBC4;
                     *   texture.type = PixelInternalFormat.Rgba;
                     *   texture.utype = OpenTK.Graphics.OpenGL.PixelFormat.Rgba;*/
                }
                else
                {
                    throw new Exception("Unsupported data type for BC4");
                }
                break;

            case ((uint)Formats.BNTXImageFormat.IMAGE_FORMAT_BC5):
                if (DataType == (byte)Formats.BNTXImageTypes.UNORM)
                {
                    //      byte[] fixBC5 = DecompressBC5(texture.data, texture.width, texture.height, false);
                    //    texture.data = fixBC5;
                    texture.type = PixelInternalFormat.CompressedRgRgtc2;
                    //    texture.utype = OpenTK.Graphics.OpenGL.PixelFormat.Rgba;
                }
                else if (DataType == (byte)Formats.BNTXImageTypes.SNORM)
                {
                    byte[] fixBC5 = DecompressBC5(texture.data, texture.width, texture.height, true);
                    texture.data  = fixBC5;
                    texture.type  = PixelInternalFormat.Rgba;
                    texture.utype = OpenTK.Graphics.OpenGL.PixelFormat.Rgba;
                }
                else
                {
                    Console.WriteLine("Unsupported data type for BC5");
                }
                break;

            case ((uint)Formats.BNTXImageFormat.IMAGE_FORMAT_BC7):
                if (DataType == (byte)Formats.BNTXImageTypes.UNORM)
                {
                    /*         ProcessStartInfo startInfo = new ProcessStartInfo();
                     *       startInfo.CreateNoWindow = false;
                     *       startInfo.UseShellExecute = false;
                     *       startInfo.FileName = "lib\texconv.exe";
                     *       startInfo.WindowStyle = ProcessWindowStyle.Hidden;
                     *       startInfo.Arguments = "-ft png -f R10G10B10A2_UNORM -y";*/
                }
                else if (DataType == (byte)Formats.BNTXImageTypes.SNORM)
                {
                }
                else
                {
                    Console.WriteLine("Unsupported data type for BC7");
                }
                break;

            case ((uint)Formats.BNTXImageFormat.IMAGE_FORMAT_R8_G8_B8_A8):
                if (DataType == (byte)Formats.BNTXImageTypes.UNORM || DataType == (byte)Formats.BNTXImageTypes.SRGB)
                {
                    texture.type  = PixelInternalFormat.Rgba;
                    texture.utype = OpenTK.Graphics.OpenGL.PixelFormat.Rgba;
                }
                else
                {
                    throw new Exception("Unsupported data type for R8_G8_B8_A8");
                }
                break;
            }
            texture.display = loadImage(texture);
            display         = texture.display;

            RenderableTex.Add(texture);
        }
Пример #12
0
        public void Read(byte[] file)
        {
            FileData f = new FileData(file);

            f.Endian = Endianness.Big;
            f.seek(0);

            f.seek(4);                 // magic check
            SwitchCheck = f.readInt(); //Switch version only has padded magic
            verNumD     = f.readByte();
            verNumC     = f.readByte();
            verNumB     = f.readByte();
            verNumA     = f.readByte();
            if (SwitchCheck == 0x20202020)
            {
                //Console.WriteLine("Version = " + verNumA + "." + verNumB + "." + verNumC + "." + verNumD);
                if (f.readShort() == 0xFEFF)
                {
                    f.Endian = Endianness.Big;
                }
                else
                {
                    f.Endian = Endianness.Little;
                }
                f.skip(2); //Size Headeer
                f.skip(4); //File Name Direct
                int fileAlignment         = f.readInt();
                int RelocationTableOffset = f.readInt();
                int BfresSize             = f.readInt();

                string name = f.readString(readOffset(f) + 2, -1);

                f.skip(4); // Padding
                long FMDLOffset      = f.readInt64();
                long FMDLDict        = f.readInt64();
                long FSKAOffset      = f.readInt64();
                long FSKADict        = f.readInt64();
                long FMAAOffset      = f.readInt64();
                long FMAADict        = f.readInt64();
                long FVISOffset      = f.readInt64();
                long FVISDict        = f.readInt64();
                long FSHUOffset      = f.readInt64();
                long FSHUDict        = f.readInt64();
                long FSCNOffset      = f.readInt64();
                long FSCNDict        = f.readInt64();
                long BuffMemPool     = f.readInt64();
                long BuffMemPoolInfo = f.readInt64();
                long EMBOffset       = f.readInt64();
                long EMBDict         = f.readInt64();
                f.skip(8); // Padding
                long StringTableOffset = f.readInt64();
                int  unk11             = f.readInt();
                int  FMDLCount         = f.readShort();
                /*FSKACount =*/ f.readShort();
                int FMAACount = f.readShort();
                int FVISCount = f.readShort();
                int FSHUCount = f.readShort();
                int FSCNCount = f.readShort();
                int EMBCount  = f.readShort();
                f.skip(12); // Padding
                            // //Console.WriteLine($"FMDLOffset {FMDLOffset} FMDLCount {FMDLCount} FMDLDict {FMDLDict} FSKAOffset {FSKAOffset} FSKADict {FSKADict}");
                            //  //Console.WriteLine($"FMAAOffset {FMAAOffset} FMAADict {FMAADict} FVISOffset {FVISOffset} FSHUOffset {FSKAOffset} FSKADict {FSHUDict}");

                //FMDLs -Models-
                for (int i = 0; i < EMBCount; i++)
                {
                    f.seek((int)EMBOffset + (i * 16));
                    int DataOffset = f.readInt();
                    f.seek(DataOffset);
                    string EmMagic = f.readString(f.pos(), 4);

                    if (EmMagic.Equals("BNTX")) //Textures
                    {
                        f.skip(24);
                        int size = f.readInt();
                        f.seek(DataOffset);
                        BinaryTexture t = new BinaryTexture(f.GetStream(size));
                        textures.Add(t.Name, t);
                    }
                }
                f.seek((int)FMDLOffset);
                for (int i = 0; i < FMDLCount; i++)
                {
                    //   //Console.WriteLine("Reading FMDL....");

                    FMDL_Model model = new FMDL_Model();



                    //FMDL modelTest = new FMDL();
                    //modelTest.Read(f);
                    f.skip(16);

                    FMDLheader fmdl_info = new FMDLheader
                    {
                        name           = f.readString(f.readInt() + 2, -1),
                        padding        = f.readInt(),
                        eofString      = f.readInt64(),
                        fsklOff        = f.readInt64(),
                        fvtxArrOff     = f.readInt64(),
                        fshpOffset     = f.readInt64(),
                        fshpIndx       = f.readInt64(),
                        fmatOffset     = f.readInt64(),
                        fmatIndx       = f.readInt64(),
                        UserDataOffset = f.readInt64(),
                        padding1       = f.readInt64(),
                        padding2       = f.readInt64(),
                        fvtxCount      = f.readShort(),
                        fshpCount      = f.readShort(),
                        fmatCount      = f.readShort(),
                        paramCount     = f.readShort(),
                        VertCount      = f.readInt(),
                        unk2           = f.readInt(),
                    };
                    int NextFMDL = f.pos();

                    model.name = fmdl_info.name;

                    //Models.Nodes.Add(fmdl_info.name);
                    //   //Console.WriteLine($" Name {fmdl_info.name} eofString {fmdl_info.eofString} fsklOff {fmdl_info.fsklOff}");
                    //  //Console.WriteLine(fmdl_info.fvtxCount);

                    List <FVTXH> FVTXArr = new List <FVTXH>();
                    f.seek((int)fmdl_info.fvtxArrOff);
                    for (int vtx = 0; vtx < fmdl_info.fvtxCount; vtx++)
                    {
                        //   //Console.WriteLine("Reading FVTX....");
                        f.skip(16);
                        FVTXArr.Add(new FVTXH
                        {
                            attArrOff           = f.readInt64(),
                            attIndxOff          = f.readInt64(),
                            unk1                = f.readInt64(),
                            unk2                = f.readInt64(),
                            unk3                = f.readInt64(),
                            buffSizeOff         = f.readInt64(),
                            buffStrideSizeOff   = f.readInt64(),
                            buffArrOff          = f.readInt64(),
                            buffOff             = f.readInt(),
                            attCount            = f.readByte(),
                            buffCount           = f.readByte(),
                            sectIndx            = f.readShort(),
                            vertCount           = f.readInt(),
                            SkinWeightInfluence = f.readInt()
                        });
                        //  //Console.WriteLine($"attCount {FVTXArr[vtx].attCount}");
                    }


                    f.seek((int)fmdl_info.fmatOffset);
                    List <FMATH> FMATheaders = new List <FMATH>();
                    for (int mat = 0; mat < fmdl_info.fmatCount; mat++)
                    {
                        //    //Console.WriteLine("Reading FMAT....");
                        f.skip(16);


                        FMATH fmat_info = new FMATH
                        {
                            name            = f.readString((int)f.readInt64() + 2, -1),
                            renderInfoOff   = f.readInt64(),
                            renderInfoIndx  = f.readInt64(),
                            shaderAssignOff = f.readInt64(),
                            u1                 = f.readInt64(),
                            texSelOff          = f.readInt64(),
                            u2                 = f.readInt64(),
                            texAttSelOff       = f.readInt64(),
                            texAttIndxOff      = f.readInt64(),
                            matParamArrOff     = f.readInt64(),
                            matParamIndxOff    = f.readInt64(),
                            matParamOff        = f.readInt64(),
                            userDataOff        = f.readInt64(),
                            userDataIndxOff    = f.readInt64(),
                            volatileFlagOffset = f.readInt64(),
                            u3                 = f.readInt64(),
                            samplerSlotOff     = f.readInt64(),
                            textureSlotOff     = f.readInt64(),
                            flags              = f.readInt(), //This toggles material visabilty
                            sectIndx           = f.readShort(),
                            rendParamCount     = f.readShort(),
                            texSelCount        = f.readByte(),
                            texAttSelCount     = f.readByte(),
                            matParamCount      = f.readShort(),
                            u4                 = f.readShort(),
                            matParamSize       = f.readShort(),
                            rawParamDataSize   = f.readShort(),
                            userDataCount      = f.readShort(),
                            padding            = f.readInt(),
                        };
                        string FMATNameOffset = fmat_info.name;
                        // //Console.WriteLine($"{FMATNameOffset} {fmat_info.texSelCount} ");
                        FMATheaders.Add(fmat_info);
                    }

                    f.seek((int)fmdl_info.fsklOff + 16);
                    // //Console.WriteLine("Reading FSKL....");
                    FSKLH fskl_info = new FSKLH
                    {
                        boneIndxOff     = f.readInt64(),
                        boneArrOff      = f.readInt64(),
                        invIndxArrOff   = f.readInt64(),
                        invMatrArrOff   = f.readInt64(),
                        padding1        = f.readInt64(),
                        fsklType        = f.readInt(), //flags
                        boneArrCount    = f.readShort(),
                        invIndxArrCount = f.readShort(),
                        exIndxCount     = f.readShort(),
                        u1 = f.readInt(),
                    };

                    f.seek((int)fmdl_info.fsklOff + 16);
                    FSKLH fskl_infov8 = new FSKLH
                    {
                        boneIndxOff     = f.readInt64(),
                        boneArrOff      = f.readInt64(),
                        invIndxArrOff   = f.readInt64(),
                        invMatrArrOff   = f.readInt64(),
                        padding1        = f.readInt64(),
                        padding2        = f.readInt64(),
                        padding3        = f.readInt64(),
                        fsklType        = f.readInt(), //flags
                        boneArrCount    = f.readShort(),
                        invIndxArrCount = f.readShort(),
                        exIndxCount     = f.readShort(),
                        u1 = f.readInt(),
                    };
                    //  //Console.WriteLine($"Bone Count {fskl_info.boneArrCount}");

                    //FSKL and many other sections will be revised and cleaner later

                    if (verNumB == 8)
                    {
                        model.Node_Array = new int[fskl_infov8.invIndxArrCount + fskl_infov8.exIndxCount];
                        f.seek((int)fskl_infov8.invIndxArrOff);
                        for (int nodes = 0; nodes < fskl_infov8.invIndxArrCount + fskl_infov8.exIndxCount; nodes++)
                        {
                            model.Node_Array[nodes] = (f.readShort());
                        }
                    }
                    else
                    {
                        model.Node_Array = new int[fskl_info.invIndxArrCount + fskl_info.exIndxCount];
                        f.seek((int)fskl_info.invIndxArrOff);
                        for (int nodes = 0; nodes < fskl_info.invIndxArrCount + fskl_info.exIndxCount; nodes++)
                        {
                            model.Node_Array[nodes] = (f.readShort());
                        }
                    }



                    List <FSHPH> FSHPArr = new List <FSHPH>();
                    // //Console.WriteLine("Reading FSHP....");
                    f.seek((int)fmdl_info.fshpOffset);
                    for (int shp = 0; shp < fmdl_info.fshpCount; shp++)
                    {
                        f.skip(16);
                        FSHPArr.Add(new FSHPH
                        {
                            polyNameOff      = f.readInt(),
                            u1               = f.readInt(),
                            fvtxOff          = f.readInt64(),
                            lodMdlOff        = f.readInt64(),
                            fsklIndxArrOff   = f.readInt64(),
                            u3               = f.readInt64(),
                            u4               = f.readInt64(),
                            boundingBoxOff   = f.readInt64(),
                            radiusOff        = f.readInt64(),
                            padding          = f.readInt64(),
                            flags            = f.readInt(),
                            sectIndx         = f.readShort(),
                            fmatIndx         = f.readShort(),
                            fsklIndx         = f.readShort(),
                            fvtxIndx         = f.readShort(),
                            fsklIndxArrCount = f.readShort(),
                            matrFlag         = f.readByte(),
                            lodMdlCount      = f.readByte(),
                            visGrpCount      = f.readInt(),
                            visGrpIndxOff    = f.readShort(),
                            visGrpNodeOff    = f.readShort(),
                        });
                    }

                    // //Console.WriteLine("Reading Bones....");

                    // //Console.WriteLine("Reading FSHP Array....");

                    //MeshTime!!

                    for (int m = 0; m < FSHPArr.Count; m++)
                    {
                        Mesh poly = new Mesh();


                        poly.name = f.readString(FSHPArr[m].polyNameOff + 2, -1);


                        //    //Console.WriteLine("Polygon = " + poly.name);

                        List <attdata> AttrArr = new List <attdata>();
                        f.seek((int)FVTXArr[FSHPArr[m].fvtxIndx].attArrOff);
                        for (int att = 0; att < FVTXArr[FSHPArr[m].fvtxIndx].attCount; att++)
                        {
                            string AttType = f.readString(f.readInt() + 2, -1);

                            f.skip(4); //padding
                            f.Endian = Endianness.Big;
                            int vertType = f.readShort();
                            f.skip(2);
                            f.Endian = Endianness.Little;
                            int buffOff  = f.readShort();
                            int buffIndx = f.readShort();
                            //   //Console.WriteLine($"{AttType} Type = {vertType} Offset = {buffOff} Index = {buffIndx} ");
                            AttrArr.Add(new attdata {
                                attName = AttType, buffIndx = buffIndx, buffOff = buffOff, vertType = vertType
                            });
                        }


                        //Get RLT real quick for buffer offset
                        f.seek(0x18);
                        int RTLOffset = f.readInt();

                        f.seek(RTLOffset);
                        f.skip(0x030);
                        int DataStart = f.readInt();

                        // //Console.WriteLine($"RLT {DataStart}");


                        List <buffData> BuffArr = new List <buffData>();
                        f.seek((int)FVTXArr[FSHPArr[m].fvtxIndx].buffArrOff);
                        for (int buff = 0; buff < FVTXArr[FSHPArr[m].fvtxIndx].buffCount; buff++)
                        {
                            buffData data = new buffData();
                            f.seek((int)FVTXArr[FSHPArr[m].fvtxIndx].buffSizeOff + ((buff) * 0x10));
                            data.buffSize = f.readInt();
                            f.seek((int)FVTXArr[FSHPArr[m].fvtxIndx].buffStrideSizeOff + ((buff) * 0x10));
                            data.strideSize = f.readInt();

                            //So these work by grabbing the RLT offset first and then adding the buffer offset. Then they keep adding each other by their buffer sizes
                            if (buff == 0)
                            {
                                data.DataOffset = (DataStart + FVTXArr[FSHPArr[m].fvtxIndx].buffOff);
                            }
                            if (buff > 0)
                            {
                                data.DataOffset = BuffArr[buff - 1].DataOffset + BuffArr[buff - 1].buffSize;
                            }
                            if (data.DataOffset % 8 != 0)
                            {
                                data.DataOffset = data.DataOffset + (8 - (data.DataOffset % 8));
                            }

                            BuffArr.Add(data);
                            //   //Console.WriteLine("Data Offset = " + data.DataOffset + " Vertex Buffer Size =" + data.buffSize + " Index = " + buff + " vertexStrideSize size =" + data.strideSize);
                        }

                        for (int v = 0; v < FVTXArr[FSHPArr[m].fvtxIndx].vertCount; v++)
                        {
                            Vertex vert = new Vertex();
                            for (int attr = 0; attr < AttrArr.Count; attr++)
                            {
                                f.seek(((BuffArr[AttrArr[attr].buffIndx].DataOffset) + (AttrArr[attr].buffOff) + (BuffArr[AttrArr[attr].buffIndx].strideSize * v)));
                                switch (AttrArr[attr].attName)
                                {
                                case "_p0":
                                    if (AttrArr[attr].vertType == 1301)
                                    {
                                        vert.pos = new Vector3 {
                                            X = f.readHalfFloat(), Y = f.readHalfFloat(), Z = f.readHalfFloat()
                                        }
                                    }
                                    ;
                                    if (AttrArr[attr].vertType == 1304)
                                    {
                                        vert.pos = new Vector3 {
                                            X = f.readFloat(), Y = f.readFloat(), Z = f.readFloat()
                                        }
                                    }
                                    ;
                                    break;

                                case "_c0":
                                    if (AttrArr[attr].vertType == 1301)
                                    {
                                        vert.col = new Vector4(f.readHalfFloat(), f.readHalfFloat(), f.readHalfFloat(), f.readHalfFloat());
                                    }
                                    if (AttrArr[attr].vertType == 2067)
                                    {
                                        vert.col = new Vector4 {
                                            X = f.readFloat(), Y = f.readFloat(), Z = f.readFloat(), W = f.readFloat()
                                        }
                                    }
                                    ;
                                    if (AttrArr[attr].vertType == 267)
                                    {
                                        vert.col = new Vector4(f.readByte() / 255f, f.readByte() / 255f, f.readByte() / 255f, f.readByte() / 255f);
                                    }
                                    break;

                                case "_n0":
                                    if (AttrArr[attr].vertType == 526)
                                    {
                                        int normVal = (int)f.readInt();
                                        //Thanks RayKoopa!
                                        vert.nrm = new Vector3 {
                                            X = sign10Bit((normVal) & 0x3FF) / (float)511, Y = sign10Bit((normVal >> 10) & 0x3FF) / (float)511, Z = sign10Bit((normVal >> 20) & 0x3FF) / (float)511
                                        };
                                    }
                                    break;

                                case "_u0":
                                case "color":
                                case "_t0":
                                case "_b0":
                                case "_u1":
                                case "_u2":
                                case "_u3":
                                    if (AttrArr[attr].vertType == 265 || AttrArr[attr].vertType == 521)
                                    {
                                        vert.tx.Add(new Vector2 {
                                            X = ((float)f.readByte()) / 255, Y = ((float)f.readByte()) / 255
                                        });
                                    }
                                    if (AttrArr[attr].vertType == 274)
                                    {
                                        vert.tx.Add(new Vector2 {
                                            X = ((float)f.readShort()) / 65535, Y = ((float)f.readShort()) / 65535
                                        });
                                    }
                                    if (AttrArr[attr].vertType == 530)
                                    {
                                        vert.tx.Add(new Vector2 {
                                            X = ((float)f.readShort()) / 32767, Y = ((float)f.readShort()) / 32767
                                        });
                                    }
                                    if (AttrArr[attr].vertType == 1298)
                                    {
                                        vert.tx.Add(new Vector2 {
                                            X = f.readHalfFloat(), Y = f.readHalfFloat()
                                        });
                                    }
                                    if (AttrArr[attr].vertType == 1303)
                                    {
                                        vert.tx.Add(new Vector2 {
                                            X = f.readFloat(), Y = f.readFloat()
                                        });
                                    }
                                    break;

                                case "_i0":
                                    if (AttrArr[attr].vertType == 770)
                                    {
                                        vert.node.Add(f.readByte());
                                        vert.weight.Add((float)1.0);
                                    }
                                    if (AttrArr[attr].vertType == 777)
                                    {
                                        vert.node.Add(f.readByte());
                                        vert.node.Add(f.readByte());
                                    }
                                    if (AttrArr[attr].vertType == 779)
                                    {
                                        vert.node.Add(f.readByte());
                                        vert.node.Add(f.readByte());
                                        vert.node.Add(f.readByte());
                                        vert.node.Add(f.readByte());
                                    }
                                    if (AttrArr[attr].vertType == 523)
                                    {
                                        vert.node.Add(f.readByte());
                                        vert.node.Add(f.readByte());
                                        vert.node.Add(f.readByte());
                                        vert.node.Add(f.readByte());
                                    }
                                    break;

                                case "_w0":
                                    if (AttrArr[attr].vertType == 258)
                                    {
                                        vert.weight.Add((f.readByte()) / (float)255);
                                    }
                                    if (AttrArr[attr].vertType == 265)
                                    {
                                        vert.weight.Add((f.readByte()) / (float)255);
                                        vert.weight.Add((f.readByte()) / (float)255);
                                    }
                                    if (AttrArr[attr].vertType == 267)
                                    {
                                        vert.weight.Add((f.readByte()) / (float)255);
                                        vert.weight.Add((f.readByte()) / (float)255);
                                        vert.weight.Add((f.readByte()) / (float)255);
                                        vert.weight.Add((f.readByte()) / (float)255);
                                    }
                                    if (AttrArr[attr].vertType == 274)
                                    {
                                        vert.weight.Add((f.readShort()) / (float)255);
                                        vert.weight.Add((f.readShort()) / (float)255);
                                    }
                                    break;

                                default:
                                    //     //Console.WriteLine(AttrArr[attr].attName + " Unknown type " + AttrArr[attr].vertType.ToString("x") + " 0x");
                                    break;
                                }
                            }
                            poly.vertices.Add(vert);
                        }
                        int LoadLOD = FSHPArr[m].lodMdlCount - 1;

                        f.seek((int)FSHPArr[m].lodMdlOff);
                        for (int lod = 0; lod < FSHPArr[m].lodMdlCount; lod++)
                        {
                            long SubMeshOff        = f.readInt64();
                            long unk1              = f.readInt64();
                            long unk2              = f.readInt64();
                            long indxBuffOff       = f.readInt64();
                            int  FaceBuffer        = f.readInt();
                            int  PrimativefaceType = f.readInt();
                            int  faceType          = f.readInt();
                            int  FaceCount         = f.readInt();
                            int  elmSkip           = f.readInt();
                            int  subMeshCount      = f.readInt();

                            int temp = f.pos();



                            f.seek(FaceBuffer + DataStart);
                            if (faceType == 1)
                            {
                                FaceCount = FaceCount / 3;
                            }
                            if (faceType == 2)
                            {
                                FaceCount = FaceCount / 6;
                            }


                            if (lod == LoadLOD)
                            {
                                for (int face = 0; face < FaceCount; face++)
                                {
                                    if (faceType == 1)
                                    {
                                        poly.faces.Add(new List <int> {
                                            elmSkip + f.readShort(), elmSkip + f.readShort(), elmSkip + f.readShort()
                                        });
                                    }
                                    else if (faceType == 2)
                                    {
                                        poly.faces.Add(new List <int> {
                                            elmSkip + f.readInt(), elmSkip + f.readInt(), elmSkip + f.readInt()
                                        });
                                    }
                                    else
                                    {
                                        Console.Write("UnkFaceFormat");
                                    }
                                }
                            }

                            f.seek(temp);
                        }



                        f.seek((int)FMATheaders[FSHPArr[m].fmatIndx].texSelOff);
                        List <string> MatTexList = new List <string>();
                        for (int tex = 0; FMATheaders[FSHPArr[m].fmatIndx].texAttSelCount > tex; tex++)
                        {
                            string TextureName = f.readString((int)f.readInt64() + 2, -1).ToLower();
                            MatTexList.Add(TextureName);
                        }

                        if (MatTexList.Count > 0)
                        {
                            poly.texNames.Add(MatTexList[0]);
                        }

                        //Console.WriteLine(String.Join(",",MatTexList));

                        model.poly.Add(poly);
                    }
                    models.Add(model);
                    f.seek(NextFMDL);
                }
            }
        }
Пример #13
0
        public void Read(FileData f)
        {
            f.Endian = Endianness.Little;
            f.seek(4);
            int count = f.readInt();

            f.skip(12);
            int dataCount  = f.readInt();
            int boneCount  = f.readInt();
            int hashCount  = f.readInt();
            int hashOffset = f.readInt() + 0x28;

            f.skip(4);

            Console.WriteLine("Count " + count);

            for (int i = 0; i < dataCount; i++)
            {
                Console.WriteLine("Bone " + i + " start at " + f.pos().ToString("x"));
                // 3 sections
                int secLength = f.readInt();
                int someCount = f.readInt(); // usually 2?

                int size1 = f.readInt();
                Console.Write(size1 + "\t");
                for (int j = 0; j < (size1 / 4) - 1; j++)
                {
                    Console.Write(f.readShort() + " " + f.readShort() + "\t");
                }
                Console.WriteLine();

                int size2 = f.readInt();
                Console.Write(size2 + "\t");
                for (int j = 0; j < (size2 / 4) - 1; j++)
                {
                    Console.Write(f.readShort() + " " + f.readShort() + "\t");
                }
                Console.WriteLine();

                int size3 = f.readInt();
                Console.Write(size3 + "\t");
                for (int j = 0; j < (size3 / 4) - 1; j++)
                {
                    Console.Write(f.readShort() + " " + f.readShort() + "\t");
                }
                Console.WriteLine();

                int size4 = f.readInt();
                Console.Write(size4 + "\t");
                for (int j = 0; j < (size4 / 4) - 1; j++)
                {
                    Console.Write(f.readShort() + " " + f.readShort() + "\t");
                }
                Console.WriteLine();

                int size5 = f.readInt();
                Console.Write(size5 + "\t");
                for (int j = 0; j < (size5 / 4) - 1; j++)
                {
                    Console.Write(f.readShort() + " " + f.readShort() + "\t");
                }
                Console.WriteLine();

                f.skip(8);
            }

            Console.WriteLine("0x" + f.pos().ToString("X"));
            f.skip(8);
            int hashSize = f.readInt();
            int unk      = f.readInt();

            for (int i = 0; i < hashCount; i++)
            {
                Console.WriteLine(f.readInt().ToString("X"));
            }
        }
Пример #14
0
        public void OpenMBN(FileData f)
        {
            f.Endian = Endianness.Little;
            f.seek(0);

            int format = f.readShort();

            f.skip(2);//0xFFFF
            int flags     = f.readInt();
            int mode      = f.readInt();
            int meshCount = f.readInt();

            int length = 0;

            if (mode == 1)
            {
                //One Attribute
                int count = f.readInt();
                for (int i = 0; i < count; i++)
                {
                    VertexAttribute a = new VertexAttribute();
                    a.Read(f);
                    Attributes.Add(a);
                }
                length = f.readInt();
            }

            // Get Mesh Nodes

            /*List<BCH_Mesh> meshes = new List<BCH_Mesh>();
             * foreach(BCH_Mesh m in Nodes)
             * {
             *  meshes.Add(m);
             *  foreach (BCH_Mesh m2 in m.Nodes)
             *      meshes.Add(m);
             * }*/

            for (int i = 0; i < meshCount; i++)
            {
                BCH_Mesh m = (BCH_Mesh)Nodes[i];

                int polyCount = f.readInt();
                for (int j = 0; j < polyCount; j++)
                {
                    BCH_PolyGroup pg = new BCH_PolyGroup();
                    m.Nodes.Add(pg);
                    int   nodeCount = f.readInt();
                    int[] nodeList  = new int[nodeCount];
                    pg.BoneList = (nodeList);
                    for (int k = 0; k < nodeCount; k++)
                    {
                        nodeList[k] = f.readInt();
                    }
                    pg.Count = (f.readInt());
                    if ((flags & 2) > 0)
                    {
                        f.readInt();
                    }
                }
            }


            if (format != 4)
            {
                f.align(32);
            }

            int stride = 0;

            foreach (VertexAttribute a in Attributes)
            {
                stride += _3DSGPU.getTypeSize(a.format) * _3DSGPU.getFormatSize(a.type);
            }

            // Vertex Bank
            Vertices = new Vertex[length / (stride + stride % 2)];
            for (int vi = 0; vi < Vertices.Length; vi++)
            {
                Vertex v = new Vertex();
                foreach (VertexAttribute a in Attributes)
                {
                    //f.align(2);
                    a.ReadVertex(f, ref v);
                }
                Vertices[vi] = v;
            }
            f.align(32);


            for (int i = 0; i < meshCount; i++)
            {
                BCH_Mesh m = (BCH_Mesh)Nodes[i];

                int pi = 0;
                foreach (BCH_PolyGroup pg in m.Nodes)
                {
                    pg.Text  = "Polygroup_" + pi++;
                    pg.Faces = new int[pg.Count];
                    for (int k = 0; k < pg.Count; k++)
                    {
                        pg.Faces[k] = f.readShort();
                    }
                    f.align(32);
                }
            }
        }
Пример #15
0
        public override void Read(string filename)
        {
            FileData f = new FileData(filename);

            f.Endian = System.IO.Endianness.Little;
            f.skip(4);
            int backwardCompatibility = f.readByte();
            int forwardCompatibility  = f.readByte();
            int version = f.readShort();

            int mainHeaderOffset   = f.readInt();
            int stringTableOffset  = f.readInt();
            int gpuCommandsOffset  = f.readInt();
            int dataOffset         = f.readInt();
            int dataExtendedOffset = 0;
            int dataExtendedLength = 0;

            if (backwardCompatibility > 0x20)
            {
                dataExtendedOffset = f.readInt();
            }
            int relocationTableOffset = f.readInt();

            int mainHeaderLength  = f.readInt();
            int stringTableLength = f.readInt();
            int gpuCommandsLength = f.readInt();
            int dataLength        = f.readInt();

            if (backwardCompatibility > 0x20)
            {
                dataExtendedLength = f.readInt();
            }
            int relocationTableLength = f.readInt();

            int uninitializedDataSectionLength        = f.readInt();
            int uninitializedDescriptionSectionLength = f.readInt();

            if (backwardCompatibility > 7)
            {
                int flags        = f.readShort();
                int addressCount = f.readShort();
            }

            // Relocation table
            for (int i = 0; i < relocationTableLength; i += 4)
            {
                f.seek(relocationTableOffset + i);
                int  val  = f.readInt();
                int  off  = val & 0x1FFFFFF;
                byte flag = (byte)(val >> 25);

                switch (flag)
                {
                case 0:
                    f.seek((off * 4) + mainHeaderOffset);
                    f.writeInt((off * 4) + mainHeaderOffset, f.readInt() + mainHeaderOffset);
                    break;

                case 1:
                    f.seek(off + mainHeaderOffset);
                    f.writeInt((off) + mainHeaderOffset, f.readInt() + stringTableOffset);
                    break;

                case 2:
                    f.seek((off * 4) + mainHeaderOffset);
                    f.writeInt((off * 4) + mainHeaderOffset, f.readInt() + gpuCommandsOffset);
                    break;

                case 0xc:
                    f.seek((off * 4) + mainHeaderOffset);
                    f.writeInt((off * 4) + mainHeaderOffset, f.readInt() + dataOffset);
                    break;
                }

                f.seek((off * 4) + gpuCommandsOffset);
                if (backwardCompatibility < 6)
                {
                    switch (flag)
                    {
                    case 0x23: f.writeInt((off * 4) + gpuCommandsOffset, f.readInt() + dataOffset); break;     //Texture

                    case 0x25: f.writeInt((off * 4) + gpuCommandsOffset, f.readInt() + dataOffset); break;     //Vertex

                    //case 0x26: f.writeInt((off * 4) + int gpuCommandsOffset, ((f.readInt() + int dataOffset) & 0x7fffffff) | 0x80000000); break; //Index 16 bits mode
                    case 0x27: f.writeInt((off * 4) + gpuCommandsOffset, (f.readInt() + dataOffset) & 0x7fffffff); break;     //Index 8 bits mode
                    }
                }
                else if (backwardCompatibility < 8)
                {
                    switch (flag)
                    {
                    case 0x24: f.writeInt((off * 4) + gpuCommandsOffset, f.readInt() + dataOffset); break;     //Texture

                    case 0x26: f.writeInt((off * 4) + gpuCommandsOffset, f.readInt() + dataOffset); break;     //Vertex

                    //case 0x27: writer.Write(((peek(input) + int dataOffset) & 0x7fffffff) | 0x80000000); break; //Index 16 bits mode
                    case 0x28: f.writeInt((off * 4) + gpuCommandsOffset, (f.readInt() + dataOffset) & 0x7fffffff); break;     //Index 8 bits mode
                    }
                }
                else if (backwardCompatibility < 0x21)
                {
                    switch (flag)
                    {
                    case 0x25: f.writeInt((off * 4) + gpuCommandsOffset, f.readInt() + dataOffset); break;     //Texture

                    case 0x27: f.writeInt((off * 4) + gpuCommandsOffset, f.readInt() + dataOffset); break;     //Vertex

                    //case 0x28: writer.Write(((peek(input) + int dataOffset) & 0x7fffffff) | 0x80000000); break; //Index 16 bits mode
                    case 0x29: f.writeInt((off * 4) + gpuCommandsOffset, (f.readInt() + dataOffset) & 0x7fffffff); break;     //Index 8 bits mode
                    }
                }
                else
                {
                    switch (flag)
                    {
                    case 0x25: f.writeInt((off * 4) + gpuCommandsOffset, f.readInt() + dataOffset); break;     //Texture

                    case 0x26: f.writeInt((off * 4) + gpuCommandsOffset, f.readInt() + dataOffset); break;     //Vertex relative to Data Offset

                    //case 0x27: writer.Write(((peek(input) + int dataOffset) & 0x7fffffff) | 0x80000000); break; //Index 16 bits mode relative to Data Offset
                    case 0x28: f.writeInt((off * 4) + gpuCommandsOffset, (f.readInt() + dataOffset) & 0x7fffffff); break; //Index 8 bits mode relative to Data Offset

                    case 0x2b: f.writeInt((off * 4) + gpuCommandsOffset, f.readInt() + dataExtendedOffset); break;        //Vertex relative to Data Extended Offset

                    //case 0x2c: writer.Write(((peek(input) + int dataExtendedOffset) & 0x7fffffff) | 0x80000000); break; //Index 16 bits mode relative to Data Extended Offset
                    case 0x2d: f.writeInt((off * 4) + gpuCommandsOffset, (f.readInt() + dataExtendedOffset) & 0x7fffffff); break;     //Index 8 bits mode relative to Data Extended Offset
                    }
                }
            }

            //File.WriteAllBytes(filename + "_offset", f.getSection(0, f.size()));

            f.seek(mainHeaderOffset);
            int modelsPointerTableOffset        = f.readInt();
            int modelsPointerTableEntries       = f.readInt();
            int modelsNameOffset                = f.readInt();
            int materialsPointerTableOffset     = f.readInt();
            int materialsPointerTableEntries    = f.readInt();
            int materialsNameOffset             = f.readInt();
            int shadersPointerTableOffset       = f.readInt();
            int shadersPointerTableEntries      = f.readInt();
            int shadersNameOffset               = f.readInt();
            int texturesPointerTableOffset      = f.readInt();
            int texturesPointerTableEntries     = f.readInt();
            int texturesNameOffset              = f.readInt();
            int materialsLUTPointerTableOffset  = f.readInt();
            int materialsLUTPointerTableEntries = f.readInt();
            int materialsLUTNameOffset          = f.readInt();
            int lightsPointerTableOffset        = f.readInt();
            int lightsPointerTableEntries       = f.readInt();
            int lightsNameOffset                = f.readInt();
            int camerasPointerTableOffset       = f.readInt();
            int camerasPointerTableEntries      = f.readInt();
            int camerasNameOffset               = f.readInt();
            int fogsPointerTableOffset          = f.readInt();
            int fogsPointerTableEntries         = f.readInt();
            int fogsNameOffset = f.readInt();
            int skeletalAnimationsPointerTableOffset    = f.readInt();
            int skeletalAnimationsPointerTableEntries   = f.readInt();
            int skeletalAnimationsNameOffset            = f.readInt();
            int materialAnimationsPointerTableOffset    = f.readInt();
            int materialAnimationsPointerTableEntries   = f.readInt();
            int materialAnimationsNameOffset            = f.readInt();
            int visibilityAnimationsPointerTableOffset  = f.readInt();
            int visibilityAnimationsPointerTableEntries = f.readInt();
            int visibilityAnimationsNameOffset          = f.readInt();
            int lightAnimationsPointerTableOffset       = f.readInt();
            int lightAnimationsPointerTableEntries      = f.readInt();
            int lightAnimationsNameOffset           = f.readInt();
            int cameraAnimationsPointerTableOffset  = f.readInt();
            int cameraAnimationsPointerTableEntries = f.readInt();
            int cameraAnimationsNameOffset          = f.readInt();
            int fogAnimationsPointerTableOffset     = f.readInt();
            int fogAnimationsPointerTableEntries    = f.readInt();
            int fogAnimationsNameOffset             = f.readInt();
            int scenePointerTableOffset             = f.readInt();
            int scenePointerTableEntries            = f.readInt();
            int sceneNameOffset = f.readInt();

            Console.WriteLine(modelsPointerTableEntries > 0 ? "Has Models" : "");
            Console.WriteLine(shadersPointerTableEntries > 0 ? "Has Shaders" : "");
            Console.WriteLine(texturesPointerTableEntries > 0 ? "Has Textures" : "");
            Console.WriteLine(materialsPointerTableEntries > 0 ? "Has Materials" : "");
            Console.WriteLine(materialsLUTPointerTableEntries > 0 ? "Has Material LUT" : "");
            Console.WriteLine(materialAnimationsPointerTableEntries > 0 ? "Has Material Animation" : "");
            Console.WriteLine(lightsPointerTableEntries > 0 ? "Has Lights" : "");
            Console.WriteLine(lightAnimationsPointerTableEntries > 0 ? "Has LightAnimations" : "");
            Console.WriteLine(camerasPointerTableEntries > 0 ? "Has Camera" : "");
            Console.WriteLine(cameraAnimationsPointerTableEntries > 0 ? "Has CameraAnimation" : "");
            Console.WriteLine(fogsPointerTableEntries > 0 ? "Has Fog" : "");
            Console.WriteLine(fogAnimationsPointerTableEntries > 0 ? "Has FogAnimation" : "");
            Console.WriteLine(skeletalAnimationsPointerTableEntries > 0 ? "Has Skeletal Animations" : "");
            Console.WriteLine(visibilityAnimationsPointerTableEntries > 0 ? "Has Visibility" : "");
            Console.WriteLine(scenePointerTableEntries > 0 ? "Has Scene" : "");

            // Textures
            for (int index = 0; index < texturesPointerTableEntries; index++)
            {
                f.seek(texturesPointerTableOffset + (index * 4));
                int dOffset = f.readInt();
                f.seek(dOffset);

                // one for each mip I assume
                int textureCommandsOffset     = f.readInt();
                int textureCommandsWordCount  = f.readInt();
                int textureCommandsOffset2    = f.readInt();
                int textureCommandsWordCount2 = f.readInt();
                int textureCommandsOffset3    = f.readInt();
                int textureCommandsWordCount3 = f.readInt();

                int unk = f.readInt();

                BCH_Texture tex = new BCH_Texture();
                tex.Text = f.readString(f.readInt(), -1);
                Textures.Nodes.Add(tex);

                f.seek(textureCommandsOffset);
                tex.ReadParameters(f, textureCommandsWordCount);
            }


            //Models

            for (int index = 0; index < modelsPointerTableEntries; index++)
            {
                f.seek(modelsPointerTableOffset + (index * 4));

                f.seek(f.readInt());

                BCH_Model model = new BCH_Model();
                Models.Nodes.Add(model);
                model.flags                     = f.readByte();
                model.skeletonScaleType         = f.readByte();
                model.silhouetteMaterialEntries = f.readShort();
                model.worldTransform            = new OpenTK.Matrix4(f.readFloat(), f.readFloat(), f.readFloat(), f.readFloat()
                                                                     , f.readFloat(), f.readFloat(), f.readFloat(), f.readFloat()
                                                                     , f.readFloat(), f.readFloat(), f.readFloat(), f.readFloat()
                                                                     , 0, 0, 0, 1);

                int materialsTableOffset  = f.readInt();
                int materialsTableEntries = f.readInt();
                int materialNameOffset    = f.readInt();
                int verticesTableOffset   = f.readInt();
                int verticesTableEntries  = f.readInt();
                f.skip(0x28);
                int skeletonOffset              = f.readInt();
                int skeletonEntries             = f.readInt();
                int skeletonNameOffset          = f.readInt();
                int objectsNodeVisibilityOffset = f.readInt();
                int objectsNodeCount            = f.readInt();
                model.Text = f.readString(f.readInt(), -1);
                int objectsNodeNameEntries = f.readInt();
                int objectsNodeNameOffset  = f.readInt();
                f.readInt(); //0x0
                int metaDataPointerOffset = f.readInt();

                f.seek(objectsNodeVisibilityOffset);
                int nodeVisibility = f.readInt();

                string[] objectName = new string[objectsNodeNameEntries];
                f.seek(objectsNodeNameOffset);
                int rootReferenceBit = f.readInt();
                int rootLeftNode     = f.readShort();
                int rootRightNode    = f.readShort();
                int rootNameOffset   = f.readInt();

                //Console.WriteLine(rootReferenceBit.ToString("x") + " " + f.readString(rootNameOffset, -1) + " " + rootLeftNode + " " + rootRightNode);
                // Object name tree Radix Tree
                for (int i = 0; i < objectsNodeNameEntries; i++)
                {
                    int   referenceBit = f.readInt();
                    short leftNode     = (short)f.readShort();
                    short rightNode    = (short)f.readShort();
                    objectName[i] = f.readString(f.readInt(), -1);
                    Console.WriteLine((referenceBit >> 3) + " " + (referenceBit & 0x7) + " " + objectName[i] + " " + leftNode + " " + rightNode);
                }

                //TODO: Metadata, boundingbox, normal mesh, materials
                f.seek(verticesTableOffset);
                Dictionary <int, BCH_Mesh> MeshIndex = new Dictionary <int, BCH_Mesh>();
                int nim = 0;
                for (int i = 0; i < verticesTableEntries; i++)
                {
                    BCH_Mesh Mesh = new BCH_Mesh();
                    Mesh.MaterialIndex = f.readShort();
                    int mflags = f.readShort();
                    int meshId = f.readShort();
                    if (!MeshIndex.ContainsKey(meshId))
                    {
                        MeshIndex.Add(meshId, Mesh);
                        Mesh.Text = nim < objectName.Length ? objectName[nim++] : i + "";
                        model.Nodes.Add(Mesh);
                    }
                    else
                    {
                        BCH_Mesh m = MeshIndex[meshId];
                        Mesh.Text = m.Text;
                        model.Nodes.Insert(model.Nodes.IndexOf(m) - 1, Mesh);
                    }

                    // node visibility TODO: finish...
                    Mesh.Checked = ((nodeVisibility & (1 << i)) > 0);

                    Mesh.renderPriority = f.readShort();

                    int vshAttBufferCommandOffset = f.readInt();
                    int vshAttBufferCommandCount  = f.readInt();
                    int faceOffset = f.readInt();
                    int faceCount  = f.readInt();
                    int vshAttBufferCommandOffsetEx = f.readInt();
                    int vshAttBufferCommandCountEx  = f.readInt();

                    Vector3 Center     = new Vector3(f.readFloat(), f.readFloat(), f.readFloat());
                    int     flagoffset = f.readInt(); // flagsOffset
                    f.skip(4);                        // 0?
                    int boundingBoxOffset = f.readInt();
                }


                //Materials
                Console.WriteLine(materialsTableOffset.ToString("x") + " " + materialsPointerTableOffset.ToString("x"));
                for (int i = 0; i < materialsTableEntries; i++)
                {
                    f.seek(materialsTableOffset + (i * 0x2c));
                    int paramOffset = f.readInt();
                    f.skip(12); // other offsets
                    int texCommandOffset = f.readInt();
                    int texCommandCount  = f.readInt();
                    int mapperOffset     = f.readInt();

                    BCH_Material mat = new BCH_Material();
                    Materials.Nodes.Add(mat);
                    mat.Text = f.readString(f.readInt(), -1);
                    Console.WriteLine(mat.Text);
                    //Console.WriteLine(f.readString(f.readInt(), -1));
                    //Console.WriteLine(f.readString(f.readInt(), -1));
                    //Console.WriteLine(f.readString(f.readInt(), -1));

                    // TODO: Parameters
                }


                //Skeleton
                f.seek(skeletonOffset);
                for (int bindex = 0; bindex < skeletonEntries; bindex++)
                {
                    Bone bone      = new Bone(model.skeleton);
                    int  boneFlags = f.readInt();
                    bone.parentIndex = (short)f.readShort();
                    short boneSpace = (short)f.readShort();
                    bone.scale       = new float[3];
                    bone.rotation    = new float[3];
                    bone.position    = new float[3];
                    bone.scale[0]    = f.readFloat();
                    bone.scale[1]    = f.readFloat();
                    bone.scale[2]    = f.readFloat();
                    bone.rotation[0] = f.readFloat();
                    bone.rotation[1] = f.readFloat();
                    bone.rotation[2] = f.readFloat();
                    bone.position[0] = f.readFloat();
                    bone.position[1] = f.readFloat();
                    bone.position[2] = f.readFloat();

                    // bone matrix... not really needed to be stored per say
                    f.skip(4 * 4 * 3);

                    bone.Text = f.readString(f.readInt(), -1);

                    int metaDataPointerOffset2 = f.readInt();
                    if (metaDataPointerOffset2 != 0)
                    {
                        int position = f.pos();
                        f.seek(metaDataPointerOffset2);
                        //bone.userData = getMetaData(input);
                        f.seek(position);
                    }

                    model.skeleton.bones.Add(bone);
                }
                model.skeleton.reset();
                model.skeleton.update();
            }
        }
Пример #16
0
        public override void Read(string filename)
        {
            bchHeader header = new bchHeader();
            FileData  f      = new FileData(filename);

            f.Endian = System.IO.Endianness.Little;

            f.skip(4);
            header.backwardCompatibility = f.readByte();
            header.forwardCompatibility  = f.readByte();
            header.version = f.readShort();

            header.mainHeaderOffset  = f.readInt();
            header.stringTableOffset = f.readInt();
            header.gpuCommandsOffset = f.readInt();
            header.dataOffset        = f.readInt();
            if (header.backwardCompatibility > 0x20)
            {
                header.dataExtendedOffset = f.readInt();
            }
            header.relocationTableOffset = f.readInt();

            header.mainHeaderLength  = f.readInt();
            header.stringTableLength = f.readInt();
            header.gpuCommandsLength = f.readInt();
            header.dataLength        = f.readInt();
            if (header.backwardCompatibility > 0x20)
            {
                header.dataExtendedLength = f.readInt();
            }
            header.relocationTableLength = f.readInt();

            header.uninitializedDataSectionLength        = f.readInt();
            header.uninitializedDescriptionSectionLength = f.readInt();

            if (header.backwardCompatibility > 7)
            {
                header.flags        = f.readShort();
                header.addressCount = f.readShort();
            }

            // Relocation table
            for (int i = 0; i < header.relocationTableLength; i += 4)
            {
                f.seek(header.relocationTableOffset + i);
                int  val  = f.readInt();
                int  off  = val & 0x1FFFFFF;
                byte flag = (byte)(val >> 25);

                switch (flag)
                {
                case 0:
                    f.seek((off * 4) + header.mainHeaderOffset);
                    f.writeInt((off * 4) + header.mainHeaderOffset, f.readInt() + header.mainHeaderOffset);
                    break;

                case 1:
                    f.seek(off + header.mainHeaderOffset);
                    f.writeInt((off) + header.mainHeaderOffset, f.readInt() + header.stringTableOffset);
                    break;

                case 2:
                    f.seek((off * 4) + header.mainHeaderOffset);
                    f.writeInt((off * 4) + header.mainHeaderOffset, f.readInt() + header.gpuCommandsOffset);
                    break;

                case 0xc:
                    f.seek((off * 4) + header.mainHeaderOffset);
                    f.writeInt((off * 4) + header.mainHeaderOffset, f.readInt() + header.dataOffset);
                    break;
                }

                f.seek((off * 4) + header.gpuCommandsOffset);
                if (header.backwardCompatibility < 6)
                {
                    switch (flag)
                    {
                    case 0x23: f.writeInt((off * 4) + header.gpuCommandsOffset, f.readInt() + header.dataOffset); break;     //Texture

                    case 0x25: f.writeInt((off * 4) + header.gpuCommandsOffset, f.readInt() + header.dataOffset); break;     //Vertex

                    //case 0x26: f.writeInt((off * 4) + header.gpuCommandsOffset, ((f.readInt() + header.dataOffset) & 0x7fffffff) | 0x80000000); break; //Index 16 bits mode
                    case 0x27: f.writeInt((off * 4) + header.gpuCommandsOffset, (f.readInt() + header.dataOffset) & 0x7fffffff); break;     //Index 8 bits mode
                    }
                }
                else if (header.backwardCompatibility < 8)
                {
                    switch (flag)
                    {
                    case 0x24: f.writeInt((off * 4) + header.gpuCommandsOffset, f.readInt() + header.dataOffset); break;     //Texture

                    case 0x26: f.writeInt((off * 4) + header.gpuCommandsOffset, f.readInt() + header.dataOffset); break;     //Vertex

                    //case 0x27: writer.Write(((peek(input) + header.dataOffset) & 0x7fffffff) | 0x80000000); break; //Index 16 bits mode
                    case 0x28: f.writeInt((off * 4) + header.gpuCommandsOffset, (f.readInt() + header.dataOffset) & 0x7fffffff); break;     //Index 8 bits mode
                    }
                }
                else if (header.backwardCompatibility < 0x21)
                {
                    switch (flag)
                    {
                    case 0x25: f.writeInt((off * 4) + header.gpuCommandsOffset, f.readInt() + header.dataOffset); break;     //Texture

                    case 0x27: f.writeInt((off * 4) + header.gpuCommandsOffset, f.readInt() + header.dataOffset); break;     //Vertex

                    //case 0x28: writer.Write(((peek(input) + header.dataOffset) & 0x7fffffff) | 0x80000000); break; //Index 16 bits mode
                    case 0x29: f.writeInt((off * 4) + header.gpuCommandsOffset, (f.readInt() + header.dataOffset) & 0x7fffffff); break;     //Index 8 bits mode
                    }
                }
                else
                {
                    switch (flag)
                    {
                    case 0x25: f.writeInt((off * 4) + header.gpuCommandsOffset, f.readInt() + header.dataOffset); break;     //Texture

                    case 0x26: f.writeInt((off * 4) + header.gpuCommandsOffset, f.readInt() + header.dataOffset); break;     //Vertex relative to Data Offset

                    //case 0x27: writer.Write(((peek(input) + header.dataOffset) & 0x7fffffff) | 0x80000000); break; //Index 16 bits mode relative to Data Offset
                    case 0x28: f.writeInt((off * 4) + header.gpuCommandsOffset, (f.readInt() + header.dataOffset) & 0x7fffffff); break; //Index 8 bits mode relative to Data Offset

                    case 0x2b: f.writeInt((off * 4) + header.gpuCommandsOffset, f.readInt() + header.dataExtendedOffset); break;        //Vertex relative to Data Extended Offset

                    //case 0x2c: writer.Write(((peek(input) + header.dataExtendedOffset) & 0x7fffffff) | 0x80000000); break; //Index 16 bits mode relative to Data Extended Offset
                    case 0x2d: f.writeInt((off * 4) + header.gpuCommandsOffset, (f.readInt() + header.dataExtendedOffset) & 0x7fffffff); break;     //Index 8 bits mode relative to Data Extended Offset
                    }
                }
            }


            // Content Header
            f.seek(header.mainHeaderOffset);
            bchContentHeader content = new bchContentHeader();

            {
                content.modelsPointerTableOffset        = f.readInt();
                content.modelsPointerTableEntries       = f.readInt();
                content.modelsNameOffset                = f.readInt();
                content.materialsPointerTableOffset     = f.readInt();
                content.materialsPointerTableEntries    = f.readInt();
                content.materialsNameOffset             = f.readInt();
                content.shadersPointerTableOffset       = f.readInt();
                content.shadersPointerTableEntries      = f.readInt();
                content.shadersNameOffset               = f.readInt();
                content.texturesPointerTableOffset      = f.readInt();
                content.texturesPointerTableEntries     = f.readInt();
                content.texturesNameOffset              = f.readInt();
                content.materialsLUTPointerTableOffset  = f.readInt();
                content.materialsLUTPointerTableEntries = f.readInt();
                content.materialsLUTNameOffset          = f.readInt();
                content.lightsPointerTableOffset        = f.readInt();
                content.lightsPointerTableEntries       = f.readInt();
                content.lightsNameOffset                = f.readInt();
                content.camerasPointerTableOffset       = f.readInt();
                content.camerasPointerTableEntries      = f.readInt();
                content.camerasNameOffset               = f.readInt();
                content.fogsPointerTableOffset          = f.readInt();
                content.fogsPointerTableEntries         = f.readInt();
                content.fogsNameOffset = f.readInt();
                content.skeletalAnimationsPointerTableOffset    = f.readInt();
                content.skeletalAnimationsPointerTableEntries   = f.readInt();
                content.skeletalAnimationsNameOffset            = f.readInt();
                content.materialAnimationsPointerTableOffset    = f.readInt();
                content.materialAnimationsPointerTableEntries   = f.readInt();
                content.materialAnimationsNameOffset            = f.readInt();
                content.visibilityAnimationsPointerTableOffset  = f.readInt();
                content.visibilityAnimationsPointerTableEntries = f.readInt();
                content.visibilityAnimationsNameOffset          = f.readInt();
                content.lightAnimationsPointerTableOffset       = f.readInt();
                content.lightAnimationsPointerTableEntries      = f.readInt();
                content.lightAnimationsNameOffset           = f.readInt();
                content.cameraAnimationsPointerTableOffset  = f.readInt();
                content.cameraAnimationsPointerTableEntries = f.readInt();
                content.cameraAnimationsNameOffset          = f.readInt();
                content.fogAnimationsPointerTableOffset     = f.readInt();
                content.fogAnimationsPointerTableEntries    = f.readInt();
                content.fogAnimationsNameOffset             = f.readInt();
                content.scenePointerTableOffset             = f.readInt();
                content.scenePointerTableEntries            = f.readInt();
                content.sceneNameOffset = f.readInt();
            }

            //Shaders (unused for now, until someone wants to add them)
            for (int index = 0; index < content.shadersPointerTableEntries; index++)
            {
                f.seek(content.shadersPointerTableOffset + (index * 4));
                int dataOffset = f.readInt();
                f.seek(dataOffset);

                int shaderDataOffset = f.readInt();
                int shaderDataLength = f.readInt();
            }

            // Textures
            // WIP Section
            for (int index = 0; index < content.texturesPointerTableEntries; index++)
            {
                f.seek(content.texturesPointerTableOffset + (index * 4));
                int dOffset = f.readInt();
                f.seek(dOffset);

                int textureCommandsOffset    = f.readInt();
                int textureCommandsWordCount = f.readInt();

                f.seek(f.pos() + 0x14);
                String textureName = f.readString(f.readInt(), -1);
                //Debug.WriteLine("gpuCommandOffset: " + header.gpuCommandsOffset.ToString("X"));
                f.seek(textureCommandsOffset);
                //Debug.WriteLine("textureCommandOffset: " + textureCommandsOffset.ToString("X"));
                BCH_Texture tex = new BCH_Texture();
                textures.Add(textureName, tex);

                tex.height = f.readShort();
                tex.width  = f.readShort();
                f.skip(12);
                int doffset = f.readInt();
                //Debug.WriteLine("doffset: " + doffset.ToString("X"));
                f.skip(4);
                tex.type = f.readInt();
                tex.data = f.getSection(doffset, f.size() - doffset);

                if (tex.type == 12)
                {
                    tex.display = NUT.loadImage(Pixel.decodeETC(tex.data, tex.width, tex.height));
                }
            }

            // Model data

            for (int modelIndex = 0; modelIndex < content.modelsPointerTableEntries; modelIndex++)
            {
                f.seek(content.modelsPointerTableOffset + (modelIndex * 4));
                int objectsHeaderOffset = f.readInt();

                // Objects
                f.seek(objectsHeaderOffset);
                BCH_Model model = new BCH_Model();
                models.Add(model);

                model.flags                     = f.readByte();
                model.skeletonScaleType         = f.readByte();
                model.silhouetteMaterialEntries = f.readShort();

                model.worldTransform = new Matrix4(f.readFloat(), f.readFloat(), f.readFloat(), f.readFloat()
                                                   , f.readFloat(), f.readFloat(), f.readFloat(), f.readFloat()
                                                   , f.readFloat(), f.readFloat(), f.readFloat(), f.readFloat()
                                                   , 0, 0, 0, 1);

                model.materialsTableOffset  = f.readInt();
                model.materialsTableEntries = f.readInt();
                model.materialsNameOffset   = f.readInt();
                model.verticesTableOffset   = f.readInt();
                //Debug.WriteLine("Mesh Count: " + f.pos().ToString("X"));
                model.verticesTableEntries = f.readInt();
                f.skip(0x28);
                model.skeletonOffset              = f.readInt();
                model.skeletonEntries             = f.readInt();
                model.skeletonNameOffset          = f.readInt();
                model.objectsNodeVisibilityOffset = f.readInt();
                model.objectsNodeCount            = f.readInt();
                model.name = f.readString(f.readInt(), -1);
                model.objectsNodeNameEntries = f.readInt();
                model.objectsNodeNameOffset  = f.readInt();
                f.readInt(); //0x0
                model.metaDataPointerOffset = f.readInt();

                f.seek(model.objectsNodeVisibilityOffset);
                int nodeVisibility = f.readInt();

                string[] objectName = new string[model.objectsNodeNameEntries];
                f.seek(model.objectsNodeNameOffset);
                int rootReferenceBit = f.readInt(); //Radix tree
                int rootLeftNode     = f.readShort();
                int rootRightNode    = f.readShort();
                int rootNameOffset   = f.readInt() + header.mainHeaderOffset;

                for (int i = 0; i < model.objectsNodeNameEntries; i++)
                {
                    int   referenceBit = f.readInt();
                    short leftNode     = (short)f.readShort();
                    short rightNode    = (short)f.readShort();
                    objectName[i] = f.readString(f.readInt(), -1);
                    //Debug.WriteLine(objectName[i]);
                }

                // Materials
                // NOTE: MATERIALS AND OBJECT SECTIONS ARE REALLY MESSY ATM

                String[] materialNames = new String[model.materialsTableEntries];
                for (int index = 0; index < model.materialsTableEntries; index++)
                {
                    f.seek(model.materialsTableOffset + (index * 0x2c));

                    int materialParametersOffset = f.readInt();
                    f.readInt();
                    f.readInt();
                    f.readInt();
                    int textureCommandsOffset    = f.readInt();
                    int textureCommandsWordCount = f.readInt();

                    int materialMapperOffset = f.readInt();
                    materialNames[index] = f.readString(f.readInt(), -1);
                }

                // Object Descriptions...
                // Assumes MBN is already loaded for now
                f.seek(model.verticesTableOffset);
                List <objDes> objDescriptors = new List <objDes>();
                Debug.WriteLine(model.name);
                if (mbn == null)
                {
                    mbn = new Smash_Forge.MBN();
                    for (int index = 0; index < model.verticesTableEntries; index++)
                    {
                        mbn.mesh.Add(new MBN.Mesh());
                    }
                    mbn.PreRender();
                }
                for (int index = 0; index < mbn.mesh.Count; index++)
                {
                    int i = f.readShort();
                    if (index > mbn.mesh.Count)
                    {
                        break;
                    }
                    if (i > materialNames.Length)
                    {
                        break;
                    }
                    mbn.mesh[index].texId = textures[materialNames[i]].display;
                    Console.WriteLine("Tex index" + mbn.mesh[index].texId);
                    f.skip(2); // flags
                    int nameId = f.readShort();
                    mbn.mesh[index].name = objectName[nameId];

                    // node visibility TODO: finish...
                    //mbn.mesh[index].isVisible = ((nodeVisibility & (1 << nameId)) > 0);

                    mbn.mesh[index].renderPriority = f.readShort();

                    objDes des = new objDes();
                    objDescriptors.Add(des);
                    des.vshAttBufferCommandOffset = f.readInt();
                    des.vshAttBufferCommandCount  = f.readInt();
                    des.faceOffset = f.readInt();
                    des.faceCount  = f.readInt();
                    des.vshAttBufferCommandOffsetEx = f.readInt();
                    des.vshAttBufferCommandCountEx  = f.readInt();

                    f.skip(12);  // center vector
                    f.skip(4);   // flagsOffset
                    f.skip(4);   // 0?
                    f.readInt(); //bbOffsets[i] =  + mainheaderOffset

                    //Debug.WriteLine(des.vshAttBufferCommandOffset.ToString("X"));
                }


                //Skeleton
                f.seek(model.skeletonOffset);
                for (int index = 0; index < model.skeletonEntries; index++)
                {
                    Bone bone      = new Smash_Forge.Bone(model.skeleton);
                    int  boneFlags = f.readInt();
                    bone.parentIndex = (short)f.readShort();
                    short boneSpace = (short)f.readShort();
                    bone.scale       = new float[3];
                    bone.rotation    = new float[3];
                    bone.position    = new float[3];
                    bone.scale[0]    = f.readFloat();
                    bone.scale[1]    = f.readFloat();
                    bone.scale[2]    = f.readFloat();
                    bone.rotation[0] = f.readFloat();
                    bone.rotation[1] = f.readFloat();
                    bone.rotation[2] = f.readFloat();
                    bone.position[0] = f.readFloat();
                    bone.position[1] = f.readFloat();
                    bone.position[2] = f.readFloat();

                    // bone matrix... not really needed to be stored per say
                    f.skip(4 * 4 * 3);

                    bone.Text = f.readString(f.readInt(), -1);

                    f.skip(4); // Meta data

                    model.skeleton.bones.Add(bone);
                }
                model.skeleton.reset();
            }
        }
Пример #17
0
        public void Read(FileData f)
        {
            f.Endian = Endianness.Little;
            f.seek(4);
            int count = f.readInt();

            f.skip(12);
            int dataCount  = f.readInt();
            int boneCount  = f.readInt();
            int hashCount  = f.readInt();
            int hashOffset = f.readInt() + 0x28;

            f.skip(4);

            int pos = f.pos();

            f.seek(hashOffset);

            csvHashes     csv      = new csvHashes(Path.Combine(MainForm.executableDir, "hashTable.csv"));
            List <string> bonename = new List <string>();

            for (int i = 0; i < hashCount; i++)
            {
                uint hash = (uint)f.readInt();
                for (int j = 0; j < csv.ids.Count; j++)
                {
                    if (csv.ids[j] == hash)
                    {
                        Console.WriteLine(csv.names[j]);
                        bonename.Add(csv.names[j]);
                        break;
                    }
                }
            }

            f.seek(pos);
            Console.WriteLine("Count " + count);

            for (int i = 0; i < dataCount; i++)
            {
                Console.WriteLine("Bone " + i + " start at " + f.pos().ToString("x"));
                // 3 sections
                int secLength = f.readInt();
                int someCount = f.readInt(); // usually 2?

                for (int sec = 0; sec < 5; sec++)
                {
                    int size = f.readInt();
                    int id   = f.readInt();
                    Console.WriteLine(id + ":\t" + size.ToString("x"));
                    for (int j = 0; j < ((size - 1) / 4) - 1; j++)
                    {
                        Console.Write("\t" + f.readShort() + " " + f.readShort() + "\t");
                    }
                    Console.WriteLine();
                }

                f.skip(8);
            }

            Console.WriteLine("0x" + f.pos().ToString("X"));
            f.skip(8);
            int hashSize = f.readInt();
            int unk      = f.readInt();
        }
Пример #18
0
        public void Read(FileData f)
        {
            f.Endian = Endianness.Little;
            f.seek(4);
            int count = f.readInt();

            f.skip(12);
            int dataCount  = f.readInt();
            int boneCount  = f.readInt();
            int hashCount  = f.readInt();
            int hashOffset = f.readInt() + 0x28;

            f.skip(4);

            int pos = f.pos();

            f.seek(hashOffset);

            csvHashes     csv      = new csvHashes(Path.Combine(MainForm.executableDir, "hashTable.csv"));
            List <string> bonename = new List <string>();

            for (int i = 0; i < hashCount; i++)
            {
                uint hash = (uint)f.readInt();
                Console.WriteLine(csv.ids[hash]);
                bonename.Add(csv.ids[hash]);
            }

            f.seek(pos);
            Console.WriteLine("Count " + count);

            for (int i = 0; i < dataCount; i++)
            {
                Console.WriteLine("Bone " + i + " start at " + f.pos().ToString("x"));
                // 3 sections
                int secLength = f.readInt();
                int someCount = f.readInt(); // usually 2?

                for (int sec = 0; sec < 5; sec++)
                {
                    int size = f.readInt();
                    int id   = f.readInt();
                    Console.WriteLine(id + ":\t" + size.ToString("x"));
                    for (int j = 0; j < ((size - 1) / 4) - 1; j++)
                    {
                        if (id == 4)
                        {
                            short b1 = f.readShort();
                            short b2 = f.readShort();
                            Console.Write("\t" + (b1 == -1 ? b1 + "" : bonename[b1]) + " " + b2 + "\t");
                        }
                        else
                        if (id == 5)
                        {
                            short b1 = f.readShort();
                            short b2 = f.readShort();
                            Console.Write("\t" + (b1 == -1 ? b1 + "" : bonename[b1]) + " " + (b2 == -1 ? b2 + "" : bonename[b2]) + "\t");
                        }
                        else
                        {
                            Console.Write("\t" + (f.readUShort() / (id == 7 ? (float)0xffff : 1)) + " " + (f.readUShort() / (id == 7 ? (float)0xffff : 1)) + "\t");
                        }
                    }
                    Console.WriteLine();
                }

                f.skip(8);
            }

            Console.WriteLine("0x" + f.pos().ToString("X"));
            f.skip(8);
            int hashSize = f.readInt();
            int unk      = f.readInt();
        }
Пример #19
0
        public override void Read(string filename)
        {
            bchHeader header = new bchHeader();
            FileData  f      = new FileData(filename);

            f.Endian = System.IO.Endianness.Little;

            f.skip(4);
            header.backwardCompatibility = f.readByte();
            header.forwardCompatibility  = f.readByte();
            header.version = f.readUShort();

            header.mainHeaderOffset  = f.readInt();
            header.stringTableOffset = f.readInt();
            header.gpuCommandsOffset = f.readInt();
            header.dataOffset        = f.readInt();
            if (header.backwardCompatibility > 0x20)
            {
                header.dataExtendedOffset = f.readInt();
            }
            header.relocationTableOffset = f.readInt();

            header.mainHeaderLength  = f.readInt();
            header.stringTableLength = f.readInt();
            header.gpuCommandsLength = f.readInt();
            header.dataLength        = f.readInt();
            if (header.backwardCompatibility > 0x20)
            {
                header.dataExtendedLength = f.readInt();
            }
            header.relocationTableLength = f.readInt();

            header.uninitializedDataSectionLength        = f.readInt();
            header.uninitializedDescriptionSectionLength = f.readInt();

            if (header.backwardCompatibility > 7)
            {
                header.flags        = f.readUShort();
                header.addressCount = f.readUShort();
            }

            // Relocation table
            for (int i = 0; i < header.relocationTableLength; i += 4)
            {
                f.seek(header.relocationTableOffset + i);
                int  val  = f.readInt();
                int  off  = val & 0x1FFFFFF;
                byte flag = (byte)(val >> 25);

                switch (flag)
                {
                case 0:
                    f.seek((off * 4) + header.mainHeaderOffset);
                    f.writeInt((off * 4) + header.mainHeaderOffset, f.readInt() + header.mainHeaderOffset);
                    break;

                case 1:
                    f.seek(off + header.mainHeaderOffset);
                    f.writeInt((off) + header.mainHeaderOffset, f.readInt() + header.stringTableOffset);
                    break;

                case 2:
                    f.seek((off * 4) + header.mainHeaderOffset);
                    f.writeInt((off * 4) + header.mainHeaderOffset, f.readInt() + header.gpuCommandsOffset);
                    break;

                case 0xc:
                    f.seek((off * 4) + header.mainHeaderOffset);
                    f.writeInt((off * 4) + header.mainHeaderOffset, f.readInt() + header.dataOffset);
                    break;
                }

                f.seek((off * 4) + header.gpuCommandsOffset);
                if (header.backwardCompatibility < 6)
                {
                    switch (flag)
                    {
                    case 0x23: f.writeInt((off * 4) + header.gpuCommandsOffset, f.readInt() + header.dataOffset); break;     //Texture

                    case 0x25: f.writeInt((off * 4) + header.gpuCommandsOffset, f.readInt() + header.dataOffset); break;     //Vertex

                    //case 0x26: f.writeInt((off * 4) + header.gpuCommandsOffset, ((f.readInt() + header.dataOffset) & 0x7fffffff) | 0x80000000); break; //Index 16 bits mode
                    case 0x27: f.writeInt((off * 4) + header.gpuCommandsOffset, (f.readInt() + header.dataOffset) & 0x7fffffff); break;     //Index 8 bits mode
                    }
                }
                else if (header.backwardCompatibility < 8)
                {
                    switch (flag)
                    {
                    case 0x24: f.writeInt((off * 4) + header.gpuCommandsOffset, f.readInt() + header.dataOffset); break;     //Texture

                    case 0x26: f.writeInt((off * 4) + header.gpuCommandsOffset, f.readInt() + header.dataOffset); break;     //Vertex

                    //case 0x27: writer.Write(((peek(input) + header.dataOffset) & 0x7fffffff) | 0x80000000); break; //Index 16 bits mode
                    case 0x28: f.writeInt((off * 4) + header.gpuCommandsOffset, (f.readInt() + header.dataOffset) & 0x7fffffff); break;     //Index 8 bits mode
                    }
                }
                else if (header.backwardCompatibility < 0x21)
                {
                    switch (flag)
                    {
                    case 0x25: f.writeInt((off * 4) + header.gpuCommandsOffset, f.readInt() + header.dataOffset); break;     //Texture

                    case 0x27: f.writeInt((off * 4) + header.gpuCommandsOffset, f.readInt() + header.dataOffset); break;     //Vertex

                    //case 0x28: writer.Write(((peek(input) + header.dataOffset) & 0x7fffffff) | 0x80000000); break; //Index 16 bits mode
                    case 0x29: f.writeInt((off * 4) + header.gpuCommandsOffset, (f.readInt() + header.dataOffset) & 0x7fffffff); break;     //Index 8 bits mode
                    }
                }
                else
                {
                    switch (flag)
                    {
                    case 0x25: f.writeInt((off * 4) + header.gpuCommandsOffset, f.readInt() + header.dataOffset); break;     //Texture

                    case 0x26: f.writeInt((off * 4) + header.gpuCommandsOffset, f.readInt() + header.dataOffset); break;     //Vertex relative to Data Offset

                    //case 0x27: writer.Write(((peek(input) + header.dataOffset) & 0x7fffffff) | 0x80000000); break; //Index 16 bits mode relative to Data Offset
                    case 0x28: f.writeInt((off * 4) + header.gpuCommandsOffset, (f.readInt() + header.dataOffset) & 0x7fffffff); break; //Index 8 bits mode relative to Data Offset

                    case 0x2b: f.writeInt((off * 4) + header.gpuCommandsOffset, f.readInt() + header.dataExtendedOffset); break;        //Vertex relative to Data Extended Offset

                    //case 0x2c: writer.Write(((peek(input) + header.dataExtendedOffset) & 0x7fffffff) | 0x80000000); break; //Index 16 bits mode relative to Data Extended Offset
                    case 0x2d: f.writeInt((off * 4) + header.gpuCommandsOffset, (f.readInt() + header.dataExtendedOffset) & 0x7fffffff); break;     //Index 8 bits mode relative to Data Extended Offset
                    }
                }
            }


            // Content Header
            f.seek(header.mainHeaderOffset);
            bchContentHeader content = new bchContentHeader();

            {
                content.modelsPointerTableOffset        = f.readInt();
                content.modelsPointerTableEntries       = f.readInt();
                content.modelsNameOffset                = f.readInt();
                content.materialsPointerTableOffset     = f.readInt();
                content.materialsPointerTableEntries    = f.readInt();
                content.materialsNameOffset             = f.readInt();
                content.shadersPointerTableOffset       = f.readInt();
                content.shadersPointerTableEntries      = f.readInt();
                content.shadersNameOffset               = f.readInt();
                content.texturesPointerTableOffset      = f.readInt();
                content.texturesPointerTableEntries     = f.readInt();
                content.texturesNameOffset              = f.readInt();
                content.materialsLUTPointerTableOffset  = f.readInt();
                content.materialsLUTPointerTableEntries = f.readInt();
                content.materialsLUTNameOffset          = f.readInt();
                content.lightsPointerTableOffset        = f.readInt();
                content.lightsPointerTableEntries       = f.readInt();
                content.lightsNameOffset                = f.readInt();
                content.camerasPointerTableOffset       = f.readInt();
                content.camerasPointerTableEntries      = f.readInt();
                content.camerasNameOffset               = f.readInt();
                content.fogsPointerTableOffset          = f.readInt();
                content.fogsPointerTableEntries         = f.readInt();
                content.fogsNameOffset = f.readInt();
                content.skeletalAnimationsPointerTableOffset    = f.readInt();
                content.skeletalAnimationsPointerTableEntries   = f.readInt();
                content.skeletalAnimationsNameOffset            = f.readInt();
                content.materialAnimationsPointerTableOffset    = f.readInt();
                content.materialAnimationsPointerTableEntries   = f.readInt();
                content.materialAnimationsNameOffset            = f.readInt();
                content.visibilityAnimationsPointerTableOffset  = f.readInt();
                content.visibilityAnimationsPointerTableEntries = f.readInt();
                content.visibilityAnimationsNameOffset          = f.readInt();
                content.lightAnimationsPointerTableOffset       = f.readInt();
                content.lightAnimationsPointerTableEntries      = f.readInt();
                content.lightAnimationsNameOffset           = f.readInt();
                content.cameraAnimationsPointerTableOffset  = f.readInt();
                content.cameraAnimationsPointerTableEntries = f.readInt();
                content.cameraAnimationsNameOffset          = f.readInt();
                content.fogAnimationsPointerTableOffset     = f.readInt();
                content.fogAnimationsPointerTableEntries    = f.readInt();
                content.fogAnimationsNameOffset             = f.readInt();
                content.scenePointerTableOffset             = f.readInt();
                content.scenePointerTableEntries            = f.readInt();
                content.sceneNameOffset = f.readInt();
            }


            //Skeletal animation
            for (int index1 = 0; index1 < content.skeletalAnimationsPointerTableEntries; index1++)
            {
                f.seek(content.skeletalAnimationsPointerTableOffset + (index1 * 4));
                int dataOffset = f.readInt();
                f.seek(dataOffset);


                string skeletalAnimationName = f.readString(f.readInt(), -1);
                int    animationFlags        = f.readInt();
                //int skeletalAnimationloopMode = f.readByte();  //pas ça du tout
                float skeletalAnimationframeSize = f.readFloat();
                int   boneTableOffset            = f.readInt();
                int   boneTableEntries           = f.readInt();
                int   metaDataPointerOffset      = f.readInt();

                //Debug.WriteLine("Animation Name: " + skeletalAnimationName);
                //Debug.WriteLine("BonetableOffset: " + boneTableOffset.ToString("X"));
                //Debug.WriteLine("BonetableEntry: " + boneTableEntries.ToString("X"));

                for (int i = 0; i < boneTableEntries; i++)
                {
                    f.seek(boneTableOffset + (i * 4));
                    int offset = f.readInt();

                    OSkeletalAnimationBone bone = new OSkeletalAnimationBone();

                    f.seek(offset);
                    bone.name = f.readString(f.readInt(), -1);
                    Console.WriteLine("Bone Name: " + bone.name);
                    int animationTypeFlags = f.readInt();
                    int flags = f.readInt();

                    OSegmentType segmentType = (OSegmentType)((animationTypeFlags >> 16) & 0xf);
                    switch (segmentType)
                    {
                    case OSegmentType.transform:
                        f.seek(offset + 0x18);

                        int notExistMask = 0x80000;
                        int constantMask = 0x200;

                        for (int j = 0; j < 2; j++)
                        {
                            for (int axis = 0; axis < 3; axis++)
                            {
                                bool notExist = (flags & notExistMask) > 0;
                                bool constant = (flags & constantMask) > 0;

                                OAnimationKeyFrameGroup frame = new OAnimationKeyFrameGroup();
                                frame.exists = !notExist;
                                if (frame.exists)
                                {
                                    if (constant)
                                    {
                                        frame.interpolation = OInterpolationMode.linear;
                                        frame.keyFrames.Add(new OAnimationKeyFrame(f.readFloat(), 0));
                                    }
                                    else
                                    {
                                        int frameOffset = f.readInt();
                                        int position    = f.pos();
                                        f.seek(frameOffset);
                                        //getAnimationKeyFrame(input, frame);
                                        f.seek(position);
                                    }
                                }
                                else
                                {
                                    f.seek(f.pos() + 0x04);
                                }

                                if (j == 0)
                                {
                                    switch (axis)
                                    {
                                    case 0: bone.rotationX = frame; break;

                                    case 1: bone.rotationY = frame; break;

                                    case 2: bone.rotationZ = frame; break;
                                    }
                                }
                                else
                                {
                                    switch (axis)
                                    {
                                    case 0: bone.translationX = frame; break;

                                    case 1: bone.translationY = frame; break;

                                    case 2: bone.translationZ = frame; break;
                                    }
                                }

                                notExistMask <<= 1;
                                constantMask <<= 1;
                            }

                            constantMask <<= 1;
                        }

                        break;

                    case OSegmentType.transformQuaternion:
                        bone.isFrameFormat = true;

                        int scaleOffset       = f.readInt();
                        int rotationOffset    = f.readInt();
                        int translationOffset = f.readInt();

                        if ((flags & 0x20) == 0)
                        {
                            bone.scale.exists = true;
                            f.seek(scaleOffset);

                            if ((flags & 4) > 0)
                            {
                                bone.scale.vector.Add(new Vector4(
                                                          f.readFloat(),
                                                          f.readFloat(),
                                                          f.readFloat(),
                                                          0));
                            }
                            else
                            {
                                bone.scale.startFrame = f.readFloat();
                                bone.scale.endFrame   = f.readFloat();

                                int scaleFlags      = f.readInt();
                                int scaleDataOffset = f.readInt();
                                int scaleEntries    = f.readInt();

                                f.seek(scaleDataOffset);
                                for (int j = 0; j < scaleEntries; j++)
                                {
                                    bone.scale.vector.Add(new Vector4(
                                                              f.readFloat(),
                                                              f.readFloat(),
                                                              f.readFloat(),
                                                              0));
                                }
                            }
                        }

                        if ((flags & 0x10) == 0)
                        {
                            bone.rotationQuaternion.exists = true;
                            f.seek(rotationOffset);

                            if ((flags & 2) > 0)
                            {
                                bone.rotationQuaternion.vector.Add(new Vector4(
                                                                       f.readFloat(),
                                                                       f.readFloat(),
                                                                       f.readFloat(),
                                                                       f.readFloat()));
                            }
                            else
                            {
                                bone.rotationQuaternion.startFrame = f.readFloat();
                                bone.rotationQuaternion.endFrame   = f.readFloat();

                                int rotationFlags      = f.readInt();
                                int rotationDataOffset = f.readInt();
                                int rotationEntries    = f.readInt();

                                f.seek(rotationDataOffset);
                                for (int j = 0; j < rotationEntries; j++)
                                {
                                    bone.rotationQuaternion.vector.Add(new Vector4(
                                                                           f.readFloat(),
                                                                           f.readFloat(),
                                                                           f.readFloat(),
                                                                           f.readFloat()));
                                }
                            }
                        }

                        if ((flags & 8) == 0)
                        {
                            bone.translation.exists = true;
                            f.seek(translationOffset);

                            if ((flags & 1) > 0)
                            {
                                bone.translation.vector.Add(new Vector4(
                                                                f.readFloat(),
                                                                f.readFloat(),
                                                                f.readFloat(),
                                                                0));
                            }
                            else
                            {
                                bone.translation.startFrame = f.readFloat();
                                bone.translation.endFrame   = f.readFloat();

                                int translationFlags      = f.readInt();
                                int translationDataOffset = f.readInt();
                                int translationEntries    = f.readInt();

                                f.seek(translationDataOffset);
                                for (int j = 0; j < translationEntries; j++)
                                {
                                    bone.translation.vector.Add(new Vector4(
                                                                    f.readFloat(),
                                                                    f.readFloat(),
                                                                    f.readFloat(),
                                                                    0));
                                }
                            }
                        }

                        break;

                    case OSegmentType.transformMatrix:
                        bone.isFullBakedFormat = true;

                        f.readInt();
                        f.readInt();
                        int matrixOffset = f.readInt();
                        int entries      = f.readInt();

                        f.seek(matrixOffset);
                        for (int j = 0; j < entries; j++)
                        {
                            /*OMatrix transform = new OMatrix();
                             * transform.M11 = f.readFloat();
                             * transform.M21 = f.readFloat();
                             * transform.M31 = f.readFloat();
                             * transform.M41 = f.readFloat();
                             *
                             * transform.M12 = f.readFloat();
                             * transform.M22 = f.readFloat();
                             * transform.M32 = f.readFloat();
                             * transform.M42 = f.readFloat();
                             *
                             * transform.M13 = f.readFloat();
                             * transform.M23 = f.readFloat();
                             * transform.M33 = f.readFloat();
                             * transform.M43 = f.readFloat();
                             *
                             * bone.transform.Add(transform);*/
                        }

                        break;

                    default: throw new Exception(string.Format("BCH: Unknow Segment Type {0} on Skeletal Animation bone {1}! STOP!", segmentType, bone.name));
                    }

                    //skeletalAnimation.bone.Add(bone);
                }
            }

            //Shaders (unused for now, until someone wants to add them)
            for (int index = 0; index < content.shadersPointerTableEntries; index++)
            {
                f.seek(content.shadersPointerTableOffset + (index * 4));
                int dataOffset = f.readInt();
                f.seek(dataOffset);

                int shaderDataOffset = f.readInt();
                int shaderDataLength = f.readInt();
            }

            // Textures
            // WIP Section
            for (int index = 0; index < content.texturesPointerTableEntries; index++)
            {
                f.seek(content.texturesPointerTableOffset + (index * 4));
                int dOffset = f.readInt();
                f.seek(dOffset);

                int textureCommandsOffset    = f.readInt();
                int textureCommandsWordCount = f.readInt();

                f.seek(f.pos() + 0x14);
                String textureName = f.readString(f.readInt(), -1);
                f.seek(textureCommandsOffset);
                BCH_Texture tex = new BCH_Texture();
                textures.Add(textureName, tex);

                tex.Height = f.readUShort();
                tex.Width  = f.readUShort();
                f.skip(12);
                int doffset = f.readInt();
                f.skip(4);
                tex.type = f.readInt();
                tex.data = f.getSection(doffset, f.size() - doffset);

                tex.texture = _3DS.DecodeImage(tex.data, tex.Width, tex.Height, (_3DS.Tex_Formats)tex.type);
                //Texture texture = new Texture2D(tex.texture);
                //tex.display = texture.Id;
            }

            // Model data

            for (int modelIndex = 0; modelIndex < content.modelsPointerTableEntries; modelIndex++)
            {
                f.seek(content.modelsPointerTableOffset + (modelIndex * 4));
                int objectsHeaderOffset = f.readInt();

                // Objects
                f.seek(objectsHeaderOffset);
                BCH_Model model = new BCH_Model();
                models.Add(model);

                model.flags                     = f.readByte();
                model.skeletonScaleType         = f.readByte();
                model.silhouetteMaterialEntries = f.readUShort();

                model.worldTransform = new Matrix4(f.readFloat(), f.readFloat(), f.readFloat(), f.readFloat()
                                                   , f.readFloat(), f.readFloat(), f.readFloat(), f.readFloat()
                                                   , f.readFloat(), f.readFloat(), f.readFloat(), f.readFloat()
                                                   , 0, 0, 0, 1);

                int materialsTableOffset  = f.readInt();
                int materialsTableEntries = f.readInt();
                int materialsNameOffset   = f.readInt();
                int verticesTableOffset   = f.readInt();
                int verticesTableEntries  = f.readInt();
                f.skip(0x28);
                int    skeletonOffset              = f.readInt();
                int    skeletonEntries             = f.readInt();
                int    skeletonNameOffset          = f.readInt();
                int    objectsNodeVisibilityOffset = f.readInt();
                int    objectsNodeCount            = f.readInt();
                String name = f.readString(f.readInt(), -1);
                int    objectsNodeNameEntries = f.readInt();
                int    objectsNodeNameOffset  = f.readInt();
                f.readInt(); //0x0
                int metaDataPointerOffset = f.readInt();

                f.seek(objectsNodeVisibilityOffset);
                int nodeVisibility = f.readInt();

                string[] objectName = new string[objectsNodeNameEntries];
                f.seek(objectsNodeNameOffset);
                int rootReferenceBit = f.readInt(); //Radix tree
                int rootLeftNode     = f.readUShort();
                int rootRightNode    = f.readUShort();
                int rootNameOffset   = f.readInt();

                for (int i = 0; i < objectsNodeNameEntries; i++)
                {
                    int   referenceBit = f.readInt();
                    short leftNode     = f.readShort();
                    short rightNode    = f.readShort();
                    objectName[i] = f.readString(f.readInt(), -1);
                }

                // Materials
                // NOTE: MATERIALS AND OBJECT SECTIONS ARE REALLY MESSY ATM

                String[] materialNames = new String[materialsTableEntries];
                for (int index = 0; index < materialsTableEntries; index++)
                {
                    f.seek(materialsTableOffset + (index * 0x2c));

                    int materialParametersOffset = f.readInt();
                    f.readInt();
                    f.readInt();
                    f.readInt();
                    int textureCommandsOffset    = f.readInt();
                    int textureCommandsWordCount = f.readInt();

                    int materialMapperOffset = f.readInt();
                    materialNames[index] = f.readString(f.readInt(), -1);
                }

                // Object Descriptions...
                // Assumes MBN is already loaded for now
                f.seek(verticesTableOffset);
                List <objDes> objDescriptors = new List <objDes>();
                if (mbn == null)
                {
                    mbn = new Smash_Forge.MBN();
                    for (int index = 0; index < verticesTableEntries; index++)
                    {
                        mbn.mesh.Add(new MBN.Mesh());
                    }
                    mbn.PreRender();
                }
                for (int index = 0; index < mbn.mesh.Count; index++)
                {
                    int i = f.readUShort();
                    if (index > mbn.mesh.Count)
                    {
                        break;
                    }
                    if (i > materialNames.Length)
                    {
                        break;
                    }
                    mbn.mesh[index].texId = textures[materialNames[i]].display;
                    Console.WriteLine("Tex index" + mbn.mesh[index].texId);
                    f.skip(2); // flags
                    int nameId = f.readUShort();
                    mbn.mesh[index].Text = objectName[nameId];

                    // node visibility TODO: finish...
                    mbn.mesh[index].Checked = ((nodeVisibility & (1 << nameId)) > 0);

                    mbn.mesh[index].renderPriority = f.readUShort();

                    objDes des = new objDes();
                    objDescriptors.Add(des);
                    des.vshAttBufferCommandOffset = f.readInt();
                    des.vshAttBufferCommandCount  = f.readInt();
                    des.faceOffset = f.readInt();
                    des.faceCount  = f.readInt();
                    des.vshAttBufferCommandOffsetEx = f.readInt();
                    des.vshAttBufferCommandCountEx  = f.readInt();

                    f.skip(12);  // center vector
                    f.skip(4);   // flagsOffset
                    f.skip(4);   // 0?
                    f.readInt(); //bbOffsets[i]
                }

                //Skeleton
                f.seek(skeletonOffset);
                for (int index = 0; index < skeletonEntries; index++)
                {
                    Bone bone      = new Bone(model.skeleton);
                    int  boneFlags = f.readInt();
                    bone.parentIndex = f.readShort();
                    short boneSpace = f.readShort();
                    bone.scale       = new float[3];
                    bone.rotation    = new float[3];
                    bone.position    = new float[3];
                    bone.scale[0]    = f.readFloat();
                    bone.scale[1]    = f.readFloat();
                    bone.scale[2]    = f.readFloat();
                    bone.rotation[0] = f.readFloat();
                    bone.rotation[1] = f.readFloat();
                    bone.rotation[2] = f.readFloat();
                    bone.position[0] = f.readFloat();
                    bone.position[1] = f.readFloat();
                    bone.position[2] = f.readFloat();

                    // bone matrix... not really needed to be stored per say
                    f.skip(4 * 4 * 3);

                    bone.Text = f.readString(f.readInt(), -1);

                    f.skip(4); // Meta data
                    bones.bones.Add(bone);


                    model.skeleton.bones.Add(bone);
                }
                model.skeleton.reset();
                model.skeleton.update();
            }
        }
Пример #20
0
        public override void Read(string filename)
        {
            FileData f = new FileData(filename);

            //Header
            f.skip(0x4);
            version    = f.readInt();
            frameCount = f.readInt();
            if (version == 4)
            {
                frameDuration = 1;
            }
            else if (version == 5)
            {
                frameDuration = f.readInt();
            }
            else
            {
                throw new NotImplementedException($"Unknown light.bin version {version}");
            }

            int[] offsets = new int[6];
            for (int i = 0; i < 6; i++)
            {
                offsets[i] = f.readInt();
            }

            //RGB properties
            for (int i = 0; i < 5; i++)
            {
                RgbProperty temp = new RgbProperty();

                temp.enabled = (offsets[i + 1] != 0);
                if (temp.enabled)
                {
                    f.seek(offsets[i + 1]);
                    for (int j = 0; j < frameCount; j++)
                    {
                        byte[] frame = new byte[3];
                        for (int k = 0; k < 3; k++)
                        {
                            frame[k] = (byte)f.readByte();
                        }
                        temp.frames.Add(frame);
                    }
                }

                rgbProperties.Add(temp);
            }

            //Light data
            f.seek(offsets[0]);
            for (int i = 0; i < frameCount; i++)
            {
                LightFrame temp = new LightFrame();

                for (int j = 0; j < 17; j++)
                {
                    for (int k = 0; k < 4; k++)
                    {
                        temp.lightSets[j].lights[k].enabled = f.readInt();
                        for (int l = 0; l < 3; l++)
                        {
                            temp.lightSets[j].lights[k].angle[l] = f.readFloat();
                        }
                        temp.lightSets[j].lights[k].colorHue = f.readFloat();
                        temp.lightSets[j].lights[k].colorSat = f.readFloat();
                        temp.lightSets[j].lights[k].colorVal = f.readFloat();
                    }
                    temp.lightSets[j].fog.unknown = (byte)f.readByte();
                    for (int k = 0; k < 3; k++)
                    {
                        temp.lightSets[j].fog.color[k] = (byte)f.readByte();
                    }
                }
                temp.effect.unknown = (byte)f.readByte();
                for (int j = 0; j < 3; j++)
                {
                    temp.effect.color[j] = (byte)f.readByte();
                }
                for (int j = 0; j < 3; j++)
                {
                    temp.effect.position[j] = f.readFloat();
                }

                lightFrames.Add(temp);
            }
        }
Пример #21
0
        public static AnimationGroupNode Read(string filename, ResFile TargetWiiUBFRES)
        {
            FileData f = new FileData(filename);

            f.seek(0);

            f.Endian = Endianness.Little;

            Console.WriteLine("Reading Animations ...");

            f.seek(4);                     // magic check
            int SwitchCheck = f.readInt(); //Switch version only has padded magic

            f.skip(4);
            if (SwitchCheck == 0x20202020)
            {
                //    SwitchAnim2WiiU(path); //Hacky auto convert switch anims to wii u


                ResNSW.ResFile b = new ResNSW.ResFile(filename);

                AnimationGroupNode ThisAnimation = new AnimationGroupNode()
                {
                    Text = "Skeleton Animations"
                };

                TreeNode dummy = new TreeNode()
                {
                    Text = "Animation Set"
                };

                int i = 0;
                foreach (ResNSW.SkeletalAnim ska in b.SkeletalAnims)
                {
                    Animation a = new Animation(ska.Name);
                    ThisAnimation.Nodes.Add(a);

                    a.FrameCount = ska.FrameCount;
                    i++;
                    try
                    {
                        foreach (Syroot.NintenTools.NSW.Bfres.BoneAnim bn in ska.BoneAnims)
                        {
                            FSKANode bonean = new FSKANode(bn);

                            Animation.KeyNode bone = new Animation.KeyNode("");
                            a.Bones.Add(bone);
                            if (ska.FlagsRotate == ResNSW.SkeletalAnimFlagsRotate.EulerXYZ)
                            {
                                bone.RotType = Animation.RotationType.EULER;
                            }
                            else
                            {
                                bone.RotType = Animation.RotationType.QUATERNION;
                            }

                            bone.Text = bonean.Text;

                            for (int Frame = 0; Frame < ska.FrameCount; Frame++)
                            {
                                //Set base/start values for bones.
                                //Note. BOTW doesn't use base values as it uses havok engine. Need to add option to disable these
                                if (Frame == 0 && Runtime.HasNoAnimationBaseValues == false)
                                {
                                    bone.XSCA.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = 1
                                    });
                                    bone.YSCA.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = 1
                                    });
                                    bone.ZSCA.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = 1
                                    });
                                    bone.XROT.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.rot.X
                                    });
                                    bone.YROT.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.rot.Y
                                    });
                                    bone.ZROT.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.rot.Z
                                    });
                                    bone.XPOS.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.pos.X
                                    });
                                    bone.YPOS.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.pos.Y
                                    });
                                    bone.ZPOS.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.pos.Z
                                    });
                                }
                                foreach (FSKATrack track in bonean.tracks)
                                {
                                    Animation.KeyFrame frame = new Animation.KeyFrame();
                                    frame.InterType = Animation.InterpolationType.HERMITE;
                                    frame.Frame     = Frame;

                                    FSKAKey left  = track.GetLeft(Frame);
                                    FSKAKey right = track.GetRight(Frame);
                                    float   value;



                                    value = Animation.Hermite(Frame, left.frame, right.frame, 0, 0, left.unk1, right.unk1);

                                    // interpolate the value and apply
                                    switch (track.flag)
                                    {
                                    case (int)TrackType.XPOS: frame.Value = value; bone.XPOS.Keys.Add(frame); break;

                                    case (int)TrackType.YPOS: frame.Value = value; bone.YPOS.Keys.Add(frame); break;

                                    case (int)TrackType.ZPOS: frame.Value = value; bone.ZPOS.Keys.Add(frame); break;

                                    case (int)TrackType.XROT: frame.Value = value; bone.XROT.Keys.Add(frame); break;

                                    case (int)TrackType.YROT: frame.Value = value; bone.YROT.Keys.Add(frame); break;

                                    case (int)TrackType.ZROT: frame.Value = value; bone.ZROT.Keys.Add(frame); break;

                                    case (int)TrackType.XSCA: frame.Value = value; bone.XSCA.Keys.Add(frame); break;

                                    case (int)TrackType.YSCA: frame.Value = value; bone.YSCA.Keys.Add(frame); break;

                                    case (int)TrackType.ZSCA: frame.Value = value; bone.ZSCA.Keys.Add(frame); break;
                                    }
                                }
                            }
                        }
                    }
                    catch
                    {
                    }
                }
                return(ThisAnimation);
            }
            else
            {
                f.eof();

                TargetWiiUBFRES = new ResFile(filename);

                ThisAnimation = new AnimationGroupNode()
                {
                    Text = "Skeleton Animations"
                };

                TreeNode dummy = new TreeNode()
                {
                    Text = "Animation Set"
                };

                int i = 0;
                foreach (SkeletalAnim ska in TargetWiiUBFRES.SkeletalAnims.Values)
                {
                    Animation a = new Animation(ska.Name);
                    ThisAnimation.Nodes.Add(a);

                    a.FrameCount = ska.FrameCount;
                    i++;
                    try
                    {
                        foreach (BoneAnim bn in ska.BoneAnims)
                        {
                            FSKANodeWiiU bonean = new FSKANodeWiiU(bn);

                            Animation.KeyNode bone = new Animation.KeyNode("");
                            a.Bones.Add(bone);
                            if (ska.FlagsRotate == SkeletalAnimFlagsRotate.EulerXYZ)
                            {
                                bone.RotType = Animation.RotationType.EULER;
                            }
                            else
                            {
                                bone.RotType = Animation.RotationType.QUATERNION;
                            }

                            bone.Text = bonean.Text;


                            for (int Frame = 0; Frame < ska.FrameCount; Frame++)
                            {
                                //Set base/start values for bones.
                                //Note. BOTW doesn't use base values as it uses havok engine. Need to add option to disable these
                                if (Frame == 0 && Runtime.HasNoAnimationBaseValues == false)
                                {
                                    bone.XSCA.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.sca.X
                                    });
                                    bone.YSCA.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.sca.Y
                                    });
                                    bone.ZSCA.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.sca.Z
                                    });
                                    bone.XROT.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.rot.X
                                    });
                                    bone.YROT.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.rot.Y
                                    });
                                    bone.ZROT.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.rot.Z
                                    });
                                    bone.XPOS.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.pos.X
                                    });
                                    bone.YPOS.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.pos.Y
                                    });
                                    bone.ZPOS.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.pos.Z
                                    });
                                }
                                foreach (FSKATrack track in bonean.tracks)
                                {
                                    Animation.KeyFrame frame = new Animation.KeyFrame();
                                    frame.InterType = Animation.InterpolationType.HERMITE;
                                    frame.Frame     = Frame;

                                    FSKAKey left  = track.GetLeft(Frame);
                                    FSKAKey right = track.GetRight(Frame);
                                    float   value;



                                    value = Animation.Hermite(Frame, left.frame, right.frame, 0, 0, left.unk1, right.unk1);

                                    // interpolate the value and apply
                                    switch (track.flag)
                                    {
                                    case (int)TrackType.XPOS: frame.Value = value; bone.XPOS.Keys.Add(frame); break;

                                    case (int)TrackType.YPOS: frame.Value = value; bone.YPOS.Keys.Add(frame); break;

                                    case (int)TrackType.ZPOS: frame.Value = value; bone.ZPOS.Keys.Add(frame); break;

                                    case (int)TrackType.XROT: frame.Value = value; bone.XROT.Keys.Add(frame); break;

                                    case (int)TrackType.YROT: frame.Value = value; bone.YROT.Keys.Add(frame); break;

                                    case (int)TrackType.ZROT: frame.Value = value; bone.ZROT.Keys.Add(frame); break;

                                    case (int)TrackType.XSCA: frame.Value = value; bone.XSCA.Keys.Add(frame); break;

                                    case (int)TrackType.YSCA: frame.Value = value; bone.YSCA.Keys.Add(frame); break;

                                    case (int)TrackType.ZSCA: frame.Value = value; bone.ZSCA.Keys.Add(frame); break;
                                    }
                                }
                            }
                        }
                    }
                    catch
                    {
                    }
                }
                return(ThisAnimation);
            }
        }
Пример #22
0
        public static AnimationGroupNode Read(string filename, ResFile TargetWiiUBFRES, BFRES bfres)
        {
            string path = filename;

            FileData f = new FileData(filename);


            int Magic = f.readInt();

            if (Magic == 0x59617A30) //YAZO compressed
            {
                using (FileStream input = new FileStream(path, System.IO.FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    Yaz0Compression.Decompress(path, TEMP_FILE);

                    path = TEMP_FILE;
                }
            }

            f = new FileData(path);

            f.seek(0);

            f.Endian = Endianness.Little;

            Console.WriteLine("Reading Animations ...");

            f.seek(4);                     // magic check
            int SwitchCheck = f.readInt(); //Switch version only has padded magic

            f.skip(4);


            //    SwitchAnim2WiiU(path); //Hacky auto convert switch anims to wii u


            Syroot.NintenTools.NSW.Bfres.ResFile b = new Syroot.NintenTools.NSW.Bfres.ResFile(path);

            AnimationGroupNode ThisAnimation = new AnimationGroupNode()
            {
                Text = "Bone Visual Animations"
            };

            TreeNode dummy = new TreeNode()
            {
                Text = "Animation Set"
            };

            int i = 0;

            foreach (Syroot.NintenTools.NSW.Bfres.VisibilityAnim vis in b.BoneVisibilityAnims)
            {
                Animation a = new Animation(vis.Name);

                ThisAnimation.Nodes.Add(a);

                a.FrameCount = vis.FrameCount;
                i++;

                int boneindx = 0;
                if (vis.Names != null)
                {
                    foreach (string nm in vis.Names) //Loop through every bone. Not all have base and curve data
                    {
                        Animation.KeyNode bone = new Animation.KeyNode("");
                        a.Bones.Add(bone);
                        bone.Text = vis.Names[boneindx];



                        if (boneindx < vis.BaseDataList.Length)
                        {
                            bool bas = vis.BaseDataList[boneindx];

                            if (bas == true)
                            {
                                bone.XSCA.Keys.Add(new Animation.KeyFrame()
                                {
                                    Frame = 0, Value = 1
                                });
                                bone.YSCA.Keys.Add(new Animation.KeyFrame()
                                {
                                    Frame = 0, Value = 1
                                });
                                bone.ZSCA.Keys.Add(new Animation.KeyFrame()
                                {
                                    Frame = 0, Value = 1
                                });
                            }
                            else
                            {
                                bone.XSCA.Keys.Add(new Animation.KeyFrame()
                                {
                                    Frame = 0, Value = 0
                                });
                                bone.YSCA.Keys.Add(new Animation.KeyFrame()
                                {
                                    Frame = 0, Value = 0
                                });
                                bone.ZSCA.Keys.Add(new Animation.KeyFrame()
                                {
                                    Frame = 0, Value = 0
                                });
                            }
                        }


                        if (vis.Curves.Count != 0)
                        {
                            if (boneindx < vis.Curves.Count)
                            {
                                Syroot.NintenTools.NSW.Bfres.AnimCurve cr = vis.Curves[boneindx];

                                Console.WriteLine($"{vis.Name} {vis.Names[boneindx]}");

                                int frm = 0;
                                foreach (bool bn in cr.KeyStepBoolData)
                                {
                                    Animation.KeyFrame frame = new Animation.KeyFrame();
                                    frame.InterType = Animation.InterpolationType.STEP;
                                    frame.Frame     = cr.Frames[frm];



                                    Console.WriteLine(vis.Name + " " + vis.Names[boneindx] + " " + bn);

                                    switch (bn)
                                    {
                                    case true:
                                        frame.Value = 1; bone.XSCA.Keys.Add(frame);
                                        frame.Value = 1; bone.YSCA.Keys.Add(frame);
                                        frame.Value = 1; bone.ZSCA.Keys.Add(frame);
                                        break;

                                    case false:
                                        frame.Value = 0; bone.XSCA.Keys.Add(frame);
                                        frame.Value = 0; bone.YSCA.Keys.Add(frame);
                                        frame.Value = 0; bone.ZSCA.Keys.Add(frame);
                                        break;
                                    }
                                    frm++;
                                }
                            }
                        }

                        boneindx++;
                    }
                }
            }
            return(ThisAnimation);
        }
Пример #23
0
        public void Read(FileData f, BNTX bntx) //Docs thanks to AboodXD!!
        {
            ImageKey         = "texture";
            SelectedImageKey = "texture";

            f.skip(4);

            int  BRTISize1 = f.readInt();
            long BRTISize2 = f.readInt64();

            surf = new TegraX1Swizzle.Surface();
            ushort Flags = (ushort)f.readShort();

            surf.dim      = (sbyte)f.readByte();
            surf.tileMode = (sbyte)f.readByte();
            surf.swizzle  = (ushort)f.readShort();
            surf.numMips  = (ushort)f.readShort();
            uint numSamples = (uint)f.readInt();

            surf.format = (uint)f.readInt();
            DataType    = (byte)(surf.format & 0xFF);
            uint accessFlags = (uint)f.readInt();

            surf.width  = f.readInt();
            surf.height = f.readInt();
            surf.depth  = f.readInt();
            int FaceCount = f.readInt();

            surf.sizeRange = f.readInt();
            uint unk38 = (uint)f.readInt();
            uint unk3C = (uint)f.readInt();
            uint unk40 = (uint)f.readInt();
            uint unk44 = (uint)f.readInt();
            uint unk48 = (uint)f.readInt();
            uint unk4C = (uint)f.readInt();

            surf.imageSize = f.readInt();
            surf.alignment = f.readInt();
            int ChannelType = f.readInt();
            int TextureType = f.readInt();

            Text = f.readString((int)f.readInt64() + BNTX.temp + 2, -1);
            long ParentOffset = f.readInt64();
            long PtrsOffset   = f.readInt64();

            format = surf.format;

            surf.data = new List <byte[]>();

            uint blk_dim = Formats.blk_dims(surf.format >> 8);

            blkWidth  = blk_dim >> 4;
            blkHeight = blk_dim & 0xF;

            f.seek((int)PtrsOffset + BNTX.temp);
            long firstMipOffset = f.readInt64();

            surf.data.Add(f.getSection((int)firstMipOffset + BNTX.temp, surf.imageSize));
            for (int mipLevel = 1; mipLevel < surf.numMips; mipLevel++)
            {
                long dataOff = f.readInt64();
                surf.data.Add(f.getSection((int)dataOff + BNTX.temp, (int)firstMipOffset + surf.imageSize - (int)dataOff));
                //    Debug.WriteLine($"{Name} Height {surf.height}wdith = {surf.width}allignment = {surf.alignment}blkwidth = {blkWidth}blkheight = {blkHeight}blkdims = {blk_dim} format = {surf.format} datatype = {DataType} dataoffset = {dataOff}");
            }
            bpp = Formats.bpps(surf.format >> 8);

            int target = 0;

            if (bntx.target == "NX  ")
            {
                target = 1;
            }

            int blockHeightLog2 = surf.sizeRange & 7;

            int linesPerBlockHeight = (1 << blockHeightLog2) * 8;
            int blockHeightShift    = 0;

            for (int mipLevel = 0; mipLevel < surf.numMips; mipLevel++)
            {
                uint width  = (uint)Math.Max(1, surf.width >> mipLevel);
                uint height = (uint)Math.Max(1, surf.height >> mipLevel);

                uint size = TegraX1Swizzle.DIV_ROUND_UP(width, blkWidth) * TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight) * bpp;

                if (TegraX1Swizzle.pow2_round_up(TegraX1Swizzle.DIV_ROUND_UP(height, blkWidth)) < linesPerBlockHeight)
                {
                    blockHeightShift += 1;
                }

                byte[] result = TegraX1Swizzle.deswizzle(width, height, blkWidth, blkHeight, target, bpp, (uint)surf.tileMode, (uint)surf.alignment, Math.Max(0, blockHeightLog2 - blockHeightShift), surf.data[mipLevel], 0);
                //Create a copy and use that to remove uneeded data
                result_ = new byte[size];
                Array.Copy(result, 0, result_, 0, size);
                texture.mipmaps.Add(result_);
            }

            LoadFormats(texture, surf.format, 0, surf.width, surf.height);

            texture.width  = surf.width;
            texture.height = surf.height;

            Width  = surf.width;
            Height = surf.height;
        }
Пример #24
0
            private static byte[] YAZ0(byte[] data)
            {
                FileData f = new FileData(data);

                f.Endian = Endianness.Big;
                f.seek(4);
                int uncompressedSize = f.readInt();

                f.seek(0x10);

                byte[] src = f.read(data.Length - 0x10);
                byte[] dst = new byte[uncompressedSize];

                int srcPlace = 0, dstPlace = 0; //current read/write positions

                uint validBitCount = 0;         //number of valid bits left in "code" byte
                byte currCodeByte  = 0;

                while (dstPlace < uncompressedSize)
                {
                    //read new "code" byte if the current one is used up
                    if (validBitCount == 0)
                    {
                        currCodeByte = src[srcPlace];
                        ++srcPlace;
                        validBitCount = 8;
                    }

                    if ((currCodeByte & 0x80) != 0)
                    {
                        //straight copy
                        dst[dstPlace] = src[srcPlace];
                        dstPlace++;
                        srcPlace++;
                    }
                    else
                    {
                        //RLE part
                        byte byte1 = src[srcPlace];
                        byte byte2 = src[srcPlace + 1];
                        srcPlace += 2;

                        uint dist       = (uint)(((byte1 & 0xF) << 8) | byte2);
                        uint copySource = (uint)(dstPlace - (dist + 1));

                        uint numBytes = (uint)(byte1 >> 4);
                        if (numBytes == 0)
                        {
                            numBytes = (uint)(src[srcPlace] + 0x12);
                            srcPlace++;
                        }
                        else
                        {
                            numBytes += 2;
                        }

                        //copy run
                        for (int i = 0; i < numBytes; ++i)
                        {
                            dst[dstPlace] = dst[copySource];
                            copySource++;
                            dstPlace++;
                        }
                    }

                    //use next bit from "code" byte
                    currCodeByte <<= 1;
                    validBitCount -= 1;
                }

                return(dst);
            }
Пример #25
0
        public override void Read(string filename)
        {
            FileData d = new FileData(filename);

            FilePath = filename;
            d.Endian = Endianness.Little; // characters are little
            d.seek(8);                    // skip magic and version?
            int count = d.readInt();      // entry count

            for (int i = 0; i < count; i++)
            {
                SBEntry sb = new SBEntry()
                {
                    hash     = (uint)d.readInt(),
                    param1_1 = d.readFloat(),
                    param1_2 = d.readInt(),
                    param1_3 = d.readInt(),
                    param2_1 = d.readFloat(),
                    param2_2 = d.readFloat(),
                    param2_3 = d.readInt(),
                    rx1      = d.readFloat(),
                    rx2      = d.readFloat(),
                    ry1      = d.readFloat(),
                    ry2      = d.readFloat(),
                    rz1      = d.readFloat(),
                    rz2      = d.readFloat()
                };

                for (int j = 0; j < 8; j++)
                {
                    sb.boneHashes[j] = (uint)d.readInt();
                }

                for (int j = 0; j < 4; j++)
                {
                    sb.unks1[j] = d.readFloat();
                }

                for (int j = 0; j < 6; j++)
                {
                    sb.unks2[j] = d.readFloat();
                }

                sb.factor = d.readFloat();

                for (int j = 0; j < 3; j++)
                {
                    sb.ints[j] = d.readInt();
                }

                bones.Add(sb);

                /*Console.WriteLine(sb.hash.ToString("x"));
                 * Console.WriteLine(d.readFloat() + " " + d.readInt() + " " + d.readInt());
                 * Console.WriteLine(d.readFloat() + " " + d.readInt() + " " + d.readInt());
                 *
                 * //28 floats?
                 * Console.WriteLine(d.readFloat() + " " + d.readFloat());
                 * Console.WriteLine(d.readFloat() + " " + d.readFloat());
                 * Console.WriteLine(d.readFloat() + " " + d.readFloat());
                 * Console.WriteLine(d.readFloat() + " " + d.readFloat() + " " + d.readFloat() + " " + d.readFloat());
                 * Console.WriteLine(d.readFloat() + " " + d.readFloat() + " " + d.readFloat() + " " + d.readFloat());
                 *
                 * Console.WriteLine(d.readFloat() + " " + d.readFloat() + " " + d.readFloat() + " " + d.readFloat());
                 * Console.WriteLine(d.readFloat() + " " + d.readFloat() + " " + d.readFloat() + " " + d.readFloat());
                 *
                 * Console.WriteLine(d.readFloat() + " " + d.readFloat());
                 * Console.WriteLine(d.readInt() +  " " + d.readInt());
                 * Console.WriteLine(d.readInt() + " " + d.readInt());
                 * Console.WriteLine();*/
            }
        }
Пример #26
0
        public static AnimationGroupNode Read(string filename)
        {
            bchHeader header = new bchHeader();
            FileData  f      = new FileData(filename);

            f.Endian = System.IO.Endianness.Little;

            f.skip(4);
            header.backwardCompatibility = f.readByte();
            header.forwardCompatibility  = f.readByte();
            header.version = f.readUShort();

            header.mainHeaderOffset  = f.readInt();
            header.stringTableOffset = f.readInt();
            header.gpuCommandsOffset = f.readInt();
            header.dataOffset        = f.readInt();
            if (header.backwardCompatibility > 0x20)
            {
                header.dataExtendedOffset = f.readInt();
            }
            header.relocationTableOffset = f.readInt();

            header.mainHeaderLength  = f.readInt();
            header.stringTableLength = f.readInt();
            header.gpuCommandsLength = f.readInt();
            header.dataLength        = f.readInt();
            if (header.backwardCompatibility > 0x20)
            {
                header.dataExtendedLength = f.readInt();
            }
            header.relocationTableLength = f.readInt();

            header.uninitializedDataSectionLength        = f.readInt();
            header.uninitializedDescriptionSectionLength = f.readInt();

            if (header.backwardCompatibility > 7)
            {
                header.flags        = f.readUShort();
                header.addressCount = f.readUShort();
            }

            // Relocation table
            for (int i = 0; i < header.relocationTableLength; i += 4)
            {
                f.seek(header.relocationTableOffset + i);
                int  val  = f.readInt();
                int  off  = val & 0x1FFFFFF;
                byte flag = (byte)(val >> 25);

                switch (flag)
                {
                case 0:
                    f.seek((off * 4) + header.mainHeaderOffset);
                    f.writeInt((off * 4) + header.mainHeaderOffset, f.readInt() + header.mainHeaderOffset);
                    break;

                case 1:
                    f.seek(off + header.mainHeaderOffset);
                    f.writeInt((off) + header.mainHeaderOffset, f.readInt() + header.stringTableOffset);
                    break;

                case 2:
                    f.seek((off * 4) + header.mainHeaderOffset);
                    f.writeInt((off * 4) + header.mainHeaderOffset, f.readInt() + header.gpuCommandsOffset);
                    break;

                case 0xc:
                    f.seek((off * 4) + header.mainHeaderOffset);
                    f.writeInt((off * 4) + header.mainHeaderOffset, f.readInt() + header.dataOffset);
                    break;
                }
            }


            // Content Header
            f.seek(header.mainHeaderOffset);
            bchContentHeader content = new bchContentHeader();
            {
                content.modelsPointerTableOffset        = f.readInt();
                content.modelsPointerTableEntries       = f.readInt();
                content.modelsNameOffset                = f.readInt();
                content.materialsPointerTableOffset     = f.readInt();
                content.materialsPointerTableEntries    = f.readInt();
                content.materialsNameOffset             = f.readInt();
                content.shadersPointerTableOffset       = f.readInt();
                content.shadersPointerTableEntries      = f.readInt();
                content.shadersNameOffset               = f.readInt();
                content.texturesPointerTableOffset      = f.readInt();
                content.texturesPointerTableEntries     = f.readInt();
                content.texturesNameOffset              = f.readInt();
                content.materialsLUTPointerTableOffset  = f.readInt();
                content.materialsLUTPointerTableEntries = f.readInt();
                content.materialsLUTNameOffset          = f.readInt();
                content.lightsPointerTableOffset        = f.readInt();
                content.lightsPointerTableEntries       = f.readInt();
                content.lightsNameOffset                = f.readInt();
                content.camerasPointerTableOffset       = f.readInt();
                content.camerasPointerTableEntries      = f.readInt();
                content.camerasNameOffset               = f.readInt();
                content.fogsPointerTableOffset          = f.readInt();
                content.fogsPointerTableEntries         = f.readInt();
                content.fogsNameOffset = f.readInt();
                content.skeletalAnimationsPointerTableOffset    = f.readInt();
                content.skeletalAnimationsPointerTableEntries   = f.readInt();
                content.skeletalAnimationsNameOffset            = f.readInt();
                content.materialAnimationsPointerTableOffset    = f.readInt();
                content.materialAnimationsPointerTableEntries   = f.readInt();
                content.materialAnimationsNameOffset            = f.readInt();
                content.visibilityAnimationsPointerTableOffset  = f.readInt();
                content.visibilityAnimationsPointerTableEntries = f.readInt();
                content.visibilityAnimationsNameOffset          = f.readInt();
                content.lightAnimationsPointerTableOffset       = f.readInt();
                content.lightAnimationsPointerTableEntries      = f.readInt();
                content.lightAnimationsNameOffset           = f.readInt();
                content.cameraAnimationsPointerTableOffset  = f.readInt();
                content.cameraAnimationsPointerTableEntries = f.readInt();
                content.cameraAnimationsNameOffset          = f.readInt();
                content.fogAnimationsPointerTableOffset     = f.readInt();
                content.fogAnimationsPointerTableEntries    = f.readInt();
                content.fogAnimationsNameOffset             = f.readInt();
                content.scenePointerTableOffset             = f.readInt();
                content.scenePointerTableEntries            = f.readInt();
                content.sceneNameOffset = f.readInt();
            }


            //Skeletal animation
            AnimationGroupNode ThisAnimation = new AnimationGroupNode()
            {
                Text = filename
            };

            for (int index1 = 0; index1 < content.skeletalAnimationsPointerTableEntries; index1++)//
            {
                f.seek(content.skeletalAnimationsPointerTableOffset + (index1 * 4));
                int dataOffset = f.readInt();
                f.seek(dataOffset);


                string skeletalAnimationName = f.readString(f.readInt(), -1);
                int    animationFlags        = f.readInt();
                //int skeletalAnimationloopMode = f.readByte();  //pas ça du tout
                float skeletalAnimationframeSize = f.readFloat();
                int   boneTableOffset            = f.readInt();
                int   boneTableEntries           = f.readInt();
                int   metaDataPointerOffset      = f.readInt();

                //Runtime.Animations.Add(skeletalAnimationName, a);
                //MainForm.animNode.Nodes.Add(skeletalAnimationName);

                //Debug.WriteLine("Animation Name: " + skeletalAnimationName);
                Animation a = new Animation(skeletalAnimationName);
                ThisAnimation.Nodes.Add(a);

                for (int i = 0; i < boneTableEntries; i++)
                {
                    f.seek(boneTableOffset + (i * 4));
                    int offset = f.readInt();

                    Animation.KeyNode bone = new Animation.KeyNode("");
                    a.Bones.Add(bone);
                    f.seek(offset);
                    bone.Text = f.readString(f.readInt(), -1);
                    //Console.WriteLine("Bone Name: " + bone.name);
                    int  animationTypeFlags = f.readInt();
                    uint flags = (uint)f.readInt();

                    OSegmentType segmentType = (OSegmentType)((animationTypeFlags >> 16) & 0xf);
                    //Debug.WriteLine(bone.Text + " " + flags.ToString("x"));
                    switch (segmentType)
                    {
                    case OSegmentType.transform:
                        f.seek(offset + 0xC);
                        //Console.WriteLine(f.pos().ToString("x") + " " + flags.ToString("x"));

                        uint notExistMask = 0x10000;
                        uint constantMask = 0x40;

                        for (int j = 0; j < 3; j++)
                        {
                            for (int axis = 0; axis < 3; axis++)
                            {
                                bool notExist = (flags & notExistMask) > 0;
                                bool constant = (flags & constantMask) > 0;
                                //Console.WriteLine(notExist + " " + constant);

                                Animation.KeyGroup group = new Animation.KeyGroup();
                                //frame.exists = !notExist;
                                if (!notExist)
                                {
                                    if (constant)
                                    {
                                        Animation.KeyFrame frame = new Animation.KeyFrame();
                                        frame.InterType = Animation.InterpolationType.LINEAR;
                                        frame.Value     = f.readFloat();
                                        frame.Frame     = 0;
                                        group.Keys.Add(frame);
                                    }
                                    else
                                    {
                                        int frameOffset = f.readInt();
                                        int position    = f.pos();
                                        f.seek(frameOffset);
                                        float c = 0;
                                        //Debug.WriteLine(j + " " + axis + " " + bone.Text);
                                        getAnimationKeyFrame(f, group, out c);
                                        if (c > a.FrameCount)
                                        {
                                            a.FrameCount = (int)c;
                                        }
                                        f.seek(position);
                                    }
                                }
                                else
                                {
                                    f.seek(f.pos() + 0x04);
                                }
                                bone.RotType = Animation.RotationType.EULER;

                                if (j == 0)
                                {
                                    switch (axis)
                                    {
                                    case 0: bone.XSCA = group; break;

                                    case 1: bone.YSCA = group; break;

                                    case 2: bone.ZSCA = group; break;
                                    }
                                }
                                else
                                if (j == 1)
                                {
                                    switch (axis)
                                    {
                                    case 0: bone.XROT = group; break;

                                    case 1: bone.YROT = group; break;

                                    case 2: bone.ZROT = group; break;
                                    }
                                }
                                else
                                if (j == 2)
                                {
                                    switch (axis)
                                    {
                                    case 0: bone.XPOS = group; break;

                                    case 1: bone.YPOS = group; break;

                                    case 2: bone.ZPOS = group; break;
                                    }
                                }

                                notExistMask <<= 1;
                                constantMask <<= 1;
                            }
                            if (j == 1)
                            {
                                constantMask <<= 1;
                            }
                        }

                        break;

                    /*case OSegmentType.transformQuaternion:
                     *  bone.isFrameFormat = true;
                     *
                     *  int scaleOffset = f.readInt();
                     *  int rotationOffset = f.readInt();
                     *  int translationOffset = f.readInt();
                     *
                     *  if ((flags & 0x20) == 0)
                     *  {
                     *      bone.scale.exists = true;
                     *      f.seek(scaleOffset);
                     *
                     *      if ((flags & 4) > 0)
                     *      {
                     *          bone.scale.vector.Add(new Vector4(
                     *              f.readFloat(),
                     *              f.readFloat(),
                     *              f.readFloat(),
                     *              0));
                     *      }
                     *      else
                     *      {
                     *          bone.scale.startFrame = f.readFloat();
                     *          bone.scale.endFrame = f.readFloat();
                     *
                     *          int scaleFlags = f.readInt();
                     *          int scaleDataOffset = f.readInt();
                     *          int scaleEntries = f.readInt();
                     *
                     *          f.seek(scaleDataOffset);
                     *          for (int j = 0; j < scaleEntries; j++)
                     *          {
                     *              bone.scale.vector.Add(new Vector4(
                     *                  f.readFloat(),
                     *                  f.readFloat(),
                     *                  f.readFloat(),
                     *                  0));
                     *          }
                     *      }
                     *  }
                     *
                     *  if ((flags & 0x10) == 0)
                     *  {
                     *      bone.rotationQuaternion.exists = true;
                     *      f.seek(rotationOffset);
                     *
                     *      if ((flags & 2) > 0)
                     *      {
                     *          bone.rotationQuaternion.vector.Add(new Vector4(
                     *              f.readFloat(),
                     *              f.readFloat(),
                     *              f.readFloat(),
                     *              f.readFloat()));
                     *      }
                     *      else
                     *      {
                     *          bone.rotationQuaternion.startFrame = f.readFloat();
                     *          bone.rotationQuaternion.endFrame = f.readFloat();
                     *
                     *          int rotationFlags = f.readInt();
                     *          int rotationDataOffset = f.readInt();
                     *          int rotationEntries = f.readInt();
                     *
                     *          f.seek(rotationDataOffset);
                     *          for (int j = 0; j < rotationEntries; j++)
                     *          {
                     *              bone.rotationQuaternion.vector.Add(new Vector4(
                     *                  f.readFloat(),
                     *                  f.readFloat(),
                     *                  f.readFloat(),
                     *                  f.readFloat()));
                     *          }
                     *      }
                     *  }
                     *
                     *  if ((flags & 8) == 0)
                     *  {
                     *      bone.translation.exists = true;
                     *      f.seek(translationOffset);
                     *
                     *      if ((flags & 1) > 0)
                     *      {
                     *          bone.translation.vector.Add(new Vector4(
                     *              f.readFloat(),
                     *              f.readFloat(),
                     *              f.readFloat(),
                     *              0));
                     *      }
                     *      else
                     *      {
                     *          bone.translation.startFrame = f.readFloat();
                     *          bone.translation.endFrame = f.readFloat();
                     *
                     *          int translationFlags = f.readInt();
                     *          int translationDataOffset = f.readInt();
                     *          int translationEntries = f.readInt();
                     *
                     *          f.seek(translationDataOffset);
                     *          for (int j = 0; j < translationEntries; j++)
                     *          {
                     *              bone.translation.vector.Add(new Vector4(
                     *                  f.readFloat(),
                     *                  f.readFloat(),
                     *                  f.readFloat(),
                     *                  0));
                     *          }
                     *      }
                     *  }
                     *
                     *  break;
                     * case OSegmentType.transformMatrix:
                     *  bone.isFullBakedFormat = true;
                     *
                     *  f.readInt();
                     *  f.readInt();
                     *  int matrixOffset = f.readInt();
                     *  int entries = f.readInt();
                     *
                     *  f.seek(matrixOffset);
                     *  for (int j = 0; j < entries; j++)
                     *  {
                     *      OMatrix transform = new OMatrix();
                     *      transform.M11 = f.readFloat();
                     *      transform.M21 = f.readFloat();
                     *      transform.M31 = f.readFloat();
                     *      transform.M41 = f.readFloat();
                     *
                     *      transform.M12 = f.readFloat();
                     *      transform.M22 = f.readFloat();
                     *      transform.M32 = f.readFloat();
                     *      transform.M42 = f.readFloat();
                     *
                     *      transform.M13 = f.readFloat();
                     *      transform.M23 = f.readFloat();
                     *      transform.M33 = f.readFloat();
                     *      transform.M43 = f.readFloat();
                     *
                     *      bone.transform.Add(transform);
                     *  }
                     *
                     *  break;*/
                    default: throw new Exception(string.Format("BCH: Unknow Segment Type {0} on Skeletal Animation bone {1}! STOP!", segmentType, bone.Text));
                    }

                    //skeletalAnimation.bone.Add(bone);
                }
            }
            //return a;
            return(ThisAnimation);
        }
Пример #27
0
        public override void Read(string filename)
        {
            FileData file = new FileData(filename);

            if (file != null)
            {
                file.Endian = Endianness.Little;
                Endian      = Endianness.Little;
                string magic = file.readString(0, 4);
                if (magic == "VBN ")
                {
                    file.Endian = Endianness.Big;
                    Endian      = Endianness.Big;
                }

                file.seek(4);

                unk_1               = file.readShort();
                unk_2               = file.readShort();
                totalBoneCount      = (UInt32)file.readInt();
                boneCountPerType[0] = (UInt32)file.readInt();
                boneCountPerType[1] = (UInt32)file.readInt();
                boneCountPerType[2] = (UInt32)file.readInt();
                boneCountPerType[3] = (UInt32)file.readInt();

                int[] pi = new int[totalBoneCount];
                for (int i = 0; i < totalBoneCount; i++)
                {
                    Bone temp = new Bone(this);
                    temp.Text = file.readString(file.pos(), -1);
                    file.skip(64);
                    temp.boneType = (UInt32)file.readInt();
                    pi[i]         = file.readInt();
                    temp.boneId   = (UInt32)file.readInt();
                    temp.position = new float[3];
                    temp.rotation = new float[3];
                    temp.scale    = new float[3];
                    //temp.isSwingBone = temp.Text.Contains("__swing");
                    bones.Add(temp);
                }

                for (int i = 0; i < bones.Count; i++)
                {
                    bones[i].position[0] = file.readFloat();
                    bones[i].position[1] = file.readFloat();
                    bones[i].position[2] = file.readFloat();
                    bones[i].rotation[0] = file.readFloat();
                    bones[i].rotation[1] = file.readFloat();
                    bones[i].rotation[2] = file.readFloat();
                    bones[i].scale[0]    = file.readFloat();
                    bones[i].scale[1]    = file.readFloat();
                    bones[i].scale[2]    = file.readFloat();
                    Bone temp = bones[i];
                    temp.parentIndex = pi[i];
                    //Debug.Write(temp.parentIndex);
                    //if (temp.parentIndex != 0x0FFFFFFF && temp.parentIndex > -1)
                    //    bones[temp.parentIndex].children.Add(i);
                    bones[i] = temp;
                }
                reset();
            }
        }
Пример #28
0
        private static void getAnimationKeyFrame(FileData input, Animation.KeyGroup group, out float endFrame)
        {
            float startFrame = input.readFloat();

            endFrame = input.readFloat();

            uint frameFlags = (uint)input.readInt();
            //Debug.WriteLine(frameFlags.ToString("x"));
            //int preRepeat = (RenderBase.ORepeatMethod)(frameFlags & 0xf);
            //int postRepeat = (RenderBase.ORepeatMethod)((frameFlags >> 8) & 0xf);

            uint  segmentFlags  = (uint)input.readInt();
            int   interpolation = ((int)segmentFlags & 0xf);
            uint  quantization  = ((segmentFlags >> 8) & 0xff);
            uint  entries       = segmentFlags >> 16;
            float valueScale    = input.readFloat();
            float valueOffset   = input.readFloat();
            float frameScale    = input.readFloat();
            float frameOffset   = input.readFloat();

            uint offset = (uint)input.readInt();

            if (offset < input.size())
            {
                input.seek((int)offset);
            }
            for (int key = 0; key < entries; key++)
            {
                Animation.KeyFrame keyFrame = new Animation.KeyFrame();
                //Console.WriteLine(quantization);
                switch (quantization)
                {
                /*case RenderBase.OSegmentQuantization.hermite128:
                 *  keyFrame.frame = input.ReadSingle();
                 *  keyFrame.value = input.ReadSingle();
                 *  keyFrame.inSlope = input.ReadSingle();
                 *  keyFrame.outSlope = input.ReadSingle();
                 *  break;
                 * case RenderBase.OSegmentQuantization.hermite64:
                 *  uint h64Value = input.ReadUInt32();
                 *  keyFrame.frame = h64Value & 0xfff;
                 *  keyFrame.value = h64Value >> 12;
                 *  keyFrame.inSlope = input.ReadInt16() / 256f;
                 *  keyFrame.outSlope = input.ReadInt16() / 256f;
                 *  break;
                 * case RenderBase.OSegmentQuantization.hermite48:
                 *  keyFrame.frame = input.ReadByte();
                 *  keyFrame.value = input.ReadUInt16();
                 *  byte slope0 = input.ReadByte();
                 *  byte slope1 = input.ReadByte();
                 *  byte slope2 = input.ReadByte();
                 *  keyFrame.inSlope = IOUtils.signExtend(slope0 | ((slope1 & 0xf) << 8), 12) / 32f;
                 *  keyFrame.outSlope = IOUtils.signExtend((slope1 >> 4) | (slope2 << 4), 12) / 32f;
                 *  break;
                 * case RenderBase.OSegmentQuantization.unifiedHermite96:
                 *  keyFrame.frame = input.ReadSingle();
                 *  keyFrame.value = input.ReadSingle();
                 *  keyFrame.inSlope = input.ReadSingle();
                 *  keyFrame.outSlope = keyFrame.inSlope;
                 *  break;
                 * case RenderBase.OSegmentQuantization.unifiedHermite48:
                 *  keyFrame.frame = input.ReadUInt16() / 32f;
                 *  keyFrame.value = input.ReadUInt16();
                 *  keyFrame.inSlope = input.ReadInt16() / 256f;
                 *  keyFrame.outSlope = keyFrame.inSlope;
                 *  break;
                 * case RenderBase.OSegmentQuantization.unifiedHermite32:
                 *  keyFrame.frame = input.ReadByte();
                 *  ushort uH32Value = input.ReadUInt16();
                 *  keyFrame.value = uH32Value & 0xfff;
                 *  keyFrame.inSlope = IOUtils.signExtend((uH32Value >> 12) | (input.ReadByte() << 4), 12) / 32f;
                 *  keyFrame.outSlope = keyFrame.inSlope;
                 *  break;
                 * case RenderBase.OSegmentQuantization.stepLinear64:
                 *  keyFrame.frame = input.ReadSingle();
                 *  keyFrame.value = input.ReadSingle();
                 *  break;*/
                case 7:    // RenderBase.OSegmentQuantization.stepLinear32:
                    uint sL32Value = (uint)input.readInt();
                    keyFrame.Frame = sL32Value & 0xfff;
                    keyFrame.Value = sL32Value >> 12;
                    break;

                default: Console.WriteLine("Unknown type " + quantization); break;
                }

                keyFrame.Frame = (keyFrame.Frame * frameScale) + frameOffset;
                keyFrame.Value = (keyFrame.Value * valueScale) + valueOffset;

                group.Keys.Add(keyFrame);
            }
        }
Пример #29
0
        /**
         * Reading and saving --------------------
         **/

        public override void Read(string filename)
        {
            FileData d = new FileData(filename);

            d.seek(0);
            d.Endian = Endianness.Little;

            format  = d.readUShort();
            unknown = d.readUShort();
            flags   = d.readInt();
            mode    = d.readInt();
            bool hasNameTable = (flags & 2) > 0;

            int polyCount = d.readInt();

            mesh     = new List <Mesh>();
            descript = new List <Descriptor>();
            List <List <int> > prim = new List <List <int> >();

            for (int i = 0; i < polyCount; i++)
            {
                if (i == 0 && mode == 1)
                {
                    Descriptor des = new Descriptor();
                    des.ReadDescription(d);
                    descript.Add(des);
                }

                Mesh m = new Mesh();
                mesh.Add(m);

                int        faceCount = d.readInt();
                List <int> prims     = new List <int>();
                prim.Add(prims);
                for (int j = 0; j < faceCount; j++)
                {
                    int        nodeCount = d.readInt();
                    List <int> nodeList  = new List <int>();
                    m.nodeList.Add(nodeList);

                    for (int k = 0; k < nodeCount; k++)
                    {
                        nodeList.Add(d.readInt()); // for a node list?
                    }
                    int primitiveCount = d.readInt();
                    prims.Add(primitiveCount);

                    if (hasNameTable)
                    {
                        int nameId = d.readInt();
                    }

                    if (mode == 0)
                    {
                        if (format == 4)
                        {
                            int[] buffer = new int[primitiveCount];
                            for (int k = 0; k < primitiveCount; k++)
                            {
                                buffer[k] = d.readUShort();
                            }
                            d.align(4);
                            List <int> buf = new List <int>();
                            buf.AddRange(buffer);
                            m.faces.Add(buf);
                        }
                        else
                        {
                            Descriptor des = new Descriptor();
                            des.ReadDescription(d);
                            descript.Add(des);
                        }
                    }
                }
            }

            if (mode == 0)
            {
                //Console.WriteLine("Extra!");
            }

            // TODO: STRING TABLE
            if (hasNameTable)
            {
                for (int i = 0; i < mesh.Count; i++)
                {
                    int index = d.readByte();
                    nameTable.Add(d.readString());
                }
            }


            if (format != 4)
            {
                d.align(32);
            }

            // Vertex Bank
            int start = d.pos();

            for (int i = 0; i < 1; i++)
            {
                if (mode == 0 || i == 0)
                {
                    Descriptor des = descript[i];

                    if (format != 4)
                    {
                        while (d.pos() < start + des.length)
                        {
                            Vertex v = new Vertex();
                            vertices.Add(v);

                            for (int k = 0; k < des.type.Length; k++)
                            {
                                d.align(2);
                                switch (des.type[k])
                                {
                                case 0:     //Position
                                    v.pos.X = readType(d, des.format[k], des.scale[k]);
                                    v.pos.Y = readType(d, des.format[k], des.scale[k]);
                                    v.pos.Z = readType(d, des.format[k], des.scale[k]);
                                    break;

                                case 1:     //Normal
                                    v.nrm.X = readType(d, des.format[k], des.scale[k]);
                                    v.nrm.Y = readType(d, des.format[k], des.scale[k]);
                                    v.nrm.Z = readType(d, des.format[k], des.scale[k]);
                                    break;

                                case 2:     //Color
                                    v.col.X = (int)(readType(d, des.format[k], des.scale[k]));
                                    v.col.Y = (int)(readType(d, des.format[k], des.scale[k]));
                                    v.col.Z = (int)(readType(d, des.format[k], des.scale[k]));
                                    v.col.W = (int)(readType(d, des.format[k], des.scale[k]));
                                    break;

                                case 3:     //Tex0
                                    v.tx.Add(new Vector2(readType(d, des.format[k], des.scale[k]), readType(d, des.format[k], des.scale[k])));
                                    break;

                                case 4:     //Tex1
                                    v.tx.Add(new Vector2(readType(d, des.format[k], des.scale[k]), readType(d, des.format[k], des.scale[k])));
                                    break;

                                case 5:     //Bone Index
                                    v.node.Add(d.readByte());
                                    v.node.Add(d.readByte());
                                    break;

                                case 6:     //Bone Weight
                                    v.weight.Add(readType(d, des.format[k], des.scale[k]));
                                    v.weight.Add(readType(d, des.format[k], des.scale[k]));
                                    break;
                                    //default:
                                    //    Console.WriteLine("WTF is this");
                                }
                            }
                        }
                        d.align(32);
                    }
                }

                for (int j = 0; j < mesh.Count; j++)
                {
                    foreach (int l in prim[j])
                    {
                        List <int> face = new List <int>();
                        mesh[j].faces.Add(face);
                        for (int k = 0; k < l; k++)
                        {
                            face.Add(d.readUShort());
                        }
                        d.align(32);
                    }
                }
            }

            PreRender();
        }
Пример #30
0
        public static SkelAnimation read(FileData d)
        {
            d.Endian = Endianness.Big;

            d.skip(4); // header OMO
            d.skip(4); // two shorts, idk

            d.skip(4); //flags?

            d.skip(2);
            int numOfBones = d.readShort();
            int frameSize  = d.readShort();
            int frameStart = d.readShort();

            int offset1 = d.readInt();
            int offset2 = d.readInt();
            int offset3 = d.readInt();

            SkelAnimation anim = new SkelAnimation();

            anim.Tag = d;
            //anim.setModel(m);

            // base frames
            // These are linked to bones somehow, hash??
            d.seek(offset1); //
            int[]     framekey = new int[numOfBones];
            KeyNode[] baseNode = new KeyNode[numOfBones];

            for (int i = 0; i < numOfBones; i++)
            {
                int flags = d.readByte();
                int tFlag = d.readByte();
                int rFlag = d.readByte();
                int sFlag = d.readByte();
                int hash  = d.readInt(); // used to find the identifying bone
                int off1  = d.readInt() + offset2;
                framekey[i] = d.readInt();

                bool hasTrans = (flags & 0x01) == 0x01;
                bool hasScale = (flags & 0x04) == 0x04;
                bool hasRot   = (flags & 0x02) == 0x02;

                KeyNode node = new KeyNode();
                baseNode[i] = node;

                node.hash = (uint)hash;

                int temp = d.pos();
                d.seek(off1);

                if (hasTrans)
                {
                    if (tFlag == 0x8)
                    { // interpolated
                        node.t_type = KeyNode.INTERPOLATED;
                        node.t      = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                        node.t2     = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                    }
                    else if (tFlag == 0x20)
                    {
                        node.t_type = KeyNode.CONSTANT;
                        node.t      = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                    }
                }
                if (hasRot)
                {
                    if ((rFlag & 0xF) != 0x50 && (rFlag & 0xF0) != 0x70 && (rFlag & 0xF0) != 0x60 && (rFlag & 0xF0) != 0xA0)
                    {
                        //Console.WriteLine(rFlag);
                    }

                    if ((rFlag & 0xF0) == 0xA0)
                    {
                        node.r_type = 3;
                    }

                    if ((rFlag & 0xF0) == 0x50)
                    { // interpolated
                        node.r_type = KeyNode.INTERPOLATED;
                        node.rv     = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                        node.rv2    = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                    }
                    if ((rFlag & 0xF0) == 0x70 || (rFlag & 0xF0) == 0x60)
                    { // constant
                        node.r_type = KeyNode.CONSTANT;
                        node.rv     = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                        if ((rFlag & 0xF0) == 0x60)
                        {
                            d.skip(4);
                        }
                    }
                }

                if (hasScale)
                {
                    if ((sFlag & 0xF0) == 0x80)
                    { // interpolated
                        node.s_type = KeyNode.INTERPOLATED;
                        node.s      = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                        node.s2     = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                    }
                    if ((rFlag & 0x0F) == 0x02 || (rFlag & 0x0F) == 0x03)
                    { // constant
                        node.s_type = KeyNode.CONSTANT;
                        node.s      = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                    }
                }
                d.seek(temp);
            }

            d.seek(offset3);
            for (int i = 0; i < frameSize; i++)
            {
                KeyFrame key = new KeyFrame();
                key.frame = i;

                int off = d.pos();

                for (int j = 0; j < numOfBones; j++)
                {
                    KeyNode node = new KeyNode();

                    node.t_type = baseNode[j].t_type;
                    node.r_type = baseNode[j].r_type;
                    node.s_type = baseNode[j].s_type;

                    node.id   = baseNode[j].id;
                    node.hash = baseNode[j].hash;

                    d.seek(off + framekey[j]);

                    if (baseNode[j].t_type == KeyNode.INTERPOLATED)
                    {
                        float i1 = ((float)d.readShort() / 0xffff);
                        float i2 = ((float)d.readShort() / 0xffff);
                        float i3 = ((float)d.readShort() / 0xffff);

                        float x = baseNode[j].t.X + (baseNode[j].t2.X * (i1));
                        float y = baseNode[j].t.Y + (baseNode[j].t2.Y * (i2));
                        float z = baseNode[j].t.Z + (baseNode[j].t2.Z * (i3));

                        node.t = new Vector3(x, y, z);
                    }
                    else
                    {
                        node.t = baseNode[j].t;
                    }

                    if (baseNode[j].r_type == 3)
                    {
                        float i1 = ((float)d.readShort() / (0xffff));
                        float i2 = ((float)d.readShort() / (0xffff));
                        float i3 = ((float)d.readShort() / (0xffff));
                        float i4 = ((float)d.readShort() / (0xffff));

                        node.r = new Quaternion(new Vector3(i1, i2, i3), i4);
                        //Console.WriteLine(node.r.ToString());
                        //node.r = VBN.FromEulerAngles(i4 * i1, i4 * i2, i4 * i3);
                        node.r_type = KeyNode.INTERPOLATED;
                        //node.r.Normalize();
                    }
                    else
                    if (baseNode[j].r_type == KeyNode.INTERPOLATED)
                    {
                        float i1 = ((float)d.readShort() / (0xffff));
                        float i2 = ((float)d.readShort() / (0xffff));
                        float i3 = ((float)d.readShort() / (0xffff));

                        float x = baseNode[j].rv.X + (baseNode[j].rv2.X * (i1));
                        float y = baseNode[j].rv.Y + (baseNode[j].rv2.Y * (i2));
                        float z = baseNode[j].rv.Z + (baseNode[j].rv2.Z * (i3));

                        float w = (float)Math.Sqrt(Math.Abs(1 - (x * x + y * y + z * z)));

                        node.r = new Quaternion(new Vector3(x, y, z), w);
                        node.r.Normalize();
                    }
                    else
                    {
                        float x = baseNode[j].rv.X;
                        float y = baseNode[j].rv.Y;
                        float z = baseNode[j].rv.Z;

                        float w = (float)Math.Sqrt(1 - (x * x + y * y + z * z));

                        node.r = new Quaternion(baseNode[j].rv, w);
                    }

                    if (baseNode[j].s_type == KeyNode.INTERPOLATED)
                    {
                        float i1 = ((float)d.readShort() / (0xffff));
                        float i2 = ((float)d.readShort() / (0xffff));
                        float i3 = ((float)d.readShort() / (0xffff));

                        float x = baseNode[j].s.X + (baseNode[j].s2.X * (i1));
                        float y = baseNode[j].s.Y + (baseNode[j].s2.Y * (i2));
                        float z = baseNode[j].s.Z + (baseNode[j].s2.Z * (i3));

                        node.s = new Vector3(x, y, z);
                    }
                    else
                    {
                        node.s = baseNode[j].s;
                    }

                    key.addNode(node);
                }
                d.seek(off + frameStart);

                anim.addKeyframe(key);
            }

            return(anim);
        }