Exemple #1
0
        public remVertex Clone()
        {
            remVertex vert = new remVertex();

            vert.Position = Position;
            vert.UV       = UV;
            vert.Normal   = Normal;
            vert.RGBA     = RGBA;

            return(vert);
        }
Exemple #2
0
        public static void CopyNormalsNear(List <remVertex> src, List <remVertex> dest)
        {
            for (int i = 0; i < dest.Count; i++)
            {
                var       destVert    = dest[i];
                var       destPos     = destVert.Position;
                float     minDistSq   = Single.MaxValue;
                remVertex nearestVert = null;
                foreach (remVertex srcVert in src)
                {
                    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;
                        nearestVert = srcVert;
                    }
                }

                destVert.Normal = nearestVert.Normal;
            }
        }
Exemple #3
0
        public static remMesh CreateMesh(WorkspaceMesh mesh, out string[] materialNames, out int[] indices, out bool[] worldCoords, out bool[] replaceSubmeshesOption)
        {
            int numUncheckedSubmeshes = 0;

            foreach (ImportedSubmesh submesh in mesh.SubmeshList)
            {
                if (!mesh.isSubmeshEnabled(submesh))
                {
                    numUncheckedSubmeshes++;
                }
            }
            int numSubmeshes = mesh.SubmeshList.Count - numUncheckedSubmeshes;

            materialNames          = new string[numSubmeshes];
            indices                = new int[numSubmeshes];
            worldCoords            = new bool[numSubmeshes];
            replaceSubmeshesOption = new bool[numSubmeshes];

            remMesh newMesh = new remMesh(numSubmeshes);

            newMesh.name = new remId(mesh.Name);

            List <remVertex> newVertices  = new List <remVertex>();
            List <int>       newFaces     = new List <int>();
            List <int>       newFaceMarks = new List <int>();

            for (int i = 0, submeshIdx = 0; i < numSubmeshes; i++, submeshIdx++)
            {
                while (!mesh.isSubmeshEnabled(mesh.SubmeshList[submeshIdx]))
                {
                    submeshIdx++;
                }

                ImportedSubmesh submesh = mesh.SubmeshList[submeshIdx];

                newMesh.AddMaterial(new remId(submesh.Material));
                materialNames[i]          = submesh.Material;
                indices[i]                = submesh.Index;
                worldCoords[i]            = submesh.WorldCoords;
                replaceSubmeshesOption[i] = mesh.isSubmeshReplacingOriginal(submesh);

                List <ImportedFace> faceList = submesh.FaceList;
                newFaces.Capacity += faceList.Count * 3;
                int[] faceMarks = new int[faceList.Count];
                for (int j = 0; j < faceList.Count; j++)
                {
                    ImportedFace face = faceList[j];
                    for (int k = 0; k < 3; k++)
                    {
                        newFaces.Add(face.VertexIndices[k] + newVertices.Count);
                    }
                    faceMarks[j] = i;
                }
                newFaceMarks.AddRange(faceMarks);

                List <ImportedVertex> vertexList = submesh.VertexList;
                newVertices.Capacity += vertexList.Count;
                for (int j = 0; j < vertexList.Count; j++)
                {
                    ImportedVertex vert      = vertexList[j];
                    remVertex      newVertex = new remVertex();

                    if (submesh.WorldCoords)
                    {
                        newVertex.Position = vert.Position;
                        newVertex.Normal   = vert.Normal;
                    }
                    else
                    {
                        newVertex.Position = new Vector3(vert.Position.X, -vert.Position.Z, vert.Position.Y);
                        newVertex.Normal   = new Vector3(vert.Normal.X, -vert.Normal.Z, vert.Normal.Y);
                    }
                    newVertex.UV = new Vector2(vert.UV[0], vert.UV[1]);
                    newVertices.Add(newVertex);
                }
            }
            newMesh.vertices  = newVertices.ToArray();
            newMesh.faces     = newFaces.ToArray();
            newMesh.faceMarks = newFaceMarks.ToArray();

            return(newMesh);
        }
Exemple #4
0
        private void FillVertexBuffer(Mesh animationMesh, List <remVertex> vertexList, float[][] vertexWeights, byte[][] vertexBoneIndices, int selectedBoneIdx)
        {
            using (DataStream vertexStream = animationMesh.LockVertexBuffer(LockFlags.None))
            {
                Color4 col = new Color4(1f, 1f, 1f);
                for (int j = 0; j < vertexList.Count; j++)
                {
                    remVertex vertex      = vertexList[j];
                    Vector3   position    = vertex.Position;
                    Vector3   normal      = vertex.Normal;
                    float[]   boneWeights = vertexWeights[j];
                    vertexStream.Write(position.X);
                    vertexStream.Write(position.Y);
                    vertexStream.Write(position.Z);
                    vertexStream.Write(boneWeights[0]);
                    vertexStream.Write(boneWeights[1]);
                    vertexStream.Write(boneWeights[2]);
                    vertexStream.Write(vertexBoneIndices[j][0]);
                    vertexStream.Write(vertexBoneIndices[j][1]);
                    vertexStream.Write(vertexBoneIndices[j][2]);
                    vertexStream.Write(vertexBoneIndices[j][3]);
                    vertexStream.Write(normal.X);
                    vertexStream.Write(normal.Y);
                    vertexStream.Write(normal.Z);
                    if (selectedBoneIdx >= 0)
                    {
                        col.Red = 0f; col.Green = 0f; col.Blue = 0f;
                        byte[] boneIndices = vertexBoneIndices[j];
                        for (int k = 0; k < boneIndices.Length; k++)
                        {
                            if (boneIndices[k] == 0xFF)
                            {
                                continue;
                            }

                            byte boneIdx = boneIndices[k];
                            if (boneIdx == selectedBoneIdx)
                            {
/*								switch (cols)
 *                                                              {
 *                                                              case WeightsColourPreset.Greyscale:
 *                                                                      col.Red = col.Green = col.Blue = boneWeights[k];
 *                                                                      break;
 *                                                              case WeightsColourPreset.Metal:
 *                                                                      col.Red = boneWeights[k] > 0.666f ? 1f : boneWeights[k] * 1.5f;
 *                                                                      col.Green = boneWeights[k] * boneWeights[k] * boneWeights[k];
 *                                                                      break;
 *                                                              case WeightsColourPreset.Rainbow:*/
                                if (boneWeights[k] > 0.75f)
                                {
                                    col.Red   = 1f;
                                    col.Green = (1f - boneWeights[k]) * 2f;
                                    col.Blue  = 0f;
                                }
                                else if (boneWeights[k] > 0.5f)
                                {
                                    col.Red   = 1f;
                                    col.Green = (1f - boneWeights[k]) * 2f;
                                    col.Blue  = 0f;
                                }
                                else if (boneWeights[k] > 0.25f)
                                {
                                    col.Red   = (boneWeights[k] - 0.25f) * 4f;
                                    col.Green = 1f;
                                    col.Blue  = 0f;
                                }
                                else
                                {
                                    col.Green = boneWeights[k] * 4f;
                                    col.Blue  = 1f - boneWeights[k] * 4f;
                                }

/*									break;
 *                                                              }*/
                                break;
                            }
                        }
                    }
                    vertexStream.Write(col.ToArgb());
                    vertexStream.Write(vertex.UV[0]);
                    vertexStream.Write(vertex.UV[1]);
                }
                animationMesh.UnlockVertexBuffer();
            }
        }
Exemple #5
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);
        }
Exemple #6
0
        static void CalculateNormals(List <Tuple <List <int>, List <remVertex> > > pairList, float threshold)
        {
            if (threshold < 0)
            {
                VertexRef[][] vertRefArray = new VertexRef[pairList.Count][];
                for (int i = 0; i < pairList.Count; i++)
                {
                    List <remVertex> vertList = pairList[i].Item2;
                    vertRefArray[i] = new VertexRef[vertList.Count];
                    for (int j = 0; j < vertList.Count; j++)
                    {
                        remVertex vert    = vertList[j];
                        VertexRef vertRef = new VertexRef();
                        vertRef.vert       = vert;
                        vertRef.norm       = new Vector3();
                        vertRefArray[i][j] = vertRef;
                    }
                }

                for (int i = 0; i < pairList.Count; i++)
                {
                    List <int> faceList = pairList[i].Item1;
                    int        numFaces = faceList.Count / 3;
                    for (int j = 0; j < numFaces; j++)
                    {
                        int[] vertIdx = new int[3] {
                            faceList[j * 3 + 0], faceList[j * 3 + 1], faceList[j * 3 + 2]
                        };
                        Vector3 v1   = vertRefArray[i][vertIdx[1]].vert.Position - vertRefArray[i][vertIdx[2]].vert.Position;
                        Vector3 v2   = vertRefArray[i][vertIdx[0]].vert.Position - vertRefArray[i][vertIdx[2]].vert.Position;
                        Vector3 norm = Vector3.Cross(v2, v1);
                        norm.Normalize();
                        for (int k = 0; k < vertIdx.Length; k++)
                        {
                            vertRefArray[i][vertIdx[k]].norm += norm;
                        }
                    }
                }

                for (int i = 0; i < vertRefArray.Length; i++)
                {
                    for (int j = 0; j < vertRefArray[i].Length; j++)
                    {
                        Vector3 norm = vertRefArray[i][j].norm;
                        norm.Normalize();
                        vertRefArray[i][j].vert.Normal = norm;
                    }
                }
            }
            else
            {
                int vertCount = 0;
                for (int i = 0; i < pairList.Count; i++)
                {
                    vertCount += pairList[i].Item2.Count;
                }

                VertexRefComparerX vertRefComparerX = new VertexRefComparerX();
                List <VertexRef>   vertRefListX     = new List <VertexRef>(vertCount);
                VertexRef[][]      vertRefArray     = new VertexRef[pairList.Count][];
                for (int i = 0; i < pairList.Count; i++)
                {
                    var vertList = pairList[i].Item2;
                    vertRefArray[i] = new VertexRef[vertList.Count];
                    for (int j = 0; j < vertList.Count; j++)
                    {
                        remVertex vert    = vertList[j];
                        VertexRef vertRef = new VertexRef();
                        vertRef.vert       = vert;
                        vertRef.norm       = new Vector3();
                        vertRefArray[i][j] = vertRef;
                        vertRefListX.Add(vertRef);
                    }
                }
                vertRefListX.Sort(vertRefComparerX);

                for (int i = 0; i < pairList.Count; i++)
                {
                    var faceList = pairList[i].Item1;
                    int numFaces = faceList.Count / 3;
                    for (int j = 0; j < numFaces; j++)
                    {
                        int[] vertIdx = new int[3] {
                            faceList[j * 3 + 0], faceList[j * 3 + 1], faceList[j * 3 + 2]
                        };
                        Vector3 v1   = vertRefArray[i][vertIdx[1]].vert.Position - vertRefArray[i][vertIdx[2]].vert.Position;
                        Vector3 v2   = vertRefArray[i][vertIdx[0]].vert.Position - vertRefArray[i][vertIdx[2]].vert.Position;
                        Vector3 norm = Vector3.Cross(v2, v1);
                        norm.Normalize();
                        for (int k = 0; k < vertIdx.Length; k++)
                        {
                            vertRefArray[i][vertIdx[k]].norm += norm;
                        }
                    }
                }

                float squaredThreshold = threshold * threshold;
                while (vertRefListX.Count > 0)
                {
                    VertexRef        vertRef  = vertRefListX[vertRefListX.Count - 1];
                    List <VertexRef> dupList  = new List <VertexRef>();
                    List <VertexRef> dupListX = GetAxisDups(vertRef, vertRefListX, 0, threshold, null);
                    foreach (VertexRef dupRef in dupListX)
                    {
                        if (((vertRef.vert.Position.Y - dupRef.vert.Position.Y) <= threshold) &&
                            ((vertRef.vert.Position.Z - dupRef.vert.Position.Z) <= threshold) &&
                            ((vertRef.vert.Position - dupRef.vert.Position).LengthSquared() <= squaredThreshold))
                        {
                            dupList.Add(dupRef);
                        }
                    }
                    vertRefListX.RemoveAt(vertRefListX.Count - 1);

                    Vector3 norm = vertRef.norm;
                    foreach (VertexRef dupRef in dupList)
                    {
                        norm += dupRef.norm;
                        vertRefListX.Remove(dupRef);
                    }
                    norm.Normalize();

                    vertRef.vert.Normal = norm;
                    foreach (VertexRef dupRef in dupList)
                    {
                        dupRef.vert.Normal = norm;
                        vertRefListX.Remove(dupRef);
                    }
                }
            }
        }
Exemple #7
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();
            }
        }
Exemple #8
0
        private static remMESCsection ReadMeshes(string sectionName, int sectionLength, int numMeshes, byte[] sectionBuffer)
        {
            remMESCsection meshSec   = new remMESCsection(numMeshes);
            int            secBufIdx = 0;

            for (int subSection = 0; subSection < numMeshes; 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);

                remMesh mesh = new remMesh(5);
                Trace.Assert(TypeCheck(remMesh.ClassType, type));
                mesh.frame = GetIdentifier(sectionBuffer, secBufIdx + 8);

                int numMats = BitConverter.ToInt32(sectionBuffer, secBufIdx + 8 + 256);
                mesh.name = GetIdentifier(sectionBuffer, secBufIdx + 8 + 256 + 4);
                int numFaces    = BitConverter.ToInt32(sectionBuffer, secBufIdx + 8 + 256 + 4 + 256);
                int numVertices = BitConverter.ToInt32(sectionBuffer, secBufIdx + 8 + 256 + 4 + 256 + 4);
                for (int i = 0; i < mesh.unknown.Length; i++)
                {
                    mesh.unknown[i] = BitConverter.ToInt32(sectionBuffer, secBufIdx + 8 + 256 + 4 + 256 + 8 + i * 4);
                }
                for (int i = 0; i < numMats; i++)
                {
                    remId mat = GetIdentifier(sectionBuffer, secBufIdx + 8 + 256 + 4 + 256 + 4 * 4 + i * 256);
                    mesh.AddMaterial(mat);
                }

                mesh.vertices = new remVertex[numVertices];
                int vertBufIdx = secBufIdx + 8 + 256 + 4 + 256 + 4 * 4 + mesh.numMats * 256;
                for (int i = 0; i < numVertices; i++)
                {
                    remVertex vertex = new remVertex();
                    vertex.Position    = new Vector3();
                    vertex.Position[0] = BitConverter.ToSingle(sectionBuffer, vertBufIdx + 0);
                    vertex.Position[1] = BitConverter.ToSingle(sectionBuffer, vertBufIdx + 4);
                    vertex.Position[2] = BitConverter.ToSingle(sectionBuffer, vertBufIdx + 8);

                    vertex.UV    = new Vector2();
                    vertex.UV[0] = BitConverter.ToSingle(sectionBuffer, vertBufIdx + 12);
                    vertex.UV[1] = BitConverter.ToSingle(sectionBuffer, vertBufIdx + 16);

                    vertex.Normal    = new Vector3();
                    vertex.Normal[0] = BitConverter.ToSingle(sectionBuffer, vertBufIdx + 20);
                    vertex.Normal[1] = BitConverter.ToSingle(sectionBuffer, vertBufIdx + 24);
                    vertex.Normal[2] = BitConverter.ToSingle(sectionBuffer, vertBufIdx + 28);

                    vertex.RGBA = new Color4(BitConverter.ToInt32(sectionBuffer, vertBufIdx + 32));

                    mesh.vertices[i] = vertex;
                    vertBufIdx      += 36;
                }

                mesh.faces = new int[numFaces * 3];
                int faceBufIdx = vertBufIdx;
                for (int i = 0; i < numFaces; i++)
                {
                    mesh.faces[i * 3 + 0] = BitConverter.ToInt32(sectionBuffer, faceBufIdx + 0);
                    mesh.faces[i * 3 + 1] = BitConverter.ToInt32(sectionBuffer, faceBufIdx + 4);
                    mesh.faces[i * 3 + 2] = BitConverter.ToInt32(sectionBuffer, faceBufIdx + 8);
                    faceBufIdx           += 12;
                }

                mesh.faceMarks = new int[numFaces];
                int faceExtraIdx = faceBufIdx;
                for (int i = 0; i < numFaces; i++)
                {
                    mesh.faceMarks[i] = BitConverter.ToInt32(sectionBuffer, faceExtraIdx);
                    faceExtraIdx     += 4;
                }

                meshSec.AddChild(mesh);

                secBufIdx += length;
            }
            if (secBufIdx != sectionLength)
            {
                Report.ReportLog("Warning! MESC section has wrong length.");
            }
            return(meshSec);
        }
Exemple #9
0
            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);
                    }
                }
            }