170 lines
6.1 KiB
C#
170 lines
6.1 KiB
C#
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<LE_TerrainManager.AlphamapData>)Delegate.Combine(terrainMgr.OnBeforeChangeAlphamaps, new Action<LE_TerrainManager.AlphamapData>(OnBeforeChangeAlphamaps));
|
|
m_terrainMgr.PaintTexture(p_splatPrototypeIndex, p_delta, p_targetValue, p_alphaBrushTexture, p_relativeBrushSize, p_relativeLocalLocation);
|
|
LE_TerrainManager terrainMgr2 = m_terrainMgr;
|
|
terrainMgr2.OnBeforeChangeAlphamaps = (Action<LE_TerrainManager.AlphamapData>)Delegate.Remove(terrainMgr2.OnBeforeChangeAlphamaps, new Action<LE_TerrainManager.AlphamapData>(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<LE_TerrainManager.HeightData>)Delegate.Combine(terrainMgr.OnBeforeChangeHeights, new Action<LE_TerrainManager.HeightData>(OnBeforeChangeHeights));
|
|
if (p_subCmd != null)
|
|
{
|
|
p_subCmd();
|
|
}
|
|
LE_TerrainManager terrainMgr2 = m_terrainMgr;
|
|
terrainMgr2.OnBeforeChangeHeights = (Action<LE_TerrainManager.HeightData>)Delegate.Remove(terrainMgr2.OnBeforeChangeHeights, new Action<LE_TerrainManager.HeightData>(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));
|
|
}
|
|
}
|
|
}
|