Rasagar/Library/PackageCache/com.unity.terrain-tools/Editor/TerrainTools/BrushControllers/BrushSpacingVariator.cs

112 lines
3.9 KiB
C#
Raw Normal View History

2024-08-26 13:07:20 -07:00
using System;
using System.Text;
using UnityEditor.TerrainTools.UI;
using UnityEngine;
using UnityEngine.TerrainTools;
namespace UnityEditor.TerrainTools
{
internal class BrushSpacingVariator : BaseBrushVariator, IBrushSpacingController
{
private float m_BrushSpacing = 0.0f;
private bool m_AllowPaint = true;
private bool m_ThresholdReached = false;
private float m_DistanceTravelled = 0.0f;
private Vector3 m_LastBrushPos;
private float m_defaultBrushSpacing;
public float brushSpacing {
get { return m_BrushSpacing; }
set
{
m_BrushSpacing = Mathf.Clamp(value, 0f, 100f);
}
}
public bool allowPaint {
get => m_AllowPaint; set => m_AllowPaint = value; }
class Styles
{
public readonly GUIContent brushSpacing = EditorGUIUtility.TrTextContent("Brush Spacing", "Distance between each brush stamp in a stroke");
}
static readonly Styles styles = new Styles();
public BrushSpacingVariator(string toolName, IBrushEventHandler eventHandler, IBrushTerrainCache terrainCache, float defaultValue = 0.0f) : base(toolName, eventHandler, terrainCache)
{
m_defaultBrushSpacing = defaultValue;
}
public override void OnEnterToolMode(BrushShortcutHandler<BrushShortcutType> shortcutHandler)
{
base.OnEnterToolMode(shortcutHandler);
m_BrushSpacing = GetEditorPrefs("TerrainBrushSpacing", m_defaultBrushSpacing);
}
public override void OnExitToolMode(BrushShortcutHandler<BrushShortcutType> shortcutHandler)
{
SetEditorPrefs("TerrainBrushSpacing", m_BrushSpacing);
base.OnExitToolMode(shortcutHandler);
}
public override void OnSceneGUI(Event currentEvent, int controlId, Terrain terrain, IOnSceneGUI editContext)
{
//maybe this should be scaled by brush size?
Vector2 a = new Vector2(m_LastBrushPos.x, m_LastBrushPos.z);
Vector2 b = new Vector2(editContext.raycastHit.point.x, editContext.raycastHit.point.z);
float d = Vector2.Distance(a, b);
float threshold = m_BrushSpacing * 200f; //TODO: make this scalar a user preference?
base.OnSceneGUI(currentEvent, controlId, terrain, editContext);
m_DistanceTravelled += d;
if (m_DistanceTravelled > threshold)
{
m_ThresholdReached = true;
m_LastBrushPos = editContext.raycastHit.point;
m_DistanceTravelled = 0.0f;
}
m_LastBrushPos = editContext.raycastHit.point;
}
// for updating condensed slider overlays
public static event Action BrushSpacingChanged;
private float prevBrushSpacing;
public override void OnInspectorGUI(Terrain terrain, IOnInspectorGUI editContext)
{
base.OnInspectorGUI(terrain, editContext);
m_BrushSpacing = TerrainToolGUIHelper.PercentSlider(styles.brushSpacing, m_BrushSpacing, 0.0f, 1.0f);
if (!Mathf.Approximately(m_BrushSpacing, prevBrushSpacing) && BrushSpacingChanged != null)
{
BrushSpacingChanged();
prevBrushSpacing = m_BrushSpacing;
}
}
public override bool OnPaint(Terrain terrain, IOnPaint editContext)
{
base.OnPaint(terrain, editContext);
m_AllowPaint = m_ThresholdReached;
if (m_AllowPaint)
{
m_ThresholdReached = false;
}
return true;
}
public override void AppendBrushInfo(Terrain terrain, IOnSceneGUI editContext, StringBuilder builder)
{
base.AppendBrushInfo(terrain, editContext, builder);
builder.AppendLine($"Spacing = {m_BrushSpacing:F3}");
}
}
}