Heroes_of_Hiis/Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain .../Runtime/Scripts/TerrainData/GGeometry.cs

592 lines
17 KiB
C#
Raw Normal View History

#if GRIFFIN
using System.Collections.Generic;
using UnityEngine;
using Type = System.Type;
namespace Pinwheel.Griffin
{
public class GGeometry : ScriptableObject
{
[System.Serializable]
public enum GStorageMode
{
SaveToAsset, GenerateOnEnable
}
public const string HEIGHT_MAP_NAME = "Height Map";
[SerializeField]
private GTerrainData terrainData;
public GTerrainData TerrainData
{
get
{
return terrainData;
}
internal set
{
terrainData = value;
}
}
[SerializeField]
internal float width;
public float Width
{
get
{
return width;
}
set
{
width = Mathf.Max(1, value);
}
}
[SerializeField]
internal float height;
public float Height
{
get
{
return height;
}
set
{
height = Mathf.Max(0, value);
}
}
[SerializeField]
internal float length;
public float Length
{
get
{
return length;
}
set
{
length = Mathf.Max(1, value);
}
}
public Vector3 Size
{
get
{
return new Vector3(Width, Height, Length);
}
}
[SerializeField]
private int heightMapResolution;
public int HeightMapResolution
{
get
{
return heightMapResolution;
}
set
{
int oldValue = heightMapResolution;
heightMapResolution = Mathf.Clamp(Mathf.ClosestPowerOfTwo(value), GCommon.TEXTURE_SIZE_MIN, GCommon.TEXTURE_SIZE_MAX);
if (oldValue != heightMapResolution)
{
ResampleHeightMap();
}
}
}
[SerializeField]
private Texture2D heightMap;
public Texture2D HeightMap
{
get
{
if (heightMap == null)
{
heightMap = GCommon.CreateTexture(HeightMapResolution, Color.clear, HeightMapFormat);
heightMap.filterMode = FilterMode.Bilinear;
heightMap.wrapMode = TextureWrapMode.Clamp;
heightMap.name = HEIGHT_MAP_NAME;
heightmapVersion = GVersionInfo.Number;
}
GCommon.TryAddObjectToAsset(heightMap, TerrainData);
if (heightMap.format != HeightMapFormat)
{
ReFormatHeightMap();
}
return heightMap;
}
}
[SerializeField]
private float heightmapVersion;
private const float HEIGHT_MAP_VERSION_ENCODE_RG = 246;
public static TextureFormat HeightMapFormat
{
get
{
return TextureFormat.RGBA32;
}
}
public static RenderTextureFormat HeightMapRTFormat
{
get
{
return RenderTextureFormat.ARGB32;
}
}
internal Texture2D subDivisionMap;
public Texture2D Internal_SubDivisionMap
{
get
{
if (subDivisionMap == null)
{
Internal_CreateNewSubDivisionMap();
}
return subDivisionMap;
}
}
[SerializeField]
private int meshBaseResolution;
public int MeshBaseResolution
{
get
{
return meshBaseResolution;
}
set
{
meshBaseResolution = Mathf.Min(meshResolution, Mathf.Clamp(value, 0, GCommon.MAX_MESH_BASE_RESOLUTION));
}
}
[SerializeField]
private int meshResolution;
public int MeshResolution
{
get
{
return meshResolution;
}
set
{
meshResolution = Mathf.Clamp(value, 0, GCommon.MAX_MESH_RESOLUTION);
}
}
[SerializeField]
private int chunkGridSize;
public int ChunkGridSize
{
get
{
return chunkGridSize;
}
set
{
chunkGridSize = Mathf.Max(1, value);
}
}
[SerializeField]
private int lodCount;
public int LODCount
{
get
{
return lodCount;
}
set
{
lodCount = Mathf.Clamp(value, 1, GCommon.MAX_LOD_COUNT);
}
}
[SerializeField]
private int displacementSeed;
public int DisplacementSeed
{
get
{
return displacementSeed;
}
set
{
displacementSeed = value;
}
}
[SerializeField]
private float displacementStrength;
public float DisplacementStrength
{
get
{
return displacementStrength;
}
set
{
displacementStrength = Mathf.Max(0, value);
}
}
[SerializeField]
private GAlbedoToVertexColorMode albedoToVertexColorMode;
public GAlbedoToVertexColorMode AlbedoToVertexColorMode
{
get
{
return albedoToVertexColorMode;
}
set
{
albedoToVertexColorMode = value;
}
}
[SerializeField]
private GStorageMode storageMode;
public GStorageMode StorageMode
{
get
{
return storageMode;
}
set
{
storageMode = value;
if (storageMode == GStorageMode.GenerateOnEnable)
{
TerrainData.GeometryData = null;
}
}
}
[SerializeField]
private bool allowTimeSlicedGeneration;
public bool AllowTimeSlicedGeneration
{
get
{
return allowTimeSlicedGeneration;
}
set
{
allowTimeSlicedGeneration = value;
}
}
[SerializeField]
private bool smoothNormal;
public bool SmoothNormal
{
get
{
return smoothNormal;
}
set
{
smoothNormal = value;
}
}
[SerializeField]
private bool useSmoothNormalMask;
public bool UseSmoothNormalMask
{
get
{
return useSmoothNormalMask;
}
set
{
useSmoothNormalMask = value;
}
}
[SerializeField]
private bool mergeUv;
public bool MergeUv
{
get
{
return mergeUv;
}
set
{
mergeUv = value;
}
}
private List<Rect> dirtyRegion;
private List<Rect> DirtyRegion
{
get
{
if (dirtyRegion == null)
{
dirtyRegion = new List<Rect>();
}
return dirtyRegion;
}
set
{
dirtyRegion = value;
}
}
public void Reset()
{
name = "Geometry";
Width = GRuntimeSettings.Instance.geometryDefault.width;
Height = GRuntimeSettings.Instance.geometryDefault.height;
Length = GRuntimeSettings.Instance.geometryDefault.length;
HeightMapResolution = GRuntimeSettings.Instance.geometryDefault.heightMapResolution;
MeshResolution = GRuntimeSettings.Instance.geometryDefault.meshResolution;
MeshBaseResolution = GRuntimeSettings.Instance.geometryDefault.meshBaseResolution;
ChunkGridSize = GRuntimeSettings.Instance.geometryDefault.chunkGridSize;
LODCount = GRuntimeSettings.Instance.geometryDefault.lodCount;
DisplacementSeed = GRuntimeSettings.Instance.geometryDefault.displacementSeed;
DisplacementStrength = GRuntimeSettings.Instance.geometryDefault.displacementStrength;
AlbedoToVertexColorMode = GRuntimeSettings.Instance.geometryDefault.albedoToVertexColorMode;
StorageMode = GRuntimeSettings.Instance.geometryDefault.storageMode;
AllowTimeSlicedGeneration = GRuntimeSettings.Instance.geometryDefault.allowTimeSlicedGeneration;
SmoothNormal = GRuntimeSettings.Instance.geometryDefault.smoothNormal;
UseSmoothNormalMask = GRuntimeSettings.Instance.geometryDefault.useSmoothNormalMask;
MergeUv = GRuntimeSettings.Instance.geometryDefault.mergeUv;
}
public void ResetFull()
{
Reset();
GCommon.FillTexture(HeightMap, Color.clear);
SetRegionDirty(GCommon.UnitRect);
TerrainData.SetDirty(GTerrainData.DirtyFlags.GeometryTimeSliced);
}
private void ResampleHeightMap()
{
if (heightMap == null)
return;
Texture2D tmp = GCommon.CreateTexture(HeightMapResolution, Color.clear, HeightMapFormat);
RenderTexture rt = new RenderTexture(HeightMapResolution, HeightMapResolution, 32, HeightMapRTFormat);
GCommon.CopyTexture(heightMap, tmp);
tmp.name = heightMap.name;
tmp.filterMode = heightMap.filterMode;
tmp.wrapMode = heightMap.wrapMode;
Object.DestroyImmediate(heightMap, true);
heightMap = tmp;
GCommon.TryAddObjectToAsset(heightMap, TerrainData);
Internal_CreateNewSubDivisionMap();
SetRegionDirty(GCommon.UnitRect);
}
private void ReFormatHeightMap()
{
if (heightMap == null)
return;
if (heightmapVersion < HEIGHT_MAP_VERSION_ENCODE_RG)
{
Texture2D tmp = GCommon.CreateTexture(HeightMapResolution, Color.clear, HeightMapFormat);
RenderTexture rt = new RenderTexture(HeightMapResolution, HeightMapResolution, 32, HeightMapRTFormat);
Material mat = GInternalMaterials.HeightmapConverterEncodeRGMaterial;
mat.SetTexture("_MainTex", heightMap);
GCommon.DrawQuad(rt, GCommon.FullRectUvPoints, mat, 0);
GCommon.CopyFromRT(tmp, rt);
rt.Release();
Object.DestroyImmediate(rt);
tmp.name = heightMap.name;
tmp.filterMode = heightMap.filterMode;
tmp.wrapMode = heightMap.wrapMode;
Object.DestroyImmediate(heightMap, true);
heightMap = tmp;
GCommon.TryAddObjectToAsset(heightMap, TerrainData);
heightmapVersion = HEIGHT_MAP_VERSION_ENCODE_RG;
Debug.Log("Polaris auto upgrade: Converted Height Map from RGBAFloat to RGBA32.");
}
}
internal void Internal_CreateNewSubDivisionMap()
{
if (subDivisionMap != null)
{
if (subDivisionMap.width != GCommon.SUB_DIV_MAP_RESOLUTION ||
subDivisionMap.height != GCommon.SUB_DIV_MAP_RESOLUTION)
Object.DestroyImmediate(subDivisionMap);
}
if (subDivisionMap == null)
{
subDivisionMap = new Texture2D(GCommon.SUB_DIV_MAP_RESOLUTION, GCommon.SUB_DIV_MAP_RESOLUTION, TextureFormat.RGBA32, false);
}
int resolution = GCommon.SUB_DIV_MAP_RESOLUTION;
RenderTexture rt = new RenderTexture(resolution, resolution, 0, RenderTextureFormat.ARGB32);
Material mat = GInternalMaterials.SubDivisionMapMaterial;
Graphics.Blit(HeightMap, rt, mat);
GCommon.CopyFromRT(subDivisionMap, rt);
rt.Release();
Object.DestroyImmediate(rt);
}
internal void Internal_CreateNewSubDivisionMap(Texture altHeightMap)
{
if (subDivisionMap != null)
{
if (subDivisionMap.width != GCommon.SUB_DIV_MAP_RESOLUTION ||
subDivisionMap.height != GCommon.SUB_DIV_MAP_RESOLUTION)
Object.DestroyImmediate(subDivisionMap);
}
if (subDivisionMap == null)
{
subDivisionMap = new Texture2D(GCommon.SUB_DIV_MAP_RESOLUTION, GCommon.SUB_DIV_MAP_RESOLUTION, TextureFormat.ARGB32, false);
}
int resolution = GCommon.SUB_DIV_MAP_RESOLUTION;
RenderTexture rt = new RenderTexture(resolution, resolution, 0, RenderTextureFormat.ARGB32);
Material mat = GInternalMaterials.SubDivisionMapMaterial;
Graphics.Blit(altHeightMap, rt, mat);
GCommon.CopyFromRT(subDivisionMap, rt);
rt.Release();
Object.DestroyImmediate(rt);
}
public void CleanUp()
{
int count = 0;
List<Vector3Int> keys = TerrainData.GeometryData.GetKeys();
for (int i = 0; i < keys.Count; ++i)
{
bool delete = false;
try
{
int indexX = keys[i].x;
int indexY = keys[i].y;
int lod = keys[i].z;
if (indexX >= ChunkGridSize || indexY >= ChunkGridSize)
{
delete = true;
}
else if (lod >= LODCount)
{
delete = true;
}
else
{
delete = false;
}
}
catch
{
delete = false;
}
if (delete)
{
count += 1;
TerrainData.GeometryData.DeleteMesh(keys[i]);
}
}
if (count > 0)
{
Debug.Log(string.Format("Deleted {0} object{1} from generated data!", count, count > 1 ? "s" : ""));
}
}
public void SetRegionDirty(Rect uvRect)
{
DirtyRegion.Add(uvRect);
}
public void SetRegionDirty(IEnumerable<Rect> uvRects)
{
DirtyRegion.AddRange(uvRects);
}
public Rect[] GetDirtyRegions()
{
return DirtyRegion.ToArray();
}
public void ClearDirtyRegions()
{
DirtyRegion.Clear();
}
public void CopyTo(GGeometry des)
{
des.Width = Width;
des.Height = Height;
des.Length = Length;
des.HeightMapResolution = HeightMapResolution;
des.MeshResolution = MeshResolution;
des.MeshBaseResolution = MeshBaseResolution;
des.ChunkGridSize = ChunkGridSize;
des.LODCount = LODCount;
des.DisplacementSeed = DisplacementSeed;
des.DisplacementStrength = DisplacementStrength;
des.AlbedoToVertexColorMode = AlbedoToVertexColorMode;
des.StorageMode = StorageMode;
des.AllowTimeSlicedGeneration = AllowTimeSlicedGeneration;
}
public Vector4 GetDecodedHeightMapSample(Vector2 uv)
{
Vector4 c = HeightMap.GetPixelBilinear(uv.x, uv.y);
Vector2 encodedHeight = new Vector2(c.x, c.y);
float decodedHeight = GCommon.DecodeTerrainHeight(encodedHeight);
c.x = decodedHeight;
c.y = decodedHeight;
return c;
}
public float GetHeightMapMemoryStats()
{
if (heightMap == null)
return 0;
return heightMap.width * heightMap.height * 4;
}
public void RemoveHeightMap()
{
if (heightMap != null)
{
GUtilities.DestroyObject(heightMap);
}
}
public float[,] GetHeights()
{
int res = HeightMapResolution;
float[,] samples = new float[res, res];
Vector4 color;
for (int z = 0; z < res; ++z)
{
for (int x = 0; x< res; ++x)
{
color = HeightMap.GetPixel(x, z);
float h = GCommon.DecodeTerrainHeight(color);
samples[z, x] = h;
}
}
return samples;
}
}
}
#endif