Skip to content

Commit

Permalink
fix - build error #10 @emrys90
Browse files Browse the repository at this point in the history
  • Loading branch information
ikpil committed Oct 27, 2024
1 parent 93850af commit 9571417
Show file tree
Hide file tree
Showing 4 changed files with 233 additions and 227 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
#
# Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore
#

/[Ll]ibrary/
/[Tt]emp/
/[Oo]bj/
/[Bb]in/
/[Bb]uild/
/[Bb]uilds/
/[Ll]ogs/
/[Uu]ser[Ss]ettings/


# MemoryCaptures can get excessive in size.
# They also could contain extremely sensitive data
/[Mm]emoryCaptures/
Expand Down
230 changes: 230 additions & 0 deletions Editor/UniRecast.Editor/UniRcTerrainObjExporter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
// 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 System;
using System.Globalization;
using System.IO;
using System.Text;
using System.Threading;
using UnityEditor;
using UnityEngine;

namespace UniRecast.Editor
{
enum SaveFormat
{
Triangles,
Quads
}

enum SaveResolution
{
Full = 0,
Half,
Quarter,
Eighth,
Sixteenth
}

public class UniRcTerrainObjExporter : 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;
}

GetWindow<UniRcTerrainObjExporter>().Show();
}

void OnGUI()
{
if (!terrain)
{
GUILayout.Label("No terrain found");
if (GUILayout.Button("Cancel"))
{
GetWindow<UniRcTerrainObjExporter>().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.heightmapResolution;
int h = terrain.heightmapResolution;
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
Thread.CurrentThread.CurrentCulture = new 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);
GetWindow<UniRcTerrainObjExporter>().Close();
EditorUtility.ClearProgressBar();
}

void UpdateProgress()
{
if (counter++ == progressUpdateInterval)
{
counter = 0;
EditorUtility.DisplayProgressBar("Saving...", "", Mathf.InverseLerp(0, totalCount, ++tCount));
}
}
}
}
Loading

0 comments on commit 9571417

Please sign in to comment.