加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

将Unity3D中的地形导出为*.Obj模型文件(转)

(2011-07-14 15:11:55)
标签:

杂谈

分类: unity

将下面的脚本放在你项目目录下资源文件夹的Editor里.
要导出地形,首先在你的场景中选中地形对象.如果没选,他将用于当前场景中可用的地形.从Terrain菜单下选择Export To Obj... ,在分辨率窗口,选择你要四边形还是三角形网格结构.同样也可以选择要导出地形的分辨率,有高中低等等.点击Export,选择要保存的位置和文件名.Obj文件将被导出.要注意如果选择大面积的Full地形导出,最终的Obj文件将非常大,而且也要导出很久.

下面为ExportTerrain.js脚本.

 
001 import System.IO;
002 import System.Text;
003 enum SaveFormat {Triangles, Quads}
004 enum SaveResolution {Full, Half, Quarter, Eighth, Sixteenth}
005 class ExportTerrain extends EditorWindow {
006     var saveFormat = SaveFormat.Triangles;
007     var saveResolution = SaveResolution.Half;
008     static var terrain : TerrainData;
009     static var terrainPos : Vector3;
010      
011     var tCount : int;
012     var counter : int;
013     var totalCount : int;
014      
015     @MenuItem ("Terrain/Export To Obj...")
016     static function Init () {
017         terrain = null;
018         var terrainObject : Terrain = Selection.activeObject as Terrain;
019         if (!terrainObject) {
020             terrainObject = Terrain.activeTerrain;
021         }
022         if (terrainObject) {
023             terrain = terrainObject.terrainData;
024             terrainPos = terrainObject.transform.position;
025         }
026         EditorWindow.GetWindow(ExportTerrain).Show();
027     }
028      
029     function OnGUI () {
030         if (!terrain) {
031             GUILayout.Label("No terrain found");
032             if (GUILayout.Button("Cancel")) {
033                 EditorWindow.GetWindow(ExportTerrain).Close();
034             }
035             return;
036         }
037         saveFormat = EditorGUILayout.EnumPopup("Export Format", saveFormat);
038         saveResolution = EditorGUILayout.EnumPopup("Resolution", saveResolution);
039          
040         if (GUILayout.Button("Export")) {
041             Export();
042         }
043     }
044      
045     function Export () {
046         var fileName = EditorUtility.SaveFilePanel("Export .obj file", "", "Terrain", "obj");
047         var w = terrain.heightmapWidth;
048         var h = terrain.heightmapHeight;
049         var meshScale = terrain.size;
050         var tRes = Mathf.Pow(2, parseInt(saveResolution));
051         meshScale = Vector3(meshScale.x/(w-1)*tRes, meshScale.y, meshScale.z/(h-1)*tRes);
052         var uvScale = Vector2(1.0/(w-1), 1.0/(h-1));
053         var tData = terrain.GetHeights(0, 0, w, h);
054          
055         w = (w-1) / tRes + 1;
056         h = (h-1) / tRes + 1;
057         var tVertices = new Vector3[w * h];
058         var tUV = new Vector2[w * h];
059         if (saveFormat == SaveFormat.Triangles) {
060             var tPolys = new int[(w-1) * (h-1) * 6];
061         }
062         else {
063             tPolys = new int[(w-1) * (h-1) * 4];
064         }
065          
066         // Build vertices and UVs
067         for (y = 0; y < h; y++) {
068             for (x = 0; x < w; x++) {
069                 tVertices[y*w + x] = Vector3.Scale(meshScale, Vector3(x, tData[x*tRes,y*tRes], y)) + terrainPos;
070                 tUV[y*w + x] = Vector2.Scale(Vector2(x*tRes, y*tRes), uvScale);
071             }
072         }
073      
074         var index = 0;
075         if (saveFormat == SaveFormat.Triangles) {
076             // Build triangle indices: 3 indices into vertex array for each triangle
077             for (y = 0; y < h-1; y++) {
078                 for (x = 0; x < w-1; x++) {
079                     // For each grid cell output two triangles
080                     tPolys[index++] = (y     * w) + x;
081                     tPolys[index++] = ((y+1) * w) + x;
082                     tPolys[index++] = (y     * w) + x + 1;
083          
084                     tPolys[index++] = ((y+1) * w) + x;
085                     tPolys[index++] = ((y+1) * w) + x + 1;
086                     tPolys[index++] = (y     * w) + x + 1;
087                 }
088             }
089         }
090         else {
091             // Build quad indices: 4 indices into vertex array for each quad
092             for (y = 0; y < h-1; y++) {
093                 for (x = 0; x < w-1; x++) {
094                     // For each grid cell output one quad
095                     tPolys[index++] = (y     * w) + x;
096                     tPolys[index++] = ((y+1) * w) + x;
097                     tPolys[index++] = ((y+1) * w) + x + 1;
098                     tPolys[index++] = (y     * w) + x + 1;
099                 }
100              
101         }
102      
103         // Export to .obj
104         try {
105             var sw = new StreamWriter(fileName);
106             sw.WriteLine("# Unity terrain OBJ File");
107              
108             // Write vertices
109             System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
110             counter = tCount = 0;
111             totalCount = (tVertices.Length*2 + (saveFormat == SaveFormat.Triangles? tPolys.Length/3 : tPolys.Length/4)) / 1000;
112             for (i = 0; i < tVertices.Length; i++) {
113                 UpdateProgress();
114                 var sb = StringBuilder("v ", 20);
115                 // StringBuilder stuff is done this way because it's faster than using the "{0} {1} {2}"etc. format
116                 // Which is important when you're exporting huge terrains.
117                 sb.Append(tVertices[i].x.ToString()).Append(" ").
118                    Append(tVertices[i].y.ToString()).Append(" ").
119                    Append(tVertices[i].z.ToString());
120                 sw.WriteLine(sb);
121             }
122             // Write UVs
123             for (i = 0; i < tUV.Length; i++) {
124                 UpdateProgress();
125                 sb = StringBuilder("vt ", 22);
126                 sb.Append(tUV[i].x.ToString()).Append(" ").
127                    Append(tUV[i].y.ToString());
128                 sw.WriteLine(sb);
129             }
130             if (saveFormat == SaveFormat.Triangles) {
131                 // Write triangles
132                 for (i = 0; i < tPolys.Length; i += 3) {
133                     UpdateProgress();
134                     sb = StringBuilder("f ", 43);
135                     sb.Append(tPolys[i]+1).Append("/").Append(tPolys[i]+1).Append(" ").
136                        Append(tPolys[i+1]+1).Append("/").Append(tPolys[i+1]+1).Append(" ").
137                        Append(tPolys[i+2]+1).Append("/").Append(tPolys[i+2]+1);
138                     sw.WriteLine(sb);
139                 }
140             }
141             else {
142                 // Write quads
143                 for (i = 0; i < tPolys.Length; i += 4) {
144                     UpdateProgress();
145                     sb = StringBuilder("f ", 57);
146                     sb.Append(tPolys[i]+1).Append("/").Append(tPolys[i]+1).Append(" ").
147                        Append(tPolys[i+1]+1).Append("/").Append(tPolys[i+1]+1).Append(" ").
148                        Append(tPolys[i+2]+1).Append("/").Append(tPolys[i+2]+1).Append(" ").
149                        Append(tPolys[i+3]+1).Append("/").Append(tPolys[i+3]+1);
150                     sw.WriteLine(sb);
151                      
152             }
153         }
154         catch (err) {
155             Debug.Log("Error saving file: " + err.Message);
156         }
157         sw.Close();
158          
159         terrain = null;
160         EditorUtility.ClearProgressBar();
161         EditorWindow.GetWindow(ExportTerrain).Close();
162     }
163      
164     function UpdateProgress () {
165         if (counter++ == 1000) {
166             counter = 0;
167             EditorUtility.DisplayProgressBar("Saving...", "", Mathf.InverseLerp(0, totalCount, ++tCount));
168         }
169     }
170 }

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有