示例#1
0
        public void ReadBNTX(FileData f)
        {
            textures.Clear();

            BFRES b = new BFRES();

            temp = f.pos();

            f.skip(8); //Magic
            int Version        = f.readInt();
            int ByteOrderMark  = f.readShort();
            int FormatRevision = f.readShort();

            Text = f.readString(f.readInt() + temp, -1);
            f.skip(2);
            int strOffset   = f.readShort();
            int relocOffset = f.readInt();
            int FileSize    = f.readInt();

            f.skip(4); //NX Magic
            int TexturesCount   = f.readInt();
            int InfoPtrsOffset  = f.readInt();
            int DataBlockOffset = f.readInt();
            int DictOffset      = f.readInt();
            int strDictSize     = f.readInt();

            Text = Text + ".bntx";

            BNTXFile = f.getSection(temp, FileSize);

            for (int i = 0; i < TexturesCount; i++)
            {
                f.seek(InfoPtrsOffset + temp + i * 8);
                BRTIOffset = f.readInt();


                f.seek(BRTIOffset + temp);

                //  textures.Add(new BRTI(f));
                BRTI texture = new BRTI(f);

                if (!textured.ContainsKey(texture.Text))
                {
                    textured.Add(texture.Text, texture);
                }

                textures.Add(texture);
            }
            Nodes.AddRange(textures.ToArray());
        }
示例#2
0
        public void read(FileData f)
        {
            f.skip(0xC);

            f.skip(1);
            name = f.readString(f.pos(), 0x38);
            f.skip(0x38);

            f.skip(1);
            subname = f.readString(f.pos(), 0x40);
            f.skip(0x40);

            f.skip(1);
            for (int i = 0; i < 3; i++)
            {
                startPos[i] = f.readFloat();
            }
            useStartPos = Convert.ToBoolean(f.readByte());

            f.skip(1);
            unk1 = f.readInt(); //Some kind of count? Only seen it as 0 so I don't know what it's for

            //Not sure what this is for, but it seems like an x,y,z followed by a hash
            f.skip(1);
            for (int i = 0; i < 3; i++)
            {
                unk2[i] = f.readFloat();
            }
            unk3 = f.readInt();

            f.skip(1);
            boneName = new char[0x40];
            for (int i = 0; i < 0x40; i++)
            {
                boneName[i] = (char)f.readByte();
            }
        }
示例#3
0
        public override void Read(string filename)
        {
            FileData buf = new FileData(filename);

            buf.Endian = Endianness.Little;

            buf.seek(0x06);

            short numAtlases    = buf.readShort();
            short numTextures   = buf.readShort();
            short flagsOffset   = buf.readShort();
            short entriesOffset = buf.readShort();
            short stringsOffset = buf.readShort();


            buf.seek(flagsOffset);
            for (int i = 0; i < numAtlases; i++)
            {
                atlases.Add((AtlasFlag)buf.readInt());
            }

            buf.seek(entriesOffset);
            for (int i = 0; i < numTextures; i++)
            {
                Texture entry       = new Texture();
                int     nameOffset  = buf.readInt();
                int     nameOffset2 = buf.readInt();

                // I have yet to see this.
                if (nameOffset != nameOffset2)
                {
                    throw new NotImplementedException("texlist name offsets don't match?");
                }

                buf.seek(stringsOffset + nameOffset);
                entry.name = buf.readString();

                entry.topLeft  = new Vector2(buf.readFloat(), buf.readFloat());
                entry.botRight = new Vector2(buf.readFloat(), buf.readFloat());

                entry.width   = buf.readShort();
                entry.height  = buf.readShort();
                entry.atlasId = buf.readShort();

                textures.Add(entry);

                buf.skip(0x02); // Padding.
            }
        }
示例#4
0
                public void Read(FileData d)
                {
                    hash = d.readInt();
                    unk1 = d.readInt();

                    int s = d.readByte();

                    name = d.readString(d.pos(), s - 1);
                    d.skip(s);
                    d.align(4);
                    data = new float[0x2c];
                    for (int i = 0; i < 0x2c; i++)
                    {
                        data[i] = d.readFloat();
                    }
                }
示例#5
0
        public void ReadBNTX(FileData f)
        {
            ImageKey         = "UVPattern";
            SelectedImageKey = "UVPattern";

            textures.Clear();
            textured.Clear();

            temp = f.pos();

            f.skip(8); //Magic
            int Version        = f.readInt();
            int ByteOrderMark  = f.readShort();
            int FormatRevision = f.readShort();

            Text = f.readString(f.readInt() + temp, -1);
            f.skip(2);
            int strOffset   = f.readShort();
            int relocOffset = f.readInt();
            int FileSize    = f.readInt();

            f.skip(4); //NX Magic
            int TexturesCount   = f.readInt();
            int InfoPtrsOffset  = f.readInt();
            int DataBlockOffset = f.readInt();
            int DictOffset      = f.readInt();
            int strDictSize     = f.readInt();

            for (int i = 0; i < TexturesCount; i++)
            {
                f.seek(InfoPtrsOffset + temp + i * 8);
                BRTIOffset = f.readInt();


                f.seek(BRTIOffset + temp);

                //  textures.Add(new BRTI(f));
                BRTI texture = new BRTI(f);

                textured.Add(texture.Text, texture);
                textures.Add(texture);
            }
            Nodes.AddRange(textures.ToArray());
        }
示例#6
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);
                }
            }
        }
示例#7
0
        public static Animation readAnim(FileData d, VBN m)
        {
            int offset  = d.readInt();
            int nameoff = d.readInt();

            d.skip(4);
            int fCount        = d.readShort();
            int animDataCount = d.readShort();

            d.skip(8);

            Animation anim = new Animation(d.readString(nameoff, -1));

            anim.FrameCount = fCount;

            //anim.setModel(m);

            d.seek(offset);
            int sectionOffset = d.readInt() + offset;
            int size          = d.readInt();    // size again

            for (int i = 0; i < size; i++)
            {
                //			System.out.print(d.readShort()); // id
                d.skip(4);                 // id and unknown
                d.readShort();             //left
                d.readShort();             //right
                int nameOffset = d.readInt() + offset;
                int dataOffset = d.readInt() + offset;
                if (dataOffset == offset)
                {
                    i--;
                    continue;
                    //				d.skip(8);
                    //				nameOffset = d.readInt() + 4;
                    //				dataOffset = d.readInt() + offset;
                }


                int temp = d.pos();

                d.seek(dataOffset);

                int pos     = d.pos();
                int nameOff = d.readInt() + sectionOffset + (d.pos() - sectionOffset) - 4;
                int flags   = d.readInt();

                int t_type = (flags >> 0x1e) & 0x3;
                int r_type = (flags >> 0x1b) & 0x7;
                int s_type = (flags >> 0x19) & 0x3;

                int hasT = (flags >> 0x18) & 0x1;
                int hasR = (flags >> 0x17) & 0x1;
                int hasS = (flags >> 0x16) & 0x1;

                int Zfixed = (flags >> 0x15) & 0x1;
                int Yfixed = (flags >> 0x14) & 0x1;
                int Xfixed = (flags >> 0x13) & 0x1;

                int RZfixed = (flags >> 0x12) & 0x1;
                int RYfixed = (flags >> 0x11) & 0x1;
                int RXfixed = (flags >> 0x10) & 0x1;

                int SZfixed = (flags >> 0xf) & 0x1;
                int SYfixed = (flags >> 0xe) & 0x1;
                int SXfixed = (flags >> 0xd) & 0x1;

                int Tiso = (flags >> 0x6) & 0x1;
                int Riso = (flags >> 0x5) & 0x1;
                int Siso = (flags >> 0x4) & 0x1;

                Animation.KeyNode node = new Animation.KeyNode(d.readString(nameOff, -1));
                anim.Bones.Add(node);
                node.RotType = Animation.RotationType.EULER;

                if (hasS == 1)
                {
                    if (Siso == 1)
                    {
                        float iss = d.readFloat();
                        node.XSCA.Keys.Add(new Animation.KeyFrame()
                        {
                            Frame = 0, Value = iss
                        });
                        node.YSCA.Keys.Add(new Animation.KeyFrame()
                        {
                            Frame = 0, Value = iss
                        });
                        node.ZSCA.Keys.Add(new Animation.KeyFrame()
                        {
                            Frame = 0, Value = iss
                        });
                    }
                    else
                    {
                        if (SXfixed == 1)
                        {
                            node.XSCA.Keys.Add(new Animation.KeyFrame()
                            {
                                Frame = 0, Value = d.readFloat()
                            });
                        }
                        else
                        {
                            process(d, s_type, pos, node, "SX", false, anim);
                        }
                        if (SYfixed == 1)
                        {
                            node.YSCA.Keys.Add(new Animation.KeyFrame()
                            {
                                Frame = 0, Value = d.readFloat()
                            });
                        }
                        else
                        {
                            process(d, s_type, pos, node, "SY", false, anim);
                        }
                        if (SZfixed == 1)
                        {
                            node.ZSCA.Keys.Add(new Animation.KeyFrame()
                            {
                                Frame = 0, Value = d.readFloat()
                            });
                        }
                        else
                        {
                            process(d, s_type, pos, node, "SZ", false, anim);
                        }
                    }
                }

                if (hasR == 1)
                {
                    if (Riso == 1)
                    {
                        float iss = (float)((d.readFloat()) * Math.PI / 180f);
                        node.XROT.Keys.Add(new Animation.KeyFrame()
                        {
                            Frame = 0, Value = iss
                        });
                        node.YROT.Keys.Add(new Animation.KeyFrame()
                        {
                            Frame = 0, Value = iss
                        });
                        node.ZROT.Keys.Add(new Animation.KeyFrame()
                        {
                            Frame = 0, Value = iss
                        });
                    }
                    else
                    {
                        if (RXfixed == 1)
                        {
                            node.XROT.Keys.Add(new Animation.KeyFrame()
                            {
                                Frame = 0, Value = (float)(Math.PI / 180f) * (d.readFloat())
                            });
                        }
                        else
                        {
                            process(d, r_type, pos, node, "RX", false, anim);
                        }
                        if (RYfixed == 1)
                        {
                            node.YROT.Keys.Add(new Animation.KeyFrame()
                            {
                                Frame = 0, Value = (float)(Math.PI / 180f) * (d.readFloat())
                            });
                        }
                        else
                        {
                            process(d, r_type, pos, node, "RY", false, anim);
                        }
                        if (RZfixed == 1)
                        {
                            node.ZROT.Keys.Add(new Animation.KeyFrame()
                            {
                                Frame = 0, Value = (float)(Math.PI / 180f) * (d.readFloat())
                            });
                        }
                        else
                        {
                            process(d, r_type, pos, node, "RZ", false, anim);
                        }
                    }
                }

                if (hasT == 1)
                {
                    if (Tiso == 1)
                    {
                        float iss = d.readFloat();
                        node.XPOS.Keys.Add(new Animation.KeyFrame()
                        {
                            Frame = 0, Value = iss
                        });
                        node.YPOS.Keys.Add(new Animation.KeyFrame()
                        {
                            Frame = 0, Value = iss
                        });
                        node.ZPOS.Keys.Add(new Animation.KeyFrame()
                        {
                            Frame = 0, Value = iss
                        });
                    }
                    else
                    {
                        if (Xfixed == 1)
                        {
                            node.XPOS.Keys.Add(new Animation.KeyFrame()
                            {
                                Frame = 0, Value = d.readFloat()
                            });
                        }
                        else
                        {
                            process(d, t_type, pos, node, "X", false, anim);
                        }
                        if (Yfixed == 1)
                        {
                            node.YPOS.Keys.Add(new Animation.KeyFrame()
                            {
                                Frame = 0, Value = d.readFloat()
                            });
                        }
                        else
                        {
                            process(d, t_type, pos, node, "Y", false, anim);
                        }
                        if (Zfixed == 1)
                        {
                            node.ZPOS.Keys.Add(new Animation.KeyFrame()
                            {
                                Frame = 0, Value = d.readFloat()
                            });
                        }
                        else
                        {
                            process(d, t_type, pos, node, "Z", false, anim);
                        }
                    }
                }

                d.seek(temp);
            }

            return(anim);
        }
示例#8
0
        public void Read(ResFile TargetSwitchBFRES, FileData f)
        {
            Nodes.Add(TModels);
            Nodes.Add(TMaterialAnim);
            Nodes.Add(TVisualAnim);
            Nodes.Add(TShapeAnim);
            Nodes.Add(TSceneAnim);
            Nodes.Add(TEmbedded);
            ImageKey         = "bfres";
            SelectedImageKey = "bfres";

            FSKACount = TargetSwitchBFRES.SkeletalAnims.Count;
            FVISCount = TargetSwitchBFRES.BoneVisibilityAnims.Count;
            FMAACount = TargetSwitchBFRES.MaterialAnims.Count;

            Console.WriteLine("Name = " + TargetSwitchBFRES.Name);

            foreach (ExternalFile ext in TargetSwitchBFRES.ExternalFiles)
            {
                f = new FileData(ext.Data);

                f.Endian = Endianness.Little;

                string EmMagic = f.readString(f.pos(), 4);

                if (EmMagic.Equals("BNTX")) //Textures
                {
                    int  temp = f.pos();
                    BNTX t    = new BNTX();
                    t.ReadBNTX(f);
                    TEmbedded.Nodes.Add(t);
                }
            }

            int ModelCur = 0;

            //FMDLs -Models-
            foreach (Model mdl in TargetSwitchBFRES.Models)
            {
                FMDL_Model model = new FMDL_Model(); //This will store VBN data and stuff
                model.Text = mdl.Name;

                TModels.Nodes.Add(model);

                ReadSkeleton(model, mdl);

                model.skeleton.reset();
                model.skeleton.update();

                //MeshTime!!
                foreach (Shape shp in mdl.Shapes)
                {
                    Mesh poly = new Mesh();
                    poly.Text          = shp.Name;
                    poly.MaterialIndex = shp.MaterialIndex;
                    poly.matrFlag      = shp.VertexSkinCount;
                    poly.fsklindx      = shp.BoneIndex;

                    TModels.Nodes[ModelCur].Nodes.Add(poly);


                    ReadVertexBuffer(mdl, shp, poly);


                    //  int LODCount = shp.Meshes.Count - 1; //For going to the lowest poly LOD mesh
                    int LODCount = 0;

                    uint   FaceCount    = FaceCount = shp.Meshes[LODCount].IndexCount;
                    uint[] indicesArray = shp.Meshes[LODCount].GetIndices().ToArray();

                    poly.BoundingCount = shp.SubMeshBoundings.Count;

                    for (int face = 0; face < FaceCount; face++)
                    {
                        poly.faces.Add((int)indicesArray[face] + (int)shp.Meshes[LODCount].FirstVertex);
                    }

                    foreach (Bounding bnd in shp.SubMeshBoundings)
                    {
                        Mesh.BoundingBox box = new Mesh.BoundingBox();
                        box.Center = new Vector3(bnd.Center.X, bnd.Center.Y, bnd.Center.Z);
                        box.Extent = new Vector3(bnd.Extent.X, bnd.Extent.Y, bnd.Extent.Z);

                        poly.boundingBoxes.Add(box); //Each box is by LOD mesh. This will be in a seperate class later so only one will be added
                    }
                    foreach (float r in shp.RadiusArray)
                    {
                        poly.radius.Add(r);
                    }

                    // Read materials
                    Material mat = mdl.Materials[shp.MaterialIndex];

                    poly.material.Name = mat.Name;

                    ReadTextureRefs(mat, poly);
                    ReadShaderParams(mat, poly);
                    ReadRenderInfo(mat, poly);

                    foreach (Sampler smp in mdl.Materials[shp.MaterialIndex].Samplers)
                    {
                        SamplerInfo s = new SamplerInfo();
                        s.WrapModeU = (int)smp.WrapModeU;
                        s.WrapModeV = (int)smp.WrapModeV;
                        s.WrapModeW = (int)smp.WrapModeW;
                        poly.material.samplerinfo.Add(s);
                    }

                    model.poly.Add(poly);
                }
                models.Add(model);
                ModelCur++;
            }
        }
示例#9
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();
            }
        }
示例#10
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);
        }
示例#11
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();
            }

            // TODO: Finished Relocation table stuff
            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.mainHeaderOffset, f.readInt() + header.dataOffset); break; //Texture
                 *      case 0x25: f.writeInt((off * 4) + header.mainHeaderOffset, f.readInt() + header.dataOffset); break; //Vertex
                 *      // Trying to understand the mess first
                 *      case 0x26: f.writeInt((off * 4) + header.mainHeaderOffset, Convert.ToInt32(((f.readInt() + header.dataOffset) & 0x7fffffff) | 0x80000000)); break; //Index 16 bits mode
                 *                                                                                                                                                           //case 0x27: writer.Write((peek(input) + header.dataOffset) & 0x7fffffff); break; //Index 8 bits mode
                 *  }
                 * }
                 *              else if (header.backwardCompatibility < 8)
                 *              {
                 *                  switch (flag)
                 *                  {
                 *                      case 0x24: writer.Write(peek(input) + header.dataOffset); break; //Texture
                 *                      case 0x26: writer.Write(peek(input) + header.dataOffset); break; //Vertex
                 *                      case 0x27: writer.Write(((peek(input) + header.dataOffset) & 0x7fffffff) | 0x80000000); break; //Index 16 bits mode
                 *                      case 0x28: writer.Write((peek(input) + header.dataOffset) & 0x7fffffff); break; //Index 8 bits mode
                 *                  }
                 *              }
                 *              else if (header.backwardCompatibility < 0x21)
                 *              {
                 *                  switch (flag)
                 *                  {
                 *                      case 0x25: writer.Write(peek(input) + header.dataOffset); break; //Texture
                 *                      case 0x27: writer.Write(peek(input) + header.dataOffset); break; //Vertex
                 *                      case 0x28: writer.Write(((peek(input) + header.dataOffset) & 0x7fffffff) | 0x80000000); break; //Index 16 bits mode
                 *                      case 0x29: writer.Write((peek(input) + header.dataOffset) & 0x7fffffff); break; //Index 8 bits mode
                 *                  }
                 *              }
                 *              else
                 *              {
                 *                  switch (flag)
                 *                  {
                 *                      case 0x25: writer.Write(peek(input) + header.dataOffset); break; //Texture
                 *                      case 0x26: writer.Write(peek(input) + 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: writer.Write((peek(input) + header.dataOffset) & 0x7fffffff); break; //Index 8 bits mode relative to Data Offset
                 *                      case 0x2b: writer.Write(peek(input) + 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: writer.Write((peek(input) + 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);
                Debug.WriteLine("dOffset: " + dOffset.ToString("X"));
                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.boneName = f.readString(f.readInt(), -1).ToCharArray();

                    f.skip(4); // Meta data

                    model.skeleton.bones.Add(bone);
                }
                model.skeleton.reset();

/*                //Skeletal Animations
 *
 *              SkelAnimation anim = new SkelAnimation();
 *
 *              for (int index = 0; index < content.skeletalAnimationsPointerTableEntries; index++)
 *               {
 *                  f.seek(content.skeletalAnimationsPointerTableOffset + (index * 4));
 *                  int dataOffset = f.readInt();
 *                  f.seek(dataOffset);
 *
 *                  RenderBase.OSkeletalAnimation skeletalAnimation = new RenderBase.OSkeletalAnimation();
 *
 *                  skeletalAnimation.name = f.readString(f.readInt(), -1);
 *                  int animationFlags = f.readInt();
 *                  skeletalAnimation.loopMode = (RenderBase.OLoopMode)(animationFlags & 1);
 *                  skeletalAnimation.frameSize = f.readFloat();
 *                  int boneTableOffset = f.readInt();
 *                  int boneTableEntries = f.readInt();
 *                  int metaDataPointerOffset = f.readInt();
 *
 * //                    /*if (metaDataPointerOffset != 0)
 * //                    {
 * //                        data.Seek(metaDataPointerOffset, SeekOrigin.Begin);
 * //                        skeletalAnimation.userData = getMetaData(input);
 * //                    }
 *
 *                  for (int i = 0; i < boneTableEntries; i++)
 *                  {
 *                      f.seek(boneTableOffset + (i * 4));
 *                      int offset = f.readInt();
 *
 *                      RenderBase.OSkeletalAnimationBone bone = new RenderBase.OSkeletalAnimationBone();
 *
 *                      f.seek(offset);
 *                      bone.name = f.readString(f.readInt(), -1);
 *                      int animationTypeFlags = f.readInt();
 *
 *                      int flags = f.readInt();
 *
 *                      RenderBase.OSegmentType segmentType = (RenderBase.OSegmentType)((animationTypeFlags >> 16) & 0xf);
 *                                      switch (segmentType)
 *                                      {
 *                          case RenderBase.OSegmentType.transform:
 *                              f.seek(offset + 0x18);
 *
 *                              uint notExistMask = 0x80000;
 *                              uint 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;
 *
 *                                      RenderBase.OAnimationKeyFrameGroup frame = new RenderBase.OAnimationKeyFrameGroup();
 *                                      frame.exists = !notExist;
 *                                      if (frame.exists)
 *                                      {
 *                                          if (constant)
 *                                          {
 *                                              frame.interpolation = RenderBase.OInterpolationMode.linear;
 *                                              frame.keyFrames.Add(new RenderBase.OAnimationKeyFrame(input.ReadSingle(), 0));
 *                                          }
 *                                          else
 *                                          {
 *                                              int frameOffset = f.readInt();
 *                                              long position = data.Position;
 *                                              f.seek(frameOffset);
 *                                              getAnimationKeyFrame(input, frame);
 *                                              f.seek(position);
 *                                          }
 *                                      }
 *                                      else
 *                                          data.Seek(4, SeekOrigin.Current);
 *
 *                                      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 RenderBase.OSegmentType.transformQuaternion:
 *                              bone.isFrameFormat = true;
 *
 *                              uint scaleOffset = input.ReadUInt32();
 *                              uint rotationOffset = input.ReadUInt32();
 *                              uint translationOffset = input.ReadUInt32();
 *
 *                              if ((flags & 0x20) == 0)
 *                              {
 *                                  bone.scale.exists = true;
 *                                  data.Seek(scaleOffset, SeekOrigin.Begin);
 *
 *                                  if ((flags & 4) > 0)
 *                                  {
 *                                      bone.scale.vector.Add(new RenderBase.OVector4(
 *                                          input.ReadSingle(),
 *                                          input.ReadSingle(),
 *                                          input.ReadSingle(),
 *                                          0));
 *                                  }
 *                                  else
 *                                  {
 *                                      bone.scale.startFrame = input.ReadSingle();
 *                                      bone.scale.endFrame = input.ReadSingle();
 *
 *                                      uint scaleFlags = input.ReadUInt32();
 *                                      uint scaleDataOffset = input.ReadUInt32();
 *                                      uint scaleEntries = input.ReadUInt32();
 *
 *                                      data.Seek(scaleDataOffset, SeekOrigin.Begin);
 *                                      for (int j = 0; j < scaleEntries; j++)
 *                                      {
 *                                          bone.scale.vector.Add(new RenderBase.OVector4(
 *                                              input.ReadSingle(),
 *                                              input.ReadSingle(),
 *                                              input.ReadSingle(),
 *                                              0));
 *                                      }
 *                                  }
 *                              }
 *
 *                              if ((flags & 0x10) == 0)
 *                                              {
 *                                                  bone.rotationQuaternion.exists = true;
 *                                                  data.Seek(rotationOffset, SeekOrigin.Begin);
 *
 *                                                  if ((flags & 2) > 0)
 *                                                  {
 *                                                      bone.rotationQuaternion.vector.Add(new RenderBase.OVector4(
 *                                                          input.ReadSingle(),
 *                                                          input.ReadSingle(),
 *                                                          input.ReadSingle(),
 *                                                          input.ReadSingle()));
 *                                                  }
 *                                                  else
 *                                                  {
 *                                                      bone.rotationQuaternion.startFrame = input.ReadSingle();
 *                                                      bone.rotationQuaternion.endFrame = input.ReadSingle();
 *
 *                                                      uint rotationFlags = input.ReadUInt32();
 *                                                      uint rotationDataOffset = input.ReadUInt32();
 *                                                      uint rotationEntries = input.ReadUInt32();
 *
 *                                                      data.Seek(rotationDataOffset, SeekOrigin.Begin);
 *                                                      for (int j = 0; j < rotationEntries; j++)
 *                                                      {
 *                                                          bone.rotationQuaternion.vector.Add(new RenderBase.OVector4(
 *                                                              input.ReadSingle(),
 *                                                              input.ReadSingle(),
 *                                                              input.ReadSingle(),
 *                                                              input.ReadSingle()));
 *                                                      }
 *                                                  }
 *                                              }
 *
 *                                              if ((flags & 8) == 0)
 *                                              {
 *                                                  bone.translation.exists = true;
 *                                                  data.Seek(translationOffset, SeekOrigin.Begin);
 *
 *                                                  if ((flags & 1) > 0)
 *                                                  {
 *                                                      bone.translation.vector.Add(new RenderBase.OVector4(
 *                                                          input.ReadSingle(),
 *                                                          input.ReadSingle(),
 *                                                          input.ReadSingle(),
 *                                                          0));
 *                                                  }
 *                                                  else
 *                                                  {
 *                                                      bone.translation.startFrame = input.ReadSingle();
 *                                                      bone.translation.endFrame = input.ReadSingle();
 *
 *                                                      uint translationFlags = input.ReadUInt32();
 *                                                      uint translationDataOffset = input.ReadUInt32();
 *                                                      uint translationEntries = input.ReadUInt32();
 *
 *                                                      data.Seek(translationDataOffset, SeekOrigin.Begin);
 *                                                      for (int j = 0; j < translationEntries; j++)
 *                                                      {
 *                                                          bone.translation.vector.Add(new RenderBase.OVector4(
 *                                                              input.ReadSingle(),
 *                                                              input.ReadSingle(),
 *                                                              input.ReadSingle(),
 *                                                              0));
 *                                                      }
 *                                                  }
 *                                              }
 *
 *                                              break;
 *                                          case RenderBase.OSegmentType.transformMatrix:
 *                                              bone.isFullBakedFormat = true;
 *
 *                                              input.ReadUInt32();
 *                                              input.ReadUInt32();
 *                                              uint matrixOffset = input.ReadUInt32();
 *                                              uint entries = input.ReadUInt32();
 *
 *                                              data.Seek(matrixOffset, SeekOrigin.Begin);
 *                                              for (int j = 0; j < entries; j++)
 *                                              {
 *                                                  RenderBase.OMatrix transform = new RenderBase.OMatrix();
 *                                                  transform.M11 = input.ReadSingle();
 *                                                  transform.M21 = input.ReadSingle();
 *                                                  transform.M31 = input.ReadSingle();
 *                                                  transform.M41 = input.ReadSingle();
 *
 *                                                  transform.M12 = input.ReadSingle();
 *                                                  transform.M22 = input.ReadSingle();
 *                                                  transform.M32 = input.ReadSingle();
 *                                                  transform.M42 = input.ReadSingle();
 *
 *                                                  transform.M13 = input.ReadSingle();
 *                                                  transform.M23 = input.ReadSingle();
 *                                                  transform.M33 = input.ReadSingle();
 *                                                  transform.M43 = input.ReadSingle();
 *
 *                                                  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);
 *                                  }
 *
 *                                  models.skeletalAnimation.list.Add(skeletalAnimation);
 *                              }
 *
 *                              //Material Animations
 *                              for (int index = 0; index < contentHeader.materialAnimationsPointerTableEntries; index++)
 *                              {
 *                                  data.Seek(contentHeader.materialAnimationsPointerTableOffset + (index * 4), SeekOrigin.Begin);
 *                                  uint dataOffset = input.ReadUInt32();
 *                                  data.Seek(dataOffset, SeekOrigin.Begin);
 *
 *                                  RenderBase.OMaterialAnimation materialAnimation = new RenderBase.OMaterialAnimation();
 *
 *                                  materialAnimation.name = readString(input);
 *                                  uint animationFlags = input.ReadUInt32();
 *                                  materialAnimation.loopMode = (RenderBase.OLoopMode)(animationFlags & 1);
 *                                  materialAnimation.frameSize = input.ReadSingle();
 *                                  uint dataTableOffset = input.ReadUInt32();
 *                                  uint dataTableEntries = input.ReadUInt32();
 *                                  input.ReadUInt32();
 *                                  uint textureNameTableOffset = input.ReadUInt32();
 *                                  uint textureNameTableEntries = input.ReadUInt32();
 *
 *                                  data.Seek(textureNameTableOffset, SeekOrigin.Begin);
 *                                  for (int i = 0; i < textureNameTableEntries; i++)
 *                                  {
 *                                      string name = readString(input);
 *                                      materialAnimation.textureName.Add(name);
 *                                  }
 *
 *                                  for (int i = 0; i < dataTableEntries; i++)
 *                                  {
 *                                      data.Seek(dataTableOffset + (i * 4), SeekOrigin.Begin);
 *                                      uint offset = input.ReadUInt32();
 *
 *                                      RenderBase.OMaterialAnimationData animationData = new RenderBase.OMaterialAnimationData();
 *
 *                                      data.Seek(offset, SeekOrigin.Begin);
 *                                      animationData.name = readString(input);
 *                                      uint animationTypeFlags = input.ReadUInt32();
 *                                      uint flags = input.ReadUInt32();
 *
 *                                      animationData.type = (RenderBase.OMaterialAnimationType)(animationTypeFlags & 0xff);
 *                                      RenderBase.OSegmentType segmentType = (RenderBase.OSegmentType)((animationTypeFlags >> 16) & 0xf);
 *
 *                                      int segmentCount = 0;
 *                                      switch (segmentType)
 *                                      {
 *                                          case RenderBase.OSegmentType.rgbaColor: segmentCount = 4; break;
 *                                          case RenderBase.OSegmentType.vector2: segmentCount = 2; break;
 *                                          case RenderBase.OSegmentType.single: segmentCount = 1; break;
 *                                          case RenderBase.OSegmentType.integer: segmentCount = 1; break;
 *                                      }
 *
 *                                      for (int j = 0; j < segmentCount; j++)
 *                                      {
 *                                          RenderBase.OAnimationKeyFrameGroup frame = new RenderBase.OAnimationKeyFrameGroup();
 *
 *                                          data.Seek(offset + 0xc + (j * 4), SeekOrigin.Begin);
 *
 *                                          frame.exists = (flags & (0x100 << j)) == 0;
 *                                          bool constant = (flags & (1 << j)) > 0;
 *
 *                                          if (frame.exists)
 *                                          {
 *                                              if (constant)
 *                                              {
 *                                                  frame.interpolation = RenderBase.OInterpolationMode.linear;
 *                                                  frame.keyFrames.Add(new RenderBase.OAnimationKeyFrame(input.ReadSingle(), 0));
 *                                              }
 *                                              else
 *                                              {
 *                                                  uint frameOffset = input.ReadUInt32();
 *                                                  data.Seek(frameOffset, SeekOrigin.Begin);
 *                                                  getAnimationKeyFrame(input, frame);
 *                                              }
 *                                          }
 *
 *                                          animationData.frameList.Add(frame);
 *                                      }
 *
 *                                      materialAnimation.data.Add(animationData);
 *                                  }
 *
 *                                  models.materialAnimation.list.Add(materialAnimation);
 *                              }
 *
 */
            }
        }
示例#12
0
文件: LVD.cs 项目: struz/Smash-Forge
        /*type 1  - collisions
         * type 2  - spawns
         * type 3  - respawns
         * type 4  - camera bounds
         * type 5  - death boundaries
         * type 6  - ???
         * type 7  - ITEMPT_transform
         * type 8  - enemyGenerator
         * type 9  - ITEMPT
         * type 10 - fsAreaCam (and other fsArea's ? )
         * type 11 - fsCamLimit
         * type 12 - damageShapes (damage sphere and damage capsule are the only ones I've seen, type 2 and 3 respectively)
         * type 13 - item spawners
         * type 14 - general shapes (general rect, general path, etc.)
         * type 15 - general points
         * type 16 - ???
         * type 17 - FsStartPoint
         * type 18 - ???
         * type 19 - ???*/

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

            f.seek(0xB);//It's magic
            int collisionCount = f.readInt();

            for (int i = 0; i < collisionCount; i++)
            {
                Collision temp = new Collision();
                temp.read(f);
                collisions.Add(temp);
            }
            f.skip(1); //Seperation char

            int spawnCount = f.readInt();

            for (int i = 0; i < spawnCount; i++)
            {
                Point temp = new Point();
                f.skip(0xD);
                temp.name = f.readString(f.pos(), 0x38);
                f.skip(0x38);
                f.skip(1);//Seperation char
                temp.subname = f.readString(f.pos(), 0x40);
                f.skip(0xA6);
                temp.x = f.readFloat();
                temp.y = f.readFloat();
                spawns.Add(temp);
            }
            f.skip(1);//Seperation char

            int respawnCount = f.readInt();

            for (int i = 0; i < respawnCount; i++)
            {
                Point temp = new Point();
                f.skip(0xD);
                temp.name = f.readString(f.pos(), 0x38);
                f.skip(0x38);
                f.skip(1);//Seperation char
                temp.subname = f.readString(f.pos(), 0x40);
                f.skip(0xA6);
                temp.x = f.readFloat();
                temp.y = f.readFloat();
                respawns.Add(temp);
            }
            f.skip(1);//Seperation char

            int cameraCount = f.readInt();

            for (int i = 0; i < cameraCount; i++)
            {
                Bounds temp = new Bounds();
                f.skip(0xD);
                temp.name = f.readString(f.pos(), 0x38);
                f.skip(0x38);
                f.skip(1);//Seperation char
                temp.subname = f.readString(f.pos(), 0x40);
                f.skip(0xA6);
                temp.left   = f.readFloat();
                temp.right  = f.readFloat();
                temp.top    = f.readFloat();
                temp.bottom = f.readFloat();
                cameraBounds.Add(temp);
            }
            f.skip(1);//Seperation char

            int blastzoneCount = f.readInt();

            for (int i = 0; i < blastzoneCount; i++)
            {
                Bounds temp = new Bounds();
                f.skip(0xD);
                temp.name = f.readString(f.pos(), 0x38);
                f.skip(0x38);
                f.skip(1);//Seperation char
                temp.subname = f.readString(f.pos(), 0x40);
                f.skip(0xA6);
                temp.left   = f.readFloat();
                temp.right  = f.readFloat();
                temp.top    = f.readFloat();
                temp.bottom = f.readFloat();
                blastzones.Add(temp);
            }
            f.skip(1);            //Seperation char

            if (f.readInt() != 0) //1
            {
                return;
            }
            f.skip(1);            //Seperation char

            if (f.readInt() != 0) //2
            {
                return;
            }
            f.skip(1);//Seperation char

            int enemyGeneratorCount = f.readInt();

            if (enemyGeneratorCount != 0)
            {
                return;
            }
            f.skip(1);            //Seperation char

            if (f.readInt() != 0) //4
            {
                return;
            }
            f.skip(1);//Seperation char

            int fsAreaCamCount = f.readInt();

            if (fsAreaCamCount != 0)
            {
                return;
            }
            f.skip(1);//Seperation char

            int fsCamLimitCount = f.readInt();

            if (fsCamLimitCount != 0)
            {
                return;
            }
            f.skip(1);//Seperation char

            int damageShapeCount = f.readInt();

            for (int i = 0; i < damageShapeCount; i++)
            {
                f.skip(0xD);

                string tempName = f.readString(f.pos(), 0x38);
                f.skip(0x38);
                f.skip(1);//Seperation char
                string tempSubname = f.readString(f.pos(), 0x40);
                f.skip(0xA6);
                int shapeType = f.readInt();
                if (shapeType == 2)
                {
                    Sphere temp = new Sphere();
                    temp.name    = tempName;
                    temp.subname = tempSubname;
                    temp.x       = f.readFloat();
                    temp.y       = f.readFloat();
                    temp.z       = f.readFloat();
                    temp.radius  = f.readFloat();
                    f.skip(0x11);
                    damageSpheres.Add(temp);
                }
                else if (shapeType == 3)
                {
                    Capsule temp = new Capsule();
                    temp.name    = tempName;
                    temp.subname = tempSubname;
                    temp.x       = f.readFloat();
                    temp.y       = f.readFloat();
                    temp.z       = f.readFloat();
                    temp.dx      = f.readFloat();
                    temp.dy      = f.readFloat();
                    temp.dz      = f.readFloat();
                    temp.r       = f.readFloat();
                    temp.unk     = f.readFloat();
                    f.skip(1);
                    damageCapsules.Add(temp);
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
            f.skip(1);//Seperation char

            int itemCount = f.readInt();

            for (int i = 0; i < itemCount; i++)
            {
                ItemSpawner temp = new ItemSpawner();
                temp.read(f);
                items.Add(temp);
            }
            f.skip(1);//Seperation char

            int generalShapeCount = f.readInt();

            for (int i = 0; i < generalShapeCount; i++)
            {
                f.skip(0xD);

                string tempName = f.readString(f.pos(), 0x38);
                f.skip(0x38);
                f.skip(1);//Seperation char
                string tempSubname = f.readString(f.pos(), 0x40);
                f.skip(0xAB);
                int             shapeType = f.readInt();
                LVDGeneralShape p;
                if (shapeType == 1)
                {
                    p = new GeneralPoint();
                }
                else if (shapeType == 3)
                {
                    p = new GeneralRect();
                }
                else if (shapeType == 4)
                {
                    p = new GeneralPath();
                }
                else
                {
                    throw new Exception($"Unknown shape type {shapeType} at offset {f.pos() - 4}");
                }
                p.name    = tempName;
                p.subname = tempSubname;
                p.Read(f);
                generalShapes.Add(p);
            }
            f.skip(1);

            int generalPointCount = f.readInt();

            for (int i = 0; i < generalPointCount; i++)
            {
                Point temp = new Point();
                f.skip(0xD);
                temp.name = f.readString(f.pos(), 0x38);
                f.skip(0x38);
                f.skip(1);//Seperation char
                temp.subname = f.readString(f.pos(), 0x40);
                f.skip(0xAF);
                temp.x = f.readFloat();
                temp.y = f.readFloat();
                f.skip(0x14);
                generalPoints.Add(temp);
            }

            if (f.readInt() != 0) //8
            {
                return;           //no clue how to be consistent in reading these so...
            }
            f.skip(1);

            if (f.readInt() != 0) //8
            {
                return;           //no clue how to be consistent in reading these so...
            }
            f.skip(1);

            if (f.readInt() != 0) //8
            {
                return;           //no clue how to be consistent in reading these so...
            }
            f.skip(1);

            if (f.readInt() != 0) //8
            {
                return;           //no clue how to be consistent in reading these so...
            }
            f.skip(1);

            if (f.readInt() != 0) //8
            {
                return;           //no clue how to be consistent in reading these so...
            }
            f.skip(1);

            if (f.readInt() != 0) //8
            {
                return;           //no clue how to be consistent in reading these so...
            }
            f.skip(1);

            //LVD doesn't end here and neither does my confusion, will update this part later
        }
示例#13
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;
        }
示例#14
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);
        }
示例#15
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();
            }
        }
示例#16
0
文件: CHR0.cs 项目: struz/Smash-Forge
        public static SkelAnimation readAnim(FileData d, VBN m)
        {
            int offset  = d.readInt();
            int nameoff = d.readInt();

            d.skip(4);
            int fCount        = d.readShort();
            int animDataCount = d.readShort();

            d.skip(8);

            SkelAnimation anim = new SkelAnimation();

            //anim.setModel(m);

            d.seek(offset);
            int sectionOffset = d.readInt() + offset;
            int size          = d.readInt();    // size again

            for (int i = 0; i < size; i++)
            {
                //			System.out.print(d.readShort()); // id
                d.skip(4);                 // id and unknown
                d.readShort();             //left
                d.readShort();             //right
                int nameOffset = d.readInt() + offset;
                int dataOffset = d.readInt() + offset;
                if (dataOffset == offset)
                {
                    i--;
                    continue;
                    //				d.skip(8);
                    //				nameOffset = d.readInt() + 4;
                    //				dataOffset = d.readInt() + offset;
                }


                int temp = d.pos();

                d.seek(dataOffset);

                int pos     = d.pos();
                int nameOff = d.readInt() + sectionOffset + (d.pos() - sectionOffset) - 4;
                int flags   = d.readInt();

                int t_type = (flags >> 0x1e) & 0x3;
                int r_type = (flags >> 0x1b) & 0x7;
                int s_type = (flags >> 0x19) & 0x3;

                int hasT = (flags >> 0x18) & 0x1;
                int hasR = (flags >> 0x17) & 0x1;
                int hasS = (flags >> 0x16) & 0x1;

                int Zfixed = (flags >> 0x15) & 0x1;
                int Yfixed = (flags >> 0x14) & 0x1;
                int Xfixed = (flags >> 0x13) & 0x1;

                int RZfixed = (flags >> 0x12) & 0x1;
                int RYfixed = (flags >> 0x11) & 0x1;
                int RXfixed = (flags >> 0x10) & 0x1;

                int SZfixed = (flags >> 0xf) & 0x1;
                int SYfixed = (flags >> 0xe) & 0x1;
                int SXfixed = (flags >> 0xd) & 0x1;

                int Tiso = (flags >> 0x6) & 0x1;
                int Riso = (flags >> 0x5) & 0x1;
                int Siso = (flags >> 0x4) & 0x1;


                if (hasS == 1)
                {
                    if (Siso == 1)
                    {
                        //System.out.println("S is ISO");

                        int     nid  = anim.getNodeIndex(d.readString(nameOff, -1), m);
                        KeyNode node = anim.getNode(0, nid);
                        node.s_type = 1;
                        float iss = d.readFloat();
                        node.s = new OpenTK.Vector3(iss, iss, iss);
                    }
                    else
                    {
                        int     nid  = anim.getNodeIndex(d.readString(nameOff, -1), m);
                        KeyNode node = anim.getNode(0, nid);
                        node.s_type = 1;

                        //					System.out.println("Scale: " + SXfixed + " " + SYfixed + " " + SZfixed + " " + s_type);
                        node.s = new OpenTK.Vector3(-99, -99, -99);
                        if (SXfixed == 1)
                        {
                            node.s.X = d.readFloat();
                        }
                        else
                        {
                            process(d, s_type, pos, anim, "SX", nid, false, m);
                        }
                        if (SYfixed == 1)
                        {
                            node.s.Y = d.readFloat();
                        }
                        else
                        {
                            process(d, s_type, pos, anim, "SY", nid, false, m);
                        }
                        if (SZfixed == 1)
                        {
                            node.s.Z = d.readFloat();
                        }
                        else
                        {
                            process(d, s_type, pos, anim, "SZ", nid, false, m);
                        }
                    }
                }

                if (hasR == 1)
                {
                    if (Riso == 1)
                    {
                        //System.out.println("R is ISO");

                        int nid = anim.getNodeIndex(d.readString(nameOff, -1), m);
                        Console.WriteLine(nid.ToString("x"));
                        KeyNode node = anim.getNode(0, nid);
                        node.r_type = 1;
                        float iss = (float)((d.readFloat()) * Math.PI / 180f);
                        node.r = VBN.FromEulerAngles(iss, iss, iss);
                    }
                    else
                    {
                        int     nid  = anim.getNodeIndex(d.readString(nameOff, -1), m);
                        KeyNode node = anim.getNode(0, nid);

                        //				System.out.println("Rot: " + RXfixed + " " + RYfixed + " " + RZfixed);

                        node.r = new OpenTK.Quaternion(-99, -99, -99, 0);

                        if (RXfixed == 1)
                        {
                            node.r.X = (float)(Math.PI / 180f) * (d.readFloat());
                        }
                        else
                        {
                            process(d, r_type, pos, anim, "RX", nid, false, m);
                        }
                        if (RYfixed == 1)
                        {
                            node.r.Y = (float)(Math.PI / 180f) * (d.readFloat());
                        }
                        else
                        {
                            process(d, r_type, pos, anim, "RY", nid, false, m);
                        }
                        if (RZfixed == 1)
                        {
                            node.r.Z = (float)(Math.PI / 180f) * (d.readFloat());
                        }
                        else
                        {
                            process(d, r_type, pos, anim, "RZ", nid, false, m);
                        }
                    }
                }

                if (hasT == 1)
                {
                    if (Tiso == 1)
                    {
                        //System.out.println("T is ISO");

                        int     nid  = anim.getNodeIndex(d.readString(nameOff, -1), m);
                        KeyNode node = anim.getNode(0, nid);
                        node.t_type = 1;
                        float iss = d.readFloat();
                        node.t = new OpenTK.Vector3(iss, iss, iss);
                    }
                    else
                    {
                        int     nid  = anim.getNodeIndex(d.readString(nameOff, -1), m);
                        KeyNode node = anim.getNode(0, nid);
                        node.t_type = 1;

                        //					System.out.println("Trans: " + Xfixed + " " + Yfixed + " " + Zfixed);

                        node.t = new OpenTK.Vector3(-99, -99, -99);
                        if (Xfixed == 1)
                        {
                            node.t.X = d.readFloat();
                        }
                        else
                        {
                            process(d, t_type, pos, anim, "X", nid, false, m);
                        }
                        if (Yfixed == 1)
                        {
                            node.t.Y = d.readFloat();
                        }
                        else
                        {
                            process(d, t_type, pos, anim, "Y", nid, false, m);
                        }
                        if (Zfixed == 1)
                        {
                            node.t.Z = d.readFloat();
                        }
                        else
                        {
                            process(d, t_type, pos, anim, "Z", nid, false, m);
                        }
                    }
                }

                d.seek(temp);
            }

            // keynode rotations need caluclation
            foreach (KeyFrame f in anim.frames)
            {
                foreach (KeyNode n in f.nodes)
                {
                    n.r = VBN.FromEulerAngles(n.r.Z, n.r.Y, n.r.X);
                }
            }
            //anim.calcMax();

            return(anim);
        }
示例#17
0
        public VBN GetVBN(FileData d)
        {
            VBN v = new VBN();

            d.Endian = Endianness.Big;
            d.seek(8);
            int ver = d.readInt();

            d.skip(4);             //outer offset to brres

            int boneHeader = 0x40; // for version 9 only

            int dlist   = d.readInt();
            int boneSec = d.readInt();
            int vertSec = d.readInt();
            int normSec = d.readInt();
            int colrSec = d.readInt();
            int texcSec = d.readInt();

            d.skip(8);
            int polySec = d.readInt();

            d.seek(0x40);
            d.skip(16);
            int vertCount = d.readInt();
            int faceCount = d.readInt();

            d.skip(4);
            int boneCount = d.readInt();

            v.totalBoneCount = (uint)boneCount;
            for (int i = 0; i < 3; i++)
            {
                v.boneCountPerType[i + 1] = 0;
            }
            d.skip(4);
            int bonetableoff = d.readInt() + boneHeader;

            d.seek(bonetableoff);
            int bcount = d.readInt();

            int[] nodeIndex = new int[bcount];
            for (int i = 0; i < bcount; i++)
            {
                nodeIndex[i] = d.readInt();
            }

            Random rng    = new Random();
            uint   boneID = (uint)rng.Next(1, 0xFFFFFF);

            // BONES-----------------------------------------------
            d.seek(boneSec);
            d.skip(4); // length
            int bseccount = d.readInt();

            for (int i = 0; i < bseccount; i++)
            {
                Debug.Write(i);
                d.skip(4); // entry id and unknown
                d.skip(4); // left and right index
                int name = d.readInt() + boneSec;
                int data = d.readInt() + boneSec;

                int temp = d.pos();
                if (name != boneSec && data != boneSec)
                {
                    // read bone data
                    d.seek(data);
                    d.skip(8);
                    int nameOff = d.readInt() + data;
                    int index   = d.readInt(); // id
                    d.skip(4);                 // index
                    d.skip(8);                 // idk billboard settings and padding
                    Bone n = new Bone(v);

                    n.scale    = new float[3];
                    n.position = new float[3];
                    n.rotation = new float[3];
                    d.skip(4);                     // index

                    n.scale[0]    = d.readFloat();
                    n.scale[1]    = d.readFloat();
                    n.scale[2]    = d.readFloat();
                    n.rotation[0] = toRadians(d.readFloat());
                    n.rotation[1] = toRadians(d.readFloat());
                    n.rotation[2] = toRadians(d.readFloat());
                    n.position[0] = d.readFloat();
                    n.position[1] = d.readFloat();
                    n.position[2] = d.readFloat();

                    n.pos = new Vector3(n.position[0], n.position[1], n.position[2]);
                    n.sca = new Vector3(n.scale[0], n.scale[1], n.scale[2]);
                    n.rot = (VBN.FromEulerAngles(n.rotation [2], n.rotation [1], n.rotation [0]));

                    d.skip(24);

                    d.seek(data + 0x5C);
                    d.seek(d.readInt() + data + 12);
                    int parentid = 0x0FFFFFFF;
                    if (d.pos() != data + 12)
                    {
                        parentid = d.readInt();
                    }
                    n.parentIndex = (int)parentid;

                    n.boneName = d.readString(nameOff, -1).ToCharArray();
                    n.boneId   = boneID;
                    boneID++;

                    v.bones.Add(n);
                }
                else
                {
                    bseccount++;
                }

                d.seek(temp);
            }
            v.update();
            //v.updateChildren();
            v.boneCountPerType[0] = (uint)v.bones.Count;

            return(v);
        }
示例#18
0
        public void Read(FileData d)
        {
            d.Endian = System.IO.Endianness.Big;
            d.seek(4); // skip filesize
            int dataSize         = d.readInt();
            int offsetTableCount = d.readInt();
            int rootA            = d.readInt();
            int headerSize       = 0x20;

            int rootOffset = headerSize + dataSize + offsetTableCount * 4;

            d.seek(rootOffset);
            int figtree = d.readInt() + headerSize;

            d.skip(4);
            String name = d.readString(d.pos(), -1);

            this.Name = name;

            d.seek(figtree);
            d.skip(8);
            float frameCount = d.readFloat();
            int   keyOffset  = d.readInt();

            if (Debug)
            {
                Console.WriteLine(name + "\tCount: " + frameCount);
            }
            this.frameCount = (int)frameCount;

            int temp = d.pos();

            d.seek(keyOffset + 0x20);
            //int boneCount = 0x2E; // TODO: Use actual bone count 0x35
            List <int> keyFrameCount = new List <int>();
            int        bid           = d.readByte();

            while (bid != 0xFF)
            {
                keyFrameCount.Add(bid);
                bid = d.readByte();
                nodes.Add(new List <DATAnimTrack>());
            }
            int boneCount = keyFrameCount.Count;

            if (Debug)
            {
                Console.WriteLine(boneCount);
            }

            d.seek(temp);

            int animDataOffset = 0;

            int[] trackcount = new int[offsetTableCount];
            for (int i = 0; i < offsetTableCount; i++)
            {
                trackcount[i] = d.readInt();
                if (i == 0)
                {
                    animDataOffset = trackcount[i];
                }
            }

            d.seek(animDataOffset + 0x20);
            for (int i = 0; i < boneCount; i++)
            { // bonecount
                if (Debug)
                {
                    Console.WriteLine("Bone " + i + ": " + keyFrameCount[i] + "\t" + d.pos().ToString("x"));
                }

                for (int j = 0; j < keyFrameCount[i]; j++)
                {
                    int length = d.readShort();
                    d.skip(2);
                    int trackType   = d.readByte();
                    int valueFormat = d.readByte();
                    int tanFormat   = d.readByte();
                    d.skip(1);
                    int dataoff = d.readInt() + 0x20;

                    if (Debug)
                    {
                        Console.WriteLine((AnimType)trackType + "\tLength: " + length + "\tOffset: " + dataoff.ToString("x") + " " + valueFormat.ToString("x") + " " + tanFormat.ToString("x"));
                    }
                    // System.out.println(valueFormat + " " + tanFormat);
                    readKeyFrame(d, length, dataoff, valueFormat, tanFormat, keyFrameCount[i], i, trackType);
                }
            }
        }
示例#19
0
        public override void Read(string filename)
        {
            FileData f = new FileData(filename);

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

            f.skip(8);
            int mainHeaderOffset      = f.readInt();
            int stringTableOffset     = f.readInt();
            int gpuCommandOffset      = f.readInt();
            int dataOffset            = f.readInt();
            int dataExtendOffset      = f.readInt();
            int relocationTableOffset = f.readInt();

            int mainHeaderLength      = f.readInt();
            int stringTableLength     = f.readInt();
            int gpuCommandLength      = f.readInt();
            int dataLength            = f.readInt();
            int dataExtendLength      = f.readInt();
            int relocationTableLength = f.readInt();

            int datsSecLength = f.readInt();
            int desSecLength  = f.readInt();

            int flags        = f.readShort();
            int addressCount = f.readShort();

            // TODO: Finished Relocation table stuff
            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);

                    break;
                }
            }

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

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

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

                f.seek(f.pos() + 0x14);
                String textureName = f.readString(f.readInt() + stringTableOffset, -1);

                f.seek(textureCommandsOffset);

                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() + dataOffset;
                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 < modelsPointerTableEntries; modelIndex++)
            {
                f.seek(modelsPointerTableOffset + (modelIndex * 4));
                int objectsHeaderOffset = f.readInt() + mainHeaderOffset;

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

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

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

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

                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() + stringTableOffset, -1);
                    //Debug.WriteLine(objectName[i]);
                }

                // 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() + stringTableOffset, -1);
                }

                // Object Descriptions...
                // Assumes MBN is already loaded for now
                f.seek(verticesTableOffset);
                List <objDes> objDescriptors = new List <objDes>();
                Debug.WriteLine(model.name);
                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.readShort();
                    if (index > mbn.mesh.Count)
                    {
                        break;
                    }
                    if (i > materialNames.Length)
                    {
                        break;
                    }
                    mbn.mesh[index].texId = textures[materialNames[i]].display;
                    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() + mainHeaderOffset;
                    des.vshAttBufferCommandCount  = f.readInt();
                    des.faceOffset = f.readInt() + mainHeaderOffset;
                    des.faceCount  = f.readInt();
                    des.vshAttBufferCommandOffsetEx = f.readInt() + mainHeaderOffset;
                    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(skeletonOffset);
                for (int index = 0; index < 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.boneName = f.readString(f.readInt() + stringTableOffset, -1).ToCharArray();

                    f.skip(4); // Meta data

                    model.skeleton.bones.Add(bone);
                }
                model.skeleton.reset();
            }
        }
示例#20
0
文件: LM.cs 项目: nnn1590/Smash-Forge
        public override void Read(string filename)
        {
            FileData f = new FileData(filename);

            header.magic = f.readInt();
            header.unk0  = f.readInt();

            if (header.unk0 == 0x10000000)
            {
                f.Endian = Endianness.Little;

                f.skip(f.pos() - 4);
                header.unk0 = f.readInt();
            }

            header.unk1     = f.readInt();
            header.unk2     = f.readInt();
            header.unk3     = f.readInt();
            header.unk4     = f.readInt();
            header.unk5     = f.readInt();
            header.filesize = f.readInt();
            header.unk6     = f.readInt();
            header.unk7     = f.readInt();
            header.unk8     = f.readInt();
            header.unk9     = f.readInt();
            header.unk10    = f.readInt();
            header.unk11    = f.readInt();
            header.unk12    = f.readInt();
            header.unk13    = f.readInt();

            bool done = false;

            while (!done)
            {
                int tagOffset = f.pos();

                TagType tagType = (TagType)f.readInt();
                int     tagSize = f.readInt(); // in dwords!

                switch (tagType)
                {
                case TagType.Invalid:
                {
                    // uhhh. i think there's a specific exception for this
                    throw new Exception("Malformed file");
                }

                case TagType.Symbols:
                {
                    int numSymbols = f.readInt();

                    while (Strings.Count < numSymbols)
                    {
                        int len = f.readInt();

                        Strings.Add(f.readString());
                        f.skip(4 - (f.pos() % 4));
                    }

                    break;
                }

                case TagType.Colors:
                {
                    int numColors = f.readInt();

                    for (int i = 0; i < numColors; i++)
                    {
                        AddColor(new Vector4(f.readShort() / 256f, f.readShort() / 256f, f.readShort() / 256f, f.readShort() / 256f));
                    }

                    break;
                }

                case TagType.Fonts:
                {
                    unk000A = new UnhandledTag(tagType, tagSize, f);
                    break;
                }

                case TagType.UnkF00A:
                {
                    unkF00A = new UnhandledTag(tagType, tagSize, f);
                    break;
                }

                case TagType.UnkF00B:
                {
                    unkF00B = new UnhandledTag(tagType, tagSize, f);
                    break;
                }

                case TagType.UnkF008:
                {
                    unkF008 = new UnhandledTag(tagType, tagSize, f);
                    break;
                }

                case TagType.UnkF009:
                {
                    unkF009 = new UnhandledTag(tagType, tagSize, f);
                    break;
                }

                case TagType.Defines:
                {
                    Defines = new Properties2(f);
                    break;
                }

                case TagType.ActionScript:
                {
                    Actionscript = new UnhandledTag(tagType, tagSize, f);
                    break;
                }

                case TagType.ActionScript2:
                {
                    Actionscript2 = new UnhandledTag(tagType, tagSize, f);
                    break;
                }

                case TagType.End:
                {
                    done = true;
                    break;
                }

                case TagType.Transforms:
                {
                    int numTransforms = f.readInt();

                    for (int i = 0; i < numTransforms; i++)
                    {
                        float a = f.readFloat();
                        float b = f.readFloat();
                        float c = f.readFloat();
                        float d = f.readFloat();
                        float x = f.readFloat();
                        float y = f.readFloat();

                        var mat = new Matrix4(
                            a, b, 0, 0,
                            c, d, 0, 0,
                            0, 0, 1, 0,
                            x, y, 0, 1
                            );

                        Transforms.Add(mat);
                    }

                    break;
                }

                case TagType.Positions:
                {
                    int numPositions = f.readInt();

                    for (int i = 0; i < numPositions; i++)
                    {
                        Positions.Add(new Vector2(f.readFloat(), f.readFloat()));
                    }

                    break;
                }

                case TagType.Bounds:
                {
                    int numBounds = f.readInt();

                    for (int i = 0; i < numBounds; i++)
                    {
                        Bounds.Add(new Rect(f.readFloat(), f.readFloat(), f.readFloat(), f.readFloat()));
                    }
                    break;
                }

                case TagType.Properties:
                {
                    properties = new Properties(f);
                    break;
                }

                case TagType.TextureAtlases:
                {
                    int numAtlases = f.readInt();

                    for (int i = 0; i < numAtlases; i++)
                    {
                        TextureAtlas atlas = new TextureAtlas();
                        atlas.id     = f.readInt();
                        atlas.nameId = f.readInt();
                        atlas.width  = f.readFloat();
                        atlas.height = f.readFloat();

                        Atlases.Add(atlas);
                    }

                    break;
                }

                case TagType.Shape:
                {
                    Shapes.Add(new Shape(f));
                    break;
                }

                case TagType.DynamicText:
                {
                    Texts.Add(new DynamicText(f));
                    break;
                }

                case TagType.DefineSprite:
                {
                    Sprites.Add(new Sprite(f));
                    break;
                }

                default:
                {
                    throw new NotImplementedException($"Unhandled tag id: 0x{(uint)tagType:X} @ 0x{tagOffset:X}");
                }
                }
            }
        } // Read()
示例#21
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();
            }
        }
示例#22
0
文件: BCH.cs 项目: soneek/Smash-Forge
        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();
            }
        }
示例#23
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();
        }
示例#24
0
文件: LVD.cs 项目: struz/Smash-Forge
        public void read(FileData f)
        {
            f.skip(0xD);
            name = f.readString(f.pos(), 0x38);
            f.skip(0x38);
            f.skip(1);//Seperation char
            subname = f.readString(f.pos(), 0x40);
            f.skip(0x40);
            f.skip(1);//Seperation char
            startPos[0] = f.readFloat();
            startPos[1] = f.readFloat();
            startPos[2] = f.readFloat();
            useStartPos = (f.readByte() != 0);
            f.skip(1);//Seperation char
            unk2 = f.readInt();
            f.skip(1);
            unk3 = f.read(0xC);
            f.skip(4); //FF FF FF FF
            f.skip(1); //Seperation char
            unk4 = new char[0x40];
            for (int i = 0; i < 0x40; i++)
            {
                unk4[i] = (char)f.readByte();
            }

            flag1 = Convert.ToBoolean(f.readByte());
            flag2 = Convert.ToBoolean(f.readByte());
            flag3 = Convert.ToBoolean(f.readByte());
            flag4 = Convert.ToBoolean(f.readByte());
            f.skip(1);//Seperation char
            //f.skip(0xAA);
            //Console.WriteLine(f.pos());
            int vertCount = f.readInt();

            for (int i = 0; i < vertCount; i++)
            {
                f.skip(1);//Seperation char
                Vector2D temp = new Vector2D();
                temp.x = f.readFloat();
                temp.y = f.readFloat();
                verts.Add(temp);
            }
            f.skip(1);//Seperation char

            int normalCount = f.readInt();

            for (int i = 0; i < normalCount; i++)
            {
                f.skip(1);//Seperation char
                Vector2D temp = new Vector2D();
                temp.x = f.readFloat();
                temp.y = f.readFloat();
                normals.Add(temp);
            }
            f.skip(1);                    //Seperation char

            int cliffCount = f.readInt(); //CLIFFS tend to be useless

            f.skip(0xFC * cliffCount);    //Standard CLIFFS are 0xFC in length, just skip em all
            f.skip(1);                    //Seperation char

            int materialCount = f.readInt();

            for (int i = 0; i < materialCount; i++)
            {
                f.skip(1);                   //Seperation char
                CollisionMat temp = new CollisionMat();
                temp.material = f.read(0xC); //Temporary, will work on fleshing out material more later

                materials.Add(temp);
            }
        }