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(); } } } }
public remBone Clone(bool mesh, bool childFrames, remParser parser, List <remMaterial> clonedMaterials, List <remMesh> clonedMeshes, List <remSkin> clonedSkins) { remBone frame = new remBone(Count); frame.name = name; frame.matrix = matrix; if (mesh) { remMesh remMesh = rem.FindMesh(this, parser.MESC); if (remMesh != null) { foreach (remId matId in remMesh.materials) { remMaterial mat = rem.FindMaterial(matId, parser.MATC); if (!clonedMaterials.Contains(mat)) { clonedMaterials.Add(mat.Clone()); } } remMesh clone = remMesh.Clone(true, true, parser, clonedSkins); clone.frame = frame.name; clonedMeshes.Add(clone); } } if (childFrames) { for (int i = 0; i < Count; i++) { frame.AddChild(this[i].Clone(mesh, true, parser, clonedMaterials, clonedMeshes, clonedSkins)); } } return(frame); }
public static void SaveREM(remParser parser, string destPath, bool keepBackup, string backupExt) { DirectoryInfo dir = new DirectoryInfo(Path.GetDirectoryName(destPath)); string backup = null; if (keepBackup && File.Exists(destPath)) { backup = Utility.GetDestFile(dir, Path.GetFileNameWithoutExtension(destPath) + ".bak", backupExt); File.Move(destPath, backup); } try { using (BufferedStream bufStr = new BufferedStream(File.OpenWrite(destPath))) { parser.WriteTo(bufStr); } } catch { if (File.Exists(backup)) { if (File.Exists(destPath)) { File.Delete(destPath); } File.Move(backup, destPath); } } }
public static HashSet <string> SearchHierarchy(remParser parser, remMesh mesh) { HashSet <string> exportFrames = new HashSet <string>(); SearchHierarchy(parser.BONC.rootFrame, mesh, exportFrames); remSkin boneList = FindSkin(mesh.name, parser.SKIC); if (boneList != null) { for (int i = 0; i < boneList.Count; i++) { if (!exportFrames.Contains(boneList[i].bone.ToString())) { remBone boneParent = FindFrame(boneList[i].bone, parser.BONC.rootFrame); if (boneParent == null) { Report.ReportLog("Missing bone frame " + boneList[i].bone); continue; } while (boneParent.Parent != null && exportFrames.Add(boneParent.name.ToString())) { boneParent = (remBone)boneParent.Parent; } } } } return(exportFrames); }
public void MergeTexture(string tex, remParser srcParser) { String src_TEXH_folder = rem.TexturePathFromREM(srcParser.RemPath); if (src_TEXH_folder == null) { Report.ReportLog("TEXH folder could not be located."); return; } String texh_folder = rem.TexturePathFromREM(Parser.RemPath); if (texh_folder == null) { Report.ReportLog("TEXH folder could not be located."); return; } if (src_TEXH_folder != texh_folder) { ImportedTexture impTex = new ImportedTexture(src_TEXH_folder + @"\" + tex); string newTex = rem.CreateTexture(impTex, texh_folder); if (!Textures.Contains(newTex)) { Textures.Add(newTex); } } }
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); } } }
public static void ReplaceMaterial(remParser parser, ImportedMaterial material) { remMaterial mat = CreateMaterial(material); bool found = false; for (int i = 0; i < parser.MATC.Count; i++) { if (parser.MATC[i].name == material.Name) { remMaterial original = parser.MATC[i]; CopyUnknown(original, mat); parser.MATC.RemoveChild(i); parser.MATC.InsertChild(i, mat); found = true; break; } } if (!found) { CreateUnknown(mat); parser.MATC.AddChild(mat); } }
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); } } }
public remMesh Clone(bool submeshes, bool boneList, remParser parser, List <remSkin> clonedSkins) { remMesh mesh = new remMesh(numMats); mesh.name = new remId(name); rem.CopyUnknowns(this, mesh); if (submeshes) { for (int i = 0; i < numMats; i++) { mesh.AddMaterial(new remId(materials[i])); } mesh.vertices = new remVertex[numVertices]; for (int i = 0; i < numVertices; i++) { mesh.vertices[i] = vertices[i].Clone(); } mesh.faces = (int[])faces.Clone(); mesh.faceMarks = (int[])faceMarks.Clone(); } remSkin skin = rem.FindSkin(name, parser.SKIC); if (skin != null) { skin = skin.Clone(); skin.mesh = mesh.name; clonedSkins.Add(skin); } return(mesh); }
public static void Export(string dirPath, remParser parser, List <remMesh> meshes, bool singleMqo, bool worldCoords) { DirectoryInfo dir = new DirectoryInfo(dirPath); List <string> usedTextures = new List <string>(parser.MATC.Count); if (singleMqo) { try { string dest = Utility.GetDestFile(dir, "meshes", ".mqo"); List <string> texList = Export(dest, parser, meshes, worldCoords); foreach (string tex in texList) { if (!usedTextures.Contains(tex)) { usedTextures.Add(tex); } } Report.ReportLog("Finished exporting meshes to " + dest); } catch (Exception ex) { Report.ReportLog("Error exporting meshes: " + ex.Message); } } else { for (int i = 0; i < meshes.Count; i++) { try { string frameName = meshes[i].name; string dest = dir.FullName + @"\" + frameName + ".mqo"; List <string> texList = Export(dest, parser, new List <remMesh> { meshes[i] }, worldCoords); foreach (string tex in texList) { if (!usedTextures.Contains(tex)) { usedTextures.Add(tex); } } Report.ReportLog("Finished exporting mesh to " + dest); } catch (Exception ex) { Report.ReportLog("Error exporting mesh: " + ex.Message); } } } foreach (string tex in usedTextures) { rem.ExportTexture(tex, parser.RemPath, dir.FullName); } }
public remEditor(remParser parser) { Parser = parser; Frames = parser.BONC.ChildList; Meshes = parser.MESC.ChildList; Materials = parser.MATC.ChildList; Textures = new List<string>(parser.MATC.Count); InitTextures(false, false); }
public remEditor(remParser parser) { Parser = parser; Frames = parser.BONC.ChildList; Meshes = parser.MESC.ChildList; Materials = parser.MATC.ChildList; Textures = new List <string>(parser.MATC.Count); InitTextures(false, false); }
public static void Export(string dirPath, remParser parser, List<remMesh> meshes, bool singleMqo, bool worldCoords) { DirectoryInfo dir = new DirectoryInfo(dirPath); List<string> usedTextures = new List<string>(parser.MATC.Count); if (singleMqo) { try { string dest = Utility.GetDestFile(dir, "meshes", ".mqo"); List<string> texList = Export(dest, parser, meshes, worldCoords); foreach (string tex in texList) { if (!usedTextures.Contains(tex)) { usedTextures.Add(tex); } } Report.ReportLog("Finished exporting meshes to " + dest); } catch (Exception ex) { Report.ReportLog("Error exporting meshes: " + ex.Message); } } else { for (int i = 0; i < meshes.Count; i++) { try { string frameName = meshes[i].name; string dest = dir.FullName + @"\" + frameName + ".mqo"; List<string> texList = Export(dest, parser, new List<remMesh> { meshes[i] }, worldCoords); foreach (string tex in texList) { if (!usedTextures.Contains(tex)) { usedTextures.Add(tex); } } Report.ReportLog("Finished exporting mesh to " + dest); } catch (Exception ex) { Report.ReportLog("Error exporting mesh: " + ex.Message); } } } foreach (string tex in usedTextures) { rem.ExportTexture(tex, parser.RemPath, dir.FullName); } }
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); } }
public void ConvertAnimation(reaANICsection animSection, remParser parser) { ImportedSampledAnimation anim = new ImportedSampledAnimation(); anim.TrackList = new List <ImportedAnimationSampledTrack>(animSection.Count); foreach (reaAnimationTrack track in animSection) { remBone boneFrame = rem.FindFrame(track.boneFrame, parser.BONC.rootFrame); bool isTopFrame = boneFrame != null && boneFrame.Parent == parser.BONC.rootFrame; ImportedAnimationSampledTrack iTrack = ConvertTrack(track, isTopFrame); anim.TrackList.Add(iTrack); } AnimationList.Add(anim); }
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); }
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); }
public REMConverter(remParser parser, List <remMesh> meshes) { FrameList = new List <ImportedFrame>(); ConvertFrames(parser.BONC.rootFrame); foreach (ImportedFrame frame in FrameList[0]) { if (rem.FindMesh(new remId(frame.Name), parser.MESC) != null) { frame.Matrix = Matrix.Identity; } else { frame.Matrix *= Matrix.Scaling(1f, 1f, -1f); } } ConvertMeshes(meshes, parser); AnimationList = new List <ImportedAnimation>(); }
public void MergeFrame(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); MergeFrame(newFrame, destParentIdx); PullNewMaterials(materialClones); Parser.MESC.ChildList.AddRange(meshClones); Parser.SKIC.ChildList.AddRange(skinClones); }
public static void ExportMqo([DefaultVar] remParser parser, object[] meshNames, string dirPath, bool singleMqo, bool worldCoords) { List <remMesh> meshes = new List <remMesh>(meshNames.Length); foreach (string meshName in Utility.Convert <string>(meshNames)) { remMesh mesh = rem.FindMesh(new remId(meshName), parser.MESC); if (mesh != null) { meshes.Add(mesh); } else { Report.ReportLog("Mesh " + meshName + " not found"); } } Mqo.Exporter.Export(dirPath, parser, meshes, singleMqo, worldCoords); }
public static void ExportFbx([DefaultVar] remParser parser, object[] meshNames, object[] reaParsers, int startKeyframe, int endKeyframe, bool linear, bool EulerFilter, double filterPrecision, string path, string exportFormat, bool allFrames, bool skins, bool compatibility) { List <reaParser> reaParserList = null; if (reaParsers != null) { reaParserList = new List <reaParser>(Utility.Convert <reaParser>(reaParsers)); } List <string> meshStrList = new List <string>(Utility.Convert <string>(meshNames)); List <remMesh> meshes = new List <remMesh>(meshStrList.Count); foreach (string meshName in meshStrList) { remMesh mesh = rem.FindMesh(new remId(meshName), parser.MESC); if (mesh != null) { meshes.Add(mesh); } else { Report.ReportLog("Mesh " + meshName + " not found."); } } REMConverter imp = new REMConverter(parser, meshes); if (reaParserList != null) { foreach (reaParser reaParser in reaParserList) { imp.ConvertAnimation(reaParser.ANIC, parser); } } FbxUtility.Export(path, imp, startKeyframe, endKeyframe, linear, EulerFilter, (float)filterPrecision, exportFormat, allFrames, false, skins, compatibility); }
private static List <string> Export(string dest, remParser parser, List <remMesh> meshes, bool worldCoords) { List <string> usedTextures = new List <string>(parser.MATC.Count); DirectoryInfo dir = new DirectoryInfo(Path.GetDirectoryName(dest)); if (!dir.Exists) { dir.Create(); } List <rem.Mesh> convertedMeshes = new List <rem.Mesh>(meshes.Count); List <int> materialList = new List <int>(parser.MATC.Count); using (StreamWriter writer = new StreamWriter(dest, false)) { for (int i = 0; i < meshes.Count; i++) { rem.Mesh meshListSome = new rem.Mesh(meshes[i], null); convertedMeshes.Add(meshListSome); for (int j = 0; j < meshListSome.Count; j++) { rem.Submesh meshObj = meshListSome[j]; remMaterial mat = rem.FindMaterial(meshObj.MaterialName, parser.MATC); if (mat != null) { int meshObjMatIdx = parser.MATC.IndexOf(mat); if (!materialList.Contains(meshObjMatIdx)) { materialList.Add(meshObjMatIdx); } } else { Report.ReportLog("Warning: Mesh " + meshes[i].name + " Object " + j + " has an invalid material"); } } } writer.WriteLine("Metasequoia Document"); writer.WriteLine("Format Text Ver 1.0"); writer.WriteLine(); writer.WriteLine("Material " + materialList.Count + " {"); foreach (int matIdx in materialList) { remMaterial mat = parser.MATC[matIdx]; string s = "\t\"" + mat.name + "\" col(0.800 0.800 0.800 1.000) dif(0.500) amb(0.100) emi(0.500) spc(0.100) power(30.00)"; string matTexName = mat.texture; if (matTexName != null) { s += " tex(\"" + Path.GetFileName(matTexName) + "\")"; } writer.WriteLine(s); } writer.WriteLine("}"); Random rand = new Random(); for (int i = 0; i < meshes.Count; i++) { remBone parent = rem.FindFrame(meshes[i].frame, parser.BONC.rootFrame); float scale = Math.Abs(parent.matrix.M11); Matrix transform = Matrix.Scaling(-1f, 1f, 1f); if (worldCoords) { while (parent != parser.BONC.rootFrame) { transform *= parent.matrix; parent = parent.Parent as remBone; } } string meshName = meshes[i].name; if (scale != 1f) { meshName += "(Scale=" + scale.ToString() + ")"; } rem.Mesh meshListSome = convertedMeshes[i]; for (int j = 0; j < meshListSome.Count; j++) { rem.Submesh meshObj = meshListSome[j]; remMaterial mat = rem.FindMaterial(meshObj.MaterialName, parser.MATC); int mqoMatIdx = -1; if (mat != null) { int meshObjMatIdx = parser.MATC.IndexOf(mat); mqoMatIdx = materialList.IndexOf(meshObjMatIdx); } float[] color = new float[3]; for (int k = 0; k < color.Length; k++) { color[k] = (float)((rand.NextDouble() / 2) + 0.5); } string mqoName = meshName + "[" + j + "]"; if (worldCoords) { mqoName += "[W]"; } writer.WriteLine("Object \"" + mqoName + "\" {"); writer.WriteLine("\tshading 1"); writer.WriteLine("\tcolor " + color[0].ToFloatString() + " " + color[1].ToFloatString() + " " + color[2].ToFloatString()); writer.WriteLine("\tcolor_type 1"); List <ImportedVertex> vertList = worldCoords ? rem.ImportedVertexListUnskinnedWorld(meshObj.VertexList, transform) : rem.ImportedVertexListUnskinned(meshObj.VertexList, scale); List <ImportedFace> faceList = rem.ImportedFaceList(meshObj.FaceList); SB3Utility.Mqo.ExporterCommon.WriteMeshObject(writer, vertList, faceList, mqoMatIdx, null); writer.WriteLine("}"); } } writer.WriteLine("Eof"); } foreach (int matIdx in materialList) { remMaterial mat = parser.MATC[matIdx]; string matTexName = mat.texture; if (matTexName != null && !usedTextures.Contains(matTexName)) { usedTextures.Add(matTexName); } } return(usedTextures); }
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--; } } } }
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(); } } } }
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); } }
private static List<string> Export(string dest, remParser parser, List<remMesh> meshes, bool worldCoords) { List<string> usedTextures = new List<string>(parser.MATC.Count); DirectoryInfo dir = new DirectoryInfo(Path.GetDirectoryName(dest)); if (!dir.Exists) { dir.Create(); } List<rem.Mesh> convertedMeshes = new List<rem.Mesh>(meshes.Count); List<int> materialList = new List<int>(parser.MATC.Count); using (StreamWriter writer = new StreamWriter(dest, false)) { for (int i = 0; i < meshes.Count; i++) { rem.Mesh meshListSome = new rem.Mesh(meshes[i], null); convertedMeshes.Add(meshListSome); for (int j = 0; j < meshListSome.Count; j++) { rem.Submesh meshObj = meshListSome[j]; remMaterial mat = rem.FindMaterial(meshObj.MaterialName, parser.MATC); if (mat != null) { int meshObjMatIdx = parser.MATC.IndexOf(mat); if (!materialList.Contains(meshObjMatIdx)) { materialList.Add(meshObjMatIdx); } } else { Report.ReportLog("Warning: Mesh " + meshes[i].name + " Object " + j + " has an invalid material"); } } } writer.WriteLine("Metasequoia Document"); writer.WriteLine("Format Text Ver 1.0"); writer.WriteLine(); writer.WriteLine("Material " + materialList.Count + " {"); foreach (int matIdx in materialList) { remMaterial mat = parser.MATC[matIdx]; string s = "\t\"" + mat.name + "\" col(0.800 0.800 0.800 1.000) dif(0.500) amb(0.100) emi(0.500) spc(0.100) power(30.00)"; string matTexName = mat.texture; if (matTexName != null) { s += " tex(\"" + Path.GetFileName(matTexName) + "\")"; } writer.WriteLine(s); } writer.WriteLine("}"); Random rand = new Random(); for (int i = 0; i < meshes.Count; i++) { remBone parent = rem.FindFrame(meshes[i].frame, parser.BONC.rootFrame); float scale = Math.Abs(parent.matrix.M11); Matrix transform = Matrix.Scaling(-1f, 1f, 1f); if (worldCoords) { while (parent != parser.BONC.rootFrame) { transform *= parent.matrix; parent = parent.Parent as remBone; } } string meshName = meshes[i].name; if (scale != 1f) { meshName += "(Scale=" + scale.ToString() + ")"; } rem.Mesh meshListSome = convertedMeshes[i]; for (int j = 0; j < meshListSome.Count; j++) { rem.Submesh meshObj = meshListSome[j]; remMaterial mat = rem.FindMaterial(meshObj.MaterialName, parser.MATC); int mqoMatIdx = -1; if (mat != null) { int meshObjMatIdx = parser.MATC.IndexOf(mat); mqoMatIdx = materialList.IndexOf(meshObjMatIdx); } float[] color = new float[3]; for (int k = 0; k < color.Length; k++) { color[k] = (float)((rand.NextDouble() / 2) + 0.5); } string mqoName = meshName + "[" + j + "]"; if (worldCoords) { mqoName += "[W]"; } writer.WriteLine("Object \"" + mqoName + "\" {"); writer.WriteLine("\tshading 1"); writer.WriteLine("\tcolor " + color[0].ToFloatString() + " " + color[1].ToFloatString() + " " + color[2].ToFloatString()); writer.WriteLine("\tcolor_type 1"); List<ImportedVertex> vertList = worldCoords ? rem.ImportedVertexListUnskinnedWorld(meshObj.VertexList, transform) : rem.ImportedVertexListUnskinned(meshObj.VertexList, scale); List<ImportedFace> faceList = rem.ImportedFaceList(meshObj.FaceList); SB3Utility.Mqo.ExporterCommon.WriteMeshObject(writer, vertList, faceList, mqoMatIdx, null); writer.WriteLine("}"); } } writer.WriteLine("Eof"); } foreach (int matIdx in materialList) { remMaterial mat = parser.MATC[matIdx]; string matTexName = mat.texture; if (matTexName != null && !usedTextures.Contains(matTexName)) { usedTextures.Add(matTexName); } } return usedTextures; }
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); }
public void Dispose() { Textures.Clear(); Parser = null; }
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; }
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--; } } } }
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; }
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); } }
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); } } }