Example #1
0
        public void HighlightBone(remParser parser, remMesh remMesh, int boneIdx, bool show)
        {
            List <List <remVertex> > submeshVertLists   = new List <List <remVertex> >(remMesh.numMats);
            List <List <ushort> >    submeshFaceLists   = new List <List <ushort> >(remMesh.numMats);
            List <int[]>             submeshVertIndices = new List <int[]>(remMesh.numMats);

            SplitMesh(remMesh, submeshVertLists, submeshFaceLists, submeshVertIndices);
            remSkin boneList = rem.FindSkin(remMesh.name, parser.SKIC);

            int submeshIdx = 0;

            for (AnimationMeshContainer mesh = (AnimationMeshContainer)meshFrames[0].MeshContainer;
                 mesh != null;
                 mesh = (AnimationMeshContainer)mesh.NextMeshContainer, submeshIdx++)
            {
                if (mesh.MeshData != null && mesh.MeshData.Mesh != null)
                {
                    List <remVertex> vertexList        = submeshVertLists[submeshIdx];
                    byte[][]         vertexBoneIndices = null;
                    float[][]        vertexWeights     = ConvertVertexWeights(vertexList, submeshVertIndices[submeshIdx], boneList, out vertexBoneIndices);
                    FillVertexBuffer(mesh.MeshData.Mesh, vertexList, vertexWeights, vertexBoneIndices, show ? boneIdx : -1);
                }
                if (mesh.BoneLines != null)
                {
                    for (int j = 0; j < BoneObjSize; j++)
                    {
                        mesh.BoneLines[boneIdx * BoneObjSize + j].Color = show ? Color.Crimson.ToArgb(): Color.CornflowerBlue.ToArgb();
                    }
                }
            }
        }
Example #2
0
        public remBone Clone(bool mesh, bool childFrames, remParser parser, List <remMaterial> clonedMaterials, List <remMesh> clonedMeshes, List <remSkin> clonedSkins)
        {
            remBone frame = new remBone(Count);

            frame.name   = name;
            frame.matrix = matrix;

            if (mesh)
            {
                remMesh remMesh = rem.FindMesh(this, parser.MESC);
                if (remMesh != null)
                {
                    foreach (remId matId in remMesh.materials)
                    {
                        remMaterial mat = rem.FindMaterial(matId, parser.MATC);
                        if (!clonedMaterials.Contains(mat))
                        {
                            clonedMaterials.Add(mat.Clone());
                        }
                    }
                    remMesh clone = remMesh.Clone(true, true, parser, clonedSkins);
                    clone.frame = frame.name;
                    clonedMeshes.Add(clone);
                }
            }
            if (childFrames)
            {
                for (int i = 0; i < Count; i++)
                {
                    frame.AddChild(this[i].Clone(mesh, true, parser, clonedMaterials, clonedMeshes, clonedSkins));
                }
            }
            return(frame);
        }
Example #3
0
        public static void SaveREM(remParser parser, string destPath, bool keepBackup, string backupExt)
        {
            DirectoryInfo dir = new DirectoryInfo(Path.GetDirectoryName(destPath));

            string backup = null;

            if (keepBackup && File.Exists(destPath))
            {
                backup = Utility.GetDestFile(dir, Path.GetFileNameWithoutExtension(destPath) + ".bak", backupExt);
                File.Move(destPath, backup);
            }

            try
            {
                using (BufferedStream bufStr = new BufferedStream(File.OpenWrite(destPath)))
                {
                    parser.WriteTo(bufStr);
                }
            }
            catch
            {
                if (File.Exists(backup))
                {
                    if (File.Exists(destPath))
                    {
                        File.Delete(destPath);
                    }
                    File.Move(backup, destPath);
                }
            }
        }
Example #4
0
        public static HashSet <string> SearchHierarchy(remParser parser, remMesh mesh)
        {
            HashSet <string> exportFrames = new HashSet <string>();

            SearchHierarchy(parser.BONC.rootFrame, mesh, exportFrames);
            remSkin boneList = FindSkin(mesh.name, parser.SKIC);

            if (boneList != null)
            {
                for (int i = 0; i < boneList.Count; i++)
                {
                    if (!exportFrames.Contains(boneList[i].bone.ToString()))
                    {
                        remBone boneParent = FindFrame(boneList[i].bone, parser.BONC.rootFrame);
                        if (boneParent == null)
                        {
                            Report.ReportLog("Missing bone frame " + boneList[i].bone);
                            continue;
                        }
                        while (boneParent.Parent != null && exportFrames.Add(boneParent.name.ToString()))
                        {
                            boneParent = (remBone)boneParent.Parent;
                        }
                    }
                }
            }

            return(exportFrames);
        }
Example #5
0
        public void MergeTexture(string tex, remParser srcParser)
        {
            String src_TEXH_folder = rem.TexturePathFromREM(srcParser.RemPath);

            if (src_TEXH_folder == null)
            {
                Report.ReportLog("TEXH folder could not be located.");
                return;
            }
            String texh_folder = rem.TexturePathFromREM(Parser.RemPath);

            if (texh_folder == null)
            {
                Report.ReportLog("TEXH folder could not be located.");
                return;
            }

            if (src_TEXH_folder != texh_folder)
            {
                ImportedTexture impTex = new ImportedTexture(src_TEXH_folder + @"\" + tex);
                string          newTex = rem.CreateTexture(impTex, texh_folder);
                if (!Textures.Contains(newTex))
                {
                    Textures.Add(newTex);
                }
            }
        }
Example #6
0
        public RenderObjectREM(remParser parser, remMesh mesh)
        {
            HighlightSubmesh          = new HashSet <int>();
            highlightMaterial         = new Material();
            highlightMaterial.Ambient = new Color4(1, 1, 1, 1);
            highlightMaterial.Diffuse = new Color4(1, 0, 1, 0);

            this.device = Gui.Renderer.Device;

            if (Textures.Count + parser.MATC.Count > Textures.Capacity)
            {
                Textures.Capacity += parser.MATC.Count;
            }
            Materials = new Material[parser.MATC.Count];

            rootFrame = CreateHierarchy(parser, mesh, device, out meshFrames);

            AnimationController = new AnimationController(numFrames, 30, 30, 1);
            Frame.RegisterNamedMatrices(rootFrame, AnimationController);

            for (int i = 0; i < meshFrames.Count; i++)
            {
                if (i == 0)
                {
                    Bounds = meshFrames[i].Bounds;
                }
                else
                {
                    Bounds = BoundingBox.Merge(Bounds, meshFrames[i].Bounds);
                }
            }
        }
Example #7
0
        public static void ReplaceMaterial(remParser parser, ImportedMaterial material)
        {
            remMaterial mat = CreateMaterial(material);

            bool found = false;

            for (int i = 0; i < parser.MATC.Count; i++)
            {
                if (parser.MATC[i].name == material.Name)
                {
                    remMaterial original = parser.MATC[i];
                    CopyUnknown(original, mat);

                    parser.MATC.RemoveChild(i);
                    parser.MATC.InsertChild(i, mat);
                    found = true;
                    break;
                }
            }

            if (!found)
            {
                CreateUnknown(mat);
                parser.MATC.AddChild(mat);
            }
        }
Example #8
0
        public RenderObjectREM(remParser parser, remMesh mesh)
        {
            HighlightSubmesh = new HashSet<int>();
            highlightMaterial = new Material();
            highlightMaterial.Ambient = new Color4(1, 1, 1, 1);
            highlightMaterial.Diffuse = new Color4(1, 0, 1, 0);

            this.device = Gui.Renderer.Device;

            if (Textures.Count + parser.MATC.Count > Textures.Capacity)
            {
                Textures.Capacity += parser.MATC.Count;
            }
            Materials = new Material[parser.MATC.Count];

            rootFrame = CreateHierarchy(parser, mesh, device, out meshFrames);

            AnimationController = new AnimationController(numFrames, 30, 30, 1);
            Frame.RegisterNamedMatrices(rootFrame, AnimationController);

            for (int i = 0; i < meshFrames.Count; i++)
            {
                if (i == 0)
                {
                    Bounds = meshFrames[i].Bounds;
                }
                else
                {
                    Bounds = BoundingBox.Merge(Bounds, meshFrames[i].Bounds);
                }
            }
        }
Example #9
0
        public remMesh Clone(bool submeshes, bool boneList, remParser parser, List <remSkin> clonedSkins)
        {
            remMesh mesh = new remMesh(numMats);

            mesh.name = new remId(name);
            rem.CopyUnknowns(this, mesh);

            if (submeshes)
            {
                for (int i = 0; i < numMats; i++)
                {
                    mesh.AddMaterial(new remId(materials[i]));
                }
                mesh.vertices = new remVertex[numVertices];
                for (int i = 0; i < numVertices; i++)
                {
                    mesh.vertices[i] = vertices[i].Clone();
                }
                mesh.faces     = (int[])faces.Clone();
                mesh.faceMarks = (int[])faceMarks.Clone();
            }

            remSkin skin = rem.FindSkin(name, parser.SKIC);

            if (skin != null)
            {
                skin      = skin.Clone();
                skin.mesh = mesh.name;
                clonedSkins.Add(skin);
            }

            return(mesh);
        }
Example #10
0
            public static void Export(string dirPath, remParser parser, List <remMesh> meshes, bool singleMqo, bool worldCoords)
            {
                DirectoryInfo dir          = new DirectoryInfo(dirPath);
                List <string> usedTextures = new List <string>(parser.MATC.Count);

                if (singleMqo)
                {
                    try
                    {
                        string        dest    = Utility.GetDestFile(dir, "meshes", ".mqo");
                        List <string> texList = Export(dest, parser, meshes, worldCoords);
                        foreach (string tex in texList)
                        {
                            if (!usedTextures.Contains(tex))
                            {
                                usedTextures.Add(tex);
                            }
                        }
                        Report.ReportLog("Finished exporting meshes to " + dest);
                    }
                    catch (Exception ex)
                    {
                        Report.ReportLog("Error exporting meshes: " + ex.Message);
                    }
                }
                else
                {
                    for (int i = 0; i < meshes.Count; i++)
                    {
                        try
                        {
                            string        frameName = meshes[i].name;
                            string        dest      = dir.FullName + @"\" + frameName + ".mqo";
                            List <string> texList   = Export(dest, parser, new List <remMesh> {
                                meshes[i]
                            }, worldCoords);
                            foreach (string tex in texList)
                            {
                                if (!usedTextures.Contains(tex))
                                {
                                    usedTextures.Add(tex);
                                }
                            }
                            Report.ReportLog("Finished exporting mesh to " + dest);
                        }
                        catch (Exception ex)
                        {
                            Report.ReportLog("Error exporting mesh: " + ex.Message);
                        }
                    }
                }

                foreach (string tex in usedTextures)
                {
                    rem.ExportTexture(tex, parser.RemPath, dir.FullName);
                }
            }
Example #11
0
        public remEditor(remParser parser)
        {
            Parser = parser;
            Frames = parser.BONC.ChildList;
            Meshes = parser.MESC.ChildList;
            Materials = parser.MATC.ChildList;

            Textures = new List<string>(parser.MATC.Count);
            InitTextures(false, false);
        }
Example #12
0
        public remEditor(remParser parser)
        {
            Parser    = parser;
            Frames    = parser.BONC.ChildList;
            Meshes    = parser.MESC.ChildList;
            Materials = parser.MATC.ChildList;

            Textures = new List <string>(parser.MATC.Count);
            InitTextures(false, false);
        }
Example #13
0
            public static void Export(string dirPath, remParser parser, List<remMesh> meshes, bool singleMqo, bool worldCoords)
            {
                DirectoryInfo dir = new DirectoryInfo(dirPath);
                List<string> usedTextures = new List<string>(parser.MATC.Count);
                if (singleMqo)
                {
                    try
                    {
                        string dest = Utility.GetDestFile(dir, "meshes", ".mqo");
                        List<string> texList = Export(dest, parser, meshes, worldCoords);
                        foreach (string tex in texList)
                        {
                            if (!usedTextures.Contains(tex))
                            {
                                usedTextures.Add(tex);
                            }
                        }
                        Report.ReportLog("Finished exporting meshes to " + dest);
                    }
                    catch (Exception ex)
                    {
                        Report.ReportLog("Error exporting meshes: " + ex.Message);
                    }
                }
                else
                {
                    for (int i = 0; i < meshes.Count; i++)
                    {
                        try
                        {
                            string frameName = meshes[i].name;
                            string dest = dir.FullName + @"\" + frameName + ".mqo";
                            List<string> texList = Export(dest, parser, new List<remMesh> { meshes[i] }, worldCoords);
                            foreach (string tex in texList)
                            {
                                if (!usedTextures.Contains(tex))
                                {
                                    usedTextures.Add(tex);
                                }
                            }
                            Report.ReportLog("Finished exporting mesh to " + dest);
                        }
                        catch (Exception ex)
                        {
                            Report.ReportLog("Error exporting mesh: " + ex.Message);
                        }
                    }
                }

                foreach (string tex in usedTextures)
                {
                    rem.ExportTexture(tex, parser.RemPath, dir.FullName);
                }
            }
Example #14
0
        public static void RemoveMesh(remParser parser, remMesh mesh)
        {
            parser.MESC.RemoveChild(mesh);
            mesh.frame = null;

            remSkin skin = FindSkin(mesh.name, parser.SKIC);

            if (skin != null)
            {
                parser.SKIC.RemoveChild(skin);
            }
        }
Example #15
0
File: Fbx.cs Project: kkdevs/sb3u
            public void ConvertAnimation(reaANICsection animSection, remParser parser)
            {
                ImportedSampledAnimation anim = new ImportedSampledAnimation();

                anim.TrackList = new List <ImportedAnimationSampledTrack>(animSection.Count);
                foreach (reaAnimationTrack track in animSection)
                {
                    remBone boneFrame  = rem.FindFrame(track.boneFrame, parser.BONC.rootFrame);
                    bool    isTopFrame = boneFrame != null && boneFrame.Parent == parser.BONC.rootFrame;
                    ImportedAnimationSampledTrack iTrack = ConvertTrack(track, isTopFrame);
                    anim.TrackList.Add(iTrack);
                }
                AnimationList.Add(anim);
            }
Example #16
0
        private AnimationFrame CreateHierarchy(remParser parser, remMesh mesh, Device device, out List <AnimationFrame> meshFrames)
        {
            meshFrames = new List <AnimationFrame>(1);
            HashSet <string> extractFrames = rem.SearchHierarchy(parser, mesh);

#if !DONT_MIRROR
            Matrix orignalMatrix = parser.BONC.rootFrame.matrix;
            parser.BONC.rootFrame.matrix *= Matrix.Scaling(1f, 1f, -1f);
#endif
            AnimationFrame rootFrame = CreateFrame(parser.BONC.rootFrame, parser, extractFrames, mesh, device, Matrix.Identity, meshFrames);
            SetupBoneMatrices(rootFrame, rootFrame);
#if !DONT_MIRROR
            parser.BONC.rootFrame.matrix = orignalMatrix;
#endif
            return(rootFrame);
        }
Example #17
0
        public void AddFrame(remBone srcFrame, remParser srcParser, int destParentIdx)
        {
            List<remMaterial> materialClones = new List<remMaterial>(srcParser.MATC.Count);
            List<remMesh> meshClones = new List<remMesh>(srcParser.MESC.Count);
            List<remSkin> skinClones = new List<remSkin>(srcParser.SKIC.Count);
            if (srcFrame == null)
            {
                srcFrame = srcParser.BONC.rootFrame;
            }
            var newFrame = srcFrame.Clone(true, true, srcParser, materialClones, meshClones, skinClones);

            AddFrame(newFrame, destParentIdx);

            PullNewMaterials(materialClones);
            Parser.MESC.ChildList.AddRange(meshClones);
            Parser.SKIC.ChildList.AddRange(skinClones);
        }
Example #18
0
File: Fbx.cs Project: kkdevs/sb3u
 public REMConverter(remParser parser, List <remMesh> meshes)
 {
     FrameList = new List <ImportedFrame>();
     ConvertFrames(parser.BONC.rootFrame);
     foreach (ImportedFrame frame in FrameList[0])
     {
         if (rem.FindMesh(new remId(frame.Name), parser.MESC) != null)
         {
             frame.Matrix = Matrix.Identity;
         }
         else
         {
             frame.Matrix *= Matrix.Scaling(1f, 1f, -1f);
         }
     }
     ConvertMeshes(meshes, parser);
     AnimationList = new List <ImportedAnimation>();
 }
Example #19
0
        public void MergeFrame(remBone srcFrame, remParser srcParser, int destParentIdx)
        {
            List <remMaterial> materialClones = new List <remMaterial>(srcParser.MATC.Count);
            List <remMesh>     meshClones     = new List <remMesh>(srcParser.MESC.Count);
            List <remSkin>     skinClones     = new List <remSkin>(srcParser.SKIC.Count);

            if (srcFrame == null)
            {
                srcFrame = srcParser.BONC.rootFrame;
            }
            var newFrame = srcFrame.Clone(true, true, srcParser, materialClones, meshClones, skinClones);

            MergeFrame(newFrame, destParentIdx);

            PullNewMaterials(materialClones);
            Parser.MESC.ChildList.AddRange(meshClones);
            Parser.SKIC.ChildList.AddRange(skinClones);
        }
Example #20
0
        public static void ExportMqo([DefaultVar] remParser parser, object[] meshNames, string dirPath, bool singleMqo, bool worldCoords)
        {
            List <remMesh> meshes = new List <remMesh>(meshNames.Length);

            foreach (string meshName in Utility.Convert <string>(meshNames))
            {
                remMesh mesh = rem.FindMesh(new remId(meshName), parser.MESC);
                if (mesh != null)
                {
                    meshes.Add(mesh);
                }
                else
                {
                    Report.ReportLog("Mesh " + meshName + " not found");
                }
            }
            Mqo.Exporter.Export(dirPath, parser, meshes, singleMqo, worldCoords);
        }
Example #21
0
File: Fbx.cs Project: kkdevs/sb3u
        public static void ExportFbx([DefaultVar] remParser parser, object[] meshNames, object[] reaParsers, int startKeyframe, int endKeyframe, bool linear, bool EulerFilter, double filterPrecision, string path, string exportFormat, bool allFrames, bool skins, bool compatibility)
        {
            List <reaParser> reaParserList = null;

            if (reaParsers != null)
            {
                reaParserList = new List <reaParser>(Utility.Convert <reaParser>(reaParsers));
            }

            List <string>  meshStrList = new List <string>(Utility.Convert <string>(meshNames));
            List <remMesh> meshes      = new List <remMesh>(meshStrList.Count);

            foreach (string meshName in meshStrList)
            {
                remMesh mesh = rem.FindMesh(new remId(meshName), parser.MESC);
                if (mesh != null)
                {
                    meshes.Add(mesh);
                }
                else
                {
                    Report.ReportLog("Mesh " + meshName + " not found.");
                }
            }

            REMConverter imp = new REMConverter(parser, meshes);

            if (reaParserList != null)
            {
                foreach (reaParser reaParser in reaParserList)
                {
                    imp.ConvertAnimation(reaParser.ANIC, parser);
                }
            }

            FbxUtility.Export(path, imp, startKeyframe, endKeyframe, linear, EulerFilter, (float)filterPrecision, exportFormat, allFrames, false, skins, compatibility);
        }
Example #22
0
            private static List <string> Export(string dest, remParser parser, List <remMesh> meshes, bool worldCoords)
            {
                List <string> usedTextures = new List <string>(parser.MATC.Count);
                DirectoryInfo dir          = new DirectoryInfo(Path.GetDirectoryName(dest));

                if (!dir.Exists)
                {
                    dir.Create();
                }

                List <rem.Mesh> convertedMeshes = new List <rem.Mesh>(meshes.Count);
                List <int>      materialList    = new List <int>(parser.MATC.Count);

                using (StreamWriter writer = new StreamWriter(dest, false))
                {
                    for (int i = 0; i < meshes.Count; i++)
                    {
                        rem.Mesh meshListSome = new rem.Mesh(meshes[i], null);
                        convertedMeshes.Add(meshListSome);
                        for (int j = 0; j < meshListSome.Count; j++)
                        {
                            rem.Submesh meshObj = meshListSome[j];
                            remMaterial mat     = rem.FindMaterial(meshObj.MaterialName, parser.MATC);
                            if (mat != null)
                            {
                                int meshObjMatIdx = parser.MATC.IndexOf(mat);
                                if (!materialList.Contains(meshObjMatIdx))
                                {
                                    materialList.Add(meshObjMatIdx);
                                }
                            }
                            else
                            {
                                Report.ReportLog("Warning: Mesh " + meshes[i].name + " Object " + j + " has an invalid material");
                            }
                        }
                    }

                    writer.WriteLine("Metasequoia Document");
                    writer.WriteLine("Format Text Ver 1.0");
                    writer.WriteLine();
                    writer.WriteLine("Material " + materialList.Count + " {");
                    foreach (int matIdx in materialList)
                    {
                        remMaterial mat        = parser.MATC[matIdx];
                        string      s          = "\t\"" + mat.name + "\" col(0.800 0.800 0.800 1.000) dif(0.500) amb(0.100) emi(0.500) spc(0.100) power(30.00)";
                        string      matTexName = mat.texture;
                        if (matTexName != null)
                        {
                            s += " tex(\"" + Path.GetFileName(matTexName) + "\")";
                        }
                        writer.WriteLine(s);
                    }
                    writer.WriteLine("}");

                    Random rand = new Random();
                    for (int i = 0; i < meshes.Count; i++)
                    {
                        remBone parent    = rem.FindFrame(meshes[i].frame, parser.BONC.rootFrame);
                        float   scale     = Math.Abs(parent.matrix.M11);
                        Matrix  transform = Matrix.Scaling(-1f, 1f, 1f);
                        if (worldCoords)
                        {
                            while (parent != parser.BONC.rootFrame)
                            {
                                transform *= parent.matrix;
                                parent     = parent.Parent as remBone;
                            }
                        }

                        string meshName = meshes[i].name;
                        if (scale != 1f)
                        {
                            meshName += "(Scale=" + scale.ToString() + ")";
                        }
                        rem.Mesh meshListSome = convertedMeshes[i];
                        for (int j = 0; j < meshListSome.Count; j++)
                        {
                            rem.Submesh meshObj   = meshListSome[j];
                            remMaterial mat       = rem.FindMaterial(meshObj.MaterialName, parser.MATC);
                            int         mqoMatIdx = -1;
                            if (mat != null)
                            {
                                int meshObjMatIdx = parser.MATC.IndexOf(mat);
                                mqoMatIdx = materialList.IndexOf(meshObjMatIdx);
                            }
                            float[] color = new float[3];
                            for (int k = 0; k < color.Length; k++)
                            {
                                color[k] = (float)((rand.NextDouble() / 2) + 0.5);
                            }

                            string mqoName = meshName + "[" + j + "]";
                            if (worldCoords)
                            {
                                mqoName += "[W]";
                            }
                            writer.WriteLine("Object \"" + mqoName + "\" {");
                            writer.WriteLine("\tshading 1");
                            writer.WriteLine("\tcolor " + color[0].ToFloatString() + " " + color[1].ToFloatString() + " " + color[2].ToFloatString());
                            writer.WriteLine("\tcolor_type 1");

                            List <ImportedVertex> vertList = worldCoords ?
                                                             rem.ImportedVertexListUnskinnedWorld(meshObj.VertexList, transform)
                                                                :
                                                             rem.ImportedVertexListUnskinned(meshObj.VertexList, scale);
                            List <ImportedFace> faceList = rem.ImportedFaceList(meshObj.FaceList);

                            SB3Utility.Mqo.ExporterCommon.WriteMeshObject(writer, vertList, faceList, mqoMatIdx, null);
                            writer.WriteLine("}");
                        }
                    }
                    writer.WriteLine("Eof");
                }

                foreach (int matIdx in materialList)
                {
                    remMaterial mat        = parser.MATC[matIdx];
                    string      matTexName = mat.texture;
                    if (matTexName != null && !usedTextures.Contains(matTexName))
                    {
                        usedTextures.Add(matTexName);
                    }
                }
                return(usedTextures);
            }
Example #23
0
        public static void RemoveSubmesh(remParser parser, remMesh mesh, int submeshIdx)
        {
            List <int> newFaces     = new List <int>(mesh.numFaces * 3);
            List <int> newFaceMarks = new List <int>(mesh.numFaces);

            bool[] usedVertices = new bool[mesh.numVertices];
            for (int i = 0; i < mesh.faceMarks.Length; i++)
            {
                if (mesh.faceMarks[i] != submeshIdx)
                {
                    newFaceMarks.Add(mesh.faceMarks[i] < submeshIdx ? mesh.faceMarks[i] : mesh.faceMarks[i] - 1);

                    for (int j = i * 3; j < i * 3 + 3; j++)
                    {
                        int vertIdx = mesh.faces[j];
                        newFaces.Add(vertIdx);
                        usedVertices[vertIdx] = true;
                    }
                }
            }
            int[]            vertIdxMap = new int[mesh.numVertices];
            List <remVertex> vertList   = new List <remVertex>(mesh.numVertices);
            int numNewVerts             = 0;

            for (int i = 0; i < mesh.numVertices; i++)
            {
                if (usedVertices[i])
                {
                    vertIdxMap[i] = numNewVerts++;
                    vertList.Add(mesh.vertices[i]);
                }
            }

            mesh.vertices = vertList.ToArray();
            for (int i = 0; i < newFaces.Count; i++)
            {
                newFaces[i] = vertIdxMap[newFaces[i]];
            }
            mesh.faces     = newFaces.ToArray();
            mesh.faceMarks = newFaceMarks.ToArray();
            mesh.materials.RemoveAt(submeshIdx);

            remSkin skin = rem.FindSkin(mesh.name, parser.SKIC);

            if (skin != null)
            {
                for (int i = 0; i < skin.Count; i++)
                {
                    remBoneWeights          bw             = skin[i];
                    Dictionary <int, float> newBoneWeights = new Dictionary <int, float>();
                    for (int j = 0; j < bw.numVertIdxWts; j++)
                    {
                        int oldVertIdx = bw.vertexIndices[j];
                        if (usedVertices[oldVertIdx])
                        {
                            newBoneWeights.Add(vertIdxMap[oldVertIdx], bw.vertexWeights[j]);
                        }
                    }
                    if (newBoneWeights.Count > 0)
                    {
                        bw.vertexIndices = new int[newBoneWeights.Count];
                        bw.vertexWeights = new float[newBoneWeights.Count];
                        newBoneWeights.Keys.CopyTo(bw.vertexIndices, 0);
                        newBoneWeights.Values.CopyTo(bw.vertexWeights, 0);
                    }
                    else
                    {
                        skin.RemoveChild(i);
                        i--;
                    }
                }
            }
        }
Example #24
0
        public void HighlightBone(remParser parser, remMesh remMesh, int boneIdx, bool show)
        {
            List<List<remVertex>> submeshVertLists = new List<List<remVertex>>(remMesh.numMats);
            List<List<ushort>> submeshFaceLists = new List<List<ushort>>(remMesh.numMats);
            List<int[]> submeshVertIndices = new List<int[]>(remMesh.numMats);
            SplitMesh(remMesh, submeshVertLists, submeshFaceLists, submeshVertIndices);
            remSkin boneList = rem.FindSkin(remMesh.name, parser.SKIC);

            int submeshIdx = 0;
            for (AnimationMeshContainer mesh = (AnimationMeshContainer)meshFrames[0].MeshContainer;
                 mesh != null;
                 mesh = (AnimationMeshContainer)mesh.NextMeshContainer, submeshIdx++)
            {
                if (mesh.MeshData != null && mesh.MeshData.Mesh != null)
                {
                    List<remVertex> vertexList = submeshVertLists[submeshIdx];
                    byte[][] vertexBoneIndices = null;
                    float[][] vertexWeights = ConvertVertexWeights(vertexList, submeshVertIndices[submeshIdx], boneList, out vertexBoneIndices);
                    FillVertexBuffer(mesh.MeshData.Mesh, vertexList, vertexWeights, vertexBoneIndices, show ? boneIdx : -1);
                }
                if (mesh.BoneLines != null)
                {
                    for (int j = 0; j < BoneObjSize; j++)
                    {
                        mesh.BoneLines[boneIdx * BoneObjSize + j].Color = show ? Color.Crimson.ToArgb(): Color.CornflowerBlue.ToArgb();
                    }
                }
            }
        }
Example #25
0
        public static void ReplaceMesh(remBone frame, remParser parser, WorkspaceMesh mesh, List <ImportedMaterial> materials, List <ImportedTexture> textures, bool merge, CopyMeshMethod normalsMethod, CopyMeshMethod bonesMethod, bool meshFrameCorrection)
        {
            remMesh frameREMMesh = rem.FindMesh(frame, parser.MESC);

            int startPos = 0;

            if (meshFrameCorrection)
            {
                // frame.matrix = Matrix.Scaling(-1f, 1f, 1f) * Matrix.RotationYawPitchRoll(0f, (float)(Math.PI / 2), (float)Math.PI);
                frame.matrix     = Matrix.Identity;
                frame.matrix.M22 = frame.matrix.M33 = 0f;
                frame.matrix.M23 = frame.matrix.M32 = 1f;
                startPos         = mesh.Name.IndexOf("(Scale");
                if (startPos > 0)
                {
                    int   endPos = mesh.Name.IndexOf(')');
                    float scale;
                    if (Single.TryParse(mesh.Name.Substring(startPos + 7, endPos - startPos - 7), out scale))
                    {
                        frame.matrix *= Matrix.Scaling(new Vector3(scale));
                    }
                    remId newFrameName = new remId(mesh.Name.Substring(0, startPos));
                    if (newFrameName != frame.name)
                    {
                        if (rem.FindFrame(newFrameName, parser.BONC.rootFrame) == null)
                        {
                            frame.name = newFrameName;
                        }
                        else
                        {
                            Report.ReportLog("Warning! Cant rename frame (and mesh) " + mesh.Name + " automatically to " + newFrameName + ".");
                        }
                    }
                }
            }

            Matrix  transform      = Matrix.Scaling(-1f, 1f, 1f);
            remBone transformFrame = frame;

            while (transformFrame != parser.BONC.rootFrame)
            {
                transform     *= transformFrame.matrix;
                transformFrame = transformFrame.Parent as remBone;
            }
            transform.Invert();

            string[] materialNames;
            int[]    indices;
            bool[]   worldCoords;
            bool[]   replaceSubmeshesOption;
            remMesh  newREMMesh = CreateMesh(mesh, out materialNames, out indices, out worldCoords, out replaceSubmeshesOption);

            if (startPos > 0)
            {
                newREMMesh.name = frame.name;
            }
            Mesh newMesh = new Mesh(newREMMesh, CreateBoneList(mesh, transform));

            remSkin frameMeshSkin = null;
            Mesh    frameMesh     = null;

            if (frameREMMesh != null)
            {
                newMesh.name  = frameREMMesh.name;
                frameMeshSkin = rem.FindSkin(frameREMMesh.name, parser.SKIC);
                frameMesh     = new Mesh(frameREMMesh, frameMeshSkin);
            }

            Submesh[]      replaceSubmeshes = frameMesh != null ? new Submesh[frameMesh.Count] : null;
            List <Submesh> addSubmeshes     = new List <Submesh>(newMesh.Count);

            for (int i = 0; i < newMesh.Count; i++)
            {
                remMaterial mat = rem.FindMaterial(new remId(materialNames[i]), parser.MATC);
                if (materials != null)
                {
                    if (mat == null)
                    {
                        mat = CreateMaterial(ImportedHelpers.FindMaterial(materialNames[i], materials));
                        parser.MATC.AddChild(mat);
                    }

/*					if (textures != null)
 *                                      {
 *                                              string texName = materials[i].Textures[0];
 *                                              remMaterial texMat = rem.FindMaterial(parser.MATC, new remId(texName));
 *                                              if (texMat == null)
 *                                              {
 *                                                      for (int k = 0; k < textures.Count; k++)
 *                                                      {
 *                                                              if (textures[k].Name == texName)
 *                                                              {
 * //									texMat = CreateTexture(textures[k], Path.GetDirectoryName(parser.ODFPath));
 *                                                                      break;
 *                                                              }
 *                                                      }
 *                                              }
 *                                      }*/
                }

                Submesh newSubmesh = newMesh[i];
                if (mat != null)
                {
                    newSubmesh.MaterialName = mat.name;
                }

                if (worldCoords[i])
                {
                    List <remVertex> newVertexList = newSubmesh.VertexList;
                    for (int j = 0; j < newVertexList.Count; j++)
                    {
                        newVertexList[j].Position = Vector3.TransformCoordinate(newVertexList[j].Position, transform);
                    }
                }

                Submesh baseSubmesh            = null;
                List <remBoneWeights> newBones = null;
                int idx = indices[i];
                if ((frameMesh != null) && (idx >= 0) && (idx < frameMesh.Count))
                {
                    baseSubmesh = frameMesh[idx];

                    if ((bonesMethod == CopyMeshMethod.CopyOrder) || (bonesMethod == CopyMeshMethod.CopyNear))
                    {
                        List <remBoneWeights> baseBones = baseSubmesh.BoneList;
                        if (baseBones != null)
                        {
                            newBones = new List <remBoneWeights>(baseBones.Count);
                            foreach (remBoneWeights boneWeights in baseBones)
                            {
                                remBoneWeights copy = boneWeights.Clone();
                                newBones.Add(copy);
                            }
                            newSubmesh.BoneList = newBones;
                        }
                    }
                    else if (bonesMethod == CopyMeshMethod.Replace)
                    {
                        newBones = newSubmesh.BoneList;
                    }
                }
                else
                {
                    newBones = newSubmesh.BoneList;
                }

                if (baseSubmesh != null)
                {
                    if (normalsMethod == CopyMeshMethod.CopyOrder)
                    {
                        rem.CopyNormalsOrder(baseSubmesh.VertexList, newSubmesh.VertexList);
                    }
                    else if (normalsMethod == CopyMeshMethod.CopyNear)
                    {
                        rem.CopyNormalsNear(baseSubmesh.VertexList, newSubmesh.VertexList);
                    }

                    if (bonesMethod == CopyMeshMethod.CopyOrder)
                    {
                        rem.CopyBonesOrder(baseSubmesh.VertexList, newSubmesh.VertexList, newBones);
                    }
                    else if (bonesMethod == CopyMeshMethod.CopyNear)
                    {
                        rem.CopyBonesNear(baseSubmesh.VertexList, newSubmesh.VertexList, newBones);
                    }
                }

                if ((baseSubmesh != null) && merge && replaceSubmeshesOption[i])
                {
                    replaceSubmeshes[idx] = newSubmesh;
                }
                else
                {
                    addSubmeshes.Add(newSubmesh);
                }
            }

            if ((frameMesh != null) && merge)
            {
                newMesh.ChildList.Clear();
                newMesh.ChildList.Capacity = replaceSubmeshes.Length + addSubmeshes.Count;
                for (int i = 0, submeshesRemoved = 0; i < replaceSubmeshes.Length; i++)
                {
                    if (replaceSubmeshes[i] == null)
                    {
                        Submesh newSubmesh = frameMesh[i - submeshesRemoved++];
                        newMesh.AddChild(newSubmesh);
                    }
                    else
                    {
                        newMesh.AddChild(replaceSubmeshes[i]);
                    }
                }
                newMesh.ChildList.AddRange(addSubmeshes);
            }

            remSkin skin;

            newREMMesh       = newMesh.CreateMesh(out skin);
            newREMMesh.frame = frame.name;
            if (frameREMMesh != null)
            {
                CopyUnknowns(frameREMMesh, newREMMesh);
                parser.MESC.InsertChild(parser.MESC.IndexOf(frameREMMesh), newREMMesh);

                RemoveMesh(parser, frameREMMesh);
            }
            else
            {
                CreateUnknowns(newREMMesh);
                parser.MESC.AddChild(newREMMesh);
            }
            if (skin.Count > 0)
            {
                parser.SKIC.AddChild(skin);
            }
        }
Example #26
0
            private static List<string> Export(string dest, remParser parser, List<remMesh> meshes, bool worldCoords)
            {
                List<string> usedTextures = new List<string>(parser.MATC.Count);
                DirectoryInfo dir = new DirectoryInfo(Path.GetDirectoryName(dest));
                if (!dir.Exists)
                {
                    dir.Create();
                }

                List<rem.Mesh> convertedMeshes = new List<rem.Mesh>(meshes.Count);
                List<int> materialList = new List<int>(parser.MATC.Count);
                using (StreamWriter writer = new StreamWriter(dest, false))
                {
                    for (int i = 0; i < meshes.Count; i++)
                    {
                        rem.Mesh meshListSome = new rem.Mesh(meshes[i], null);
                        convertedMeshes.Add(meshListSome);
                        for (int j = 0; j < meshListSome.Count; j++)
                        {
                            rem.Submesh meshObj = meshListSome[j];
                            remMaterial mat = rem.FindMaterial(meshObj.MaterialName, parser.MATC);
                            if (mat != null)
                            {
                                int meshObjMatIdx = parser.MATC.IndexOf(mat);
                                if (!materialList.Contains(meshObjMatIdx))
                                {
                                    materialList.Add(meshObjMatIdx);
                                }
                            }
                            else
                            {
                                Report.ReportLog("Warning: Mesh " + meshes[i].name + " Object " + j + " has an invalid material");
                            }
                        }
                    }

                    writer.WriteLine("Metasequoia Document");
                    writer.WriteLine("Format Text Ver 1.0");
                    writer.WriteLine();
                    writer.WriteLine("Material " + materialList.Count + " {");
                    foreach (int matIdx in materialList)
                    {
                        remMaterial mat = parser.MATC[matIdx];
                        string s = "\t\"" + mat.name + "\" col(0.800 0.800 0.800 1.000) dif(0.500) amb(0.100) emi(0.500) spc(0.100) power(30.00)";
                        string matTexName = mat.texture;
                        if (matTexName != null)
                        {
                            s += " tex(\"" + Path.GetFileName(matTexName) + "\")";
                        }
                        writer.WriteLine(s);
                    }
                    writer.WriteLine("}");

                    Random rand = new Random();
                    for (int i = 0; i < meshes.Count; i++)
                    {
                        remBone parent = rem.FindFrame(meshes[i].frame, parser.BONC.rootFrame);
                        float scale = Math.Abs(parent.matrix.M11);
                        Matrix transform = Matrix.Scaling(-1f, 1f, 1f);
                        if (worldCoords)
                        {
                            while (parent != parser.BONC.rootFrame)
                            {
                                transform *= parent.matrix;
                                parent = parent.Parent as remBone;
                            }
                        }

                        string meshName = meshes[i].name;
                        if (scale != 1f)
                        {
                            meshName += "(Scale=" + scale.ToString() + ")";
                        }
                        rem.Mesh meshListSome = convertedMeshes[i];
                        for (int j = 0; j < meshListSome.Count; j++)
                        {
                            rem.Submesh meshObj = meshListSome[j];
                            remMaterial mat = rem.FindMaterial(meshObj.MaterialName, parser.MATC);
                            int mqoMatIdx = -1;
                            if (mat != null)
                            {
                                int meshObjMatIdx = parser.MATC.IndexOf(mat);
                                mqoMatIdx = materialList.IndexOf(meshObjMatIdx);
                            }
                            float[] color = new float[3];
                            for (int k = 0; k < color.Length; k++)
                            {
                                color[k] = (float)((rand.NextDouble() / 2) + 0.5);
                            }

                            string mqoName = meshName + "[" + j + "]";
                            if (worldCoords)
                            {
                                mqoName += "[W]";
                            }
                            writer.WriteLine("Object \"" + mqoName + "\" {");
                            writer.WriteLine("\tshading 1");
                            writer.WriteLine("\tcolor " + color[0].ToFloatString() + " " + color[1].ToFloatString() + " " + color[2].ToFloatString());
                            writer.WriteLine("\tcolor_type 1");

                            List<ImportedVertex> vertList = worldCoords ?
                                rem.ImportedVertexListUnskinnedWorld(meshObj.VertexList, transform)
                                :
                                rem.ImportedVertexListUnskinned(meshObj.VertexList, scale);
                            List<ImportedFace> faceList = rem.ImportedFaceList(meshObj.FaceList);

                            SB3Utility.Mqo.ExporterCommon.WriteMeshObject(writer, vertList, faceList, mqoMatIdx, null);
                            writer.WriteLine("}");
                        }
                    }
                    writer.WriteLine("Eof");
                }

                foreach (int matIdx in materialList)
                {
                    remMaterial mat = parser.MATC[matIdx];
                    string matTexName = mat.texture;
                    if (matTexName != null && !usedTextures.Contains(matTexName))
                    {
                        usedTextures.Add(matTexName);
                    }
                }
                return usedTextures;
            }
Example #27
0
        private AnimationFrame CreateFrame(remBone frame, remParser parser, HashSet <string> extractFrames, remMesh mesh, Device device, Matrix combinedParent, List <AnimationFrame> meshFrames)
        {
            AnimationFrame animationFrame = new AnimationFrame();

            animationFrame.Name = frame.name.ToString();
            animationFrame.TransformationMatrix = frame.matrix;
            animationFrame.OriginalTransform    = animationFrame.TransformationMatrix;
            animationFrame.CombinedTransform    = combinedParent * animationFrame.TransformationMatrix;

            if (frame.name == mesh.frame)
            {
                ExtendedMaterial[] materials = new ExtendedMaterial[mesh.numMats];

                List <List <remVertex> > submeshVertLists   = new List <List <remVertex> >(mesh.numMats);
                List <List <ushort> >    submeshFaceLists   = new List <List <ushort> >(mesh.numMats);
                List <int[]>             submeshVertIndices = new List <int[]>(mesh.numMats);
                SplitMesh(mesh, submeshVertLists, submeshFaceLists, submeshVertIndices);

                remSkin       boneList        = rem.FindSkin(mesh.name, parser.SKIC);
                bool          skinned         = boneList != null;
                int           numBones        = skinned ? boneList.Count : 0;
                List <string> boneNamesList   = new List <string>(numBones);
                List <Matrix> boneOffsetsList = new List <Matrix>(numBones);
                for (int boneIdx = 0; boneIdx < numBones; boneIdx++)
                {
                    boneNamesList.Add(boneList[boneIdx].bone.ToString());
                    boneOffsetsList.Add(boneList[boneIdx].matrix);
                }
                List <string> boneFrameParentNames    = new List <string>(numBones);
                List <Matrix> boneFrameParentMatrices = new List <Matrix>(numBones);
                for (int boneIdx = 0; boneIdx < numBones; boneIdx++)
                {
                    remBone boneFrame = rem.FindFrame(boneList[boneIdx].bone, parser.BONC.rootFrame);
                    if (boneFrame == null)
                    {
                        continue;
                    }
                    remBone boneFrameParent = boneFrame.Parent;
                    if (!boneNamesList.Contains(boneFrameParent.name) && !boneFrameParentNames.Contains(boneFrameParent.name))
                    {
                        boneFrameParentNames.Add(boneFrameParent.name);
                        Matrix incompleteMeshFrameCorrection = Matrix.Invert(frame.matrix);
                        boneFrameParentMatrices.Add(incompleteMeshFrameCorrection * Matrix.Invert(boneFrame.matrix) * boneList[boneIdx].matrix);
                    }
                }
                boneNamesList.AddRange(boneFrameParentNames);
                string[] boneNames = boneNamesList.ToArray();
                boneOffsetsList.AddRange(boneFrameParentMatrices);
                Matrix[] boneOffsets = boneOffsetsList.ToArray();

                AnimationMeshContainer[] meshContainers = new AnimationMeshContainer[submeshFaceLists.Count];
                Vector3 min = new Vector3(Single.MaxValue);
                Vector3 max = new Vector3(Single.MinValue);
                for (int i = 0; i < submeshFaceLists.Count; i++)
                {
                    List <ushort>    faceList   = submeshFaceLists[i];
                    List <remVertex> vertexList = submeshVertLists[i];

                    Mesh animationMesh = new Mesh(device, faceList.Count, vertexList.Count, MeshFlags.Managed, PositionBlendWeightsIndexedNormalTexturedColoured.Format);

                    using (DataStream indexStream = animationMesh.LockIndexBuffer(LockFlags.None))
                    {
                        for (int j = 0; j < faceList.Count; j++)
                        {
                            indexStream.Write(faceList[j]);
                        }
                        animationMesh.UnlockIndexBuffer();
                    }

                    byte[][]  vertexBoneIndices = null;
                    float[][] vertexWeights     = ConvertVertexWeights(vertexList, submeshVertIndices[i], boneList, out vertexBoneIndices);
                    FillVertexBuffer(animationMesh, vertexList, vertexWeights, vertexBoneIndices, -1);

                    var normalLines = new PositionBlendWeightsIndexedColored[vertexList.Count * 2];
                    for (int j = 0; j < vertexList.Count; j++)
                    {
                        remVertex vertex      = vertexList[j];
                        Vector3   position    = vertex.Position;
                        Vector3   normal      = vertex.Normal;
                        float[]   boneWeights = vertexWeights[j];

                        normalLines[j * 2]       = new PositionBlendWeightsIndexedColored(position, boneWeights, vertexBoneIndices[j], Color.Coral.ToArgb());
                        normalLines[(j * 2) + 1] = new PositionBlendWeightsIndexedColored(position + normal, boneWeights, vertexBoneIndices[j], Color.Blue.ToArgb());

#if !DONT_MIRROR
                        position.Z *= -1f;
#endif
                        min = Vector3.Minimize(min, position);
                        max = Vector3.Maximize(max, position);
                    }

                    AnimationMeshContainer meshContainer = new AnimationMeshContainer();
                    meshContainer.Name        = animationFrame.Name;
                    meshContainer.MeshData    = new MeshData(animationMesh);
                    meshContainer.NormalLines = normalLines;
                    meshContainer.BoneNames   = boneNames;
                    meshContainer.BoneOffsets = boneOffsets;
                    meshContainers[i]         = meshContainer;

                    remMaterial mat = rem.FindMaterial(mesh.materials[i], parser.MATC);
                    if (mat != null)
                    {
                        Material material3D = new Material();
                        material3D.Ambient  = new Color4(mat.ambient);
                        material3D.Diffuse  = new Color4(mat.diffuse);
                        material3D.Emissive = new Color4(mat.emissive);
                        material3D.Specular = new Color4(mat.specular);
                        material3D.Power    = mat.specularPower;
                        int matIdx = parser.MATC.IndexOf(mat);
                        Materials[matIdx]           = material3D;
                        meshContainer.MaterialIndex = matIdx;

                        int texIdx = 0;
                        if (mat.texture != null && !TextureDic.TryGetValue(mat.texture.ToString(), out texIdx))
                        {
                            ImportedTexture importedTex = null;
                            if (!ImportedTextures.TryGetValue(mat.texture.ToString(), out importedTex))
                            {
                                importedTex = rem.ImportedTexture(mat.texture, parser.RemPath, true);
                                if (importedTex == null)
                                {
                                    Report.ReportLog("Export textures of TEXH.FPK!");
                                    continue;
                                }
                                ImportedTextures.Add(mat.texture.ToString(), importedTex);
                            }
                            Texture memTex = Texture.FromMemory(device, importedTex.Data);
                            texIdx = TextureDic.Count;
                            TextureDic.Add(mat.texture.ToString(), texIdx);
                            Textures.Add(memTex);
                        }
                        meshContainer.TextureIndex = texIdx;
                    }
                }

                for (int i = 0; i < (meshContainers.Length - 1); i++)
                {
                    meshContainers[i].NextMeshContainer = meshContainers[i + 1];
                }

                min = Vector3.TransformCoordinate(min, animationFrame.CombinedTransform);
                max = Vector3.TransformCoordinate(max, animationFrame.CombinedTransform);
                animationFrame.Bounds        = new BoundingBox(min, max);
                animationFrame.MeshContainer = meshContainers[0];
                meshFrames.Add(animationFrame);
            }

            for (int i = 0; i < frame.Count; i++)
            {
                remBone child = frame[i];
                if (extractFrames.Contains(child.name.ToString()))
                {
                    AnimationFrame childAnimationFrame = CreateFrame(child, parser, extractFrames, mesh, device, animationFrame.CombinedTransform, meshFrames);
                    childAnimationFrame.Parent = animationFrame;
                    animationFrame.AppendChild(childAnimationFrame);
                }
            }

            numFrames++;
            return(animationFrame);
        }
Example #28
0
        public static void RemoveMesh(remParser parser, remMesh mesh)
        {
            parser.MESC.RemoveChild(mesh);
            mesh.frame = null;

            remSkin skin = FindSkin(mesh.name, parser.SKIC);
            if (skin != null)
            {
                parser.SKIC.RemoveChild(skin);
            }
        }
Example #29
0
 public void Dispose()
 {
     Textures.Clear();
     Parser = null;
 }
Example #30
0
        public static void ReplaceMaterial(remParser parser, ImportedMaterial material)
        {
            remMaterial mat = CreateMaterial(material);

            bool found = false;
            for (int i = 0; i < parser.MATC.Count; i++)
            {
                if (parser.MATC[i].name == material.Name)
                {
                    remMaterial original = parser.MATC[i];
                    CopyUnknown(original, mat);

                    parser.MATC.RemoveChild(i);
                    parser.MATC.InsertChild(i, mat);
                    found = true;
                    break;
                }
            }

            if (!found)
            {
                CreateUnknown(mat);
                parser.MATC.AddChild(mat);
            }
        }
Example #31
0
        public void MergeTexture(string tex, remParser srcParser)
        {
            String src_TEXH_folder = rem.TexturePathFromREM(srcParser.RemPath);
            if (src_TEXH_folder == null)
            {
                Report.ReportLog("TEXH folder could not be located.");
                return;
            }
            String texh_folder = rem.TexturePathFromREM(Parser.RemPath);
            if (texh_folder == null)
            {
                Report.ReportLog("TEXH folder could not be located.");
                return;
            }

            if (src_TEXH_folder != texh_folder)
            {
                ImportedTexture impTex = new ImportedTexture(src_TEXH_folder + @"\" + tex);
                string newTex = rem.CreateTexture(impTex, texh_folder);
                if (!Textures.Contains(newTex))
                {
                    Textures.Add(newTex);
                }
            }
        }
Example #32
0
        private AnimationFrame CreateFrame(remBone frame, remParser parser, HashSet<string> extractFrames, remMesh mesh, Device device, Matrix combinedParent, List<AnimationFrame> meshFrames)
        {
            AnimationFrame animationFrame = new AnimationFrame();
            animationFrame.Name = frame.name.ToString();
            animationFrame.TransformationMatrix = frame.matrix;
            animationFrame.OriginalTransform = animationFrame.TransformationMatrix;
            animationFrame.CombinedTransform = combinedParent * animationFrame.TransformationMatrix;

            if (frame.name == mesh.frame)
            {
                ExtendedMaterial[] materials = new ExtendedMaterial[mesh.numMats];

                List<List<remVertex>> submeshVertLists = new List<List<remVertex>>(mesh.numMats);
                List<List<ushort>> submeshFaceLists = new List<List<ushort>>(mesh.numMats);
                List<int[]> submeshVertIndices = new List<int[]>(mesh.numMats);
                SplitMesh(mesh, submeshVertLists, submeshFaceLists, submeshVertIndices);

                remSkin boneList = rem.FindSkin(mesh.name, parser.SKIC);
                bool skinned = boneList != null;
                int numBones = skinned ? boneList.Count : 0;
                List<string> boneNamesList = new List<string>(numBones);
                List<Matrix> boneOffsetsList = new List<Matrix>(numBones);
                for (int boneIdx = 0; boneIdx < numBones; boneIdx++)
                {
                    boneNamesList.Add(boneList[boneIdx].bone.ToString());
                    boneOffsetsList.Add(boneList[boneIdx].matrix);
                }
                List<string> boneFrameParentNames = new List<string>(numBones);
                List<Matrix> boneFrameParentMatrices = new List<Matrix>(numBones);
                for (int boneIdx = 0; boneIdx < numBones; boneIdx++)
                {
                    remBone boneFrame = rem.FindFrame(boneList[boneIdx].bone, parser.BONC.rootFrame);
                    if (boneFrame == null)
                    {
                        continue;
                    }
                    remBone boneFrameParent = boneFrame.Parent;
                    if (!boneNamesList.Contains(boneFrameParent.name) && !boneFrameParentNames.Contains(boneFrameParent.name))
                    {
                        boneFrameParentNames.Add(boneFrameParent.name);
                        Matrix incompleteMeshFrameCorrection = Matrix.Invert(frame.matrix);
                        boneFrameParentMatrices.Add(incompleteMeshFrameCorrection * Matrix.Invert(boneFrame.matrix) * boneList[boneIdx].matrix);
                    }
                }
                boneNamesList.AddRange(boneFrameParentNames);
                string[] boneNames = boneNamesList.ToArray();
                boneOffsetsList.AddRange(boneFrameParentMatrices);
                Matrix[] boneOffsets = boneOffsetsList.ToArray();

                AnimationMeshContainer[] meshContainers = new AnimationMeshContainer[submeshFaceLists.Count];
                Vector3 min = new Vector3(Single.MaxValue);
                Vector3 max = new Vector3(Single.MinValue);
                for (int i = 0; i < submeshFaceLists.Count; i++)
                {
                    List<ushort> faceList = submeshFaceLists[i];
                    List<remVertex> vertexList = submeshVertLists[i];

                    Mesh animationMesh = new Mesh(device, faceList.Count, vertexList.Count, MeshFlags.Managed, PositionBlendWeightsIndexedNormalTexturedColoured.Format);

                    using (DataStream indexStream = animationMesh.LockIndexBuffer(LockFlags.None))
                    {
                        for (int j = 0; j < faceList.Count; j++)
                        {
                            indexStream.Write(faceList[j]);
                        }
                        animationMesh.UnlockIndexBuffer();
                    }

                    byte[][] vertexBoneIndices = null;
                    float[][] vertexWeights = ConvertVertexWeights(vertexList, submeshVertIndices[i], boneList, out vertexBoneIndices);
                    FillVertexBuffer(animationMesh, vertexList, vertexWeights, vertexBoneIndices, -1);

                    var normalLines = new PositionBlendWeightsIndexedColored[vertexList.Count * 2];
                    for (int j = 0; j < vertexList.Count; j++)
                    {
                        remVertex vertex = vertexList[j];
                        Vector3 position = vertex.Position;
                        Vector3 normal = vertex.Normal;
                        float[] boneWeights = vertexWeights[j];

                        normalLines[j * 2] = new PositionBlendWeightsIndexedColored(position, boneWeights, vertexBoneIndices[j], Color.Coral.ToArgb());
                        normalLines[(j * 2) + 1] = new PositionBlendWeightsIndexedColored(position + normal, boneWeights, vertexBoneIndices[j], Color.Blue.ToArgb());

            #if !DONT_MIRROR
                        position.Z *= -1f;
            #endif
                        min = Vector3.Minimize(min, position);
                        max = Vector3.Maximize(max, position);
                    }

                    AnimationMeshContainer meshContainer = new AnimationMeshContainer();
                    meshContainer.Name = animationFrame.Name;
                    meshContainer.MeshData = new MeshData(animationMesh);
                    meshContainer.NormalLines = normalLines;
                    meshContainer.BoneNames = boneNames;
                    meshContainer.BoneOffsets = boneOffsets;
                    meshContainers[i] = meshContainer;

                    remMaterial mat = rem.FindMaterial(mesh.materials[i], parser.MATC);
                    if (mat != null)
                    {
                        Material material3D = new Material();
                        material3D.Ambient = new Color4(mat.ambient);
                        material3D.Diffuse = new Color4(mat.diffuse);
                        material3D.Emissive = new Color4(mat.emissive);
                        material3D.Specular = new Color4(mat.specular);
                        material3D.Power = mat.specularPower;
                        int matIdx = parser.MATC.IndexOf(mat);
                        Materials[matIdx] = material3D;
                        meshContainer.MaterialIndex = matIdx;

                        int texIdx = 0;
                        if (mat.texture != null && !TextureDic.TryGetValue(mat.texture.ToString(), out texIdx))
                        {
                            ImportedTexture importedTex = null;
                            if (!ImportedTextures.TryGetValue(mat.texture.ToString(), out importedTex))
                            {
                                importedTex = rem.ImportedTexture(mat.texture, parser.RemPath, true);
                                if (importedTex == null)
                                {
                                    Report.ReportLog("Export textures of TEXH.FPK!");
                                    continue;
                                }
                                ImportedTextures.Add(mat.texture.ToString(), importedTex);
                            }
                            Texture memTex = Texture.FromMemory(device, importedTex.Data);
                            texIdx = TextureDic.Count;
                            TextureDic.Add(mat.texture.ToString(), texIdx);
                            Textures.Add(memTex);
                        }
                        meshContainer.TextureIndex = texIdx;
                    }
                }

                for (int i = 0; i < (meshContainers.Length - 1); i++)
                {
                    meshContainers[i].NextMeshContainer = meshContainers[i + 1];
                }

                min = Vector3.TransformCoordinate(min, animationFrame.CombinedTransform);
                max = Vector3.TransformCoordinate(max, animationFrame.CombinedTransform);
                animationFrame.Bounds = new BoundingBox(min, max);
                animationFrame.MeshContainer = meshContainers[0];
                meshFrames.Add(animationFrame);
            }

            for (int i = 0; i < frame.Count; i++)
            {
                remBone child = frame[i];
                if (extractFrames.Contains(child.name.ToString()))
                {
                    AnimationFrame childAnimationFrame = CreateFrame(child, parser, extractFrames, mesh, device, animationFrame.CombinedTransform, meshFrames);
                    childAnimationFrame.Parent = animationFrame;
                    animationFrame.AppendChild(childAnimationFrame);
                }
            }

            numFrames++;
            return animationFrame;
        }
Example #33
0
        public static void RemoveSubmesh(remParser parser, remMesh mesh, int submeshIdx)
        {
            List<int> newFaces = new List<int>(mesh.numFaces * 3);
            List<int> newFaceMarks = new List<int>(mesh.numFaces);
            bool[] usedVertices = new bool[mesh.numVertices];
            for (int i = 0; i < mesh.faceMarks.Length; i++)
            {
                if (mesh.faceMarks[i] != submeshIdx)
                {
                    newFaceMarks.Add(mesh.faceMarks[i] < submeshIdx ? mesh.faceMarks[i] : mesh.faceMarks[i] - 1);

                    for (int j = i * 3; j < i * 3 + 3; j++)
                    {
                        int vertIdx = mesh.faces[j];
                        newFaces.Add(vertIdx);
                        usedVertices[vertIdx] = true;
                    }
                }
            }
            int[] vertIdxMap = new int[mesh.numVertices];
            List<remVertex> vertList = new List<remVertex>(mesh.numVertices);
            int numNewVerts = 0;
            for (int i = 0; i < mesh.numVertices; i++)
            {
                if (usedVertices[i])
                {
                    vertIdxMap[i] = numNewVerts++;
                    vertList.Add(mesh.vertices[i]);
                }
            }

            mesh.vertices = vertList.ToArray();
            for (int i = 0; i < newFaces.Count; i++)
            {
                newFaces[i] = vertIdxMap[newFaces[i]];
            }
            mesh.faces = newFaces.ToArray();
            mesh.faceMarks = newFaceMarks.ToArray();
            mesh.materials.RemoveAt(submeshIdx);

            remSkin skin = rem.FindSkin(mesh.name, parser.SKIC);
            if (skin != null)
            {
                for (int i = 0; i < skin.Count; i++)
                {
                    remBoneWeights bw = skin[i];
                    Dictionary<int, float> newBoneWeights = new Dictionary<int,float>();
                    for (int j = 0; j < bw.numVertIdxWts; j++)
                    {
                        int oldVertIdx = bw.vertexIndices[j];
                        if (usedVertices[oldVertIdx])
                        {
                            newBoneWeights.Add(vertIdxMap[oldVertIdx], bw.vertexWeights[j]);
                        }
                    }
                    if (newBoneWeights.Count > 0)
                    {
                        bw.vertexIndices = new int[newBoneWeights.Count];
                        bw.vertexWeights = new float[newBoneWeights.Count];
                        newBoneWeights.Keys.CopyTo(bw.vertexIndices, 0);
                        newBoneWeights.Values.CopyTo(bw.vertexWeights, 0);
                    }
                    else
                    {
                        skin.RemoveChild(i);
                        i--;
                    }
                }
            }
        }
Example #34
0
 private AnimationFrame CreateHierarchy(remParser parser, remMesh mesh, Device device, out List<AnimationFrame> meshFrames)
 {
     meshFrames = new List<AnimationFrame>(1);
     HashSet<string> extractFrames = rem.SearchHierarchy(parser, mesh);
     #if !DONT_MIRROR
     Matrix orignalMatrix = parser.BONC.rootFrame.matrix;
     parser.BONC.rootFrame.matrix *= Matrix.Scaling(1f, 1f, -1f);
     #endif
     AnimationFrame rootFrame = CreateFrame(parser.BONC.rootFrame, parser, extractFrames, mesh, device, Matrix.Identity, meshFrames);
     SetupBoneMatrices(rootFrame, rootFrame);
     #if !DONT_MIRROR
     parser.BONC.rootFrame.matrix = orignalMatrix;
     #endif
     return rootFrame;
 }
Example #35
0
        public static void ReplaceMesh(remBone frame, remParser parser, WorkspaceMesh mesh, List<ImportedMaterial> materials, List<ImportedTexture> textures, bool merge, CopyMeshMethod normalsMethod, CopyMeshMethod bonesMethod, bool meshFrameCorrection)
        {
            remMesh frameREMMesh = rem.FindMesh(frame, parser.MESC);

            int startPos = 0;
            if (meshFrameCorrection)
            {
                // frame.matrix = Matrix.Scaling(-1f, 1f, 1f) * Matrix.RotationYawPitchRoll(0f, (float)(Math.PI / 2), (float)Math.PI);
                frame.matrix = Matrix.Identity;
                frame.matrix.M22 = frame.matrix.M33 = 0f;
                frame.matrix.M23 = frame.matrix.M32 = 1f;
                startPos = mesh.Name.IndexOf("(Scale");
                if (startPos > 0)
                {
                    int endPos = mesh.Name.IndexOf(')');
                    float scale;
                    if (Single.TryParse(mesh.Name.Substring(startPos + 7, endPos - startPos - 7), out scale))
                    {
                        frame.matrix *= Matrix.Scaling(new Vector3(scale));
                    }
                    remId newFrameName = new remId(mesh.Name.Substring(0, startPos));
                    if (newFrameName != frame.name)
                    {
                        if (rem.FindFrame(newFrameName, parser.BONC.rootFrame) == null)
                        {
                            frame.name = newFrameName;
                        }
                        else
                        {
                            Report.ReportLog("Warning! Cant rename frame (and mesh) " + mesh.Name + " automatically to " + newFrameName + ".");
                        }
                    }
                }
            }

            Matrix transform = Matrix.Scaling(-1f, 1f, 1f);
            remBone transformFrame = frame;
            while (transformFrame != parser.BONC.rootFrame)
            {
                transform *= transformFrame.matrix;
                transformFrame = transformFrame.Parent as remBone;
            }
            transform.Invert();

            string[] materialNames;
            int[] indices;
            bool[] worldCoords;
            bool[] replaceSubmeshesOption;
            remMesh newREMMesh = CreateMesh(mesh, out materialNames, out indices, out worldCoords, out replaceSubmeshesOption);
            if (startPos > 0)
            {
                newREMMesh.name = frame.name;
            }
            Mesh newMesh = new Mesh(newREMMesh, CreateBoneList(mesh, transform));

            remSkin frameMeshSkin = null;
            Mesh frameMesh = null;
            if (frameREMMesh != null)
            {
                newMesh.name = frameREMMesh.name;
                frameMeshSkin = rem.FindSkin(frameREMMesh.name, parser.SKIC);
                frameMesh = new Mesh(frameREMMesh, frameMeshSkin);
            }

            Submesh[] replaceSubmeshes = frameMesh != null ? new Submesh[frameMesh.Count] : null;
            List<Submesh> addSubmeshes = new List<Submesh>(newMesh.Count);
            for (int i = 0; i < newMesh.Count; i++)
            {
                remMaterial mat = rem.FindMaterial(new remId(materialNames[i]), parser.MATC);
                if (materials != null)
                {
                    if (mat == null)
                    {
                        mat = CreateMaterial(ImportedHelpers.FindMaterial(materialNames[i], materials));
                        parser.MATC.AddChild(mat);
                    }
            /*					if (textures != null)
                    {
                        string texName = materials[i].Textures[0];
                        remMaterial texMat = rem.FindMaterial(parser.MATC, new remId(texName));
                        if (texMat == null)
                        {
                            for (int k = 0; k < textures.Count; k++)
                            {
                                if (textures[k].Name == texName)
                                {
            //									texMat = CreateTexture(textures[k], Path.GetDirectoryName(parser.ODFPath));
                                    break;
                                }
                            }
                        }
                    }*/
                }

                Submesh newSubmesh = newMesh[i];
                if (mat != null)
                {
                    newSubmesh.MaterialName = mat.name;
                }

                if (worldCoords[i])
                {
                    List<remVertex> newVertexList = newSubmesh.VertexList;
                    for (int j = 0; j < newVertexList.Count; j++)
                    {
                        newVertexList[j].Position = Vector3.TransformCoordinate(newVertexList[j].Position, transform);
                    }
                }

                Submesh baseSubmesh = null;
                List<remBoneWeights> newBones = null;
                int idx = indices[i];
                if ((frameMesh != null) && (idx >= 0) && (idx < frameMesh.Count))
                {
                    baseSubmesh = frameMesh[idx];

                    if ((bonesMethod == CopyMeshMethod.CopyOrder) || (bonesMethod == CopyMeshMethod.CopyNear))
                    {
                        List<remBoneWeights> baseBones = baseSubmesh.BoneList;
                        if (baseBones != null)
                        {
                            newBones = new List<remBoneWeights>(baseBones.Count);
                            foreach (remBoneWeights boneWeights in baseBones)
                            {
                                remBoneWeights copy = boneWeights.Clone();
                                newBones.Add(copy);
                            }
                            newSubmesh.BoneList = newBones;
                        }
                    }
                    else if (bonesMethod == CopyMeshMethod.Replace)
                        newBones = newSubmesh.BoneList;
                }
                else
                {
                    newBones = newSubmesh.BoneList;
                }

                if (baseSubmesh != null)
                {
                    if (normalsMethod == CopyMeshMethod.CopyOrder)
                    {
                        rem.CopyNormalsOrder(baseSubmesh.VertexList, newSubmesh.VertexList);
                    }
                    else if (normalsMethod == CopyMeshMethod.CopyNear)
                    {
                        rem.CopyNormalsNear(baseSubmesh.VertexList, newSubmesh.VertexList);
                    }

                    if (bonesMethod == CopyMeshMethod.CopyOrder)
                    {
                        rem.CopyBonesOrder(baseSubmesh.VertexList, newSubmesh.VertexList, newBones);
                    }
                    else if (bonesMethod == CopyMeshMethod.CopyNear)
                    {
                        rem.CopyBonesNear(baseSubmesh.VertexList, newSubmesh.VertexList, newBones);
                    }
                }

                if ((baseSubmesh != null) && merge && replaceSubmeshesOption[i])
                {
                    replaceSubmeshes[idx] = newSubmesh;
                }
                else
                {
                    addSubmeshes.Add(newSubmesh);
                }
            }

            if ((frameMesh != null) && merge)
            {
                newMesh.ChildList.Clear();
                newMesh.ChildList.Capacity = replaceSubmeshes.Length + addSubmeshes.Count;
                for (int i = 0, submeshesRemoved = 0; i < replaceSubmeshes.Length; i++)
                {
                    if (replaceSubmeshes[i] == null)
                    {
                        Submesh newSubmesh = frameMesh[i - submeshesRemoved++];
                        newMesh.AddChild(newSubmesh);
                    }
                    else
                    {
                        newMesh.AddChild(replaceSubmeshes[i]);
                    }
                }
                newMesh.ChildList.AddRange(addSubmeshes);
            }

            remSkin skin;
            newREMMesh = newMesh.CreateMesh(out skin);
            newREMMesh.frame = frame.name;
            if (frameREMMesh != null)
            {
                CopyUnknowns(frameREMMesh, newREMMesh);
                parser.MESC.InsertChild(parser.MESC.IndexOf(frameREMMesh), newREMMesh);

                RemoveMesh(parser, frameREMMesh);
            }
            else
            {
                CreateUnknowns(newREMMesh);
                parser.MESC.AddChild(newREMMesh);
            }
            if (skin.Count > 0)
            {
                parser.SKIC.AddChild(skin);
            }
        }
Example #36
0
File: Fbx.cs Project: kkdevs/sb3u
            private void ConvertMeshes(List <remMesh> meshes, remParser parser)
            {
                MeshList     = new List <ImportedMesh>(meshes.Count);
                MaterialList = new List <ImportedMaterial>(meshes.Count);
                TextureList  = new List <ImportedTexture>(parser.MATC.Count);
                foreach (remMesh mesh in meshes)
                {
                    ImportedMesh iMesh = new ImportedMesh();
                    MeshList.Add(iMesh);
                    iMesh.BoneList = new List <ImportedBone>();
                    Dictionary <remId, byte> boneDic = new Dictionary <remId, byte>();
                    remSkin  skin          = rem.FindSkin(mesh.name, parser.SKIC);
                    rem.Mesh convertedMesh = new rem.Mesh(mesh, skin);
                    iMesh.SubmeshList = new List <ImportedSubmesh>(convertedMesh.Count);
                    remBone       meshFrame = rem.FindFrame(mesh.frame, parser.BONC.rootFrame);
                    ImportedFrame iFrame    = ImportedHelpers.FindFrame(mesh.frame, FrameList[0]);
                    float         s         = (float)Math.Round(Math.Abs(meshFrame.matrix.M11), 5);
                    iFrame.Name = iMesh.Name = mesh.name + (s != 1f ? "(Scale=" + s.ToString() + ")" : String.Empty);
                    foreach (rem.Submesh submesh in convertedMesh)
                    {
                        ImportedSubmesh iSubmesh = new ImportedSubmesh();
                        iMesh.SubmeshList.Add(iSubmesh);
                        remMaterial mat = rem.FindMaterial(submesh.MaterialName, parser.MATC);
                        if (mat != null)
                        {
                            iSubmesh.Material = mat.name;
                            ImportedMaterial iMat = ImportedHelpers.FindMaterial(iSubmesh.Material, MaterialList);
                            if (iMat == null)
                            {
                                iMat = new ImportedMaterial();
                                MaterialList.Add(iMat);
                                iMat.Name     = iSubmesh.Material;
                                iMat.Diffuse  = new Color4(mat.diffuse);
                                iMat.Ambient  = new Color4(mat.ambient);
                                iMat.Specular = new Color4(mat.specular);
                                iMat.Emissive = new Color4(mat.emissive);
                                iMat.Power    = mat.specularPower;

                                iMat.Textures = new string[4] {
                                    String.Empty, String.Empty, String.Empty, String.Empty
                                };
                                if (mat.texture != null)
                                {
                                    iMat.Textures[0] = mat.texture;
                                    if (ImportedHelpers.FindTexture(iMat.Textures[0], TextureList) == null)
                                    {
                                        try
                                        {
                                            ImportedTexture iTex = rem.ImportedTexture(mat.texture, parser.RemPath, true);
                                            TextureList.Add(iTex);
                                        }
                                        catch
                                        {
                                            Report.ReportLog("cant read texture " + iMat.Textures[0]);
                                        }
                                    }
                                }
                            }
                        }

                        List <Tuple <byte, float> >[] iSkin = new List <Tuple <byte, float> > [submesh.numVertices];
                        for (int i = 0; i < submesh.numVertices; i++)
                        {
                            iSkin[i] = new List <Tuple <byte, float> >(4);
                        }
                        List <remBoneWeights> boneList = submesh.BoneList;
                        if (boneList != null)
                        {
                            if (iMesh.BoneList.Capacity < boneList.Count)
                            {
                                iMesh.BoneList.Capacity += boneList.Count;
                            }
                            foreach (remBoneWeights boneWeights in boneList)
                            {
                                byte idx;
                                if (!boneDic.TryGetValue(boneWeights.bone, out idx))
                                {
                                    ImportedBone iBone = new ImportedBone();
                                    iMesh.BoneList.Add(iBone);
                                    iBone.Name = boneWeights.bone;
                                    Vector3    scale, translate;
                                    Quaternion rotate;
                                    meshFrame.matrix.Decompose(out scale, out rotate, out translate);
                                    scale.X      = Math.Abs(scale.X);
                                    scale.Y      = Math.Abs(scale.Y);
                                    scale.Z      = Math.Abs(scale.Z);
                                    iBone.Matrix = Matrix.Scaling(1f, 1f, -1f) * Matrix.Invert(meshFrame.matrix) * Matrix.Scaling(scale) * boneWeights.matrix;
                                    boneDic.Add(boneWeights.bone, idx = (byte)boneDic.Count);
                                }
                                for (int i = 0; i < boneWeights.numVertIdxWts; i++)
                                {
                                    iSkin[boneWeights.vertexIndices[i]].Add(new Tuple <byte, float>(idx, boneWeights.vertexWeights[i]));
                                }
                            }
                        }

                        iSubmesh.VertexList = new List <ImportedVertex>(submesh.numVertices);
                        for (int i = 0; i < submesh.numVertices; i++)
                        {
                            remVertex      vert  = submesh.VertexList[i];
                            ImportedVertex iVert = new ImportedVertex();
                            iSubmesh.VertexList.Add(iVert);
                            iVert.Position    = new Vector3(vert.Position.X, vert.Position.Z, -vert.Position.Y);
                            iVert.Normal      = new Vector3(vert.Normal.X, vert.Normal.Z, -vert.Normal.Y);
                            iVert.UV          = new float[] { vert.UV[0], vert.UV[1] };
                            iVert.BoneIndices = new byte[4];
                            iVert.Weights     = new float[4];
                            for (int j = 0; j < 4; j++)
                            {
                                if (j < iSkin[i].Count)
                                {
                                    Tuple <byte, float> vertIdxWeight = iSkin[i][j];
                                    iVert.BoneIndices[j] = vertIdxWeight.Item1;
                                    iVert.Weights[j]     = vertIdxWeight.Item2;
                                }
                                else
                                {
                                    iVert.BoneIndices[j] = 0xFF;
                                }
                            }
                        }

                        iSubmesh.FaceList = rem.ImportedFaceList(submesh.FaceList);
                    }
                }
            }