Exemple #1
0
        private void ReadSkeleton(FMDL_Model model, Model mdl)
        {
            if (mdl.Skeleton.MatrixToBoneList == null)
            {
                mdl.Skeleton.MatrixToBoneList = new List <ushort>();
            }

            model.Node_Array = new int[mdl.Skeleton.MatrixToBoneList.Count];
            int nodes = 0;

            foreach (ushort node in mdl.Skeleton.MatrixToBoneList)
            {
                model.Node_Array[nodes] = node;
                nodes++;
            }

            foreach (Syroot.NintenTools.NSW.Bfres.Bone bn in mdl.Skeleton.Bones)
            {
                Bone bone = new Bone(model.skeleton);
                bone.Text        = bn.Name;
                bone.boneId      = bn.BillboardIndex;
                bone.parentIndex = bn.ParentIndex;
                bone.scale       = new float[3];
                bone.rotation    = new float[4];
                bone.position    = new float[3];

                if (bn.FlagsRotation == BoneFlagsRotation.Quaternion)
                {
                    bone.boneRotationType = 1;
                }
                else
                {
                    bone.boneRotationType = 0;
                }
                bone.scale[0]    = bn.Scale.X;
                bone.scale[1]    = bn.Scale.Y;
                bone.scale[2]    = bn.Scale.Z;
                bone.rotation[0] = bn.Rotation.X;
                bone.rotation[1] = bn.Rotation.Y;
                bone.rotation[2] = bn.Rotation.Z;
                bone.rotation[3] = bn.Rotation.W;
                bone.position[0] = bn.Position.X;
                bone.position[1] = bn.Position.Y;
                bone.position[2] = bn.Position.Z;

                model.skeleton.bones.Add(bone);
            }
            model.skeleton.Text = "Skeleton";
            model.Nodes.Add(model.skeleton);

            foreach (TreeNode nod in model.skeleton.Nodes)
            {
                if (nod.Text == "model.sb")
                {
                    nod.Remove();
                }
            }
        }
Exemple #2
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);
                }
            }
        }
Exemple #3
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++;
            }
        }
Exemple #4
0
        private void ReadVertexBuffer(Model mdl, Shape shp, Mesh poly, FMDL_Model model)
        {
            //Create a buffer instance which stores all the buffer data
            VertexBufferHelper helper = new VertexBufferHelper(mdl.VertexBuffers[shp.VertexBufferIndex], TargetSwitchBFRES.ByteOrder);

            //Set each array first from the lib if exist. Then add the data all in one loop
            Syroot.Maths.Vector4F[] vec4Positions = new Syroot.Maths.Vector4F[0];
            Syroot.Maths.Vector4F[] vec4Normals   = new Syroot.Maths.Vector4F[0];
            Syroot.Maths.Vector4F[] vec4uv0       = new Syroot.Maths.Vector4F[0];
            Syroot.Maths.Vector4F[] vec4uv1       = new Syroot.Maths.Vector4F[0];
            Syroot.Maths.Vector4F[] vec4uv2       = new Syroot.Maths.Vector4F[0];
            Syroot.Maths.Vector4F[] vec4c0        = new Syroot.Maths.Vector4F[0];
            Syroot.Maths.Vector4F[] vec4t0        = new Syroot.Maths.Vector4F[0];
            Syroot.Maths.Vector4F[] vec4b0        = new Syroot.Maths.Vector4F[0];
            Syroot.Maths.Vector4F[] vec4w0        = new Syroot.Maths.Vector4F[0];
            Syroot.Maths.Vector4F[] vec4i0        = new Syroot.Maths.Vector4F[0];

            //For shape morphing
            Syroot.Maths.Vector4F[] vec4Positions1 = new Syroot.Maths.Vector4F[0];
            Syroot.Maths.Vector4F[] vec4Positions2 = new Syroot.Maths.Vector4F[0];

            foreach (VertexAttrib att in mdl.VertexBuffers[shp.VertexBufferIndex].Attributes)
            {
                Mesh.VertexAttribute attr = new Mesh.VertexAttribute();
                attr.Name   = att.Name;
                attr.Format = att.Format;

                if (att.Name == "_p0")
                {
                    vec4Positions = AttributeData(att, helper, "_p0");
                }
                if (att.Name == "_n0")
                {
                    vec4Normals = AttributeData(att, helper, "_n0");
                }
                if (att.Name == "_u0")
                {
                    vec4uv0 = AttributeData(att, helper, "_u0");
                }
                if (att.Name == "_u1")
                {
                    vec4uv1 = AttributeData(att, helper, "_u1");
                }
                if (att.Name == "_u2")
                {
                    vec4uv2 = AttributeData(att, helper, "_u2");
                }
                if (att.Name == "_c0")
                {
                    vec4c0 = AttributeData(att, helper, "_c0");
                }
                if (att.Name == "_t0")
                {
                    vec4t0 = AttributeData(att, helper, "_t0");
                }
                if (att.Name == "_b0")
                {
                    vec4b0 = AttributeData(att, helper, "_b0");
                }
                if (att.Name == "_w0")
                {
                    vec4w0 = AttributeData(att, helper, "_w0");
                }
                if (att.Name == "_i0")
                {
                    vec4i0 = AttributeData(att, helper, "_i0");
                }

                if (att.Name == "_p1")
                {
                    vec4Positions1 = AttributeData(att, helper, "_p1");
                }
                if (att.Name == "_p2")
                {
                    vec4Positions2 = AttributeData(att, helper, "_p2");
                }

                poly.vertexAttributes.Add(attr);
            }
            for (int i = 0; i < vec4Positions.Length; i++)
            {
                Vertex v = new Vertex();
                if (vec4Positions.Length > 0)
                {
                    v.pos = new Vector3(vec4Positions[i].X, vec4Positions[i].Y, vec4Positions[i].Z);
                }
                if (vec4Positions1.Length > 0)
                {
                    v.pos1 = new Vector3(vec4Positions1[i].X, vec4Positions1[i].Y, vec4Positions1[i].Z);
                }
                if (vec4Positions2.Length > 0)
                {
                    v.pos2 = new Vector3(vec4Positions2[i].X, vec4Positions2[i].Y, vec4Positions2[i].Z);
                }
                if (vec4Normals.Length > 0)
                {
                    v.nrm = new Vector3(vec4Normals[i].X, vec4Normals[i].Y, vec4Normals[i].Z);
                }
                if (vec4uv0.Length > 0)
                {
                    v.uv0 = new Vector2(vec4uv0[i].X, vec4uv0[i].Y);
                }
                if (vec4uv1.Length > 0)
                {
                    v.uv1 = new Vector2(vec4uv1[i].X, vec4uv1[i].Y);
                }
                if (vec4uv2.Length > 0)
                {
                    v.uv2 = new Vector2(vec4uv2[i].X, vec4uv2[i].Y);
                }
                if (vec4w0.Length > 0)
                {
                    v.boneWeights.Add(vec4w0[i].X);
                    v.boneWeights.Add(vec4w0[i].Y);
                    v.boneWeights.Add(vec4w0[i].Z);
                    v.boneWeights.Add(vec4w0[i].W);
                }
                if (vec4i0.Length > 0)
                {
                    v.boneIds.Add((int)vec4i0[i].X);
                    v.boneIds.Add((int)vec4i0[i].Y);
                    v.boneIds.Add((int)vec4i0[i].Z);
                    v.boneIds.Add((int)vec4i0[i].W);
                }

                if (vec4t0.Length > 0)
                {
                    v.tan = new Vector4(vec4t0[i].X, vec4t0[i].Y, vec4t0[i].Z, vec4t0[i].W);
                }
                if (vec4b0.Length > 0)
                {
                    v.bitan = new Vector4(vec4b0[i].X, vec4b0[i].Y, vec4b0[i].Z, vec4b0[i].W);
                }
                if (vec4c0.Length > 0)
                {
                    v.col = new Vector4(vec4c0[i].X, vec4c0[i].Y, vec4c0[i].Z, vec4c0[i].W);
                }

                if (poly.VertexSkinCount == 1)
                {
                    Matrix4 sb = model.skeleton.bones[model.Node_Array[v.boneIds[0]]].transform;
                    //  Console.WriteLine(model.skeleton.bones[model.Node_Array[v.boneIds[0]]].Text);
                    v.pos = Vector3.TransformPosition(v.pos, sb);
                    v.nrm = Vector3.TransformNormal(v.nrm, sb);
                }
                if (poly.VertexSkinCount == 0)
                {
                    Matrix4 NoBindFix = model.skeleton.bones[poly.boneIndx].transform;
                    v.pos = Vector3.TransformPosition(v.pos, NoBindFix);
                    v.nrm = Vector3.TransformNormal(v.nrm, NoBindFix);
                }

                poly.vertices.Add(v);
            }
        }
Exemple #5
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";

            AnimationCountTotal = TargetSwitchBFRES.SkeletalAnims.Count
                                  + TargetSwitchBFRES.BoneVisibilityAnims.Count
                                  + TargetSwitchBFRES.MaterialAnims.Count
                                  + TargetSwitchBFRES.ShapeAnims.Count;

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

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

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

                foreach (int node in model.Node_Array)
                {
                    Console.WriteLine(model.skeleton.bones[node].Text);
                }

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

                    foreach (int bn in shp.SkinBoneIndices)
                    {
                        poly.BoneIndexList.Add(model.skeleton.bones[bn].Text, bn);
                    }

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


                    ReadVertexBuffer(mdl, shp, poly, model);

                    poly.BoundingCount = shp.SubMeshBoundings.Count;

                    int CurLOD = 0;
                    foreach (var lod in shp.Meshes)
                    {
                        Mesh.LOD_Mesh lodmsh = new Mesh.LOD_Mesh();
                        lodmsh.index = CurLOD++;

                        uint   FaceCount    = lod.IndexCount;
                        uint[] indicesArray = lod.GetIndices().ToArray();


                        for (int face = 0; face < FaceCount; face++)
                        {
                            lodmsh.faces.Add((int)indicesArray[face] + (int)lod.FirstVertex);
                        }

                        poly.lodMeshes.Add(lodmsh);
                    }

                    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;

                    int SampIndex = 0;
                    foreach (var smp in mat.SamplerDict)
                    {
                        poly.material.Samplers.Add(smp.Key, SampIndex);
                        SampIndex++;
                    }

                    MaterialData.ShaderAssign shaderassign = new MaterialData.ShaderAssign();

                    if (mat.ShaderAssign != null)
                    {
                        shaderassign.ShaderModel   = mat.ShaderAssign.ShadingModelName;
                        shaderassign.ShaderArchive = mat.ShaderAssign.ShaderArchiveName;

                        int o = 0;
                        foreach (var op in mat.ShaderAssign.ShaderOptionDict)
                        {
                            shaderassign.options.Add(op.Key, mat.ShaderAssign.ShaderOptions[o]);
                            o++;
                        }
                        int sa = 0;
                        foreach (var smp in mat.ShaderAssign.SamplerAssignDict)
                        {
                            //       Console.WriteLine($"{smp.Key} ---> {mat.ShaderAssign.SamplerAssigns[sa]}");
                            if (!shaderassign.samplers.ContainsKey(mat.ShaderAssign.SamplerAssigns[sa]))
                            {
                                shaderassign.samplers.Add(mat.ShaderAssign.SamplerAssigns[sa], smp.Key);
                            }
                            sa++;
                        }

                        int va = 0;
                        foreach (var att in mat.ShaderAssign.AttribAssignDict)
                        {
                            shaderassign.attributes.Add(att.Key, mat.ShaderAssign.AttribAssigns[va]);
                            va++;
                        }
                    }
                    else
                    {
                        shaderassign.ShaderModel   = "Not Assigned";
                        shaderassign.ShaderArchive = "Not Assigned";
                    }
                    poly.material.shaderassign = shaderassign;

                    ReadTextureRefs(mat, poly);
                    if (mat.ShaderParamData != null)
                    {
                        ReadShaderParams(mat, poly);
                    }
                    if (mat.RenderInfos != null)
                    {
                        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++;
            }
        }
        public void Read(ResFile TargetWiiUBFRES)
        {
            Nodes.Add(TModels);
            Nodes.Add(TTextures);
            Nodes.Add(TShaderparam);
            Nodes.Add(TColoranim);
            Nodes.Add(TTextureSRT);
            Nodes.Add(TTexturePat);
            Nodes.Add(TBonevisabilty);
            Nodes.Add(TVisualAnim);
            Nodes.Add(TShapeAnim);
            Nodes.Add(TSceneAnim);
            Nodes.Add(TEmbedded);
            ImageKey         = "bfres";
            SelectedImageKey = "bfres";

            FSKACount = TargetWiiUBFRES.SkeletalAnims.Count;
            FTXPCount = TargetWiiUBFRES.TexPatternAnims.Count;
            FSHUCount = TargetWiiUBFRES.ColorAnims.Count + TargetWiiUBFRES.TexSrtAnims.Count + TargetWiiUBFRES.ShaderParamAnims.Count;

            AnimationCountTotal = FSKACount + FTXPCount + FSHUCount;

            FTEXContainer = new FTEXContainer();
            foreach (Texture tex in TargetWiiUBFRES.Textures.Values)
            {
                string TextureName = tex.Name;
                FTEX   texture     = new FTEX();
                texture.ReadFTEX(tex);

                TTextures.Nodes.Add(texture);

                FTEXContainer.FTEXtextures.Add(texture.Text, texture);
                Runtime.FTEXContainerList.Add(FTEXContainer);
            }

            int ModelCur = 0;

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

                TModels.Nodes.Add(model);

                model.Node_Array = new int[mdl.Skeleton.MatrixToBoneList.Count];
                int nodes = 0;
                foreach (ushort node in mdl.Skeleton.MatrixToBoneList)
                {
                    model.Node_Array[nodes] = node;
                    nodes++;
                }

                foreach (Syroot.NintenTools.Bfres.Bone bn in mdl.Skeleton.Bones.Values)
                {
                    Bone bone = new Bone(model.skeleton);
                    bone.Text        = bn.Name;
                    bone.boneId      = bn.BillboardIndex;
                    bone.parentIndex = bn.ParentIndex;
                    bone.scale       = new float[3];
                    bone.rotation    = new float[4];
                    bone.position    = new float[3];

                    if (bn.FlagsRotation == BoneFlagsRotation.Quaternion)
                    {
                        bone.boneRotationType = 1;
                    }
                    else
                    {
                        bone.boneRotationType = 0;
                    }

                    bone.scale[0]    = bn.Scale.X;
                    bone.scale[1]    = bn.Scale.Y;
                    bone.scale[2]    = bn.Scale.Z;
                    bone.rotation[0] = bn.Rotation.X;
                    bone.rotation[1] = bn.Rotation.Y;
                    bone.rotation[2] = bn.Rotation.Z;
                    bone.rotation[3] = bn.Rotation.W;
                    bone.position[0] = bn.Position.X;
                    bone.position[1] = bn.Position.Y;
                    bone.position[2] = bn.Position.Z;

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

                //MeshTime!!
                int ShapeCur = 0;
                foreach (Shape shp in mdl.Shapes.Values)
                {
                    Mesh poly = new Mesh();
                    poly.Text            = shp.Name;
                    poly.MaterialIndex   = shp.MaterialIndex;
                    poly.VertexSkinCount = shp.VertexSkinCount;
                    poly.boneIndx        = shp.BoneIndex;
                    poly.fmdlIndx        = ModelCur;

                    foreach (int bn in shp.SkinBoneIndices)
                    {
                        if (!poly.BoneIndexList.ContainsKey(model.skeleton.bones[bn].Text))
                        {
                            poly.BoneIndexList.Add(model.skeleton.bones[bn].Text, bn);
                        }
                    }

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

                    //Create a buffer instance which stores all the buffer data
                    VertexBufferHelper helper = new VertexBufferHelper(mdl.VertexBuffers[shp.VertexBufferIndex], TargetWiiUBFRES.ByteOrder);

                    //Set each array first from the lib if exist. Then add the data all in one loop
                    Syroot.Maths.Vector4F[] vec4Positions = new Syroot.Maths.Vector4F[0];
                    Syroot.Maths.Vector4F[] vec4Normals   = new Syroot.Maths.Vector4F[0];
                    Syroot.Maths.Vector4F[] vec4uv0       = new Syroot.Maths.Vector4F[0];
                    Syroot.Maths.Vector4F[] vec4uv1       = new Syroot.Maths.Vector4F[0];
                    Syroot.Maths.Vector4F[] vec4uv2       = new Syroot.Maths.Vector4F[0];
                    Syroot.Maths.Vector4F[] vec4c0        = new Syroot.Maths.Vector4F[0];
                    Syroot.Maths.Vector4F[] vec4t0        = new Syroot.Maths.Vector4F[0];
                    Syroot.Maths.Vector4F[] vec4b0        = new Syroot.Maths.Vector4F[0];
                    Syroot.Maths.Vector4F[] vec4w0        = new Syroot.Maths.Vector4F[0];
                    Syroot.Maths.Vector4F[] vec4i0        = new Syroot.Maths.Vector4F[0];


                    foreach (VertexAttrib att in mdl.VertexBuffers[shp.VertexBufferIndex].Attributes.Values)
                    {
                        Mesh.VertexAttribute attr = new Mesh.VertexAttribute();
                        attr.Name = att.Name;
                        // attr.Format = att.Format;

                        if (att.Name == "_p0")
                        {
                            vec4Positions = WiiUAttributeData(att, helper, "_p0");
                        }
                        if (att.Name == "_n0")
                        {
                            vec4Normals = WiiUAttributeData(att, helper, "_n0");
                        }
                        if (att.Name == "_u0")
                        {
                            vec4uv0 = WiiUAttributeData(att, helper, "_u0");
                        }
                        if (att.Name == "_u1")
                        {
                            vec4uv1 = WiiUAttributeData(att, helper, "_u1");
                        }
                        if (att.Name == "_u2")
                        {
                            vec4uv2 = WiiUAttributeData(att, helper, "_u2");
                        }
                        if (att.Name == "_c0")
                        {
                            vec4c0 = WiiUAttributeData(att, helper, "_c0");
                        }
                        if (att.Name == "_t0")
                        {
                            vec4t0 = WiiUAttributeData(att, helper, "_t0");
                        }
                        if (att.Name == "_b0")
                        {
                            vec4b0 = WiiUAttributeData(att, helper, "_b0");
                        }
                        if (att.Name == "_w0")
                        {
                            vec4w0 = WiiUAttributeData(att, helper, "_w0");
                        }
                        if (att.Name == "_i0")
                        {
                            vec4i0 = WiiUAttributeData(att, helper, "_i0");
                        }

                        poly.vertexAttributes.Add(attr);
                    }
                    for (int i = 0; i < vec4Positions.Length; i++)
                    {
                        Vertex v = new Vertex();
                        if (vec4Positions.Length > 0)
                        {
                            v.pos = new Vector3(vec4Positions[i].X, vec4Positions[i].Y, vec4Positions[i].Z);
                        }
                        if (vec4Normals.Length > 0)
                        {
                            v.nrm = new Vector3(vec4Normals[i].X, vec4Normals[i].Y, vec4Normals[i].Z);
                        }
                        if (vec4uv0.Length > 0)
                        {
                            v.uv0 = new Vector2(vec4uv0[i].X, vec4uv0[i].Y);
                        }
                        if (vec4uv1.Length > 0)
                        {
                            v.uv1 = new Vector2(vec4uv1[i].X, vec4uv1[i].Y);
                        }
                        if (vec4uv2.Length > 0)
                        {
                            v.uv2 = new Vector2(vec4uv2[i].X, vec4uv2[i].Y);
                        }
                        if (vec4w0.Length > 0)
                        {
                            v.boneWeights.Add(vec4w0[i].X);
                            v.boneWeights.Add(vec4w0[i].Y);
                            v.boneWeights.Add(vec4w0[i].Z);
                            v.boneWeights.Add(vec4w0[i].W);
                        }
                        if (vec4i0.Length > 0)
                        {
                            v.boneIds.Add((int)vec4i0[i].X);
                            v.boneIds.Add((int)vec4i0[i].Y);
                            v.boneIds.Add((int)vec4i0[i].Z);
                            v.boneIds.Add((int)vec4i0[i].W);
                        }
                        if (vec4t0.Length > 0)
                        {
                            v.tan = new Vector4(vec4t0[i].X, vec4t0[i].Y, vec4t0[i].Z, vec4t0[i].W);
                        }
                        if (vec4b0.Length > 0)
                        {
                            v.bitan = new Vector4(vec4b0[i].X, vec4b0[i].Y, vec4b0[i].Z, vec4b0[i].W);
                        }
                        if (vec4c0.Length > 0)
                        {
                            v.col = new Vector4(vec4c0[i].X, vec4c0[i].Y, vec4c0[i].Z, vec4c0[i].W);
                        }

                        if (poly.VertexSkinCount == 1)
                        {
                            Matrix4 sb = model.skeleton.bones[model.Node_Array[v.boneIds[0]]].transform;
                            //  Console.WriteLine(model.skeleton.bones[model.Node_Array[v.boneIds[0]]].Text);
                            v.pos = Vector3.TransformPosition(v.pos, sb);
                            v.nrm = Vector3.TransformNormal(v.nrm, sb);
                        }
                        if (poly.VertexSkinCount == 0)
                        {
                            Matrix4 NoBindFix = model.skeleton.bones[poly.boneIndx].transform;
                            v.pos = Vector3.TransformPosition(v.pos, NoBindFix);
                            v.nrm = Vector3.TransformNormal(v.nrm, NoBindFix);
                        }

                        poly.vertices.Add(v);
                    }

                    //shp.Meshes.Count - 1 //For going to the lowest poly LOD mesh


                    poly.BoundingCount = shp.SubMeshBoundings.Count;

                    int CurLOD = 0;
                    foreach (var lod in shp.Meshes)
                    {
                        Mesh.LOD_Mesh lodmsh = new Mesh.LOD_Mesh();
                        lodmsh.index = CurLOD++;

                        uint   FaceCount    = lod.IndexCount;
                        uint[] indicesArray = lod.GetIndices().ToArray();

                        for (int face = 0; face < FaceCount; face++)
                        {
                            lodmsh.faces.Add((int)indicesArray[face] + (int)lod.FirstVertex);
                        }

                        poly.lodMeshes.Add(lodmsh);
                    }

                    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];

                    int SampIndex = 0;
                    foreach (var smp in mat.Samplers)
                    {
                        poly.material.Samplers.Add(smp.Key, SampIndex);
                        SampIndex++;
                    }

                    int AlbedoCount = 0;

                    string TextureName = "";

                    MaterialData.ShaderAssign shaderassign = new MaterialData.ShaderAssign();

                    if (mat.ShaderAssign != null) //Some special cases (env models) have none
                    {
                        shaderassign.ShaderModel   = mat.ShaderAssign.ShadingModelName;
                        shaderassign.ShaderArchive = mat.ShaderAssign.ShaderArchiveName;


                        int o = 0;
                        foreach (var op in mat.ShaderAssign.ShaderOptions)
                        {
                            shaderassign.options.Add(op.Key, mat.ShaderAssign.ShaderOptions[o]);
                            o++;
                        }

                        int sa = 0;
                        foreach (var smp in mat.ShaderAssign.SamplerAssigns)
                        {
                            shaderassign.samplers.Add(smp.Key, mat.ShaderAssign.SamplerAssigns[sa]);
                            sa++;
                        }

                        int va = 0;
                        foreach (var att in mat.ShaderAssign.AttribAssigns)
                        {
                            shaderassign.attributes.Add(att.Key, mat.ShaderAssign.AttribAssigns[va]);
                            va++;
                        }
                    }

                    poly.material.shaderassign = shaderassign;

                    int id = 0;
                    foreach (TextureRef tex in mdl.Materials[shp.MaterialIndex].TextureRefs)
                    {
                        TextureName = tex.Name;

                        MatTexture texture = new MatTexture();

                        texture.wrapModeS = (int)mdl.Materials[shp.MaterialIndex].Samplers[id].TexSampler.ClampX;
                        texture.wrapModeT = (int)mdl.Materials[shp.MaterialIndex].Samplers[id].TexSampler.ClampY;


                        bool IsAlbedo = HackyTextureList.Any(TextureName.Contains);

                        if (mdl.Materials[shp.MaterialIndex].Samplers[id].Name == "_a0")
                        {
                            poly.material.HasDiffuseMap = true;
                            texture.hash = 0;
                            texture.Type = MatTexture.TextureType.Diffuse;
                        }
                        if (mdl.Materials[shp.MaterialIndex].Samplers[id].Name == "_a1")
                        {
                            poly.material.HasDiffuseLayer = true;
                            texture.hash = 19;
                            texture.Type = MatTexture.TextureType.DiffuseLayer2;
                        }
                        if (mdl.Materials[shp.MaterialIndex].Samplers[id].Name == "_n0")
                        {
                            texture.hash = 1;
                            poly.material.HasNormalMap = true;
                            texture.Type = MatTexture.TextureType.Normal;
                        }
                        if (mdl.Materials[shp.MaterialIndex].Samplers[id].Name == "_s0")
                        {
                            texture.hash = 4;
                            poly.material.HasSpecularMap = true;
                            texture.Type = MatTexture.TextureType.Specular;
                        }
                        if (mdl.Materials[shp.MaterialIndex].Samplers[id].Name == "_b0")
                        {
                            texture.hash = 2;
                            poly.material.HasShadowMap = true;
                            texture.Type = MatTexture.TextureType.Shadow;
                        }
                        if (mdl.Materials[shp.MaterialIndex].Samplers[id].Name == "_b1")
                        {
                            texture.hash = 3;
                            poly.material.HasLightMap = true;
                            texture.Type = MatTexture.TextureType.Light;
                        }
                        if (mdl.Materials[shp.MaterialIndex].Samplers[id].Name == "_e0")
                        {
                            texture.hash = 8;
                            poly.material.HasEmissionMap = true;
                            texture.Type = MatTexture.TextureType.Emission;
                        }

                        texture.Name = TextureName;
                        poly.material.textures.Add(texture);
                        id++;
                    }

                    foreach (Sampler smp in mat.Samplers.Values)
                    {
                        SamplerInfo s = new SamplerInfo();
                        s.WrapModeU = (int)smp.TexSampler.ClampX;
                        s.WrapModeV = (int)smp.TexSampler.ClampY;
                        s.WrapModeW = (int)smp.TexSampler.ClampZ;
                        poly.material.samplerinfo.Add(s);
                    }

                    poly.material.Name = mdl.Materials[shp.MaterialIndex].Name;
                    if (mdl.Materials[shp.MaterialIndex].ShaderParamData != null) //Some special cases (env models) have none
                    {
                        using (Syroot.BinaryData.BinaryDataReader reader = new Syroot.BinaryData.BinaryDataReader(new MemoryStream(mdl.Materials[shp.MaterialIndex].ShaderParamData)))
                        {
                            reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
                            foreach (Syroot.NintenTools.Bfres.ShaderParam param in mdl.Materials[shp.MaterialIndex].ShaderParams.Values)
                            {
                                ShaderParam prm = new ShaderParam();

                                prm.Type = param.Type;
                                prm.Name = param.Name;

                                switch (param.Type)
                                {
                                case ShaderParamType.Float:
                                    reader.Seek(param.DataOffset, SeekOrigin.Begin);
                                    prm.Value_float = reader.ReadSingle();
                                    break;

                                case ShaderParamType.Float2:
                                    reader.Seek(param.DataOffset, SeekOrigin.Begin);
                                    prm.Value_float2 = new Vector2(
                                        reader.ReadSingle(),
                                        reader.ReadSingle());
                                    break;

                                case ShaderParamType.Float3:
                                    reader.Seek(param.DataOffset, SeekOrigin.Begin);
                                    prm.Value_float3 = new Vector3(
                                        reader.ReadSingle(),
                                        reader.ReadSingle(),
                                        reader.ReadSingle()); break;

                                case ShaderParamType.Float4:
                                    reader.Seek(param.DataOffset, SeekOrigin.Begin);
                                    prm.Value_float4 = new Vector4(
                                        reader.ReadSingle(),
                                        reader.ReadSingle(),
                                        reader.ReadSingle(),
                                        reader.ReadSingle()); break;

                                case ShaderParamType.TexSrt:
                                    reader.Seek(param.DataOffset, SeekOrigin.Begin);
                                    ShaderParam.TextureSRT texSRT = new ShaderParam.TextureSRT();
                                    texSRT.Mode      = reader.ReadSingle(); //Scale mode, Maya, max ect
                                    texSRT.scale     = new Vector2(reader.ReadSingle(), reader.ReadSingle());
                                    texSRT.rotate    = reader.ReadSingle();
                                    texSRT.translate = new Vector2(reader.ReadSingle(), reader.ReadSingle());

                                    prm.Value_TexSrt = texSRT; break;
                                }
                                poly.material.matparam.Add(param.Name, prm);
                            }
                            reader.Close();
                        }
                    }


                    model.poly.Add(poly);
                    ShapeCur++;
                }
                models.Add(model);
                ModelCur++;
            }
        }
Exemple #7
0
        public void Read(ResFile TargetWiiUBFRES)
        {
            Nodes.Add(TModels);
            Nodes.Add(TTextures);
            Nodes.Add(TShaderparam);
            Nodes.Add(TColoranim);
            Nodes.Add(TTextureSRT);
            Nodes.Add(TTexturePat);
            Nodes.Add(TBonevisabilty);
            Nodes.Add(TVisualAnim);
            Nodes.Add(TShapeAnim);
            Nodes.Add(TSceneAnim);
            Nodes.Add(TEmbedded);
            ImageKey         = "bfres";
            SelectedImageKey = "bfres";

            FSKACount = TargetWiiUBFRES.SkeletalAnims.Count;

            textures.Clear();

            foreach (Texture tex in TargetWiiUBFRES.Textures.Values)
            {
                string TextureName = tex.Name;
                FTEX   texture     = new FTEX();
                texture.ReadFTEX(tex);
                textures.Add(TextureName, texture);
                TTextures.Nodes.Add(texture);
            }

            int ModelCur = 0;

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

                TModels.Nodes.Add(model);

                model.Node_Array = new int[mdl.Skeleton.MatrixToBoneList.Count];
                int nodes = 0;
                foreach (ushort node in mdl.Skeleton.MatrixToBoneList)
                {
                    model.Node_Array[nodes] = node;
                    nodes++;
                }

                foreach (Syroot.NintenTools.Bfres.Bone bn in mdl.Skeleton.Bones.Values)
                {
                    Bone bone = new Bone(model.skeleton);
                    bone.Text        = bn.Name;
                    bone.boneId      = bn.BillboardIndex;
                    bone.parentIndex = bn.ParentIndex;
                    bone.scale       = new float[3];
                    bone.rotation    = new float[4];
                    bone.position    = new float[3];

                    if (bn.FlagsRotation == BoneFlagsRotation.Quaternion)
                    {
                        bone.boneRotationType = 1;
                    }
                    else
                    {
                        bone.boneRotationType = 0;
                    }

                    bone.scale[0]    = bn.Scale.X;
                    bone.scale[1]    = bn.Scale.Y;
                    bone.scale[2]    = bn.Scale.Z;
                    bone.rotation[0] = bn.Rotation.X;
                    bone.rotation[1] = bn.Rotation.Y;
                    bone.rotation[2] = bn.Rotation.Z;
                    bone.rotation[3] = bn.Rotation.W;
                    bone.position[0] = bn.Position.X;
                    bone.position[1] = bn.Position.Y;
                    bone.position[2] = bn.Position.Z;

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

                //MeshTime!!
                int ShapeCur = 0;
                foreach (Shape shp in mdl.Shapes.Values)
                {
                    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);

                    //Create a buffer instance which stores all the buffer data
                    VertexBufferHelper helper = new VertexBufferHelper(mdl.VertexBuffers[shp.VertexBufferIndex], TargetWiiUBFRES.ByteOrder);

                    // VertexBufferHelperAttrib uv1 = helper["_u1"];


                    Vertex v = new Vertex();
                    foreach (VertexAttrib att in mdl.VertexBuffers[shp.VertexBufferIndex].Attributes.Values)
                    {
                        if (att.Name == "_p0")
                        {
                            Console.WriteLine(att.Name);
                            VertexBufferHelperAttrib position      = helper["_p0"];
                            Syroot.Maths.Vector4F[]  vec4Positions = position.Data;

                            foreach (Syroot.Maths.Vector4F p in vec4Positions)
                            {
                                v.pos.Add(new Vector3 {
                                    X = p.X, Y = p.Y, Z = p.Z
                                });
                            }
                        }
                        if (att.Name == "_n0")
                        {
                            Console.WriteLine(att.Name);
                            VertexBufferHelperAttrib normal      = helper["_n0"];
                            Syroot.Maths.Vector4F[]  vec4Normals = normal.Data;

                            foreach (Syroot.Maths.Vector4F n in vec4Normals)
                            {
                                v.nrm.Add(new Vector3 {
                                    X = n.X, Y = n.Y, Z = n.Z
                                });
                            }
                        }
                        if (att.Name == "_u0")
                        {
                            Console.WriteLine(att.Name);
                            VertexBufferHelperAttrib uv0     = helper["_u0"];
                            Syroot.Maths.Vector4F[]  vec4uv0 = uv0.Data;

                            foreach (Syroot.Maths.Vector4F u in vec4uv0)
                            {
                                v.uv0.Add(new Vector2 {
                                    X = u.X, Y = u.Y
                                });
                            }
                        }
                        if (att.Name == "_u1")
                        {
                            Console.WriteLine(att.Name);
                            VertexBufferHelperAttrib uv1     = helper["_u1"];
                            Syroot.Maths.Vector4F[]  vec4uv1 = uv1.Data;

                            foreach (Syroot.Maths.Vector4F u in vec4uv1)
                            {
                                v.uv1.Add(new Vector2 {
                                    X = u.X, Y = u.Y
                                });
                            }
                        }
                        if (att.Name == "_u2")
                        {
                            Console.WriteLine(att.Name);
                            VertexBufferHelperAttrib uv2     = helper["_u2"];
                            Syroot.Maths.Vector4F[]  vec4uv2 = uv2.Data;

                            foreach (Syroot.Maths.Vector4F u in vec4uv2)
                            {
                                v.uv2.Add(new Vector2 {
                                    X = u.X, Y = u.Y
                                });
                            }
                        }
                        if (att.Name == "_c0")
                        {
                            Console.WriteLine(att.Name);
                            VertexBufferHelperAttrib c0     = helper["_c0"];
                            Syroot.Maths.Vector4F[]  vec4c0 = c0.Data;

                            foreach (Syroot.Maths.Vector4F c in vec4c0)
                            {
                                v.col.Add(new Vector4 {
                                    X = c.X, Y = c.Y, Z = c.Z, W = c.W
                                });
                            }
                        }
                        if (att.Name == "_t0")
                        {
                            Console.WriteLine(att.Name);
                            VertexBufferHelperAttrib t0     = helper["_t0"];
                            Syroot.Maths.Vector4F[]  vec4t0 = t0.Data;

                            foreach (Syroot.Maths.Vector4F u in vec4t0)
                            {
                                v.tans.Add(new Vector4 {
                                    X = u.X, Y = u.Y, Z = u.Z, W = u.W
                                });
                            }
                        }
                        if (att.Name == "_b0")
                        {
                            Console.WriteLine(att.Name);
                            VertexBufferHelperAttrib b0     = helper["_b0"];
                            Syroot.Maths.Vector4F[]  vec4b0 = b0.Data;

                            foreach (Syroot.Maths.Vector4F u in vec4b0)
                            {
                                v.bitans.Add(new Vector4 {
                                    X = u.X, Y = u.Y, Z = u.Z, W = u.W
                                });
                            }
                        }
                        if (att.Name == "_w0")
                        {
                            Console.WriteLine(att.Name);
                            VertexBufferHelperAttrib w0     = helper["_w0"];
                            Syroot.Maths.Vector4F[]  vec4w0 = w0.Data;

                            foreach (Syroot.Maths.Vector4F w in vec4w0)
                            {
                                v.weights.Add(new Vector4 {
                                    X = w.X, Y = w.Y, Z = w.Z, W = w.W
                                });
                            }
                        }
                        if (att.Name == "_i0")
                        {
                            Console.WriteLine(att.Name);
                            VertexBufferHelperAttrib i0     = helper["_i0"];
                            Syroot.Maths.Vector4F[]  vec4i0 = i0.Data;

                            foreach (Syroot.Maths.Vector4F i in vec4i0)
                            {
                                v.nodes.Add(new Vector4 {
                                    X = i.X, Y = i.Y, Z = i.Z, W = i.W
                                });
                            }
                        }
                    }
                    poly.vertices = v;

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

                    int AlbedoCount = 0;

                    string TextureName = "";
                    int    id          = 0;
                    foreach (TextureRef tex in mdl.Materials[shp.MaterialIndex].TextureRefs)
                    {
                        TextureName = tex.Name;

                        MatTexture texture = new MatTexture();

                        poly.Nodes.Add(new TreeNode {
                            Text = TextureName
                        });

                        if (mdl.Materials[shp.MaterialIndex].Samplers[id].Name == "_a0")
                        {
                            if (AlbedoCount == 0)
                            {
                                try
                                {
                                    poly.texHashs.Add(textures[TextureName].texture.display);
                                    AlbedoCount++;
                                }
                                catch
                                {
                                    poly.texHashs.Add(0);
                                }
                                poly.TextureMapTypes.Add("Diffuse");
                            }
                        }
                        if (mdl.Materials[shp.MaterialIndex].Samplers[id].Name == "_a1")
                        {
                            try
                            {
                                poly.texHashs.Add(textures[TextureName].texture.display);
                                AlbedoCount++;
                            }
                            catch
                            {
                                poly.texHashs.Add(0);
                            }
                            poly.TextureMapTypes.Add("Diffuse_Layer");
                        }
                        if (mdl.Materials[shp.MaterialIndex].Samplers[id].Name == "_n0")
                        {
                            try
                            {
                                poly.texHashs.Add(textures[TextureName].texture.display);
                            }
                            catch
                            {
                                poly.texHashs.Add(1);
                            }
                            poly.material.HasNormalMap = true;
                            poly.TextureMapTypes.Add("Normal");
                        }
                        if (mdl.Materials[shp.MaterialIndex].Samplers[id].Name == "_b0")
                        {
                            try
                            {
                                poly.texHashs.Add(textures[TextureName].texture.display);
                            }
                            catch
                            {
                                poly.texHashs.Add(2);
                            }
                            poly.TextureMapTypes.Add("Bake1");
                        }
                        if (mdl.Materials[shp.MaterialIndex].Samplers[id].Name == "_b1")
                        {
                            try
                            {
                                poly.texHashs.Add(textures[TextureName].texture.display);
                            }
                            catch
                            {
                                poly.texHashs.Add(3);
                            }
                            poly.TextureMapTypes.Add("Bake2");
                        }
                        id++;
                        texture.Name = TextureName;
                    }

                    poly.material.Name = mdl.Materials[shp.MaterialIndex].Name;

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

                    using (Syroot.BinaryData.BinaryDataReader reader = new Syroot.BinaryData.BinaryDataReader(new MemoryStream(mdl.Materials[shp.MaterialIndex].ShaderParamData)))
                    {
                        reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
                        foreach (Syroot.NintenTools.Bfres.ShaderParam param in mdl.Materials[shp.MaterialIndex].ShaderParams.Values)
                        {
                            ShaderParam prm = new ShaderParam();

                            prm.Type = param.Type;

                            switch (param.Type)
                            {
                            case ShaderParamType.Float:
                                reader.Seek(param.DataOffset, SeekOrigin.Begin);
                                prm.Value_float = reader.ReadSingle();
                                break;

                            case ShaderParamType.Float2:
                                reader.Seek(param.DataOffset, SeekOrigin.Begin);
                                prm.Value_float2 = new Vector2(
                                    reader.ReadSingle(),
                                    reader.ReadSingle());
                                break;

                            case ShaderParamType.Float3:
                                reader.Seek(param.DataOffset, SeekOrigin.Begin);
                                prm.Value_float3 = new Vector3(
                                    reader.ReadSingle(),
                                    reader.ReadSingle(),
                                    reader.ReadSingle()); break;

                            case ShaderParamType.Float4:
                                reader.Seek(param.DataOffset, SeekOrigin.Begin);
                                prm.Value_float4 = new Vector4(
                                    reader.ReadSingle(),
                                    reader.ReadSingle(),
                                    reader.ReadSingle(),
                                    reader.ReadSingle()); break;
                            }
                            poly.material.matparam.Add(param.Name, prm);
                        }
                        reader.Close();
                    }
                    model.poly.Add(poly);
                    ShapeCur++;
                }
                models.Add(model);
                ModelCur++;
            }
        }