コード例 #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();
                    }
                }
            }
        }
コード例 #2
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);
        }
コード例 #3
0
ファイル: remOps.cs プロジェクト: kkdevs/sb3u
        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);
        }
コード例 #4
0
ファイル: remEditor.cs プロジェクト: kkdevs/sb3u
        public void SetBoneMatrix(int meshIdx, int boneIdx,
                                  double m11, double m12, double m13, double m14,
                                  double m21, double m22, double m23, double m24,
                                  double m31, double m32, double m33, double m34,
                                  double m41, double m42, double m43, double m44)
        {
            remMesh        mesh        = Parser.MESC[meshIdx];
            remSkin        skin        = rem.FindSkin(mesh.name, Parser.SKIC);
            remBoneWeights boneWeights = skin[boneIdx];
            Matrix         m           = new Matrix();

            m.M11 = (float)m11;
            m.M12 = (float)m12;
            m.M13 = (float)m13;
            m.M14 = (float)m14;

            m.M21 = (float)m21;
            m.M22 = (float)m22;
            m.M23 = (float)m23;
            m.M24 = (float)m24;

            m.M31 = (float)m31;
            m.M32 = (float)m32;
            m.M33 = (float)m33;
            m.M34 = (float)m34;

            m.M41 = (float)m41;
            m.M42 = (float)m42;
            m.M43 = (float)m43;
            m.M44 = (float)m44;

            boneWeights.matrix = m;
        }
コード例 #5
0
        private void listViewAnimationTrack_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            List <DockContent> formREMList;

            if (!Gui.Docking.DockContents.TryGetValue(typeof(FormREM), out formREMList))
            {
                return;
            }

            foreach (FormREM formMesh in formREMList)
            {
                for (int i = 0; i < formMesh.renderObjectMeshes.Count; i++)
                {
                    RenderObjectREM mesh = formMesh.renderObjectMeshes[i];
                    if (mesh != null && formMesh.renderObjectIds[i] > -1)
                    {
                        remMesh remMesh = formMesh.Editor.Parser.MESC[i];
                        remSkin skin    = rem.FindSkin(remMesh.name, formMesh.Editor.Parser.SKIC);
                        if (skin == null)
                        {
                            continue;
                        }
                        remBoneWeights boneWeights = rem.FindBoneWeights(skin, new remId(e.Item.Text));
                        if (boneWeights == null)
                        {
                            continue;
                        }
                        mesh.HighlightBone(formMesh.Editor.Parser, remMesh, skin.IndexOf(boneWeights), e.IsSelected);
                        Gui.Renderer.Render();
                    }
                }
            }
        }
コード例 #6
0
ファイル: remReplace.cs プロジェクト: kkdevs/sb3u
        public static remSkin CreateBoneList(ImportedMesh mesh, Matrix lMeshMatrixInv)
        {
            if (mesh.BoneList == null || mesh.BoneList.Count == 0)
            {
                return(null);
            }

            Dictionary <int, float>[] boneDic = new Dictionary <int, float> [mesh.BoneList.Count];
            for (int i = 0; i < mesh.BoneList.Count; i++)
            {
                boneDic[i] = new Dictionary <int, float>();
            }
            int vertexOffset = 0;

            foreach (ImportedSubmesh submesh in mesh.SubmeshList)
            {
                List <ImportedVertex> vertices = submesh.VertexList;
                for (int i = 0; i < vertices.Count; i++)
                {
                    ImportedVertex vert = vertices[i];
                    for (int j = 0; j < vert.BoneIndices.Length; j++)
                    {
                        if (vert.BoneIndices[j] == 0xFF)
                        {
                            continue;
                        }

                        boneDic[vert.BoneIndices[j]].Add(vertexOffset + i, vert.Weights[j]);
                    }
                }
                vertexOffset += vertices.Count;
            }

            remSkin remBoneList = new remSkin(mesh.BoneList.Count);

            remBoneList.mesh = new remId(mesh.Name);
            Vector3    scale, translate;
            Quaternion rotate;

            lMeshMatrixInv.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);
            Matrix combinedCorrection = Matrix.Scaling(-1f / scale.X, 1f / scale.Y, -1f / scale.Z) * lMeshMatrixInv;

            for (int i = 0; i < mesh.BoneList.Count; i++)
            {
                remBoneWeights boneWeights = new remBoneWeights();
                boneWeights.bone = new remId(mesh.BoneList[i].Name);
                Matrix lMatrix = Matrix.Invert(mesh.BoneList[i].Matrix);
                boneWeights.matrix        = Matrix.Invert(lMatrix * combinedCorrection);
                boneWeights.vertexIndices = new int[boneDic[i].Count];
                boneDic[i].Keys.CopyTo(boneWeights.vertexIndices, 0);
                boneWeights.vertexWeights = new float[boneDic[i].Count];
                boneDic[i].Values.CopyTo(boneWeights.vertexWeights, 0);
                remBoneList.AddChild(boneWeights);
            }
            return(remBoneList);
        }
コード例 #7
0
ファイル: remEditor.cs プロジェクト: kkdevs/sb3u
        public void CopyBoneWeights(int meshIdx, int boneIdx)
        {
            remMesh        mesh        = Parser.MESC[meshIdx];
            remSkin        skin        = rem.FindSkin(mesh.name, Parser.SKIC);
            remBoneWeights boneWeights = skin[boneIdx];

            skin.AddChild(boneWeights.Clone());
        }
コード例 #8
0
ファイル: remEditor.cs プロジェクト: kkdevs/sb3u
        public void SetBoneSRT(int meshIdx, int boneIdx, double sX, double sY, double sZ, double rX, double rY, double rZ, double tX, double tY, double tZ)
        {
            remMesh        mesh        = Parser.MESC[meshIdx];
            remSkin        skin        = rem.FindSkin(mesh.name, Parser.SKIC);
            remBoneWeights boneWeights = skin[boneIdx];

            boneWeights.matrix = FbxUtility.SRTToMatrix(new Vector3((float)sX, (float)sY, (float)sZ), new Vector3((float)rX, (float)rY, (float)rZ), new Vector3((float)tX, (float)tY, (float)tZ));
        }
コード例 #9
0
ファイル: remOps.cs プロジェクト: kkdevs/sb3u
            public Mesh(remMesh mesh, remSkin skin)
            {
                name = mesh.name;
                InitChildren(mesh.numMats);

                for (int i = 0; i < mesh.numMats; i++)
                {
                    Submesh submesh = new Submesh(mesh, skin, i);
                    AddChild(submesh);
                }
            }
コード例 #10
0
        public remSkin Clone()
        {
            remSkin skin = new remSkin(Count);

            foreach (remBoneWeights boneWeights in this)
            {
                skin.AddChild(boneWeights.Clone());
            }

            return(skin);
        }
コード例 #11
0
ファイル: remEditor.cs プロジェクト: kkdevs/sb3u
        public void SetMeshName(int idx, string name)
        {
            remId   newName = new remId(name);
            remMesh mesh    = Parser.MESC[idx];
            remSkin skin    = rem.FindSkin(mesh.name, Parser.SKIC);

            if (skin != null)
            {
                skin.mesh = newName;
            }
            Parser.MESC[idx].name = newName;
        }
コード例 #12
0
ファイル: remReplace.cs プロジェクト: kkdevs/sb3u
        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);
            }
        }
コード例 #13
0
ファイル: remOps.cs プロジェクト: kkdevs/sb3u
        public static remBoneWeights FindBoneWeights(remSkin skin, remId boneFrame)
        {
            for (int i = 0; i < skin.Count; i++)
            {
                remBoneWeights boneWeights = skin[i];
                if (boneWeights.bone == boneFrame)
                {
                    return(boneWeights);
                }
            }

            return(null);
        }
コード例 #14
0
ファイル: remEditor.cs プロジェクト: kkdevs/sb3u
        public void SetBoneFrame(int meshIdx, int boneIdx, string frame)
        {
            remId   newBoneFrameId = new remId(frame);
            remBone boneFrame      = rem.FindFrame(newBoneFrameId, Parser.BONC.rootFrame);

            if (boneFrame == null)
            {
                throw new FormatException("Frame not found");
            }

            remSkin        skin        = rem.FindSkin(Parser.MESC[meshIdx].name, Parser.SKIC);
            remBoneWeights boneWeights = skin[boneIdx];

            boneWeights.bone = boneFrame.name;
        }
コード例 #15
0
ファイル: remEditor.cs プロジェクト: kkdevs/sb3u
        public bool RemoveBone(int meshIdx, int boneIdx)
        {
            remMesh mesh     = Parser.MESC[meshIdx];
            remSkin boneList = rem.FindSkin(mesh.name, Parser.SKIC);

            if (boneList.Count == 1 && boneIdx == 0)
            {
                Parser.SKIC.RemoveChild(boneList);
                return(true);
            }
            else
            {
                boneList.RemoveChild(boneIdx);
                return(false);
            }
        }
コード例 #16
0
ファイル: remEditor.cs プロジェクト: kkdevs/sb3u
        void DeleteReferringBones(remBone frame)
        {
            for (int i = 0; i < Parser.MESC.Count; i++)
            {
                remMesh mesh = Parser.MESC[i];
                remSkin skin = rem.FindSkin(mesh.name, Parser.SKIC);
                if (skin != null)
                {
                    remBoneWeights boneWeights = rem.FindBoneWeights(skin, frame.name);
                    if (boneWeights != null)
                    {
                        RemoveBone(i, skin.IndexOf(boneWeights));
                    }
                }
            }

            foreach (remBone child in frame)
            {
                DeleteReferringBones(child);
            }
        }
コード例 #17
0
ファイル: remReplace.cs プロジェクト: kkdevs/sb3u
        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);
            }
        }
コード例 #18
0
ファイル: REMParser.cs プロジェクト: kkdevs/sb3u
        private static remSKICsection ReadSkin(string sectionName, int sectionLength, int numSkins, byte[] sectionBuffer)
        {
            remSKICsection skinSec   = new remSKICsection(numSkins);
            int            secBufIdx = 0;

            for (int subSection = 0; subSection < numSkins; subSection++)
            {
                byte[] type = new byte[4] {
                    sectionBuffer[secBufIdx + 0], sectionBuffer[secBufIdx + 1], sectionBuffer[secBufIdx + 2], sectionBuffer[secBufIdx + 3]
                };
                int length = BitConverter.ToInt32(sectionBuffer, secBufIdx + 4);

                remId   mesh       = GetIdentifier(sectionBuffer, secBufIdx + 8);
                int     numWeights = BitConverter.ToInt32(sectionBuffer, secBufIdx + 8 + 256);
                remSkin skin       = new remSkin(numWeights);
                Trace.Assert(TypeCheck(remSkin.ClassType, type));
                skin.mesh = mesh;
                int weightBufIdx = secBufIdx + 8 + 256 + 4;
                for (int weightIdx = 0; weightIdx < numWeights; weightIdx++)
                {
                    remBoneWeights weights = new remBoneWeights();
                    weights.bone  = GetIdentifier(sectionBuffer, weightBufIdx);
                    weightBufIdx += 256;
                    int numVertIdxWts = BitConverter.ToInt32(sectionBuffer, weightBufIdx);
                    weightBufIdx += 4;

                    Matrix matrix = new Matrix();
                    for (int i = 0; i < 4; i++)
                    {
                        Vector4 row = new Vector4();
                        for (int j = 0; j < 4; j++)
                        {
                            row[j]        = BitConverter.ToSingle(sectionBuffer, weightBufIdx);
                            weightBufIdx += 4;
                        }
                        matrix.set_Rows(i, row);
                    }
                    weights.matrix = matrix;

                    weights.vertexIndices = new int[numVertIdxWts];
                    for (int i = 0; i < numVertIdxWts; i++)
                    {
                        weights.vertexIndices[i] = BitConverter.ToInt32(sectionBuffer, weightBufIdx);
                        weightBufIdx            += 4;
                    }
                    weights.vertexWeights = new float[weights.numVertIdxWts];
                    for (int i = 0; i < numVertIdxWts; i++)
                    {
                        weights.vertexWeights[i] = BitConverter.ToSingle(sectionBuffer, weightBufIdx);
                        weightBufIdx            += 4;
                    }

                    skin.AddChild(weights);
                }

                skinSec.AddChild(skin);

                secBufIdx += length;
            }
            if (secBufIdx != sectionLength)
            {
                Report.ReportLog("Warning! SKIC section has wrong length.");
            }
            return(skinSec);
        }
コード例 #19
0
ファイル: remOps.cs プロジェクト: kkdevs/sb3u
            public Submesh(remMesh mesh, remSkin skin, int submeshIdx)
            {
                MaterialName = mesh.materials[submeshIdx];
                VertexList   = new List <remVertex>(mesh.numVertices);
                FaceList     = new List <int>(mesh.numFaces * 3);
                int[] vertIndices = new int[mesh.numVertices];
                for (int i = 0; i < mesh.numVertices; i++)
                {
                    vertIndices[i] = -1;
                }
                for (int i = 0; i < mesh.numFaces; i++)
                {
                    if (mesh.faceMarks[i] != submeshIdx)
                    {
                        continue;
                    }

                    for (int j = 0; j < 3; j++)
                    {
                        int vertIdx = mesh.faces[i * 3 + j];
                        if (vertIndices[vertIdx] < 0)
                        {
                            vertIndices[vertIdx] = VertexList.Count;
                            VertexList.Add(mesh.vertices[vertIdx]);
                        }
                        FaceList.Add(vertIndices[vertIdx]);
                    }
                }
                VertexList.TrimExcess();
                FaceList.TrimExcess();

                if (skin == null)
                {
                    return;
                }
                BoneList = new List <remBoneWeights>(skin.Count);
                foreach (remBoneWeights boneWeights in skin)
                {
                    Dictionary <int, float> boneDic = new Dictionary <int, float>(boneWeights.numVertIdxWts);
                    for (int i = 0; i < boneWeights.numVertIdxWts; i++)
                    {
                        int oldVertIdx = boneWeights.vertexIndices[i];
                        int newVertIdx = vertIndices[oldVertIdx];
                        if (newVertIdx >= 0)
                        {
                            boneDic.Add(newVertIdx, boneWeights.vertexWeights[i]);
                        }
                    }
                    if (boneDic.Count == 0)
                    {
                        continue;
                    }

                    remBoneWeights newBoneWeights = new remBoneWeights();
                    newBoneWeights.bone          = boneWeights.bone;
                    newBoneWeights.matrix        = boneWeights.matrix;
                    newBoneWeights.vertexIndices = new int[boneDic.Count];
                    boneDic.Keys.CopyTo(newBoneWeights.vertexIndices, 0);
                    newBoneWeights.vertexWeights = new float[boneDic.Count];
                    boneDic.Values.CopyTo(newBoneWeights.vertexWeights, 0);
                    BoneList.Add(newBoneWeights);
                }
            }
コード例 #20
0
ファイル: remOps.cs プロジェクト: kkdevs/sb3u
            public remMesh CreateMesh(out remSkin skin)
            {
                remMesh mesh = new remMesh(Count);

                skin      = new remSkin(0);
                skin.mesh = mesh.name = name;

                List <remVertex> newVertices  = new List <remVertex>();
                List <int>       newFaces     = new List <int>();
                List <int>       newFaceMarks = new List <int>();
                Dictionary <remId, Tuple <Matrix, List <int>, List <float> > > boneDic = new Dictionary <remId, Tuple <Matrix, List <int>, List <float> > >();

                for (int i = 0; i < Count; i++)
                {
                    Submesh submesh = this[i];

                    mesh.AddMaterial(submesh.MaterialName);

                    newFaces.Capacity += submesh.FaceList.Count;
                    foreach (int vertexIdx in submesh.FaceList)
                    {
                        newFaces.Add(newVertices.Count + vertexIdx);
                    }
                    int[] faceMarks = new int[submesh.numFaces];
                    for (int j = 0; j < submesh.numFaces; j++)
                    {
                        faceMarks[j] = i;
                    }
                    newFaceMarks.AddRange(faceMarks);

                    if (submesh.BoneList != null)
                    {
                        foreach (remBoneWeights boneWeights in submesh.BoneList)
                        {
                            Tuple <Matrix, List <int>, List <float> > newBone = null;
                            if (!boneDic.TryGetValue(boneWeights.bone, out newBone))
                            {
                                newBone = new Tuple <Matrix, List <int>, List <float> >(boneWeights.matrix, new List <int>(boneWeights.numVertIdxWts), new List <float>(boneWeights.numVertIdxWts));
                                boneDic.Add(boneWeights.bone, newBone);
                            }
                            List <int> vertIdxs = newBone.Item2;
                            vertIdxs.Capacity += boneWeights.vertexIndices.Length;
                            foreach (int vertexIdx in boneWeights.vertexIndices)
                            {
                                vertIdxs.Add(newVertices.Count + vertexIdx);
                            }
                            List <float> weights = newBone.Item3;
                            weights.AddRange(boneWeights.vertexWeights);
                        }
                    }

                    newVertices.AddRange(submesh.VertexList);
                }

                mesh.vertices  = newVertices.ToArray();
                mesh.faces     = newFaces.ToArray();
                mesh.faceMarks = newFaceMarks.ToArray();

                foreach (var pair in boneDic)
                {
                    remBoneWeights newBoneWeights = new remBoneWeights();
                    newBoneWeights.bone          = pair.Key;
                    newBoneWeights.matrix        = pair.Value.Item1;
                    newBoneWeights.vertexIndices = pair.Value.Item2.ToArray();
                    newBoneWeights.vertexWeights = pair.Value.Item3.ToArray();
                    skin.AddChild(newBoneWeights);
                }
                return(mesh);
            }
コード例 #21
0
        private float[][] ConvertVertexWeights(List <remVertex> vertexList, int[] vertexIndices, remSkin boneList, out byte[][] vertexBoneIndices)
        {
            int numBones = boneList != null ? boneList.Count : 0;

            float[][] vertexWeights = new float[vertexList.Count][];
            vertexBoneIndices = new byte[vertexList.Count][];
            for (int j = 0; j < vertexList.Count; j++)
            {
                int meshVertIdx = -1;
                for (int k = 0; k < vertexIndices.Length; k++)
                {
                    if (vertexIndices[k] == j)
                    {
                        meshVertIdx = k;
                        break;
                    }
                }
                if (meshVertIdx < 0)
                {
                    throw new Exception("ConvertVertexWeights : index not found");
                }
                vertexWeights[j]     = new float[4];
                vertexBoneIndices[j] = new byte[4];
                int weightIdx = 0;
                for (int k = 0; k < numBones; k++)
                {
                    remBoneWeights bone = boneList[k];
                    for (int l = 0; l < bone.numVertIdxWts; l++)
                    {
                        if (bone.vertexIndices[l] == meshVertIdx)
                        {
                            vertexBoneIndices[j][weightIdx] = (byte)k;
                            if (weightIdx < 3)
                            {
                                vertexWeights[j][weightIdx++] = bone.vertexWeights[l];
                            }
                            else
                            {
                                vertexWeights[j][3] = 1f - vertexWeights[j][0] - vertexWeights[j][1] - vertexWeights[j][2];
                            }
                            break;
                        }
                    }
                }
            }

            return(vertexWeights);
        }
コード例 #22
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);
        }
コード例 #23
0
ファイル: remReplace.cs プロジェクト: kkdevs/sb3u
        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--;
                    }
                }
            }
        }
コード例 #24
0
ファイル: Fbx.cs プロジェクト: 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);
                    }
                }
            }