Пример #1
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;
        }
Пример #2
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;
        }
Пример #3
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;
        }