我要发帖 回复

正式会员

1

主题

29

积分

0

专家分

兴趣点(最多三项):

地形仿真

私信
发表时间 : 2015-10-12 19:42:53 | 浏览 : 1312    评论 : 0
将下面的脚本放在你项目目录下资源文件夹的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        }

最近VR访客

手机版|VR开发网 统计 津ICP备18009691号
网安备12019202000257

GMT+8, 2022-6-27 07:39 PM

返回顶部