162 lines
4.0 KiB
C#
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;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|