Heroes_of_Hiis/Assets/Polaris - Low Poly Ecosystem/Polaris - Low Poly Terrain .../Runtime/Scripts/ErosionTool/GErosionInitializer.cs

132 lines
5.5 KiB
C#

#if GRIFFIN
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
namespace Pinwheel.Griffin.ErosionTool
{
public class GErosionInitializer
{
public GErosionSimulator Simulator { get; private set; }
private Material fetchWorldDataMaterial;
private Material FetchWorldDataMaterial
{
get
{
if (fetchWorldDataMaterial == null)
{
fetchWorldDataMaterial = new Material(GRuntimeSettings.Instance.internalShaders.fetchWorldDataShader);
}
return fetchWorldDataMaterial;
}
}
private static readonly int MAIN_TEX = Shader.PropertyToID("_MainTex");
private static readonly int BOUNDS = Shader.PropertyToID("_Bounds");
private static readonly int ENABLE_TERRAIN_MASK = Shader.PropertyToID("_EnableTerrainMask");
private static readonly int PASS_HEIGHT = 0;
private static readonly int PASS_MASK = 1;
private static readonly int PASS_EROSION_MAP = 2;
public GErosionInitializer(GErosionSimulator s)
{
Simulator = s;
}
public void Init(ref Vector3 bounds, ref RenderTexture simulationData, ref RenderTexture simulationMask, ref RenderTexture erosionMap)
{
List<GStylizedTerrain> terrains = Simulator.GetIntersectedTerrains();
bounds = GetSimulationBounds(terrains);
CreateRenderTexture(bounds, ref simulationData, ref simulationMask, ref erosionMap);
FetchWorldData(terrains, bounds, ref simulationData, ref simulationMask, ref erosionMap);
}
private Vector3 GetSimulationBounds(List<GStylizedTerrain> terrains)
{
Vector3 bounds = new Vector3();
bounds.x = Mathf.CeilToInt(Simulator.DetailLevel * Simulator.transform.lossyScale.x);
bounds.z = Mathf.CeilToInt(Simulator.DetailLevel * Simulator.transform.lossyScale.z);
for (int i = 0; i < terrains.Count; ++i)
{
bounds.y = Mathf.Max(bounds.y, terrains[i].TerrainData.Geometry.Height);
}
return bounds;
}
private void CreateRenderTexture(Vector3 bounds, ref RenderTexture simulationData, ref RenderTexture simulationMask, ref RenderTexture erosionMap)
{
if (simulationData != null)
{
simulationData.Release();
}
if (simulationMask!=null)
{
simulationMask.Release();
}
if (erosionMap!=null)
{
erosionMap.Release();
}
int width = Mathf.Clamp((int)bounds.x, 1, 4096);
int height = Mathf.Clamp((int)bounds.z, 1, 4096);
int depth = 0;
RenderTextureReadWrite rw = RenderTextureReadWrite.Linear;
simulationData = new RenderTexture(width, height, depth, RenderTextureFormat.ARGBFloat, rw);
simulationData.enableRandomWrite = true;
simulationData.wrapMode = TextureWrapMode.Clamp;
simulationData.Create();
simulationMask = new RenderTexture(width, height, depth, RenderTextureFormat.ARGBFloat, rw);
simulationMask.enableRandomWrite = true;
simulationMask.wrapMode = TextureWrapMode.Clamp;
simulationMask.Create();
erosionMap = new RenderTexture(width, height, depth, RenderTextureFormat.RGFloat, rw);
erosionMap.enableRandomWrite = true;
erosionMap.wrapMode = TextureWrapMode.Clamp;
erosionMap.Create();
}
private void FetchWorldData(List<GStylizedTerrain> terrains, Vector3 bounds, ref RenderTexture simulationData, ref RenderTexture simulationMask, ref RenderTexture erosionMap)
{
GCommon.DrawQuad(erosionMap, GCommon.FullRectUvPoints, FetchWorldDataMaterial, PASS_EROSION_MAP);
for (int i = 0; i < terrains.Count; ++i)
{
GStylizedTerrain t = terrains[i];
Vector3 terrainPos = t.transform.position;
Vector3 terrainSize = t.TerrainData.Geometry.Size;
Vector3[] terrainWorldCorners = new Vector3[4]
{
new Vector3(terrainPos.x, 0, terrainPos.z),
new Vector3(terrainPos.x, 0, terrainPos.z + terrainSize.z),
new Vector3(terrainPos.x + terrainSize.x, 0, terrainPos.z + terrainSize.z),
new Vector3(terrainPos.x + terrainSize.x, 0, terrainPos.z)
};
Vector2[] uvCorner = new Vector2[4];
for (int c = 0; c < uvCorner.Length; ++c)
{
Vector3 simSpaceCorner = Simulator.transform.InverseTransformPoint(terrainWorldCorners[c]);
uvCorner[c] = new Vector2(simSpaceCorner.x + 0.5f, simSpaceCorner.z + 0.5f);
}
FetchWorldDataMaterial.SetTexture(MAIN_TEX, t.TerrainData.Geometry.HeightMap);
FetchWorldDataMaterial.SetVector(BOUNDS, bounds);
GCommon.DrawQuad(simulationData, uvCorner, FetchWorldDataMaterial, PASS_HEIGHT);
FetchWorldDataMaterial.SetTexture(MAIN_TEX, t.TerrainData.Mask.MaskMapOrDefault);
FetchWorldDataMaterial.SetFloat(ENABLE_TERRAIN_MASK, Simulator.EnableTerrainMask ? 1 : 0);
GCommon.DrawQuad(simulationMask, uvCorner, FetchWorldDataMaterial, PASS_MASK);
}
}
}
}
#endif