Esempio n. 1
0
        public RenderObjectREM(remParser parser, remMesh mesh)
        {
            HighlightSubmesh = new HashSet<int>();
            highlightMaterial = new Material();
            highlightMaterial.Ambient = new Color4(1, 1, 1, 1);
            highlightMaterial.Diffuse = new Color4(1, 0, 1, 0);

            this.device = Gui.Renderer.Device;

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

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

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

            for (int i = 0; i < meshFrames.Count; i++)
            {
                if (i == 0)
                {
                    Bounds = meshFrames[i].Bounds;
                }
                else
                {
                    Bounds = BoundingBox.Merge(Bounds, meshFrames[i].Bounds);
                }
            }
        }
Esempio n. 2
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;
        }
Esempio n. 3
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--;
                    }
                }
            }
        }
Esempio n. 4
0
        public static void RemoveMesh(remParser parser, remMesh mesh)
        {
            parser.MESC.RemoveChild(mesh);
            mesh.frame = null;

            remSkin skin = FindSkin(mesh.name, parser.SKIC);
            if (skin != null)
            {
                parser.SKIC.RemoveChild(skin);
            }
        }
Esempio n. 5
0
 private AnimationFrame CreateHierarchy(remParser parser, remMesh mesh, Device device, out List<AnimationFrame> meshFrames)
 {
     meshFrames = new List<AnimationFrame>(1);
     HashSet<string> extractFrames = rem.SearchHierarchy(parser, mesh);
     #if !DONT_MIRROR
     Matrix orignalMatrix = parser.BONC.rootFrame.matrix;
     parser.BONC.rootFrame.matrix *= Matrix.Scaling(1f, 1f, -1f);
     #endif
     AnimationFrame rootFrame = CreateFrame(parser.BONC.rootFrame, parser, extractFrames, mesh, device, Matrix.Identity, meshFrames);
     SetupBoneMatrices(rootFrame, rootFrame);
     #if !DONT_MIRROR
     parser.BONC.rootFrame.matrix = orignalMatrix;
     #endif
     return rootFrame;
 }
Esempio n. 6
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;
        }
Esempio n. 7
0
        private static void SplitMesh(remMesh mesh, List<List<remVertex>> submeshVertLists, List<List<ushort>> submeshFaceLists, List<int[]> submeshVertIndices)
        {
            for (int i = 0; i < mesh.numFaces; i++)
            {
                while (mesh.faceMarks[i] >= submeshFaceLists.Count)
                {
                    List<ushort> newFaceList = new List<ushort>(mesh.numFaces);
                    submeshFaceLists.Add(newFaceList);
                    List<remVertex> newVertList = new List<remVertex>(mesh.numVertices);
                    submeshVertLists.Add(newVertList);
                    int[] newVertIndices = new int[mesh.numVertices];
                    for (int j = 0; j < mesh.numVertices; j++)
                        newVertIndices[j] = -1;
                    submeshVertIndices.Add(newVertIndices);
                }

                int submesh = mesh.faceMarks[i];
                for (int j = 0; j < 3; j++)
                {
                    int vertIdx = mesh.faces[i * 3 + j];
                    if (submeshVertIndices[submesh][vertIdx] < 0)
                    {
                        submeshVertIndices[submesh][vertIdx] = submeshVertLists[submesh].Count;
                        submeshVertLists[submesh].Add(mesh.vertices[vertIdx]);
                    }
                    submeshFaceLists[submesh].Add((ushort)submeshVertIndices[submesh][vertIdx]);
                }
            }
        }
Esempio n. 8
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();
                    }
                }
            }
        }
Esempio n. 9
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;
        }