using System; using LE_LevelEditor.Core; using LE_LevelEditor.UI; using UnityEngine; namespace LE_LevelEditor.Commands { public class LE_GenCmdTerrain { public enum Mode { HEIGHTS_CMD = 0, ALPHAMAPS_CMD = 1 } private LE_GUI3dTerrain m_gui3d; private LE_TerrainManager m_terrainMgr; private Mode m_cmdMode; private float[,] m_heightsBeforeChange; private float[,,] m_alphamapsBeforeChange; private int m_xBase = -1; private int m_yBase = -1; private int m_xMax = -1; private int m_yMax = -1; private int m_lastEditedFrame; public int LastEditedFrame { get { return m_lastEditedFrame; } } public LE_GenCmdTerrain(LE_GUI3dTerrain p_gui3d, LE_TerrainManager p_terrainMgr, Mode p_cmdMode) { m_gui3d = p_gui3d; m_terrainMgr = p_terrainMgr; m_cmdMode = p_cmdMode; if (m_cmdMode == Mode.HEIGHTS_CMD) { m_heightsBeforeChange = p_terrainMgr.TerrainData.GetHeights(0, 0, p_terrainMgr.TerrainData.heightmapWidth, p_terrainMgr.TerrainData.heightmapHeight); } else { m_alphamapsBeforeChange = p_terrainMgr.TerrainData.GetAlphamaps(0, 0, p_terrainMgr.TerrainData.alphamapWidth, p_terrainMgr.TerrainData.alphamapHeight); } m_lastEditedFrame = Time.frameCount; } public void ChangeHeight(float p_delta, Texture2D p_alphaBrushTexture, float p_relativeBrushSize, Vector2 p_relativeLocalLocation) { ExecuteHeightsSubCmd(delegate { m_terrainMgr.ChangeHeight(p_delta, p_alphaBrushTexture, p_relativeBrushSize, p_relativeLocalLocation); }); } public void ChangeHeight(float p_delta, float p_targetHeight, Texture2D p_alphaBrushTexture, float p_relativeBrushSize, Vector2 p_relativeLocalLocation) { ExecuteHeightsSubCmd(delegate { m_terrainMgr.ChangeHeight(p_delta, p_targetHeight, p_alphaBrushTexture, p_relativeBrushSize, p_relativeLocalLocation); }); } public void SmoothHeight(float p_amount, int p_neighbourCount, Texture2D p_alphaBrushTexture, float p_relativeBrushSize, Vector2 p_relativeLocalLocation, bool p_isDirected, float p_angle) { ExecuteHeightsSubCmd(delegate { m_terrainMgr.SmoothHeight(p_amount, p_neighbourCount, p_alphaBrushTexture, p_relativeBrushSize, p_relativeLocalLocation, p_isDirected, p_angle); }); } public void PaintTexture(int p_splatPrototypeIndex, float p_delta, float p_targetValue, Texture2D p_alphaBrushTexture, float p_relativeBrushSize, Vector2 p_relativeLocalLocation) { if (m_cmdMode != Mode.ALPHAMAPS_CMD) { Debug.LogError(string.Concat("LE_GenCmdTerrain: ExecuteHeightsSubCmd: this instance was initialised in the '", m_cmdMode, "' mode, but you are trying to change terrain's alphamap!")); return; } LE_TerrainManager terrainMgr = m_terrainMgr; terrainMgr.OnBeforeChangeAlphamaps = (Action)Delegate.Combine(terrainMgr.OnBeforeChangeAlphamaps, new Action(OnBeforeChangeAlphamaps)); m_terrainMgr.PaintTexture(p_splatPrototypeIndex, p_delta, p_targetValue, p_alphaBrushTexture, p_relativeBrushSize, p_relativeLocalLocation); LE_TerrainManager terrainMgr2 = m_terrainMgr; terrainMgr2.OnBeforeChangeAlphamaps = (Action)Delegate.Remove(terrainMgr2.OnBeforeChangeAlphamaps, new Action(OnBeforeChangeAlphamaps)); m_lastEditedFrame = Time.frameCount; } public LE_CmdBase GetCmd() { if (m_xBase < 0 || m_yBase < 0 || m_xMax < 0 || m_yMax < 0) { return null; } int num = m_xMax - m_xBase; int num2 = m_yMax - m_yBase; if (m_cmdMode == Mode.HEIGHTS_CMD) { m_gui3d.TerrainInstance.ApplyDelayedHeightmapModification(); float[,] heights = m_terrainMgr.TerrainData.GetHeights(m_xBase, m_yBase, num, num2); for (int i = 0; i < num; i++) { for (int j = 0; j < num2; j++) { heights[j, i] -= m_heightsBeforeChange[m_yBase + j, m_xBase + i]; } } return new LE_CmdChangeTerrainHeights(m_terrainMgr, new LE_TerrainManager.HeightData(m_xBase, m_yBase, heights)); } float[,,] alphamaps = m_terrainMgr.TerrainData.GetAlphamaps(m_xBase, m_yBase, num, num2); int length = alphamaps.GetLength(2); for (int k = 0; k < num; k++) { for (int l = 0; l < num2; l++) { for (int m = 0; m < length; m++) { alphamaps[l, k, m] -= m_alphamapsBeforeChange[m_yBase + l, m_xBase + k, m]; } } } return new LE_CmdChangeTerrainAlphamaps(m_terrainMgr, new LE_TerrainManager.AlphamapData(m_xBase, m_yBase, alphamaps)); } private void ExecuteHeightsSubCmd(Action p_subCmd) { if (m_cmdMode != Mode.HEIGHTS_CMD) { Debug.LogError(string.Concat("LE_GenCmdTerrain: ExecuteHeightsSubCmd: this instance was initialised in the '", m_cmdMode, "' mode, but you are trying to change terrain's height!")); return; } LE_TerrainManager terrainMgr = m_terrainMgr; terrainMgr.OnBeforeChangeHeights = (Action)Delegate.Combine(terrainMgr.OnBeforeChangeHeights, new Action(OnBeforeChangeHeights)); if (p_subCmd != null) { p_subCmd(); } LE_TerrainManager terrainMgr2 = m_terrainMgr; terrainMgr2.OnBeforeChangeHeights = (Action)Delegate.Remove(terrainMgr2.OnBeforeChangeHeights, new Action(OnBeforeChangeHeights)); m_lastEditedFrame = Time.frameCount; } private void OnBeforeChangeHeights(LE_TerrainManager.HeightData p_data) { m_xBase = ((m_xBase != -1) ? Mathf.Min(m_xBase, p_data.m_xBase) : p_data.m_xBase); m_yBase = ((m_yBase != -1) ? Mathf.Min(m_yBase, p_data.m_yBase) : p_data.m_yBase); m_xMax = Mathf.Max(m_xMax, p_data.m_xBase + p_data.m_heights.GetLength(1)); m_yMax = Mathf.Max(m_yMax, p_data.m_yBase + p_data.m_heights.GetLength(0)); } private void OnBeforeChangeAlphamaps(LE_TerrainManager.AlphamapData p_data) { m_xBase = ((m_xBase != -1) ? Mathf.Min(m_xBase, p_data.m_xBase) : p_data.m_xBase); m_yBase = ((m_yBase != -1) ? Mathf.Min(m_yBase, p_data.m_yBase) : p_data.m_yBase); m_xMax = Mathf.Max(m_xMax, p_data.m_xBase + p_data.m_alphamaps.GetLength(1)); m_yMax = Mathf.Max(m_yMax, p_data.m_yBase + p_data.m_alphamaps.GetLength(0)); } } }