452 lines
12 KiB
C#
452 lines
12 KiB
C#
using System;
|
|
using System.Reflection;
|
|
using UnityEngine;
|
|
|
|
[ExecuteInEditMode]
|
|
[AddComponentMenu("Relief Terrain/Engine - Terrain or Mesh")]
|
|
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<Renderer>().bounds.size;
|
|
globalSettingsHolder.terrainTileSize.y = globalSettingsHolder.tessHeight;
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
UpdateBasemapDistance(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(true);
|
|
Terrain terrain = (Terrain)GetComponent(typeof(Terrain));
|
|
globalSettingsHolder.use_mat = mat;
|
|
if (!terrain && !mat)
|
|
{
|
|
if (GetComponent<Renderer>().sharedMaterial == null || GetComponent<Renderer>().sharedMaterial.name != "RTPMaterial")
|
|
{
|
|
GetComponent<Renderer>().sharedMaterial = new Material(Shader.Find("Relief Pack/Terrain2Geometry"));
|
|
GetComponent<Renderer>().sharedMaterial.name = "RTPMaterial";
|
|
}
|
|
globalSettingsHolder.use_mat = GetComponent<Renderer>().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<Renderer>().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;
|
|
}
|
|
}
|