Unity3D中的地形转成模型

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().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));
}
}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值