using UnityEngine;
using UnityEditor;
using System;
using System.Collections;
using System.IO;
using System.Text;
enum SaveFormat { Triangles, Quads }
enum SaveResolution { Full=0, Half, Quarter, Eighth, Sixteenth }
class ExportTerrain : EditorWindow
{
SaveFormat saveFormat = SaveFormat.Triangles;
SaveResolution saveResolution = SaveResolution.Half;
static TerrainData terrain;
static Vector3 terrainPos;
int tCount; int counter; int totalCount; int progressUpdateInterval = 10000;
[MenuItem("Terrain/Export To Obj...")]
static void Init() {
terrain = null;
Terrain terrainObject = Selection.activeObject as Terrain;
if (!terrainObject)
{
terrainObject = Terrain.activeTerrain;
}
if (terrainObject)
{
terrain = terrainObject.terrainData; terrainPos = terrainObject.transform.position;
}
EditorWindow.GetWindow<ExportTerrain>().Show();
}
void OnGUI()
{
if (!terrain) {
GUILayout.Label("No terrain found");
if (GUILayout.Button("Cancel"))
{
EditorWindow.GetWindow<ExportTerrain>().Close();
}
return;
}
saveFormat = (SaveFormat) EditorGUILayout.EnumPopup("Export Format", saveFormat);
saveResolution = (SaveResolution) EditorGUILayout.EnumPopup("Resolution", saveResolution);
if (GUILayout.Button("Export"))
{
Export();
}
}
void Export()
{
string fileName = EditorUtility.SaveFilePanel("Export .obj file", "", "Terrain", "obj");
int w = terrain.heightmapWidth;
int h = terrain.heightmapHeight;
Vector3 meshScale = terrain.size;
int tRes = (int)Mathf.Pow(2, (int)saveResolution );
meshScale = new Vector3(meshScale.x / (w - 1) * tRes, meshScale.y, meshScale.z / (h - 1) * tRes); Vector2 uvScale = new Vector2(1.0f / (w - 1), 1.0f / (h - 1));
float[,] tData = terrain.GetHeights(0, 0, w, h);
w = (w - 1) / tRes + 1; h = (h - 1) / tRes + 1;
Vector3[] tVertices = new Vector3[w * h];
Vector2[] tUV = new Vector2[w * h];
int[] tPolys;
if (saveFormat == SaveFormat.Triangles)
{
tPolys = new int[(w - 1) * (h - 1) * 6];
} else {
tPolys = new int[(w - 1) * (h - 1) * 4];
}
// Build vertices and UVs
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
tVertices[y * w + x] = Vector3.Scale(meshScale, new Vector3(-y, tData[x * tRes, y * tRes], x)) + terrainPos; tUV[y * w + x] = Vector2.Scale( new Vector2(x * tRes, y * tRes), uvScale);
}
}
int index = 0;
if (saveFormat == SaveFormat.Triangles)
{
// Build triangle indices: 3 indices into vertex array for each triangle
for (int y = 0; y < h - 1; y++)
{ for (int x = 0; x < w - 1; x++)
{
// For each grid cell output two triangles
tPolys[index++] = (y * w) + x;
tPolys[index++] = ((y + 1) * w) + x;
tPolys[index++] = (y * w) + x + 1;
tPolys[index++] = ((y + 1) * w) + x;
tPolys[index++] = ((y + 1) * w) + x + 1;
tPolys[index++] = (y * w) + x + 1; }
}
} else {
// Build quad indices: 4 indices into vertex array for each quad
for (int y = 0; y < h - 1; y++)
{ for (int x = 0; x < w - 1; x++)
{ // For each grid cell output one quad
tPolys[index++] = (y * w) + x; tPolys[index++] = ((y + 1) * w) + x;
tPolys[index++] = ((y + 1) * w) + x + 1; tPolys[index++] = (y * w) + x + 1;
}
}
}
// Export to .obj
StreamWriter sw = new StreamWriter(fileName);
try {
sw.WriteLine("# Unity terrain OBJ File");
// Write vertices
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
counter = tCount = 0;
totalCount = (tVertices.Length * 2 + (saveFormat == SaveFormat.Triangles ? tPolys.Length / 3 : tPolys.Length / 4)) / progressUpdateInterval;
for (int i = 0; i < tVertices.Length; i++)
{
UpdateProgress();
StringBuilder sb = new StringBuilder("v ", 20);
// StringBuilder stuff is done this way because it's faster than using the "{0} {1} {2}"etc. format
// Which is important when you're exporting huge terrains.
sb.Append(tVertices[i].x.ToString()).Append(" "). Append(tVertices[i].y.ToString()).Append(" "). Append(tVertices[i].z.ToString()); sw.WriteLine(sb);
}
// Write UVs
for (int i = 0; i < tUV.Length; i++) {
UpdateProgress();
StringBuilder sb = new StringBuilder("vt ", 22);
sb.Append(tUV[i].x.ToString()).Append(" "). Append(tUV[i].y.ToString()); sw.WriteLine(sb); }
if (saveFormat == SaveFormat.Triangles)
{
// Write triangles
for (int i = 0; i < tPolys.Length; i += 3)
{
UpdateProgress();
StringBuilder sb = new StringBuilder("f ", 43);
sb.Append(tPolys[i] + 1).Append("/").Append(tPolys[i] + 1).Append(" ").
Append(tPolys[i + 1] + 1).Append("/").Append(tPolys[i + 1] + 1).
Append(" "). Append(tPolys[i + 2] + 1).Append("/").Append(tPolys[i + 2] + 1);
sw.WriteLine(sb);
}
} else {
// Write quads
for (int i = 0; i < tPolys.Length; i += 4)
{
UpdateProgress();
StringBuilder sb = new StringBuilder("f ", 57);
sb.Append(tPolys[i] + 1).Append("/").Append(tPolys[i] + 1).Append(" ").
Append(tPolys[i + 1] + 1).Append("/").Append(tPolys[i + 1] + 1).Append(" ").
Append(tPolys[i + 2] + 1).Append("/").Append(tPolys[i + 2] + 1).Append(" ").
Append(tPolys[i + 3] + 1).Append("/").Append(tPolys[i + 3] + 1); sw.WriteLine(sb);
}
}
} catch(Exception err)
{
Debug.Log("Error saving file: " + err.Message);
}
sw.Close();
terrain = null;
EditorUtility.DisplayProgressBar("Saving file to disc.", "This might take a while...", 1f);
EditorWindow.GetWindow<ExportTerrain>().Close(); EditorUtility.ClearProgressBar();
}
void UpdateProgress()
{
if (counter++ == progressUpdateInterval)
{ counter = 0; EditorUtility.DisplayProgressBar("Saving...", "", Mathf.InverseLerp(0, totalCount, ++tCount));
}
}
}
Unity3D中的地形轉成模型
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章
unity3d筆記(3)——地形創建
大禹不治水
2020-06-16 14:45:31
Unity 使用SpriteShape製作2D遊戲任意形狀地形
林新发
2020-04-23 11:55:55
中級Shader教程15 地形渲染
JiepengTan
2018-09-02 06:25:02
數字表面模型(DSM)
yongzhewuju888
2018-08-30 21:22:08
A Robust and Easy to Implement Method for IMU Calibration without
木独
2020-06-26 15:40:28
MPU9250和ICM20948區別(含詳細對比和遷移方案)電源設計部分要注意
灵魂新纪元
2020-05-21 00:52:27
更改MPU6050的IIC端口
大写的小写字母
2020-05-03 03:24:44
無人機中的IMU單元(MEMS 三軸加速計、三軸陀螺儀、三軸磁力計)
qq_35379989
2020-03-02 20:39:37
基於無跡卡爾曼濾波器(UKF)的9軸IMU姿態解算算法
木独
2020-02-23 00:39:32
ios檢測設備攝像頭、指南針、錄音、陀螺儀的狀態
穿马甲的小样
2020-02-22 20:22:48
iOS 搖一搖,陀螺儀,距離傳感器,計步器簡單介紹
sw_gegewu
2020-02-22 06:47:07
Allan Variance:傳感器隨機誤差實驗代碼(matlab)
print("滚去学习")
2020-02-21 15:17:50
安卓系統通過"陀螺儀"計算當前座標(焦點位置)
大昱
2019-02-03 02:22:35
unity 陀螺儀的腳本
2537God
2018-09-04 06:08:39
【翻譯】加速度計和陀螺儀指南
gmdjmawy
2018-08-28 13:04:06