165 lines
7.1 KiB
C#
165 lines
7.1 KiB
C#
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<Vector3>();
|
|
var uv = new List<Vector2>();
|
|
var normal = new List<Vector3>();
|
|
var triangles = new List<int>();
|
|
var meshFilters = Object.FindObjectsOfType<MeshFilter>();
|
|
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>();
|
|
// meshFilter.sharedMesh = mesh;
|
|
// meshObj.AddComponent<MeshRenderer>();
|
|
|
|
//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<Vector3> vertices, IList<Vector2> uv, IList<Vector3> normal, IList<int> 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);
|
|
// }
|
|
//} |