#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 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 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 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