Skip to content

Instantly share code, notes, and snippets.

@samjessup
Created June 9, 2015 12:01
Show Gist options
  • Save samjessup/88230a7f21dcf87c9e3c to your computer and use it in GitHub Desktop.
Save samjessup/88230a7f21dcf87c9e3c to your computer and use it in GitHub Desktop.
// Terrain offset thing
// Offsets terrain height, splats, details, trees
// I place this code in the public domain. I accept no responsibility for broken terrains or any other bad things.
// Version 1
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
public class TerrainFixer : MonoBehaviour {
static float wrapfloat(float v, float m)
{
if (v < 0)
v += m;
if (v >= m)
v -= m;
return v;
}
static int wrapint( int v, int m )
{
return (v%m+m)%m;
}
[MenuItem("Sam/TerrainOffsetThing")]
public static void DoSomething()
{
var Offset = new Vector3(-100, -100, 0);
Terrain terr = Selection.activeGameObject.GetComponent<Terrain>();
if (terr == null)
{
Debug.LogError("You must select a terrain object.");
return;
}
if (!EditorUtility.DisplayDialog("Confirm Terrain Mashing", "Are you sure you want to mangle terrain: " + terr.name, "OK", "Cancel"))
return;
TerrainData td = terr.terrainData;
// Move trees
Vector3 TreeOffset = new Vector3(Offset.x / td.size.x, 0, Offset.y / td.size.z);
var oldtrees = td.treeInstances;
List<TreeInstance> newTrees = new List<TreeInstance>();
for (int i = 0; i < oldtrees.Length; i++)
{
var tree = oldtrees[i];
Vector3 newpos = tree.position - TreeOffset;
newpos.x = wrapfloat(newpos.x, 1.0f);
newpos.z = wrapfloat(newpos.z, 1.0f);
tree.position = newpos;
newTrees.Add(tree);
}
td.treeInstances = new TreeInstance[newTrees.Count];
td.treeInstances = newTrees.ToArray();
// Move splatmaps
{
var oldalpha = td.GetAlphamaps(0, 0, td.alphamapWidth, td.alphamapHeight);
var newalpha = new float[td.alphamapWidth, td.alphamapHeight, oldalpha.GetLength(2)];
int xoff = (int)((Offset.x / td.size.x) * td.alphamapWidth);
int yoff = (int)((Offset.y / td.size.z) * td.alphamapHeight);
for (int x = 0; x < td.alphamapWidth; x++)
{
for (int y = 0; y < td.alphamapHeight; y++)
{
for (int z = 0; z < oldalpha.GetLength(2); z++)
{
newalpha[x, y, z] = oldalpha[
wrapint( (x + xoff), td.alphamapWidth),
wrapint( (y + yoff), td.alphamapHeight), z];
}
}
}
td.SetAlphamaps(0, 0, newalpha);
}
// Move details:
var layers = td.GetSupportedLayers(0,0,td.detailWidth, td.detailHeight);
foreach( int layer in layers )
{
var details = td.GetDetailLayer( 0, 0, td.detailWidth, td.detailHeight, layer );
var newdetails = new int[td.detailWidth, td.detailHeight];
int xoff = (int)((Offset.x / td.size.x) * td.detailWidth);
int yoff = (int)((Offset.y / td.size.z) * td.detailHeight);
for (int x = 0; x < td.detailWidth; x++)
{
for (int y = 0; y < td.detailHeight; y++)
{
newdetails[x, y] = details[wrapint((x + xoff) , td.detailWidth), wrapint( (y + yoff), td.detailHeight )];
}
}
td.SetDetailLayer(0, 0, layer, newdetails );
}
// Move terrain height:
{
var heights = td.GetHeights(0, 0, td.heightmapWidth, td.heightmapHeight);
var newheights = new float[td.heightmapWidth, td.heightmapHeight];
int yoff = (int)((Offset.y / td.size.z) * td.heightmapHeight);
int xoff = (int)((Offset.x / td.size.x) * td.heightmapWidth);
for (int x = 0; x < td.heightmapWidth; x++)
{
for (int y = 0; y < td.heightmapHeight; y++)
{
newheights[x, y] = heights[ wrapint( (x + xoff), td.heightmapWidth), wrapint( (y + yoff) , td.heightmapHeight)];
}
}
td.SetHeights(0, 0, newheights);
}
Debug.Log("Done!");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment