Files
2026-03-04 10:03:45 +08:00

891 lines
29 KiB
C#

using System.Text;
using GaiaCommon1;
using UnityEngine;
namespace Gaia
{
public class GaiaWorldManager
{
private Bounds m_worldBoundsWU;
private Vector3 m_worldBoundsWUMin;
private Vector3 m_worldBoundsWUMax;
private Vector3 m_worldBoundsWUSize;
private Bounds m_worldBoundsTU;
private Vector3 m_worldBoundsTUMin;
private Vector3 m_worldBoundsTUMax;
private Vector3 m_worldBoundsTUSize;
private Bounds m_worldBoundsNU;
private Vector3 m_worldBoundsNUMin;
private Vector3 m_worldBoundsNUMax;
private Vector3 m_WUtoTU = Vector3.one;
private Vector3 m_TUtoWU = Vector3.one;
private Vector3 m_TUtoNU = Vector3.one;
private Vector3 m_NUtoTU = Vector3.one;
private Vector3 m_WUtoNU = Vector3.one;
private Vector3 m_NUtoWU = Vector3.one;
private Vector3 m_NUZeroOffset = Vector3.zero;
private Vector3 m_TUZeroOffset = Vector3.zero;
private ulong m_boundsCheckErrors;
private Terrain[,] m_physicalTerrainArray;
private UnityHeightMap[,] m_heightMapTerrainArray;
private int m_tileCount;
public int TileCount => m_tileCount;
public Terrain[,] PhysicalTerrainArray
{
get
{
return m_physicalTerrainArray;
}
set
{
m_physicalTerrainArray = value;
}
}
public UnityHeightMap[,] HeightMapTerrainArray
{
get
{
return m_heightMapTerrainArray;
}
set
{
m_heightMapTerrainArray = value;
}
}
public Bounds WorldBoundsWU => m_worldBoundsWU;
public Bounds WorldBoundsTU => m_worldBoundsTU;
public Bounds WorldBoundsNU => m_worldBoundsNU;
public Vector3 WUtoTUConversionFactor => m_WUtoTU;
public Vector3 WUtoNUConversionFactor => m_WUtoNU;
public ulong BoundsCheckErrors
{
get
{
return m_boundsCheckErrors;
}
set
{
m_boundsCheckErrors = value;
}
}
public GaiaWorldManager()
{
}
public GaiaWorldManager(Terrain[] terrains)
{
Terrain terrain = null;
m_worldBoundsWU = default(Bounds);
m_worldBoundsTU = default(Bounds);
m_worldBoundsNU = default(Bounds);
string text = IsValidWorld(terrains);
if (!string.IsNullOrEmpty(text))
{
Debug.LogError("GaiaWorldManager(terrains) ERROR" + text);
return;
}
for (int i = 0; i < terrains.Length; i++)
{
terrain = terrains[i];
Bounds bounds = new Bounds(terrain.transform.position, terrain.terrainData.size);
bounds.center += bounds.extents;
if (i == 0)
{
m_worldBoundsWU = new Bounds(bounds.center, bounds.size);
}
else
{
m_worldBoundsWU.Encapsulate(bounds);
}
Bounds bounds2 = default(Bounds);
m_WUtoTU = new Vector3((float)terrain.terrainData.heightmapResolution / terrain.terrainData.size.x, (float)(terrain.terrainData.heightmapResolution - 1) / Mathf.Max(terrain.terrainData.size.x, terrain.terrainData.size.z) * terrain.terrainData.size.y / terrain.terrainData.size.y, (float)terrain.terrainData.heightmapResolution / terrain.terrainData.size.z);
m_TUtoWU = new Vector3(1f / m_WUtoTU.x, 1f / m_WUtoTU.y, 1f / m_WUtoTU.z);
bounds2.center = Vector3.Scale(bounds.center, m_WUtoTU);
bounds2.size = Vector3.Scale(bounds.size, m_WUtoTU);
if (i == 0)
{
m_worldBoundsTU = new Bounds(bounds2.center, bounds2.size);
}
else
{
m_worldBoundsTU.Encapsulate(bounds2);
}
}
if (terrain != null)
{
m_TUtoNU = new Vector3(1f / m_worldBoundsTU.size.x, 1f / m_worldBoundsTU.size.y, 1f / m_worldBoundsTU.size.z);
m_NUtoTU = m_worldBoundsTU.size;
m_WUtoNU = Vector3.Scale(m_WUtoTU, m_TUtoNU);
m_NUtoWU = m_worldBoundsWU.size;
}
m_worldBoundsNU.center = Vector3.Scale(m_worldBoundsTU.center, m_TUtoNU);
m_worldBoundsNU.size = Vector3.Scale(m_worldBoundsTU.size, m_TUtoNU);
m_NUZeroOffset = Vector3.zero - m_worldBoundsNU.min;
m_TUZeroOffset = Vector3.zero - m_worldBoundsTU.min;
m_tileCount = (int)(m_worldBoundsNU.size.x * m_worldBoundsNU.size.z);
m_physicalTerrainArray = new Terrain[(int)m_worldBoundsNU.size.x, (int)m_worldBoundsNU.size.z];
m_heightMapTerrainArray = new UnityHeightMap[(int)m_worldBoundsNU.size.x, (int)m_worldBoundsNU.size.z];
for (int j = 0; j < terrains.Length; j++)
{
terrain = terrains[j];
Vector3 vector = WUtoPTI(terrain.transform.position);
m_physicalTerrainArray[(int)vector.x, (int)vector.z] = terrain;
}
m_worldBoundsWUMax = m_worldBoundsWU.max;
m_worldBoundsWUMin = m_worldBoundsWU.min;
m_worldBoundsWUSize = m_worldBoundsWU.size;
m_worldBoundsTUMax = m_worldBoundsTU.max;
m_worldBoundsTUMin = m_worldBoundsTU.min;
m_worldBoundsTUSize = m_worldBoundsTU.size;
m_worldBoundsNUMax = m_worldBoundsNU.max;
m_worldBoundsNUMin = m_worldBoundsNU.min;
}
public string IsValidWorld(Terrain[] terrains)
{
Terrain terrain = null;
Terrain terrain2 = null;
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < terrains.Length; i++)
{
terrain2 = terrains[i];
if (terrain == null)
{
terrain = terrain2;
}
if (terrain2.terrainData.size.x != terrain2.terrainData.size.z)
{
stringBuilder.Append($"\nTerrain {terrain2.name} is not a square {terrain2.terrainData.size.x} {terrain2.terrainData.size.z}");
}
if (terrain2.terrainData.size != terrain.terrainData.size)
{
stringBuilder.Append($"\nTerrain {terrain2.name} - {terrain.name} size does not match {terrain2.terrainData.size} {terrain.terrainData.size}");
}
if (terrain2.terrainData.heightmapResolution != terrain.terrainData.heightmapResolution)
{
stringBuilder.Append($"\nTerrain {terrain2.name} - {terrain.name} heightmapResolution does not match {terrain2.terrainData.heightmapResolution} {terrain.terrainData.heightmapResolution}");
}
if (terrain2.terrainData.alphamapResolution != terrain.terrainData.alphamapResolution)
{
stringBuilder.Append($"\nTerrain {terrain2.name} - {terrain.name} alphamapResolution does not match {terrain2.terrainData.alphamapResolution} {terrain.terrainData.alphamapResolution}");
}
if (terrain2.terrainData.baseMapResolution != terrain.terrainData.baseMapResolution)
{
stringBuilder.Append($"\nTerrain {terrain2.name} - {terrain.name} baseMapResolution does not match {terrain2.terrainData.baseMapResolution} {terrain.terrainData.baseMapResolution}");
}
if (terrain2.terrainData.detailResolution != terrain.terrainData.detailResolution)
{
stringBuilder.Append($"\nTerrain {terrain2.name} - {terrain.name} detailResolution does not match {terrain2.terrainData.detailResolution} {terrain.terrainData.detailResolution}");
}
if (terrain2.terrainData.alphamapLayers != terrain.terrainData.alphamapLayers)
{
stringBuilder.Append($"\nTerrain {terrain2.name} - {terrain.name} alphamapLayers does not match {terrain2.terrainData.alphamapLayers} {terrain.terrainData.alphamapLayers}");
}
if (terrain2.terrainData.detailPrototypes.Length != terrain.terrainData.detailPrototypes.Length)
{
stringBuilder.Append($"\nTerrain {terrain2.name} - {terrain.name} detailPrototypes.Length does not match {terrain2.terrainData.detailPrototypes.Length} {terrain.terrainData.detailPrototypes.Length}");
}
if (GaiaSplatPrototype.GetGaiaSplatPrototypes(terrain2).Length != GaiaSplatPrototype.GetGaiaSplatPrototypes(terrain).Length)
{
stringBuilder.Append($"\nTerrain {terrain2.name} - {terrain.name} splatPrototypes.Length does not match {GaiaSplatPrototype.GetGaiaSplatPrototypes(terrain2).Length} {GaiaSplatPrototype.GetGaiaSplatPrototypes(terrain).Length}");
}
if (terrain2.terrainData.treePrototypes.Length != terrain.terrainData.treePrototypes.Length)
{
stringBuilder.Append($"\nTerrain {terrain2.name} - {terrain.name} treePrototypes.Length does not match {terrain2.terrainData.treePrototypes.Length} {terrain.terrainData.treePrototypes.Length}");
}
}
return stringBuilder.ToString();
}
private Terrain GetTerrainWU(Vector3 positionWU)
{
if (!InBoundsWU(positionWU))
{
m_boundsCheckErrors++;
return null;
}
Vector3 vector = WUtoPTI(positionWU);
return m_physicalTerrainArray[(int)vector.x, (int)vector.z];
}
private Terrain GetTerrainTU(Vector3 positionTU)
{
if (!InBoundsTU(positionTU))
{
m_boundsCheckErrors++;
return null;
}
TUtoPTI(ref positionTU);
return m_physicalTerrainArray[(int)positionTU.x, (int)positionTU.z];
}
private Terrain GetTerrainNU(Vector3 positionNU)
{
if (!InBoundsNU(positionNU))
{
m_boundsCheckErrors++;
return null;
}
NUtoPTI(ref positionNU);
return m_physicalTerrainArray[(int)positionNU.x, (int)positionNU.z];
}
private UnityHeightMap GetHeightMapWU(Vector3 positionWU)
{
if (!InBoundsWU(positionWU))
{
m_boundsCheckErrors++;
return null;
}
Vector3 vector = WUtoPTI(positionWU);
UnityHeightMap unityHeightMap = m_heightMapTerrainArray[(int)vector.x, (int)vector.z];
if (unityHeightMap == null)
{
Terrain terrainWU = GetTerrainWU(positionWU);
if (terrainWU != null)
{
unityHeightMap = (m_heightMapTerrainArray[(int)vector.x, (int)vector.z] = new UnityHeightMap(terrainWU));
}
}
return unityHeightMap;
}
private UnityHeightMap GetHeightMapTU(Vector3 positionTU)
{
if (!InBoundsTU(positionTU))
{
m_boundsCheckErrors++;
return null;
}
TUtoPTI(ref positionTU);
UnityHeightMap unityHeightMap = m_heightMapTerrainArray[(int)positionTU.x, (int)positionTU.z];
if (unityHeightMap == null)
{
Terrain terrainTU = GetTerrainTU(positionTU);
if (terrainTU != null)
{
unityHeightMap = (m_heightMapTerrainArray[(int)positionTU.x, (int)positionTU.z] = new UnityHeightMap(terrainTU));
}
}
return unityHeightMap;
}
private UnityHeightMap GetHeightMapNU(Vector3 positionNU)
{
if (!InBoundsNU(positionNU))
{
m_boundsCheckErrors++;
return null;
}
NUtoPTI(ref positionNU);
UnityHeightMap unityHeightMap = m_heightMapTerrainArray[(int)positionNU.x, (int)positionNU.z];
if (unityHeightMap == null)
{
Terrain terrainNU = GetTerrainNU(positionNU);
if (terrainNU != null)
{
unityHeightMap = (m_heightMapTerrainArray[(int)positionNU.x, (int)positionNU.z] = new UnityHeightMap(terrainNU));
}
}
return unityHeightMap;
}
public void LoadFromWorld()
{
for (int i = 0; i < m_heightMapTerrainArray.GetLength(0); i++)
{
for (int j = 0; j < m_heightMapTerrainArray.GetLength(1); j++)
{
UnityHeightMap unityHeightMap = m_heightMapTerrainArray[i, j];
if (unityHeightMap == null)
{
Terrain terrain = m_physicalTerrainArray[i, j];
if (terrain != null)
{
m_heightMapTerrainArray[i, j] = new UnityHeightMap(terrain);
}
}
else
{
unityHeightMap.LoadFromTerrain(m_physicalTerrainArray[i, j]);
}
}
}
}
public void SaveToWorld(bool forceWrite = false)
{
for (int i = 0; i < m_heightMapTerrainArray.GetLength(0); i++)
{
for (int j = 0; j < m_heightMapTerrainArray.GetLength(1); j++)
{
UnityHeightMap unityHeightMap = m_heightMapTerrainArray[i, j];
if (unityHeightMap == null)
{
continue;
}
if (!forceWrite)
{
if (unityHeightMap.IsDirty())
{
unityHeightMap.SaveToTerrain(m_physicalTerrainArray[i, j]);
}
}
else
{
unityHeightMap.SaveToTerrain(m_physicalTerrainArray[i, j]);
}
}
}
}
public void SetHeightWU(float heightWU)
{
float height = Mathf.Clamp01(heightWU / m_worldBoundsWUSize.y);
for (int i = 0; i < m_heightMapTerrainArray.GetLength(0); i++)
{
for (int j = 0; j < m_heightMapTerrainArray.GetLength(1); j++)
{
m_heightMapTerrainArray[i, j].SetHeight(height);
}
}
}
public void SetHeightWU(Vector3 positionWU, float height)
{
UnityHeightMap heightMapWU = GetHeightMapWU(positionWU);
if (heightMapWU != null)
{
positionWU = WUtoPTO(positionWU);
heightMapWU[(int)positionWU.x, (int)positionWU.z] = height;
}
else
{
m_boundsCheckErrors++;
}
}
public float GetHeightWU(Vector3 positionWU)
{
UnityHeightMap heightMapWU = GetHeightMapWU(positionWU);
if (heightMapWU != null)
{
positionWU = WUtoPTO(positionWU);
return heightMapWU[(int)positionWU.x, (int)positionWU.z];
}
return float.MinValue;
}
public float GetHeightInterpolatedWU(Vector3 positionWU)
{
UnityHeightMap heightMapWU = GetHeightMapWU(positionWU);
if (heightMapWU != null)
{
positionWU = WUtoPTO(positionWU);
return heightMapWU[positionWU.x, positionWU.z];
}
return float.MinValue;
}
public void SetHeightTU(Vector3 positionTU, float height)
{
UnityHeightMap heightMapTU = GetHeightMapTU(positionTU);
if (heightMapTU != null)
{
TUtoPTO(ref positionTU);
heightMapTU[(int)positionTU.x, (int)positionTU.z] = height;
}
else
{
m_boundsCheckErrors++;
}
}
public float GetHeightTU(Vector3 positionTU)
{
UnityHeightMap heightMapTU = GetHeightMapTU(positionTU);
if (heightMapTU != null)
{
TUtoPTO(ref positionTU);
return heightMapTU[(int)positionTU.x, (int)positionTU.z];
}
return float.MinValue;
}
public float GetHeightInterpolatedTU(Vector3 positionTU)
{
UnityHeightMap heightMapTU = GetHeightMapTU(positionTU);
if (heightMapTU != null)
{
TUtoPTO(ref positionTU);
return heightMapTU[positionTU.x, positionTU.z];
}
return float.MinValue;
}
public void FlattenWorld()
{
for (int i = 0; i < m_heightMapTerrainArray.GetLength(0); i++)
{
for (int j = 0; j < m_heightMapTerrainArray.GetLength(1); j++)
{
UnityHeightMap unityHeightMap = m_heightMapTerrainArray[i, j];
if (unityHeightMap == null)
{
Terrain terrain = m_physicalTerrainArray[i, j];
if (terrain != null)
{
unityHeightMap = (m_heightMapTerrainArray[i, j] = new UnityHeightMap(terrain));
}
}
if (unityHeightMap != null)
{
unityHeightMap.SetHeight(0f);
unityHeightMap.SaveToTerrain(m_physicalTerrainArray[i, j]);
}
}
}
}
public void SmoothWorld()
{
for (int i = 0; i < m_heightMapTerrainArray.GetLength(0); i++)
{
for (int j = 0; j < m_heightMapTerrainArray.GetLength(1); j++)
{
UnityHeightMap unityHeightMap = m_heightMapTerrainArray[i, j];
if (unityHeightMap == null)
{
Terrain terrain = m_physicalTerrainArray[i, j];
if (terrain != null)
{
unityHeightMap = (m_heightMapTerrainArray[i, j] = new UnityHeightMap(terrain));
}
}
if (unityHeightMap != null)
{
unityHeightMap.Smooth(1);
unityHeightMap.SaveToTerrain(m_physicalTerrainArray[i, j]);
}
}
}
}
public void ExportWorldAsPng(string path)
{
Vector3 center = m_worldBoundsTU.center;
HeightMap heightMap = new HeightMap((int)m_worldBoundsTUSize.z, (int)m_worldBoundsTUSize.x);
int num = 0;
for (int i = (int)m_worldBoundsTUMin.x; i < (int)m_worldBoundsTUMax.x; i++)
{
center.x = i;
int num2 = 0;
for (int j = (int)m_worldBoundsTUMin.z; j < (int)m_worldBoundsTUMax.z; j++)
{
center.z = j;
heightMap[num2, num] = GetHeightTU(center);
num2++;
}
num++;
}
GaiaUtils.CompressToSingleChannelFileImage(heightMap.Heights(), path, TextureFormat.RGBA32, exportPNG: true, exportJPG: false);
}
public void ExportSplatmapAsPng(string path, int textureIdx)
{
Terrain activeTerrain = Terrain.activeTerrain;
if (activeTerrain == null)
{
Debug.LogError("No active terrain, unable to export splatmaps");
return;
}
int alphamapWidth = activeTerrain.terrainData.alphamapWidth;
int alphamapHeight = activeTerrain.terrainData.alphamapHeight;
int alphamapLayers = activeTerrain.terrainData.alphamapLayers;
if (textureIdx < alphamapLayers)
{
HeightMap heightMap = new HeightMap(activeTerrain.terrainData.GetAlphamaps(0, 0, alphamapWidth, alphamapHeight), textureIdx);
heightMap.Flip();
GaiaUtils.CompressToSingleChannelFileImage(heightMap.Heights(), path, TextureFormat.RGBA32, exportPNG: true, exportJPG: false);
}
else
{
GaiaUtils.CompressToMultiChannelFileImage(activeTerrain.terrainData.GetAlphamaps(0, 0, alphamapWidth, alphamapHeight), path, TextureFormat.RGBA32, exportPNG: true, exportJPG: false);
}
}
public void ExportGrassmapAsPng(string path)
{
Terrain activeTerrain = Terrain.activeTerrain;
if (activeTerrain == null)
{
Debug.LogError("No active terrain, unable to export grassmaps");
return;
}
int detailWidth = activeTerrain.terrainData.detailWidth;
int detailHeight = activeTerrain.terrainData.detailHeight;
int num = activeTerrain.terrainData.detailPrototypes.Length;
float[,,] array = new float[detailWidth, detailHeight, num];
for (int i = 0; i < activeTerrain.terrainData.detailPrototypes.Length; i++)
{
int[,] detailLayer = activeTerrain.terrainData.GetDetailLayer(0, 0, activeTerrain.terrainData.detailWidth, activeTerrain.terrainData.detailHeight, i);
for (int j = 0; j < detailWidth; j++)
{
for (int k = 0; k < detailHeight; k++)
{
array[j, k, i] = (float)detailLayer[j, k] / 16f;
}
}
for (int l = 0; l < detailWidth; l++)
{
for (int m = 0; m < detailHeight; m++)
{
array[m, l, i] = array[l, m, i];
}
}
}
GaiaUtils.CompressToMultiChannelFileImage(array, path, TextureFormat.RGBA32, exportPNG: true, exportJPG: false);
}
public void ExportNormalmapAsPng(string path)
{
for (int i = 0; i < m_physicalTerrainArray.GetLength(0); i++)
{
for (int j = 0; j < m_physicalTerrainArray.GetLength(1); j++)
{
}
}
}
public void ExportNormalmapAsPng1(string path)
{
Terrain terrain = null;
int num = 0;
int num2 = 0;
float[,,] array = null;
for (int i = 0; i < m_physicalTerrainArray.GetLength(0); i++)
{
for (int j = 0; j < m_physicalTerrainArray.GetLength(1); j++)
{
terrain = m_physicalTerrainArray[i, j];
if (!(terrain != null))
{
continue;
}
num = terrain.terrainData.heightmapResolution;
num2 = terrain.terrainData.heightmapResolution;
array = new float[num, num2, 4];
for (int k = 0; k < num; k++)
{
for (int l = 0; l < num2; l++)
{
Vector3 interpolatedNormal = terrain.terrainData.GetInterpolatedNormal((float)k / (float)num, (float)l / (float)num2);
array[k, l, 0] = interpolatedNormal.x * 0.5f + 0.5f;
array[k, l, 1] = interpolatedNormal.y * 0.5f + 0.5f;
array[k, l, 2] = interpolatedNormal.z * 0.5f + 0.5f;
}
}
GaiaUtils.CompressToMultiChannelFileImage(array, path + "_" + i + "_" + j, TextureFormat.RGBA32, exportPNG: true, exportJPG: false);
}
}
}
public void ExportWaterflowMapAsPng(int iterations, string path)
{
for (int i = 0; i < m_physicalTerrainArray.GetLength(0); i++)
{
for (int j = 0; j < m_physicalTerrainArray.GetLength(1); j++)
{
GaiaUtils.CompressToSingleChannelFileImage(m_heightMapTerrainArray[i, j].FlowMap(iterations).Normalise().Heights(), path + "_" + i + "_" + j + ".png", TextureFormat.RGBA32, exportPNG: true, exportJPG: false);
}
}
}
public void ExportShorelineMask(string path, float shoreHeightWU, float shoreWidthWU)
{
Vector3 center = m_worldBoundsTU.center;
float shoreHeightNU = shoreHeightWU / m_worldBoundsWUSize.y;
Vector3 vector = WUtoTU(new Vector3(shoreWidthWU, shoreWidthWU, shoreWidthWU));
HeightMap heightMap = new HeightMap((int)m_worldBoundsTUSize.z, (int)m_worldBoundsTUSize.x);
float num = 0f;
for (float num2 = m_worldBoundsTUMin.x; num2 < m_worldBoundsTUMax.x; num2 += 1f)
{
center.x = num2;
float num3 = 0f;
for (float num4 = m_worldBoundsTUMin.z; num4 < m_worldBoundsTUMax.z; num4 += 1f)
{
center.z = num4;
MakeMask(center, shoreHeightNU, vector.x, heightMap);
num3 += 1f;
}
num += 1f;
}
heightMap.Flip();
GaiaUtils.CompressToSingleChannelFileImage(heightMap.Heights(), path, TextureFormat.RGBA32, exportPNG: true, exportJPG: false);
}
private void MakeMask(Vector3 positionTU, float shoreHeightNU, float maskSizeTU, HeightMap waterMask)
{
float num = positionTU.x - maskSizeTU;
float num2 = positionTU.x + maskSizeTU;
float num3 = positionTU.z - maskSizeTU;
float num4 = positionTU.z + maskSizeTU;
Vector3 center = m_worldBoundsTU.center;
for (float num5 = num; num5 < num2; num5 += 1f)
{
center.x = num5;
for (float num6 = num3; num6 < num4; num6 += 1f)
{
center.z = num6;
if (!InBoundsTU(center) || !(GetHeightTU(center) <= shoreHeightNU))
{
continue;
}
float num7 = GaiaCommon1.Utils.Math_Distance(num5, num6, positionTU.x, positionTU.z) / maskSizeTU;
if (num7 <= 1f)
{
num7 = 1f - num7;
int x = (int)(num5 + m_TUZeroOffset.x);
int z = (int)(num6 + m_TUZeroOffset.z);
if (num7 > waterMask[x, z])
{
waterMask[x, z] = num7;
}
}
}
}
}
public bool InBoundsWU(Vector3 positionWU)
{
if (positionWU.x >= m_worldBoundsWUMin.x && positionWU.z >= m_worldBoundsWUMin.z && positionWU.x < m_worldBoundsWUMax.x && positionWU.z < m_worldBoundsWUMax.z)
{
return true;
}
return false;
}
public bool InBoundsTU(Vector3 positionTU)
{
if (positionTU.x >= m_worldBoundsTUMin.x && positionTU.z >= m_worldBoundsTUMin.z && positionTU.x < m_worldBoundsTUMax.x && positionTU.z < m_worldBoundsTUMax.z)
{
return true;
}
return false;
}
public bool InBoundsNU(Vector3 positionNU)
{
if (positionNU.x >= m_worldBoundsNUMin.x && positionNU.z >= m_worldBoundsNUMin.z && positionNU.x < m_worldBoundsNUMax.x && positionNU.z < m_worldBoundsNUMax.z)
{
return true;
}
return false;
}
public Vector3 WUtoTU(Vector3 positionWU)
{
return Vector3.Scale(positionWU, m_WUtoTU);
}
public Vector3 WUtoNU(Vector3 positionWU)
{
return Vector3.Scale(positionWU, m_WUtoNU);
}
public Vector3 WUtoPTI(Vector3 positionWU)
{
positionWU = WUtoNU(positionWU);
NUtoPTI(ref positionWU);
return positionWU;
}
public Vector3 WUtoPTO(Vector3 positionWU)
{
positionWU = WUtoTU(positionWU);
TUtoPTO(ref positionWU);
return positionWU;
}
public Vector3 TUtoWU(Vector3 positionTU)
{
return Vector3.Scale(positionTU, m_TUtoWU);
}
public Vector3 TUtoNU(Vector3 positionTU)
{
return Vector3.Scale(positionTU, m_TUtoNU);
}
public void TUtoPTI(ref Vector3 positionTU)
{
positionTU.x = (float)(int)(positionTU.x + m_NUZeroOffset.x) * m_TUtoNU.x;
positionTU.y = (float)(int)(positionTU.y + m_NUZeroOffset.y) * m_TUtoNU.y;
positionTU.z = (float)(int)(positionTU.z + m_NUZeroOffset.z) * m_TUtoNU.z;
}
public void TUtoPTO(ref Vector3 positionTU)
{
positionTU.x = (positionTU.x + m_TUZeroOffset.x) % m_worldBoundsTUSize.x;
positionTU.y = (positionTU.y + m_TUZeroOffset.y) % m_worldBoundsTUSize.y;
positionTU.z = (positionTU.z + m_TUZeroOffset.z) % m_worldBoundsTUSize.z;
}
public Vector3 NUtoWU(Vector3 positionNU)
{
return Vector3.Scale(positionNU, m_NUtoWU);
}
public Vector3 NUtoTU(Vector3 positionNU)
{
return Vector3.Scale(positionNU, m_NUtoTU);
}
public void NUtoPTI(ref Vector3 positionNU)
{
positionNU.x = Mathf.Floor(positionNU.x + m_NUZeroOffset.x);
positionNU.y = Mathf.Floor(positionNU.y + m_NUZeroOffset.y);
positionNU.z = Mathf.Floor(positionNU.z + m_NUZeroOffset.z);
}
public void NUtoPTO(ref Vector3 positionNU)
{
positionNU.x = (positionNU.x + m_NUZeroOffset.x) % 1f * m_worldBoundsTUSize.x;
positionNU.y = (positionNU.y + m_NUZeroOffset.y) % 1f * m_worldBoundsTUSize.y;
positionNU.z = (positionNU.z + m_NUZeroOffset.z) % 1f * m_worldBoundsTUSize.z;
}
public Vector3 Ceil(Vector3 source)
{
return new Vector3(Mathf.Ceil(source.x), Mathf.Ceil(source.y), Mathf.Ceil(source.z));
}
public Vector3 Floor(Vector3 source)
{
return new Vector3(Mathf.Floor(source.x), Mathf.Floor(source.y), Mathf.Floor(source.z));
}
public void Test()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("GaiaWorldManagerTest\n");
stringBuilder.Append($"World Bounds WU : Min {m_worldBoundsWU.min}, Centre {m_worldBoundsWU.center}, Max {m_worldBoundsWU.max}, Size {m_worldBoundsWU.size}\n");
stringBuilder.Append($"World Bounds TU : Min {m_worldBoundsTU.min}, Centre {m_worldBoundsTU.center}, Max {m_worldBoundsTU.max}, Size {m_worldBoundsTU.size}\n");
stringBuilder.Append($"World Bounds NU : Min {m_worldBoundsNU.min}, Centre {m_worldBoundsNU.center}, Max {m_worldBoundsNU.max}, Size {m_worldBoundsNU.size}\n");
stringBuilder.Append("\nBounds Tests:");
Vector3 vector = new Vector3(m_worldBoundsWU.min.x - 1f, m_worldBoundsWU.min.y, m_worldBoundsWU.min.z);
stringBuilder.Append($"\n<MIN - InBoundsWU({vector}) = {InBoundsWU(vector)}\n");
vector = new Vector3(m_worldBoundsWU.min.x, m_worldBoundsWU.min.y, m_worldBoundsWU.min.z);
stringBuilder.Append($" MIN - InBoundsWU({vector}) = {InBoundsWU(vector)}\n");
vector = new Vector3(m_worldBoundsWU.max.x, m_worldBoundsWU.max.y, m_worldBoundsWU.max.z);
stringBuilder.Append($" MAX - InBoundsWU({vector}) = {InBoundsWU(vector)}\n");
vector = new Vector3(m_worldBoundsWU.max.x + 1f, m_worldBoundsWU.max.y, m_worldBoundsWU.max.z);
stringBuilder.Append($">MAX - InBoundsWU({vector}) = {InBoundsWU(vector)}\n");
vector = new Vector3(m_worldBoundsTU.min.x - 1f, m_worldBoundsTU.min.y, m_worldBoundsTU.min.z);
stringBuilder.Append($"\n<MIN - InBoundsTU({vector}) = {InBoundsTU(vector)}\n");
vector = new Vector3(m_worldBoundsTU.min.x, m_worldBoundsTU.min.y, m_worldBoundsTU.min.z);
stringBuilder.Append($" MIN - InBoundsTU({vector}) = {InBoundsTU(vector)}\n");
vector = new Vector3(m_worldBoundsTU.max.x, m_worldBoundsTU.max.y, m_worldBoundsTU.max.z);
stringBuilder.Append($" MAX - InBoundsTU({vector}) = {InBoundsTU(vector)}\n");
vector = new Vector3(m_worldBoundsTU.max.x + 1f, m_worldBoundsTU.max.y, m_worldBoundsTU.max.y);
stringBuilder.Append($">MAX - InBoundsTU({vector}) = {InBoundsTU(vector)}\n");
vector = new Vector3(m_worldBoundsNU.min.x - 0.1f, m_worldBoundsNU.min.y, m_worldBoundsNU.min.z);
stringBuilder.Append($"\n<MIN - InBoundsNU({vector}) = {InBoundsNU(vector)}\n");
vector = new Vector3(m_worldBoundsNU.min.x, m_worldBoundsNU.min.y, m_worldBoundsNU.min.z);
stringBuilder.Append($" MIN - InBoundsNU({vector}) = {InBoundsNU(vector)}\n");
vector = new Vector3(m_worldBoundsNU.max.x, m_worldBoundsNU.max.y, m_worldBoundsNU.max.z);
stringBuilder.Append($" MAX - InBoundsNU({vector}) = {InBoundsNU(vector)}\n");
vector = new Vector3(m_worldBoundsNU.max.x + 0.1f, m_worldBoundsNU.max.y, m_worldBoundsNU.max.z);
stringBuilder.Append($">MAX - InBoundsNU({vector}) = {InBoundsNU(vector)}\n");
stringBuilder.Append("\nPosition Conversion Tests (<MIN, CENTRE, >MAX):");
vector = new Vector3(m_worldBoundsWU.min.x - 1f, m_worldBoundsWU.center.y, m_worldBoundsWU.max.z + 1f);
stringBuilder.Append($"\nInBoundsWU({vector}) = {InBoundsWU(vector)}\n");
stringBuilder.Append($"WUtoTU({vector}) = {WUtoTU(vector).x:0.000}, {WUtoTU(vector).z:0.000}\n");
stringBuilder.Append($"WUtoNU({vector}) = {WUtoNU(vector).x:0.000}, {WUtoNU(vector).z:0.000}\n");
stringBuilder.Append($"WUtoPTI({vector}) = {WUtoPTI(vector).x}, {WUtoPTI(vector).z}\n");
stringBuilder.Append($"WUtoPTO({vector}) = {WUtoPTO(vector).x}, {WUtoPTO(vector).z}\n");
stringBuilder.Append("\nPosition Conversion Tests (MIN, CENTRE, MAX):");
vector = new Vector3(m_worldBoundsWU.min.x, m_worldBoundsWU.center.y, m_worldBoundsWU.max.z);
stringBuilder.Append($"\nInBoundsWU({vector}) = {InBoundsWU(vector)}\n");
stringBuilder.Append($"WUtoTU({vector}) = {WUtoTU(vector).x:0.000}, {WUtoTU(vector).z:0.000}\n");
stringBuilder.Append($"WUtoNU({vector}) = {WUtoNU(vector).x:0.000}, {WUtoNU(vector).z:0.000}\n");
stringBuilder.Append($"WUtoPTI({vector}) = {WUtoPTI(vector).x}, {WUtoPTI(vector).z}\n");
stringBuilder.Append($"WUtoPTO({vector}) = {WUtoPTO(vector).x}, {WUtoPTO(vector).z}\n");
vector = WUtoTU(vector);
stringBuilder.Append($"\nTUtoWU({vector}) = {TUtoWU(vector)}\n");
stringBuilder.Append($"TUtoNU({vector}) = {TUtoNU(vector)}\n");
vector = TUtoNU(vector);
stringBuilder.Append($"\nNUtoWU({vector}) = {NUtoWU(vector)}\n");
stringBuilder.Append($"NUtoTU({vector}) = {NUtoTU(vector)}\n");
stringBuilder.Append("\nTerrain Tests:");
FlattenWorld();
m_boundsCheckErrors = 0uL;
TestBlobWU(m_worldBoundsWU.min, 100, 0.25f);
TestBlobTU(m_worldBoundsTU.center, 100, 0.5f);
TestBlobWU(m_worldBoundsWU.max, 100, 1f);
SaveToWorld();
stringBuilder.Append($"Bounds check errors : {m_boundsCheckErrors}");
Debug.Log(stringBuilder.ToString());
}
public void TestBlobWU(Vector3 positionWU, int widthWU, float height)
{
Vector3 vector = WUtoTU(new Vector3(widthWU, widthWU, widthWU));
Vector3 vector2 = WUtoTU(positionWU);
for (int i = (int)(vector2.x - vector.x); i < (int)(vector2.x + vector.x); i++)
{
for (int j = (int)(vector2.z - vector.z); j < (int)(vector2.z + vector.z); j++)
{
Vector3 positionTU = new Vector3(i, m_worldBoundsTU.center.y, j);
SetHeightTU(positionTU, height);
}
}
}
public void TestBlobTU(Vector3 positionTU, int widthWU, float height)
{
Vector3 vector = WUtoTU(new Vector3(widthWU, widthWU, widthWU));
for (int i = (int)(positionTU.x - vector.x); i < (int)(positionTU.x + vector.x); i++)
{
for (int j = (int)(positionTU.z - vector.z); j < (int)(positionTU.z + vector.z); j++)
{
Vector3 positionTU2 = new Vector3(i, m_worldBoundsTU.center.y, j);
SetHeightTU(positionTU2, height);
}
}
}
}
}