132 lines
5.5 KiB
C#
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
|