Files
2025-05-29 22:31:40 +03:00

162 lines
4.0 KiB
C#

using UnityEngine;
using UnityEditor;
using System;
namespace Obi
{
public abstract class ObiBrushBase
{
static int particleBrushHash = "ObiBrushHash".GetHashCode();
public IObiBrushMode brushMode;
public float radius = 1;
public float innerRadius = 0.5f;
public float opacity = 1;
public float[] weights = new float[0];
public bool drag = true;
public float speed = 0.1f;
protected int controlID;
protected Action onStrokeStart;
protected Action onStrokeUpdate;
protected Action onStrokeEnd;
public float SqrRadius
{
get{ return radius * radius; }
}
public ObiBrushBase(Action onStrokeStart, Action onStrokeUpdate, Action onStrokeEnd)
{
this.onStrokeStart = onStrokeStart;
this.onStrokeUpdate = onStrokeUpdate;
this.onStrokeEnd = onStrokeEnd;
}
protected virtual float WeightFromDistance(float distance)
{
// anything outside the brush should have zero weight:
if (distance > radius)
return 0;
float t = Mathf.InverseLerp(innerRadius * radius, radius, distance);
return Mathf.SmoothStep(1, 0, t);
}
protected abstract void GenerateWeights(Vector3[] positions);
protected virtual void OnMouseDown(Vector3[] positions)
{
if (Event.current.button != 0 || (Event.current.modifiers & ~EventModifiers.Shift) != EventModifiers.None)
return;
GUIUtility.hotControl = controlID;
GenerateWeights(positions);
if (onStrokeStart != null)
onStrokeStart();
if (brushMode != null)
brushMode.ApplyStamps(this, (Event.current.modifiers & EventModifiers.Shift) != 0);
if (onStrokeUpdate != null)
onStrokeUpdate();
Event.current.Use();
}
protected virtual void OnMouseMove(Vector3[] positions)
{
}
protected virtual void OnMouseDrag(Vector3[] positions)
{
if (GUIUtility.hotControl == controlID && drag)
{
GenerateWeights(positions);
if (brushMode != null)
brushMode.ApplyStamps(this, (Event.current.modifiers & EventModifiers.Shift) != 0);
if (onStrokeUpdate != null)
onStrokeUpdate();
Event.current.Use();
}
}
protected virtual void OnMouseUp(Vector3[] positions)
{
if (GUIUtility.hotControl == controlID)
{
GUIUtility.hotControl = 0;
Event.current.Use();
if (onStrokeEnd != null)
onStrokeEnd();
}
}
protected virtual void OnRepaint()
{
}
public void DoBrush(Vector3[] positions)
{
Matrix4x4 cachedMatrix = Handles.matrix;
controlID = GUIUtility.GetControlID(particleBrushHash, FocusType.Passive);
Array.Resize(ref weights, positions.Length);
switch (Event.current.GetTypeForControl(controlID))
{
case EventType.MouseDown:
OnMouseDown(positions);
break;
case EventType.MouseMove:
OnMouseMove(positions);
SceneView.RepaintAll();
break;
case EventType.MouseDrag:
OnMouseDrag(positions);
break;
case EventType.MouseUp:
OnMouseUp(positions);
break;
case EventType.Repaint:
Handles.matrix = Matrix4x4.identity;
OnRepaint();
Handles.matrix = cachedMatrix;
break;
}
}
}
}