Пример #1
0
        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;
        }
Пример #2
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();
                    }
                }
            }
        }
Пример #3
0
        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);
        }
Пример #4
0
        public remBoneWeights Clone()
        {
            remBoneWeights boneWeights = CloneWithoutWeightInfo();

            boneWeights.vertexIndices = (int[])this.vertexIndices.Clone();
            boneWeights.vertexWeights = (float[])this.vertexWeights.Clone();
            return(boneWeights);
        }
Пример #5
0
        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());
        }
Пример #6
0
        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));
        }
Пример #7
0
        public remBoneWeights CloneWithoutWeightInfo()
        {
            remBoneWeights boneWeights = new remBoneWeights();

            boneWeights.bone   = new remId(this.bone);
            boneWeights.matrix = this.matrix;
            return(boneWeights);
        }
Пример #8
0
        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);
        }
Пример #9
0
        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;
        }
Пример #10
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);
        }
Пример #11
0
        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);
            }
        }
Пример #12
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--;
                    }
                }
            }
        }
Пример #13
0
        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);
        }
Пример #14
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);
            }
        }
Пример #15
0
            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);
                }
            }
Пример #16
0
            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);
            }
Пример #17
0
        public static void CopyBonesNear(List <remVertex> src, List <remVertex> dest, List <remBoneWeights> destBones)
        {
            Dictionary <remBoneWeights, Tuple <List <int>, List <float> > > boneTranslation = new Dictionary <remBoneWeights, Tuple <List <int>, List <float> > >(destBones.Count);

            for (int i = 0; i < dest.Count; i++)
            {
                var   destVert       = dest[i];
                var   destPos        = destVert.Position;
                float minDistSq      = Single.MaxValue;
                int   nearestVertIdx = -1;
                for (int j = 0; j < src.Count; j++)
                {
                    remVertex srcVert = src[j];
                    var       srcPos  = srcVert.Position;
                    float[]   diff    = new float[] { destPos[0] - srcPos[0], destPos[1] - srcPos[1], destPos[2] - srcPos[2] };
                    float     distSq  = (diff[0] * diff[0]) + (diff[1] * diff[1]) + (diff[2] * diff[2]);
                    if (distSq < minDistSq)
                    {
                        minDistSq      = distSq;
                        nearestVertIdx = j;
                    }
                }

                int numInfluences = 0;
                foreach (remBoneWeights srcBone in destBones)
                {
                    for (int k = 0; k < srcBone.numVertIdxWts; k++)
                    {
                        if (srcBone.vertexIndices[k] == nearestVertIdx)
                        {
                            List <int>   idxList;
                            List <float> weightList;
                            Tuple <List <int>, List <float> > destLists;
                            if (!boneTranslation.TryGetValue(srcBone, out destLists))
                            {
                                idxList    = new List <int>();
                                weightList = new List <float>();
                                destLists  = new Tuple <List <int>, List <float> >(idxList, weightList);
                                boneTranslation.Add(srcBone, destLists);
                            }
                            else
                            {
                                idxList    = destLists.Item1;
                                weightList = destLists.Item2;
                            }
                            idxList.Add(i);
                            weightList.Add(srcBone.vertexWeights[k]);
                            numInfluences++;
                            break;
                        }
                    }
                    if (numInfluences == 4)
                    {
                        break;
                    }
                }
            }
            foreach (var boneListPair in boneTranslation)
            {
                remBoneWeights srcBone = boneListPair.Key;
                Tuple <List <int>, List <float> > destLists = boneListPair.Value;
                srcBone.vertexIndices = destLists.Item1.ToArray();
                srcBone.vertexWeights = destLists.Item2.ToArray();
            }
        }