public void CalculateNormals(object[] editors, object[] numMeshes, object[] meshes, double threshold) { if (editors == null || numMeshes == null || meshes == null) { return; } List <rem.Submesh> submeshList = new List <rem.Submesh>(meshes.Length); remEditor editor = null; int editorIdx = -1; int i = 1; foreach (object id in meshes) { if (--i == 0) { editorIdx++; i = (int)(double)numMeshes[editorIdx]; editor = (remEditor)editors[editorIdx]; } rem.Mesh mesh = new rem.Mesh(editor.Meshes[(int)(double)id], rem.FindSkin(editor.Meshes[(int)(double)id].name, editor.Parser.SKIC)); submeshList.AddRange(mesh.ChildList); } rem.CalculateNormals(submeshList, (float)threshold); }
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 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); } } }