using System; using System.Collections.Generic; using System.IO; using System.Text; using Module.Log; using UnityEditor; using UnityEngine; using UnityEngine.SceneManagement; using Object = UnityEngine.Object; public class ExtractSceneMesh { [MenuItem("Scene/Extract SceneMesh Combined")] public static void Extract() { if (EditorUtility.DisplayDialog("导出场景模型", "将场景的所有物体导出为合并模型?", "确认", "取消")) { var vertices = new List(); var uv = new List(); var normal = new List(); var triangles = new List(); var meshFilters = Object.FindObjectsOfType(); for (var i = 0; i < meshFilters.Length; i++) { var filter = meshFilters[i]; if (!filter.gameObject.activeInHierarchy) { } else if (filter.sharedMesh == null) { LogModule.ErrorLog("Filter has no mesh " + filter.transform.GetHierarchyName()); } else if (!filter.sharedMesh.isReadable) { LogModule.WarningLog("Mesh isn't readable " + filter.sharedMesh.name); } else { var start = vertices.Count; var trs = Matrix4x4.TRS(filter.transform.position, filter.transform.rotation, filter.transform.localScale); var meshVertices = filter.sharedMesh.vertices; var meshUv = filter.sharedMesh.uv; var meshNormal = filter.sharedMesh.normals; var subMeshCount = filter.sharedMesh.subMeshCount; for (var j = 0; j < meshVertices.Length; j++) vertices.Add(trs.MultiplyPoint3x4(meshVertices[j])); for (var j = 0; j < meshNormal.Length; j++) normal.Add(filter.transform.rotation * meshNormal[j]); for (var j = 0; j < meshUv.Length; j++) uv.Add(meshUv[j]); for (var k = 0; k < subMeshCount; k++) { var meshTriangle = filter.sharedMesh.GetTriangles(k); for (var j = 0; j < meshTriangle.Length; j++) triangles.Add(meshTriangle[j] + start); } } } // // var mesh = new Mesh(); // mesh.SetVertices(vertices); // mesh.SetNormals(normal); // mesh.SetUVs(0, uv); // mesh.SetTriangles(triangles, 0); // LogModule.WarningLog("V Count " + vertices.Count); // var meshObj = new GameObject("Mesh"); // var meshFilter = meshObj.AddComponent(); // meshFilter.sharedMesh = mesh; // meshObj.AddComponent(); //ObjExtractHelp.DoExport(mesh); var sceneName = SceneManager.GetActiveScene().name; if (string.IsNullOrEmpty(sceneName)) sceneName = "NewScene"; var path = Application.dataPath + "/_Test/SceneMesh"; if (!Directory.Exists(path)) Directory.CreateDirectory(path); path += "/" + sceneName + "SceneMesh.obj"; ObjExtract(vertices, uv, normal, triangles, path); AssetDatabase.Refresh(); LogModule.WarningLog("Mesh Exported at " + path); } } public static void ObjExtract(IList vertices, IList uv, IList normal, IList triangleList, string path) { var builder = new StringBuilder(); var sceneName = Path.GetFileNameWithoutExtension(path); builder.Append("#" + sceneName + ".obj" + "\n#" + DateTime.Now.ToLongDateString() + "\n#" + DateTime.Now.ToLongTimeString() + "\n#-------" + "\n\n"); builder.Append("g ").Append(sceneName).Append("\n"); builder.Append("#").Append(sceneName).Append("\n#-------").Append("\n"); foreach (var v in vertices) builder.Append(string.Format("v {0} {1} {2}\n", -v.x, v.y, v.z)); builder.Append("\n"); foreach (var v in normal) builder.Append(string.Format("vn {0} {1} {2}\n", -v.x, v.y, v.z)); builder.Append("\n"); foreach (var v in uv) builder.Append(string.Format("vt {0} {1}\n", v.x, v.y)); builder.Append("\n"); builder.Append("usemtl ").Append("Dummy").Append("\n"); builder.Append("usemap ").Append("Dummy").Append("\n"); var triangles = triangleList; for (var i = 0; i < triangles.Count; i += 3) builder.Append(string.Format("f {0}/{0}/{0} {2}/{2}/{2} {1}/{1}/{1}\n", triangles[i] + 1, triangles[i + 1] + 1, triangles[i + 2] + 1)); File.WriteAllText(path, builder.ToString()); } // // public static void MeshToString(StringBuilder builder, Mesh m) // { // foreach (var v in m.vertices) // builder.Append(string.Format("v {0} {1} {2}\n", -v.x, v.y, v.z)); // builder.Append("\n"); // foreach (var v in m.normals) // builder.Append(string.Format("vn {0} {1} {2}\n", -v.x, v.y, v.z)); // builder.Append("\n"); // foreach (var v in m.uv) // builder.Append(string.Format("vt {0} {1}\n", v.x, v.y)); // builder.Append("\n"); // builder.Append("usemtl ").Append("Dummy").Append("\n"); // builder.Append("usemap ").Append("Dummy").Append("\n"); // var triangles = m.triangles; // for (var i = 0; i < triangles.Length; i += 3) // builder.Append(string.Format("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}\n", // triangles[i] + 1, triangles[i + 1] + 1, triangles[i + 2] + 1)); // } } // //public static class ObjExtractScript //{ // //} // //public static class ObjExtractHelp //{ // public static void DoExport(Mesh mesh) // { // var builder = new StringBuilder(); // var sceneName = SceneManager.GetActiveScene().name; // if (string.IsNullOrEmpty(sceneName)) // sceneName = "NewScene"; // builder.Append("#" + sceneName + ".obj" // + "\n#" + DateTime.Now.ToLongDateString() // + "\n#" + DateTime.Now.ToLongTimeString() // + "\n#-------" // + "\n\n"); // builder.Append("g ").Append(sceneName).Append("\n"); // builder.Append("#").Append(sceneName).Append("\n#-------").Append("\n"); // ObjExtractScript.MeshToString(builder, mesh); // var path = Application.dataPath + "/_Test/SceneMesh"; // if (!Directory.Exists(path)) // Directory.CreateDirectory(path); // path += "/" + sceneName + "SceneMesh.obj"; // File.WriteAllText(path, builder.ToString()); // AssetDatabase.Refresh(); // LogModule.WarningLog("Mesh Exported at " + path); // } //}