Пример #1
0
        public static remBone CreateFrame(ImportedFrame frame)
        {
            remBone remFrame = new remBone(frame.Count);
            remFrame.matrix = frame.Matrix;
            remFrame.name = new remId(frame.Name);

            for (int i = 0; i < frame.Count; i++)
            {
                remFrame.AddChild(CreateFrame(frame[i]));
            }

            return remFrame;
        }
Пример #2
0
        public void AddFrame(remBone srcFrame, remParser srcParser, int destParentIdx)
        {
            List<remMaterial> materialClones = new List<remMaterial>(srcParser.MATC.Count);
            List<remMesh> meshClones = new List<remMesh>(srcParser.MESC.Count);
            List<remSkin> skinClones = new List<remSkin>(srcParser.SKIC.Count);
            if (srcFrame == null)
            {
                srcFrame = srcParser.BONC.rootFrame;
            }
            var newFrame = srcFrame.Clone(true, true, srcParser, materialClones, meshClones, skinClones);

            AddFrame(newFrame, destParentIdx);

            PullNewMaterials(materialClones);
            Parser.MESC.ChildList.AddRange(meshClones);
            Parser.SKIC.ChildList.AddRange(skinClones);
        }
Пример #3
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);
            }
        }
Пример #4
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;
        }
Пример #5
0
        void ReplaceFrame(remBone newFrame, int destParentIdx)
        {
            if (destParentIdx < 0)
            {
                Parser.BONC.rootFrame.ChildList.Clear();
                foreach (remBone child in newFrame)
                {
                    Parser.BONC.rootFrame.AddChild(child);
                }
                Parser.MESC.ChildList.Clear();
                Parser.SKIC.ChildList.Clear();
            }
            else
            {
                var destParent = Parser.BONC[destParentIdx];
                bool found = false;
                for (int i = 0; i < destParent.Count; i++)
                {
                    var dest = destParent[i];
                    if (dest.name == newFrame.name)
                    {
                        remMesh mesh = rem.FindMesh(dest, Parser.MESC);
                        if (mesh != null)
                        {
                            rem.RemoveMesh(Parser, mesh);
                        }
                        destParent.RemoveChild(i);
                        destParent.InsertChild(i, newFrame);
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    destParent.AddChild(newFrame);
                }
            }
            RebuildBONC();
        }
Пример #6
0
        void MergeFrame(remBone srcParent, remBone destParent)
        {
            for (int i = 0; i < destParent.Count; i++)
            {
                var dest = destParent[i];
                for (int j = 0; j < srcParent.Count; j++)
                {
                    var src = srcParent[j];
                    if (src.name == dest.name)
                    {
                        MergeFrame(src, dest);

                        srcParent.RemoveChild(j);
                        remMesh mesh = rem.FindMesh(dest, Parser.MESC);
                        if (mesh != null)
                        {
                            rem.RemoveMesh(Parser, mesh);
                        }
                        destParent.RemoveChild(i);
                        destParent.InsertChild(i, src);
                        break;
                    }
                }
            }

            if (srcParent.name == destParent.name)
            {
                while (destParent.Count > 0)
                {
                    var dest = destParent[0];
                    remMesh mesh = rem.FindMesh(dest, Parser.MESC);
                    if (mesh != null)
                    {
                        rem.RemoveMesh(Parser, mesh);
                    }
                    destParent.RemoveChild(0);
                    srcParent.AddChild(dest);
                }
            }
            else
            {
                while (srcParent.Count > 0)
                {
                    var src = srcParent[0];
                    srcParent.RemoveChild(0);
                    destParent.AddChild(src);
                }
            }
        }
Пример #7
0
        void MergeFrame(remBone newFrame, int destParentIdx)
        {
            remBone srcParent = new remBone(1);
            srcParent.AddChild(newFrame);

            remBone destParent;
            if (destParentIdx < 0)
            {
                destParent = Parser.BONC.rootFrame;
            }
            else
            {
                destParent = Parser.BONC[destParentIdx];
            }

            MergeFrame(srcParent, destParent);
            RebuildBONC();
        }
Пример #8
0
        void FindFrames(remBone frame, List<string> duplicates)
        {
            foreach (remBone remFrame in Parser.BONC)
            {
                if (remFrame.name == frame.name)
                {
                    duplicates.Add(frame.name);
                }
            }

            foreach (remBone child in frame)
            {
                FindFrames(child, duplicates);
            }
        }
Пример #9
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);
            }
        }
Пример #10
0
        void DeleteMeshesInSubframes(remBone frame)
        {
            remMesh mesh = rem.FindMesh(frame, Parser.MESC);
            if (mesh != null)
            {
                rem.RemoveMesh(Parser, mesh);
            }

            foreach (remBone child in frame)
            {
                DeleteMeshesInSubframes(child);
            }
        }
Пример #11
0
        void ChildsFirst(remBone frame)
        {
            foreach (remBone child in frame)
            {
                ChildsFirst(child);
            }

            Parser.BONC.ChildList.Add(frame);
        }
Пример #12
0
        void AddFrame(remBone newFrame, int destParentIdx)
        {
            List<string> duplicates = new List<string>();
            FindFrames(newFrame, duplicates);
            if (duplicates.Count > 0)
            {
                StringBuilder builder = new StringBuilder(1000);
                for (int i = 0; i < duplicates.Count; i++)
                {
                    string s = duplicates[i];
                    builder.AppendFormat(" {0}", s);
                    if (i < duplicates.Count - 1)
                    {
                        builder.Append(',');
                    }
                }
                throw new Exception("New hierarchy includes frames with names already present.\n   " + builder.ToString());
            }

            if (destParentIdx < 0)
            {
                Parser.BONC.rootFrame.AddChild(newFrame);
            }
            else
            {
                Parser.BONC[destParentIdx].AddChild(newFrame);
            }
            RebuildBONC();
        }
Пример #13
0
        private static remBONCsection ReadBones(string sectionName, int sectionLength, int numBones, byte[] sectionBuffer)
        {
            remBONCsection boneSec = new remBONCsection(numBones);
            int secBufIdx = 0;
            for (int subSection = 0; subSection < numBones; 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);

                remBone bone = new remBone(length > 256+16*4+4 ? (length - 256+16*4+4) / 256 : 0);
                Trace.Assert(TypeCheck(remBone.ClassType, type));
                bone.name = GetIdentifier(sectionBuffer, secBufIdx+8);

                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, secBufIdx+8+256 + (i*4 + j) * 4);
                    matrix.set_Rows(i, row);
                }
                bone.matrix = matrix;

                int numChilds = BitConverter.ToInt32(sectionBuffer, secBufIdx+8+256 + 16*4);
                List<remId> childNames = new List<remId>(numChilds);
                for (int i = 0; i < numChilds; i++)
                    childNames.Add(GetIdentifier(sectionBuffer, secBufIdx+8+256 + 16*4 + 4 + i*256));
                AddParentBone(boneSec, bone, childNames);

                secBufIdx += length;
            }

            for (int i = 0; i < numBones; i++)
            {
                if (boneSec[i].Parent == null)
                {
                    boneSec[i].Parent = boneSec.rootFrame;
                    boneSec.rootFrame.AddChild(boneSec[i]);
                }
            }

            if (secBufIdx != sectionLength)
                Report.ReportLog("Warning! BONC section has wrong length.");
            return boneSec;
        }
Пример #14
0
        private static void AddParentBone(remBONCsection sec, remBone parent, List<remId> childNames)
        {
            for (int i = 0; i < childNames.Count; i++)
            {
                remId child = childNames[i];
                for (int j = 0; j < sec.Count; j++)
                {
                    if (sec[j].name == child)
                    {
                        parent.AddChild(sec[j]);
                        break;
                    }
                }
            }

            sec.ChildList.Add(parent);
        }