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; } } } }