Beispiel #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="model"></param>
        public void WriteFMDLData(XmlWriter writer, ResU.Model model)
        {
            writer.WriteStartElement("FMDL");
            writer.WriteAttributeString("Name", model.Name);

            // TODO Wrap these functions in if exists conditions, so that the xml only contains relevant data
            JPSkeleton jpSkeleton = new JPSkeleton();

            jpSkeleton.ReadSkeleton(model.Skeleton);
            FSKL.WriteSkeleton(writer, model.Skeleton);

            writer.WriteStartElement("Materials");
            writer.WriteAttributeString("FMATCount", model.Materials.Count.ToString());
            foreach (Material mat in model.Materials.Values)
            {
                FMAT.ReadMaterial(writer, mat);
            }
            writer.WriteEndElement();

            writer.WriteStartElement("Shapes");

            writer.WriteAttributeString("FSHPCount", model.Shapes.Count.ToString());
            writer.WriteAttributeString("FVTXCount", model.VertexBuffers.Count.ToString());
            writer.WriteAttributeString("TotalVertices", model.TotalVertexCount.ToString());
            foreach (Shape shp in model.Shapes.Values)
            {
                writer.WriteStartElement("FSHP");
                VertexBuffer vertexBuffer = model.VertexBuffers[shp.VertexBufferIndex];
                Material     material     = model.Materials[shp.MaterialIndex];
                WriteShapesVertices(writer, shp, vertexBuffer, model, jpSkeleton);
                writer.WriteEndElement();
            }
            writer.WriteEndElement();

            writer.WriteEndElement();
            writer.Flush();
        }
Beispiel #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="shp"></param>
        /// <param name="vertexBuffer"></param>
        /// <param name="model"></param>
        public static void WriteShapesVertices(XmlWriter writer, Shape shp, VertexBuffer vertexBuffer, ResU.Model model, JPSkeleton jpSkeleton)
        {
            writer.WriteAttributeString("Name", shp.Name);
            writer.WriteAttributeString("Flags", shp.Flags.ToString());
            writer.WriteAttributeString("MaterialIndex", shp.MaterialIndex.ToString());
            Program.AssertAndLog(Program.ErrorType.eBoneIndexSet, shp.BoneIndex == 0, $"{shp.Name}: Bone index is set. Why?");
            writer.WriteAttributeString("BoneIndex", shp.BoneIndex.ToString());
            writer.WriteAttributeString("VertexBufferIndex", shp.VertexBufferIndex.ToString());

            // Write Bounding Radius
            string tempRadiusArray = "";

            foreach (float rad in shp.RadiusArray)
            {
                tempRadiusArray += (rad.ToString() + ',');
            }
            tempRadiusArray = tempRadiusArray.Trim(',');

            writer.WriteAttributeString("RadiusArray", tempRadiusArray);
            writer.WriteAttributeString("VertexSkinCount", shp.VertexSkinCount.ToString());
            Program.AssertAndLog(Program.ErrorType.eShapeTargetAttributeCountGreaterThanZero, shp.TargetAttribCount == 0, $"{shp.Name}: target attribute count of greater than 0. Unsure of this meaning.");
            writer.WriteAttributeString("TargetAttributeCount", shp.TargetAttribCount.ToString());

            // Write Skin Bone Indices
            if (shp.SkinBoneIndices != null)
            {
                string tempSkinBoneIndices = "";
                foreach (ushort bn in shp.SkinBoneIndices)
                {
                    tempSkinBoneIndices += (bn + ",");
                }
                tempSkinBoneIndices = tempSkinBoneIndices.Trim(',');
                writer.WriteAttributeString("SkinBoneIndices", tempSkinBoneIndices);
            }

            // Write Key Shapes
            Program.AssertAndLog(Program.ErrorType.eKeyShapes, shp.KeyShapes.Count == 0, "If you hit this assert, write KeyShapes you lazy f**k.");

            // Write Bounding Boxes
            //
            // Summary:
            //     Represents a spatial bounding box.
            writer.WriteStartElement("SubMeshBoundings");
            writer.WriteAttributeString("SubMeshBoundingsCount", shp.SubMeshBoundings.Count.ToString());
            foreach (Bounding bnd in shp.SubMeshBoundings)
            {
                writer.WriteStartElement("SubMeshBounding");
                writer.WriteAttributeString("Center", Program.Vector3FToString(bnd.Center));
                writer.WriteAttributeString("Extent", Program.Vector3FToString(bnd.Extent));
                writer.WriteEndElement();
            }
            writer.WriteEndElement();

            //
            // Summary:
            //     Represents a node in a Syroot.NintenTools.Bfres.SubMesh bounding tree to determine
            //     when to show which sub mesh of a Syroot.NintenTools.Bfres.Mesh.
            writer.WriteStartElement("SubMeshBoundingNodes");
            writer.WriteAttributeString("SubMeshBoundingNodesCount", shp.SubMeshBoundingNodes.Count.ToString());
            foreach (BoundingNode node in shp.SubMeshBoundingNodes)
            {
                writer.WriteStartElement("SubMeshBoundingNode");

                writer.WriteAttributeString("LeftChildIndex", node.LeftChildIndex.ToString());
                writer.WriteAttributeString("NextSibling", node.NextSibling.ToString());
                writer.WriteAttributeString("RightChildIndex", node.RightChildIndex.ToString());
                writer.WriteAttributeString("Unknown", node.Unknown.ToString());
                writer.WriteAttributeString("SubMeshIndex", node.SubMeshIndex.ToString());
                writer.WriteAttributeString("SubMeshCount", node.SubMeshCount.ToString());

                writer.WriteEndElement();
            }
            writer.WriteEndElement();

            // Write SubMesh Bounding Indices
            writer.WriteStartElement("SubMeshBoundingIndices");
            writer.WriteAttributeString("SubMeshBoundingIndicesCount", shp.SubMeshBoundingIndices.Count.ToString());
            if (shp.SubMeshBoundingIndices != null)
            {
                string tempSubMeshBoundingIndices = "";
                foreach (ushort smbi in shp.SubMeshBoundingIndices)
                {
                    tempSubMeshBoundingIndices += (smbi + ",");
                }
                tempSubMeshBoundingIndices = tempSubMeshBoundingIndices.Trim(',');
                writer.WriteAttributeString("SubMeshBoundingIndices", tempSubMeshBoundingIndices);
            }
            writer.WriteEndElement();

            WriteMeshes(writer, shp);
            WriteVertexBuffer(writer, shp, vertexBuffer, model, jpSkeleton);
        }
Beispiel #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="shp"></param>
        /// <param name="vtx"></param>
        /// <param name="model"></param>
        private static void WriteVertexBuffer(XmlWriter writer, Shape shp, VertexBuffer vtx, ResU.Model model, JPSkeleton jPSkeleton)
        {
            //Create a buffer instance which stores all the buffer data
            VertexBufferHelper helper = new VertexBufferHelper(vtx, Syroot.BinaryData.ByteOrder.BigEndian); // TODO if this supports Switch files, you will need to re-look at this

            //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[] vec4c1        = 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];

            List <VertexAttrib> SortedList = vtx.Attributes.Values.OrderBy(o => o.BufferIndex).ToList();

            foreach (VertexAttrib att in vtx.Attributes.Values)
            {
                if (att.Name == "_p0")
                {
                    vec4Positions = AttributeData(att, helper, "_p0");
                }
                else if (att.Name == "_n0")
                {
                    vec4Normals = AttributeData(att, helper, "_n0");
                }
                else if (att.Name == "_u0")
                {
                    vec4uv0 = AttributeData(att, helper, "_u0");
                }
                else if (att.Name == "_u1")
                {
                    vec4uv1 = AttributeData(att, helper, "_u1");
                }
                else if (att.Name == "_u2")
                {
                    vec4uv2 = AttributeData(att, helper, "_u2");
                }
                else if (att.Name == "_c0")
                {
                    vec4c0 = AttributeData(att, helper, "_c0");
                }
                else if (att.Name == "_c1")
                {
                    vec4c1 = AttributeData(att, helper, "_c1");
                }
                else if (att.Name == "_t0")
                {
                    vec4t0 = AttributeData(att, helper, "_t0");
                }
                else if (att.Name == "_b0")
                {
                    vec4b0 = AttributeData(att, helper, "_b0");
                }
                else if (att.Name == "_w0")
                {
                    vec4w0 = AttributeData(att, helper, "_w0");
                }
                else if (att.Name == "_i0")
                {
                    vec4i0 = AttributeData(att, helper, "_i0");
                }

                else if (att.Name == "_p1")
                {
                    vec4Positions1 = AttributeData(att, helper, "_p1");
                }
                else if (att.Name == "_p2")
                {
                    vec4Positions2 = AttributeData(att, helper, "_p2");
                }
                else
                {
                    Program.AssertAndLog(Program.ErrorType.eUnhandledVertexAttrType, false, $"Vertex Attribute type {att.Name} not handled.");
                }
            }
            List <Vertex> vertices = new List <Vertex>();

            for (int i = 0; i < vec4Positions.Length; i++)
            {
                Vertex v = new Vertex();
                if (vec4Positions.Length > 0)
                {
                    v.pos = new OpenTK.Vector3(vec4Positions[i].X, vec4Positions[i].Y, vec4Positions[i].Z);
                }
                if (vec4Positions1.Length > 0)
                {
                    v.pos1 = new OpenTK.Vector3(vec4Positions1[i].X, vec4Positions1[i].Y, vec4Positions1[i].Z);
                }
                if (vec4Positions2.Length > 0)
                {
                    v.pos2 = new OpenTK.Vector3(vec4Positions2[i].X, vec4Positions2[i].Y, vec4Positions2[i].Z);
                }
                if (vec4Normals.Length > 0)
                {
                    v.nrm = new OpenTK.Vector3(vec4Normals[i].X, vec4Normals[i].Y, vec4Normals[i].Z);
                }
                if (vec4uv0.Length > 0)
                {
                    v.uv0 = new OpenTK.Vector2(vec4uv0[i].X, vec4uv0[i].Y);
                }
                if (vec4uv1.Length > 0)
                {
                    v.uv1 = new OpenTK.Vector2(vec4uv1[i].X, vec4uv1[i].Y);
                }
                if (vec4uv2.Length > 0)
                {
                    v.uv2 = new OpenTK.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 OpenTK.Vector4(vec4t0[i].X, vec4t0[i].Y, vec4t0[i].Z, vec4t0[i].W);
                }
                if (vec4b0.Length > 0)
                {
                    v.bitan = new OpenTK.Vector4(vec4b0[i].X, vec4b0[i].Y, vec4b0[i].Z, vec4b0[i].W);
                }
                if (vec4c0.Length > 0)
                {
                    v.col = new OpenTK.Vector4(vec4c0[i].X, vec4c0[i].Y, vec4c0[i].Z, vec4c0[i].W);
                }
                if (vec4c1.Length > 0)
                {
                    v.col2 = new OpenTK.Vector4(vec4c1[i].X, vec4c1[i].Y, vec4c1[i].Z, vec4c1[i].W);
                }


                int[] boneList = new int[model.Skeleton.MatrixToBoneList.Count];
                int   uiBone   = 0;
                foreach (ushort node in model.Skeleton.MatrixToBoneList)
                {
                    boneList[uiBone] = node;
                    uiBone++;
                }
                if (shp.VertexSkinCount == 1)
                {
                    int boneIndex = shp.BoneIndex;
                    if (v.boneIds.Count > 0)
                    {
                        boneIndex = boneList[v.boneIds[0]];
                    }

                    //Check if the bones are a rigid type
                    //In game it seems to not transform if they are not rigid
                    if (model.Skeleton.Bones[boneIndex].RigidMatrixIndex != -1)
                    {
                        OpenTK.Matrix4 absTransform = jPSkeleton.bones[boneIndex].Transform;

                        v.pos = OpenTK.Vector3.TransformPosition(v.pos, absTransform);
                        v.nrm = OpenTK.Vector3.TransformNormal(v.nrm, absTransform);
                    }
                }
                if (shp.VertexSkinCount == 0)
                {
                    try
                    {
                        if (model.Skeleton.Bones.Count > 0)
                        {
                            int boneIndex = shp.BoneIndex;


                            // Create the Transform Matrix4
                            OpenTK.Vector3 mPos = new OpenTK.Vector3(
                                model.Skeleton.Bones[boneIndex].Position.X,
                                model.Skeleton.Bones[boneIndex].Position.Y,
                                model.Skeleton.Bones[boneIndex].Position.Z);

                            OpenTK.Quaternion mRot;
                            OpenTK.Vector3    v3 = new OpenTK.Vector3(
                                model.Skeleton.Bones[boneIndex].Rotation.X,
                                model.Skeleton.Bones[boneIndex].Rotation.Y,
                                model.Skeleton.Bones[boneIndex].Rotation.Z
                                );
                            if (model.Skeleton.Bones[boneIndex].FlagsRotation == BoneFlagsRotation.Quaternion)
                            {
                                mRot = new OpenTK.Quaternion(v3, model.Skeleton.Bones[boneIndex].Rotation.W);
                            }
                            else if (model.Skeleton.Bones[boneIndex].FlagsRotation == BoneFlagsRotation.EulerXYZ)
                            {
                                mRot = new OpenTK.Quaternion(v3);
                            }
                            else
                            {
                                mRot = new OpenTK.Quaternion();
                            }
                            OpenTK.Vector3 mSca = new OpenTK.Vector3(
                                model.Skeleton.Bones[boneIndex].Scale.X,
                                model.Skeleton.Bones[boneIndex].Scale.Y,
                                model.Skeleton.Bones[boneIndex].Scale.Z);

                            OpenTK.Matrix4 NoBindFix = OpenTK.Matrix4.CreateScale(mSca) * OpenTK.Matrix4.CreateFromQuaternion(mRot) * OpenTK.Matrix4.CreateTranslation(mPos);
                            v.pos = OpenTK.Vector3.TransformPosition(v.pos, NoBindFix);
                            v.nrm = OpenTK.Vector3.TransformNormal(v.nrm, NoBindFix);
                        }
                    }
                    catch //Matrix failed. Print the coordinate data of the bone
                    {
                        //Console.WriteLine(model.Skeleton.bones[fshp.BoneIndex].Text);
                        //Console.WriteLine(model.Skeleton.bones[fshp.BoneIndex].GetPosition());
                        //Console.WriteLine(model.Skeleton.bones[fshp.BoneIndex].GetRotation());
                        //Console.WriteLine(model.Skeleton.bones[fshp.BoneIndex].GetScale());
                    }
                }

                vertices.Add(v);
            }

            // Write Vertex Data
            writer.WriteStartElement("Vertices");
            writer.WriteAttributeString("VertexCount", vtx.VertexCount.ToString());
            for (int i = 0; i < vertices.Count; i++)
            {
                writer.WriteStartElement("Vertex");

                writer.WriteAttributeString("Index", i.ToString());
                writer.WriteAttributeString("Position0", Program.Vector3ToString(vertices[i].pos));
                writer.WriteAttributeString("Position1", Program.Vector3ToString(vertices[i].pos1)); Program.AssertAndLog(Program.ErrorType.eVertexPosSet, vertices[i].pos1 == OpenTK.Vector3.Zero, $"Vertex index {i} pos1 is set to {vertices[i].pos1} and not 0");     // Add C++ support
                writer.WriteAttributeString("Position2", Program.Vector3ToString(vertices[i].pos2)); Program.AssertAndLog(Program.ErrorType.eVertexPosSet, vertices[i].pos2 == OpenTK.Vector3.Zero, $"Vertex index {i} pos2 is set to {vertices[i].pos2} and not 0");     // Add C++ support
                writer.WriteAttributeString("Normal", Program.Vector3ToString(vertices[i].nrm));
                writer.WriteAttributeString("UV0", Program.Vector2ToString(vertices[i].uv0));
                writer.WriteAttributeString("UV1", Program.Vector2ToString(vertices[i].uv1));
                writer.WriteAttributeString("UV2", Program.Vector2ToString(vertices[i].uv2));
                writer.WriteAttributeString("Color0", Program.Vector4ToString(vertices[i].col));
                writer.WriteAttributeString("Color1", Program.Vector4ToString(vertices[i].col2)); Program.AssertAndLog(Program.ErrorType.eVertexPosSet, vertices[i].col2 == OpenTK.Vector4.One, $"Vertex index {i} col2 is set to {vertices[i].col2} and not One");        // Add C++ support. Unknown use of col2
                writer.WriteAttributeString("Tangent", Program.Vector4ToString(vertices[i].tan));
                writer.WriteAttributeString("Binormal", Program.Vector4ToString(vertices[i].bitan));

                string tempBoneWeights = "";
                foreach (var w in vertices[i].boneWeights)
                {
                    tempBoneWeights += (w.ToString() + ',');
                }
                tempBoneWeights = tempBoneWeights.Trim(',');
                writer.WriteAttributeString("BlendWeights", tempBoneWeights);

                string tempBoneIds = "";
                foreach (var w in vertices[i].boneIds)
                {
                    tempBoneIds += (w.ToString() + ',');
                }
                tempBoneIds = tempBoneIds.Trim(',');
                writer.WriteAttributeString("BlendIndex", tempBoneIds);
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
        }
Beispiel #4
0
        //Function addes shapes, vertices and meshes
        public void AddOjects(string FileName, ResFile resFileNX, ResU.ResFile resFileU, bool Replace = true)
        {
            int totalSkinCountLimiter = 0;

            bool IsWiiU = (resFileU != null);

            if (shapes.Count > 0)
            {
                totalSkinCountLimiter = shapes[0].VertexSkinCount;
            }

            int    MatStartIndex = materials.Count;
            string ext           = System.IO.Path.GetExtension(FileName);

            ext = ext.ToLower();

            switch (ext)
            {
            case ".bfobj":
                Cursor.Current = Cursors.WaitCursor;

                if (Replace)
                {
                    shapes.Clear();
                    Nodes["FshpFolder"].Nodes.Clear();
                }
                if (IsWiiU)
                {
                    var shpS          = new ResU.Shape();
                    var vertexBufferU = new ResU.VertexBuffer();
                    shpS.Import(FileName, vertexBufferU, resFileU);

                    FSHP shapeS = new FSHP();
                    shapeS.ShapeU = shpS;
                    BfresWiiU.ReadShapesVertices(shapeS, shpS, vertexBufferU, this);
                    shapes.Add(shapeS);
                    Nodes["FshpFolder"].Nodes.Add(shapeS);
                }
                else
                {
                    Shape        shpS         = new Shape();
                    VertexBuffer vertexBuffer = new VertexBuffer();
                    shpS.Import(FileName, vertexBuffer);

                    FSHP shapeS = new FSHP();
                    shapeS.Shape = shpS;
                    BfresSwitch.ReadShapesVertices(shapeS, shpS, vertexBuffer, this);
                    shapes.Add(shapeS);
                    Nodes["FshpFolder"].Nodes.Add(shapeS);
                }

                IsEdited = true;

                Cursor.Current = Cursors.Default;
                break;

            case ".bfmdl":
                Cursor.Current = Cursors.WaitCursor;

                if (Replace)
                {
                    shapes.Clear();
                    Nodes["FshpFolder"].Nodes.Clear();
                    materials.Clear();
                    Nodes["FmatFolder"].Nodes.Clear();
                }

                if (IsWiiU)
                {
                    var mdlU = new ResU.Model();
                    mdlU.Import(FileName, resFileU);
                    mdlU.Name = Text;
                    BfresWiiU.ReadModel(this, mdlU);
                }
                else
                {
                    Model mdl = new Model();
                    mdl.Import(FileName, resFileNX);
                    mdl.Name = Text;

                    Console.WriteLine(mdl.ShapeCount);
                    Console.WriteLine(mdl.MaterialCount);
                    Console.WriteLine(mdl.VertexBufferCount);
                    Console.WriteLine(mdl.Skeleton.Bones.Count);

                    BfresSwitch.ReadModel(this, mdl);
                }
                IsEdited = true;

                Cursor.Current = Cursors.Default;
                break;

            case ".csv":
                CsvModel csvModel = new CsvModel();
                csvModel.LoadFile(new System.IO.FileStream(FileName, System.IO.FileMode.Open), true);

                if (csvModel.objects.Count == 0)
                {
                    MessageBox.Show("No models found!");
                    return;
                }
                BfresModelImportSettings csvsettings = new BfresModelImportSettings();
                csvsettings.DisableMaterialEdits();
                csvsettings.SkinCountLimit = totalSkinCountLimiter;
                csvsettings.SetModelAttributes(csvModel.objects[0]);
                if (csvsettings.ShowDialog() == DialogResult.OK)
                {
                    if (Replace)
                    {
                        shapes.Clear();
                        Nodes["FshpFolder"].Nodes.Clear();
                    }

                    Cursor.Current = Cursors.WaitCursor;

                    foreach (STGenericObject obj in csvModel.objects)
                    {
                        FSHP shape = new FSHP();
                        Nodes["FshpFolder"].Nodes.Add(shape);
                        shapes.Add(shape);

                        shape.VertexBufferIndex = shapes.Count;
                        shape.vertices          = obj.vertices;
                        shape.MaterialIndex     = 0;
                        shape.vertexAttributes  = csvsettings.CreateNewAttributes();
                        shape.BoneIndex         = 0;
                        shape.Text      = obj.ObjectName;
                        shape.lodMeshes = obj.lodMeshes;
                        shape.CreateNewBoundingBoxes();
                        shape.CreateBoneList(obj, this);
                        shape.CreateIndexList(obj, this);
                        //Todo find better way. Currently uses import settings now
                        shape.ApplyImportSettings(csvsettings, GetMaterial(shape.MaterialIndex));
                        shape.VertexSkinCount = obj.GetMaxSkinInfluenceCount();
                        shape.BoneIndices     = shape.GetIndices(Skeleton);
                        shape.SaveShape(IsWiiU);
                        shape.SaveVertexBuffer();

                        if (IsWiiU)
                        {
                            shape.ShapeU.SubMeshBoundingIndices = new List <ushort>();
                            shape.ShapeU.SubMeshBoundingIndices.Add(0);
                            shape.ShapeU.SubMeshBoundingNodes = new List <ResU.BoundingNode>();
                            shape.ShapeU.SubMeshBoundingNodes.Add(new ResU.BoundingNode()
                            {
                                LeftChildIndex  = 0,
                                NextSibling     = 0,
                                SubMeshIndex    = 0,
                                RightChildIndex = 0,
                                Unknown         = 0,
                                SubMeshCount    = 1,
                            });
                        }

                        if (IsWiiU)
                        {
                            BfresWiiU.ReadShapesVertices(shape, shape.ShapeU, shape.VertexBufferU, this);
                        }
                        else
                        {
                            BfresSwitch.ReadShapesVertices(shape, shape.Shape, shape.VertexBuffer, this);
                        }
                    }
                    Cursor.Current = Cursors.Default;
                }
                IsEdited = true;

                break;

            default:
                AssimpData assimp = new AssimpData();
                assimp.LoadFile(FileName);

                if (assimp.objects.Count == 0)
                {
                    MessageBox.Show("No models found!");
                    return;
                }
                BfresModelImportSettings settings = new BfresModelImportSettings();
                settings.SetModelAttributes(assimp.objects[0]);
                if (settings.ShowDialog() == DialogResult.OK)
                {
                    bool UseMats = settings.ExternalMaterialPath != string.Empty;

                    if (Replace)
                    {
                        shapes.Clear();
                        Nodes["FshpFolder"].Nodes.Clear();
                    }

                    Cursor.Current = Cursors.WaitCursor;
                    if (Replace && UseMats)
                    {
                        materials.Clear();
                        Nodes["FmatFolder"].Nodes.Clear();
                        MatStartIndex = 0;
                    }
                    if (UseMats)
                    {
                        foreach (STGenericMaterial mat in assimp.materials)
                        {
                            FMAT fmat = new FMAT();

                            if (IsWiiU)
                            {
                                fmat.MaterialU = new ResU.Material();
                                fmat.MaterialU.Import(settings.ExternalMaterialPath, resFileU);
                                BfresWiiU.ReadMaterial(fmat, fmat.MaterialU);
                            }
                            else
                            {
                                fmat.Material = new Material();
                                fmat.Material.Import(settings.ExternalMaterialPath);
                                fmat.ReadMaterial(fmat.Material);
                            }

                            fmat.Text = mat.Text;
                            //Setup placeholder textures
                            //Note we can't add/remove samplers so we must fill these slots
                            foreach (var t in fmat.TextureMaps)
                            {
                                t.wrapModeS = 0;
                                t.wrapModeT = 0;

                                switch (t.Type)
                                {
                                case STGenericMatTexture.TextureType.Diffuse:
                                    t.Name = "Basic_Alb";
                                    break;

                                case STGenericMatTexture.TextureType.Emission:
                                    t.Name = "Basic_Emm";
                                    break;

                                case STGenericMatTexture.TextureType.Normal:
                                    t.Name = "Basic_Nrm";
                                    break;

                                case STGenericMatTexture.TextureType.Specular:
                                    t.Name = "Basic_Spm";
                                    break;

                                case STGenericMatTexture.TextureType.SphereMap:
                                    t.Name = "Basic_Sphere";
                                    break;

                                case STGenericMatTexture.TextureType.Metalness:
                                    t.Name = "Basic_Mtl";
                                    break;

                                case STGenericMatTexture.TextureType.Roughness:
                                    t.Name = "Basic_Rgh";
                                    break;

                                case STGenericMatTexture.TextureType.MRA:
                                    t.Name = "Basic_MRA";
                                    break;

                                case STGenericMatTexture.TextureType.Shadow:
                                    t.Name = "Basic_Bake_st0";
                                    break;

                                case STGenericMatTexture.TextureType.Light:
                                    t.Name = "Basic_Bake_st1";
                                    break;
                                }
                            }

                            if (PluginRuntime.bntxContainers.Count > 0 && Parent != null)
                            {
                                foreach (var node in Parent.Parent.Nodes)
                                {
                                    if (node is BNTX)
                                    {
                                        var bntx = (BNTX)node;

                                        bntx.ImportBasicTextures("Basic_Alb");
                                        bntx.ImportBasicTextures("Basic_Nrm");
                                        bntx.ImportBasicTextures("Basic_Spm");
                                        bntx.ImportBasicTextures("Basic_Sphere");
                                        bntx.ImportBasicTextures("Basic_Mtl");
                                        bntx.ImportBasicTextures("Basic_Rgh");
                                        bntx.ImportBasicTextures("Basic_MRA");
                                        bntx.ImportBasicTextures("Basic_Bake_st0");
                                        bntx.ImportBasicTextures("Basic_Bake_st1");
                                        bntx.ImportBasicTextures("Basic_Emm");
                                    }
                                }
                            }
                            if (PluginRuntime.ftexContainers.Count > 0 && Parent != null)
                            {
                                foreach (var node in Parent.Parent.Nodes)
                                {
                                    if (node is BFRESGroupNode)
                                    {
                                        if (((BFRESGroupNode)node).Type == BRESGroupType.Textures)
                                        {
                                            var ftexCont = (BFRESGroupNode)node;

                                            ftexCont.ImportBasicTextures("Basic_Alb");
                                            ftexCont.ImportBasicTextures("Basic_Nrm");
                                            ftexCont.ImportBasicTextures("Basic_Spm");
                                            ftexCont.ImportBasicTextures("Basic_Sphere");
                                            ftexCont.ImportBasicTextures("Basic_Mtl");
                                            ftexCont.ImportBasicTextures("Basic_Rgh");
                                            ftexCont.ImportBasicTextures("Basic_MRA");
                                            ftexCont.ImportBasicTextures("Basic_Bake_st0");
                                            ftexCont.ImportBasicTextures("Basic_Bake_st1");
                                            ftexCont.ImportBasicTextures("Basic_Emm");
                                        }
                                    }
                                }
                            }

                            foreach (var tex in mat.TextureMaps)
                            {
                                foreach (var t in fmat.TextureMaps)
                                {
                                    if (t.Type == tex.Type)
                                    {
                                        t.Name      = tex.Name;
                                        t.wrapModeS = tex.wrapModeS;
                                        t.wrapModeT = tex.wrapModeT;
                                        t.wrapModeW = tex.wrapModeW;
                                        t.Type      = tex.Type;
                                    }
                                }
                            }

                            List <string> keyList = new List <string>(materials.Keys);
                            fmat.Text = Utils.RenameDuplicateString(keyList, fmat.Text);

                            if (IsWiiU)
                            {
                                fmat.MaterialU.Name = Text;
                                fmat.SetMaterial(fmat.MaterialU, resFileU);
                            }
                            else
                            {
                                fmat.Material.Name = Text;
                                fmat.SetMaterial(fmat.Material);
                            }

                            materials.Add(fmat.Text, fmat);
                            Nodes["FmatFolder"].Nodes.Add(fmat);
                        }
                    }

                    if (settings.ImportBones)
                    {
                        if (assimp.skeleton.bones.Count > 0)
                        {
                            Skeleton.bones.Clear();
                            Skeleton.node.Nodes.Clear();

                            if (IsWiiU)
                            {
                                BfresWiiU.SaveSkeleton(Skeleton, assimp.skeleton.bones);
                            }
                            else
                            {
                                BfresSwitch.SaveSkeleton(Skeleton, assimp.skeleton.bones);
                            }
                        }
                    }

                    if (materials.Count <= 0)
                    {
                        //Force material creation if there is none present
                        FMAT fmat = new FMAT();
                        fmat.Text = "NewMaterial";
                        materials.Add(fmat.Text, fmat);
                        Nodes["FmatFolder"].Nodes.Add(fmat);

                        if (IsWiiU)
                        {
                            fmat.MaterialU      = new ResU.Material();
                            fmat.MaterialU.Name = "NewMaterial";
                            BfresWiiU.ReadMaterial(fmat, fmat.MaterialU);
                        }
                        else
                        {
                            fmat.Material      = new Material();
                            fmat.Material.Name = "NewMaterial";
                            fmat.ReadMaterial(fmat.Material);
                        }
                    }

                    foreach (STGenericObject obj in assimp.objects)
                    {
                        FSHP shape = new FSHP();
                        Nodes["FshpFolder"].Nodes.Add(shape);
                        shapes.Add(shape);

                        shape.VertexBufferIndex = shapes.Count;
                        shape.vertices          = obj.vertices;
                        shape.vertexAttributes  = settings.CreateNewAttributes();
                        shape.BoneIndex         = obj.BoneIndex;

                        STConsole.WriteLine(Text + " " + obj.MaterialIndex);

                        if (UseMats)
                        {
                            shape.MaterialIndex = obj.MaterialIndex + MatStartIndex;
                        }
                        else
                        {
                            shape.MaterialIndex = 0;
                        }

                        if (shape.MaterialIndex >= materials.Count)
                        {
                            shape.MaterialIndex = 0;
                        }

                        shape.Text      = obj.ObjectName;
                        shape.lodMeshes = obj.lodMeshes;
                        shape.CreateNewBoundingBoxes();
                        shape.CreateBoneList(obj, this);
                        shape.CreateIndexList(obj, this);
                        shape.ApplyImportSettings(settings, GetMaterial(shape.MaterialIndex));
                        shape.VertexSkinCount = obj.GetMaxSkinInfluenceCount();
                        shape.BoneIndices     = shape.GetIndices(Skeleton);

                        shape.SaveShape(IsWiiU);
                        shape.SaveVertexBuffer();

                        if (IsWiiU)
                        {
                            shape.ShapeU.SubMeshBoundingIndices = new List <ushort>();
                            shape.ShapeU.SubMeshBoundingIndices.Add(0);
                            shape.ShapeU.SubMeshBoundingNodes = new List <ResU.BoundingNode>();
                            shape.ShapeU.SubMeshBoundingNodes.Add(new ResU.BoundingNode()
                            {
                                LeftChildIndex  = 0,
                                NextSibling     = 0,
                                SubMeshIndex    = 0,
                                RightChildIndex = 0,
                                Unknown         = 0,
                                SubMeshCount    = 1,
                            });
                        }

                        List <string> keyList = shapes.Select(o => o.Text).ToList();
                        shape.Text = Utils.RenameDuplicateString(keyList, shape.Text);

                        if (IsWiiU)
                        {
                            BfresWiiU.ReadShapesVertices(shape, shape.ShapeU, shape.VertexBufferU, this);
                        }
                        else
                        {
                            BfresSwitch.ReadShapesVertices(shape, shape.Shape, shape.VertexBuffer, this);
                        }
                    }


                    IsEdited = true;

                    Cursor.Current = Cursors.Default;
                }
                break;
            }

            if (IsEdited)
            {
                UpdateVertexData();
            }
        }