using System; using System.Reflection; using UnityEngine; [AddComponentMenu("Relief Terrain/Engine - Terrain or Mesh")] [ExecuteInEditMode] public class ReliefTerrain : MonoBehaviour { public Texture2D controlA; public Texture2D controlB; public Texture2D controlC; public string save_path_controlA = string.Empty; public string save_path_controlB = string.Empty; public string save_path_controlC = string.Empty; public string save_path_colormap = string.Empty; public string save_path_BumpGlobalCombined = string.Empty; public string save_path_WetMask = string.Empty; public Texture2D NormalGlobal; public Texture2D TreesGlobal; public Texture2D ColorGlobal; public Texture2D AmbientEmissiveMap; public Texture2D BumpGlobalCombined; public Texture2D TERRAIN_WetMask; public Texture2D tmp_globalColorMap; public Texture2D tmp_CombinedMap; public Texture2D tmp_WaterMap; public bool globalColorModifed_flag; public bool globalCombinedModifed_flag; public bool globalWaterModifed_flag; public bool splat_layer_ordered_mode; public RTPColorChannels[] source_controls_channels; public int[] splat_layer_seq; public float[] splat_layer_boost; public bool[] splat_layer_calc; public bool[] splat_layer_masked; public RTPColorChannels[] source_controls_mask_channels; public Texture2D[] source_controls; public bool[] source_controls_invert; public Texture2D[] source_controls_mask; public bool[] source_controls_mask_invert; public Vector2 customTiling = new Vector2(3f, 3f); [SerializeField] public ReliefTerrainPresetHolder[] presetHolders; [SerializeField] public ReliefTerrainGlobalSettingsHolder globalSettingsHolder; public void GetGlobalSettingsHolder() { if (globalSettingsHolder != null) { return; } ReliefTerrain[] array = (ReliefTerrain[])UnityEngine.Object.FindObjectsOfType(typeof(ReliefTerrain)); bool flag = GetComponent(typeof(Terrain)); for (int i = 0; i < array.Length; i++) { if (array[i].transform.parent == base.transform.parent && array[i].globalSettingsHolder != null && ((flag && array[i].GetComponent(typeof(Terrain)) != null) || (!flag && array[i].GetComponent(typeof(Terrain)) == null))) { globalSettingsHolder = array[i].globalSettingsHolder; if ((bool)globalSettingsHolder.Get_RTP_LODmanagerScript() && !globalSettingsHolder.Get_RTP_LODmanagerScript().RTP_WETNESS_FIRST && !globalSettingsHolder.Get_RTP_LODmanagerScript().RTP_WETNESS_ADD) { BumpGlobalCombined = array[i].BumpGlobalCombined; globalCombinedModifed_flag = false; } break; } } if (globalSettingsHolder == null) { globalSettingsHolder = new ReliefTerrainGlobalSettingsHolder(); if (flag) { globalSettingsHolder.numTiles = 0; Terrain terrain = (Terrain)GetComponent(typeof(Terrain)); globalSettingsHolder.splats = new Texture2D[terrain.terrainData.splatPrototypes.Length]; globalSettingsHolder.Bumps = new Texture2D[terrain.terrainData.splatPrototypes.Length]; for (int j = 0; j < terrain.terrainData.splatPrototypes.Length; j++) { globalSettingsHolder.splats[j] = terrain.terrainData.splatPrototypes[j].texture; globalSettingsHolder.Bumps[j] = terrain.terrainData.splatPrototypes[j].normalMap; } } else { globalSettingsHolder.splats = new Texture2D[4]; } globalSettingsHolder.numLayers = globalSettingsHolder.splats.Length; globalSettingsHolder.ReturnToDefaults(string.Empty); } else if (flag) { GetSplatsFromGlobalSettingsHolder(); } source_controls_mask = new Texture2D[12]; source_controls = new Texture2D[12]; source_controls_channels = new RTPColorChannels[12]; source_controls_mask_channels = new RTPColorChannels[12]; splat_layer_seq = new int[12] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; splat_layer_boost = new float[12] { 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f }; splat_layer_calc = new bool[12]; splat_layer_masked = new bool[12]; source_controls_invert = new bool[12]; source_controls_mask_invert = new bool[12]; if (flag) { globalSettingsHolder.numTiles++; } } private void GetSplatsFromGlobalSettingsHolder() { SplatPrototype[] array = new SplatPrototype[globalSettingsHolder.numLayers]; for (int i = 0; i < globalSettingsHolder.numLayers; i++) { array[i] = new SplatPrototype(); array[i].tileSize = Vector2.one; array[i].tileOffset = new Vector2(1f / customTiling.x, 1f / customTiling.y); array[i].texture = globalSettingsHolder.splats[i]; array[i].normalMap = globalSettingsHolder.Bumps[i]; } Terrain terrain = (Terrain)GetComponent(typeof(Terrain)); terrain.terrainData.splatPrototypes = array; } public void InitTerrainTileSizes() { Terrain terrain = (Terrain)GetComponent(typeof(Terrain)); if ((bool)terrain) { globalSettingsHolder.terrainTileSize = terrain.terrainData.size; return; } globalSettingsHolder.terrainTileSize = GetComponent().bounds.size; globalSettingsHolder.terrainTileSize.y = globalSettingsHolder.tessHeight; } private void Awake() { UpdateBasemapDistance(apply_material_if_applicable: false); RefreshTextures(); } public void InitArrays() { RefreshTextures(); } private void UpdateBasemapDistance(bool apply_material_if_applicable) { Terrain terrain = (Terrain)GetComponent(typeof(Terrain)); if (!terrain || globalSettingsHolder == null) { return; } terrain.basemapDistance = globalSettingsHolder.distance_start + globalSettingsHolder.distance_transition; if (apply_material_if_applicable) { if (terrain.materialTemplate == null) { terrain.materialType = Terrain.MaterialType.Custom; Shader shader = Shader.Find("Relief Pack/ReliefTerrain-FirstPass"); if ((bool)shader) { Material material = new Material(shader); material.name = base.gameObject.name + " material"; terrain.materialTemplate = material; } } else { Material materialTemplate = terrain.materialTemplate; terrain.materialTemplate = null; terrain.materialTemplate = materialTemplate; } } if (globalSettingsHolder != null && globalSettingsHolder._RTP_LODmanagerScript != null && globalSettingsHolder._RTP_LODmanagerScript.numLayersProcessedByFarShader != globalSettingsHolder.numLayers) { terrain.basemapDistance = 500000f; } globalSettingsHolder.Refresh(terrain.materialTemplate); } public void RefreshTextures(Material mat = null, bool check_weak_references = false) { GetGlobalSettingsHolder(); InitTerrainTileSizes(); if (globalSettingsHolder != null && BumpGlobalCombined != null) { globalSettingsHolder.BumpGlobalCombinedSize = BumpGlobalCombined.width; } UpdateBasemapDistance(apply_material_if_applicable: true); Terrain terrain = (Terrain)GetComponent(typeof(Terrain)); globalSettingsHolder.use_mat = mat; if (!terrain && !mat) { if (GetComponent().sharedMaterial == null || GetComponent().sharedMaterial.name != "RTPMaterial") { GetComponent().sharedMaterial = new Material(Shader.Find("Relief Pack/Terrain2Geometry")); GetComponent().sharedMaterial.name = "RTPMaterial"; } globalSettingsHolder.use_mat = GetComponent().sharedMaterial; } if ((bool)terrain && terrain.materialTemplate != null) { globalSettingsHolder.use_mat = terrain.materialTemplate; terrain.materialTemplate.SetVector("RTP_CustomTiling", new Vector4(1f / customTiling.x, 1f / customTiling.y, 0f, 0f)); } globalSettingsHolder.use_mat = null; RefreshControlMaps(mat); if ((bool)mat) { mat.SetVector("RTP_CustomTiling", new Vector4(1f / customTiling.x, 1f / customTiling.y, 0f, 0f)); } } public void RefreshControlMaps(Material mat = null) { globalSettingsHolder.use_mat = mat; Terrain terrain = (Terrain)GetComponent(typeof(Terrain)); if (!terrain && !mat) { globalSettingsHolder.use_mat = GetComponent().sharedMaterial; } if ((bool)terrain && !mat && terrain.materialTemplate != null) { globalSettingsHolder.use_mat = terrain.materialTemplate; } globalSettingsHolder.SetShaderParam("_Control1", controlA); if (globalSettingsHolder.numLayers > 4) { globalSettingsHolder.SetShaderParam("_Control3", controlB); globalSettingsHolder.SetShaderParam("_Control2", controlB); } if (globalSettingsHolder.numLayers > 8) { globalSettingsHolder.SetShaderParam("_Control3", controlC); } globalSettingsHolder.SetShaderParam("_ColorMapGlobal", ColorGlobal); globalSettingsHolder.SetShaderParam("_NormalMapGlobal", NormalGlobal); globalSettingsHolder.SetShaderParam("_TreesMapGlobal", TreesGlobal); globalSettingsHolder.SetShaderParam("_AmbientEmissiveMapGlobal", AmbientEmissiveMap); globalSettingsHolder.SetShaderParam("_BumpMapGlobal", BumpGlobalCombined); globalSettingsHolder.use_mat = null; } public void GetControlMaps() { Terrain terrain = (Terrain)GetComponent(typeof(Terrain)); if (!terrain) { Debug.Log("Can't fint terrain component !!!"); return; } Type type = terrain.terrainData.GetType(); PropertyInfo property = type.GetProperty("alphamapTextures", BindingFlags.Instance | BindingFlags.Public); if (property != null) { Texture2D[] array = (Texture2D[])property.GetValue(terrain.terrainData, null); if (array.Length > 0) { controlA = array[0]; } else { controlA = null; } if (array.Length > 1) { controlB = array[1]; } else { controlB = null; } if (array.Length > 2) { controlC = array[2]; } else { controlC = null; } } else { Debug.LogError("Can't access alphamapTexture directly..."); } } public void SetCustomControlMaps() { Terrain terrain = (Terrain)GetComponent(typeof(Terrain)); if (!terrain) { Debug.Log("Can't fint terrain component !!!"); } else { if (controlA == null) { return; } if (terrain.terrainData.alphamapResolution != controlA.width) { Debug.LogError("Terrain controlmap resolution differs fromrequested control texture..."); } else { if (!controlA) { return; } float[,,] alphamaps = terrain.terrainData.GetAlphamaps(0, 0, terrain.terrainData.alphamapResolution, terrain.terrainData.alphamapResolution); Color[] pixels = controlA.GetPixels(); for (int i = 0; i < terrain.terrainData.alphamapLayers; i++) { int num = 0; switch (i) { case 4: if (!controlB) { return; } pixels = controlB.GetPixels(); break; case 8: if (!controlC) { return; } pixels = controlC.GetPixels(); break; } int index = i & 3; for (int j = 0; j < terrain.terrainData.alphamapResolution; j++) { for (int k = 0; k < terrain.terrainData.alphamapResolution; k++) { alphamaps[j, k, i] = pixels[num++][index]; } } } terrain.terrainData.SetAlphamaps(0, 0, alphamaps); } } } public void RestorePreset(ReliefTerrainPresetHolder holder) { controlA = holder.controlA; controlB = holder.controlB; controlC = holder.controlC; SetCustomControlMaps(); ColorGlobal = holder.ColorGlobal; NormalGlobal = holder.NormalGlobal; TreesGlobal = holder.TreesGlobal; AmbientEmissiveMap = holder.AmbientEmissiveMap; BumpGlobalCombined = holder.BumpGlobalCombined; TERRAIN_WetMask = holder.TERRAIN_WetMask; globalColorModifed_flag = holder.globalColorModifed_flag; globalCombinedModifed_flag = holder.globalCombinedModifed_flag; globalWaterModifed_flag = holder.globalWaterModifed_flag; RefreshTextures(); globalSettingsHolder.RestorePreset(holder); } public ReliefTerrainPresetHolder GetPresetByID(string PresetID) { if (presetHolders != null) { for (int i = 0; i < presetHolders.Length; i++) { if (presetHolders[i].PresetID == PresetID) { return presetHolders[i]; } } } return null; } public ReliefTerrainPresetHolder GetPresetByName(string PresetName) { if (presetHolders != null) { for (int i = 0; i < presetHolders.Length; i++) { if (presetHolders[i].PresetName == PresetName) { return presetHolders[i]; } } } return null; } public bool InterpolatePresets(string PresetID1, string PresetID2, float t) { ReliefTerrainPresetHolder presetByID = GetPresetByID(PresetID1); ReliefTerrainPresetHolder presetByID2 = GetPresetByID(PresetID2); if (presetByID == null || presetByID2 == null || presetByID.Spec == null || presetByID2.Spec == null || presetByID.Spec.Length != presetByID2.Spec.Length) { return false; } globalSettingsHolder.InterpolatePresets(presetByID, presetByID2, t); return true; } }