126 lines
4.1 KiB
C#
126 lines
4.1 KiB
C#
using UnityEngine;
|
|
|
|
namespace TT_TerrainTools
|
|
{
|
|
public static class TT_TerrainHelpers
|
|
{
|
|
public enum EDirection
|
|
{
|
|
TOP = 0,
|
|
BOTTOM = 1,
|
|
LEFT = 2,
|
|
RIGHT = 3
|
|
}
|
|
|
|
public static void FixBorders(Terrain p_terrainA, Terrain p_terrainB, EDirection p_borderA, EDirection p_borderB, float p_fade)
|
|
{
|
|
int heightmapResolution = p_terrainA.terrainData.heightmapResolution;
|
|
if (p_terrainA.terrainData.heightmapResolution != heightmapResolution || p_terrainB.terrainData.heightmapResolution != heightmapResolution)
|
|
{
|
|
Debug.LogError("TT_Terrain9Patch: both TerrainData assets must have the same 'heightmapResolution'!");
|
|
return;
|
|
}
|
|
p_fade = Mathf.Clamp01(p_fade);
|
|
bool flag = false;
|
|
bool flag2 = false;
|
|
float y = p_terrainA.transform.position.y;
|
|
float y2 = p_terrainA.terrainData.size.y;
|
|
float y3 = p_terrainB.transform.position.y;
|
|
float y4 = p_terrainB.terrainData.size.y;
|
|
float[,] directedHeights = GetDirectedHeights(p_terrainA.terrainData, p_borderA);
|
|
float[,] directedHeights2 = GetDirectedHeights(p_terrainB.terrainData, p_borderB);
|
|
for (int i = 0; i < heightmapResolution; i++)
|
|
{
|
|
float directedWorldHeight = GetDirectedWorldHeight(i, p_borderA, directedHeights, p_terrainA);
|
|
float directedWorldHeight2 = GetDirectedWorldHeight(i, p_borderB, directedHeights2, p_terrainB);
|
|
float num = directedWorldHeight * (1f - p_fade) + directedWorldHeight2 * p_fade;
|
|
SetDirectedWorldHeight(num, i, p_borderA, directedHeights, y, y2);
|
|
SetDirectedWorldHeight(num, i, p_borderB, directedHeights2, y3, y4);
|
|
flag = flag || num != directedWorldHeight;
|
|
flag2 = flag2 || num != directedWorldHeight2;
|
|
}
|
|
if (flag)
|
|
{
|
|
SetDirectedHeights(directedHeights, p_terrainA.terrainData, p_borderA);
|
|
}
|
|
if (flag2)
|
|
{
|
|
SetDirectedHeights(directedHeights2, p_terrainB.terrainData, p_borderB);
|
|
}
|
|
}
|
|
|
|
private static float GetDirectedWorldHeight(int p_index, EDirection p_border, float[,] p_heights, Terrain p_terrain)
|
|
{
|
|
return p_terrain.transform.position.y + p_terrain.terrainData.size.y * GetDirectedLocalHeight(p_index, p_border, p_heights);
|
|
}
|
|
|
|
private static float GetDirectedLocalHeight(int p_index, EDirection p_border, float[,] p_heights)
|
|
{
|
|
switch (p_border)
|
|
{
|
|
case EDirection.LEFT:
|
|
case EDirection.RIGHT:
|
|
return p_heights[p_index, 0];
|
|
default:
|
|
return p_heights[0, p_index];
|
|
}
|
|
}
|
|
|
|
private static void SetDirectedWorldHeight(float p_value, int p_index, EDirection p_border, float[,] p_heights, float p_terrainPosY, float p_terrainSizeY)
|
|
{
|
|
float p_value2 = (p_value - p_terrainPosY) / p_terrainSizeY;
|
|
SetDirectedLocalHeight(p_value2, p_index, p_border, p_heights);
|
|
}
|
|
|
|
private static void SetDirectedLocalHeight(float p_value, int p_index, EDirection p_border, float[,] p_heights)
|
|
{
|
|
switch (p_border)
|
|
{
|
|
case EDirection.LEFT:
|
|
case EDirection.RIGHT:
|
|
p_heights[p_index, 0] = p_value;
|
|
break;
|
|
default:
|
|
p_heights[0, p_index] = p_value;
|
|
break;
|
|
}
|
|
}
|
|
|
|
private static float[,] GetDirectedHeights(TerrainData p_terrainData, EDirection p_border)
|
|
{
|
|
int heightmapResolution = p_terrainData.heightmapResolution;
|
|
switch (p_border)
|
|
{
|
|
case EDirection.RIGHT:
|
|
return p_terrainData.GetHeights(heightmapResolution - 1, 0, 1, heightmapResolution);
|
|
case EDirection.LEFT:
|
|
return p_terrainData.GetHeights(0, 0, 1, heightmapResolution);
|
|
case EDirection.BOTTOM:
|
|
return p_terrainData.GetHeights(0, 0, heightmapResolution, 1);
|
|
default:
|
|
return p_terrainData.GetHeights(0, heightmapResolution - 1, heightmapResolution, 1);
|
|
}
|
|
}
|
|
|
|
private static void SetDirectedHeights(float[,] p_heights, TerrainData p_terrainData, EDirection p_border)
|
|
{
|
|
int heightmapResolution = p_terrainData.heightmapResolution;
|
|
switch (p_border)
|
|
{
|
|
case EDirection.RIGHT:
|
|
p_terrainData.SetHeights(heightmapResolution - 1, 0, p_heights);
|
|
break;
|
|
case EDirection.LEFT:
|
|
p_terrainData.SetHeights(0, 0, p_heights);
|
|
break;
|
|
case EDirection.BOTTOM:
|
|
p_terrainData.SetHeights(0, 0, p_heights);
|
|
break;
|
|
default:
|
|
p_terrainData.SetHeights(0, heightmapResolution - 1, p_heights);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|