Quantcast
Channel: Questions in topic: "obj"
Viewing all articles
Browse latest Browse all 167

Modifying TerraintoObj for multiple terrain export

$
0
0
I am attempting to modify TerraintoObj (originally made by @Eric5h5) to export more than a single mesh by looping. I just started learning the scripting language and I've been holding out asking for help so I could figure it out myself but I'm stuck. In the code below I'm trying to use a do while loop to cycle through the code if terrains still exist in the scene. My end game was to have this script run without me having to confirm anything after the first format and resolution selection but I need to get past this do while loop issue first. Any help or insight is greatly appreciated! **WARNING THE CODE BELOW LOCKS UP UNITY** // Converted from UnityScript to C# at http://www.M2H.nl/files/js_to_c.php - by Mike Hergaarden // C # manual conversion work by Yun Kyu Choi 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; bool terrainPresent = true; [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().Show(); } void OnGUI() { if (!terrain) { GUILayout.Label("No terrain found"); if (GUILayout.Button("Cancel")) { EditorWindow.GetWindow().Close(); terrainPresent = false; } 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.activeTerrain.name, "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().Close(); EditorUtility.ClearProgressBar(); DestroyImmediate (Terrain.activeTerrain); if (!terrain) { terrainPresent = false; } while (terrainPresent = true) { Export (); } } void UpdateProgress() { if (counter++ == progressUpdateInterval) { counter = 0; EditorUtility.DisplayProgressBar("Saving...", "", Mathf.InverseLerp(0, totalCount, ++tCount)); } } }

Viewing all articles
Browse latest Browse all 167

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>