@@ -9,17 +9,25 @@ public class MaskVolumeBrush
9
9
const float k_Stepping = 0.5f ;
10
10
const int k_RaycastBufferSize = 128 ;
11
11
12
- public float Radius = 0.5f ;
12
+ public float OuterRadius = 0.5f ;
13
+ public float InnerRadius = 1f ;
14
+ public float NormalBias = 0f ;
13
15
14
16
public bool MeshCollidersOnly = true ;
15
17
public LayerMask PhysicsLayerMask = ~ 0 ;
16
18
17
19
bool m_Hovering = false ;
18
20
Vector3 m_Position ;
21
+ Vector3 m_Normal ;
22
+
19
23
bool m_Applying = false ;
20
24
Vector3 m_LastApplyPosition ;
25
+ Vector3 m_LastApplyNormal ;
26
+ float m_LastApplyPressure ;
21
27
22
- public event Action < Vector3 > OnApply ;
28
+ public delegate void Apply ( Vector3 position , Vector3 normal , float pressure , bool control ) ;
29
+
30
+ public event Apply OnApply ;
23
31
public event Action OnStopApplying ;
24
32
25
33
public void OnSceneGUI ( SceneView sceneView )
@@ -48,7 +56,7 @@ public void OnSceneGUI(SceneView sceneView)
48
56
case EventType . MouseDown :
49
57
case EventType . MouseDrag :
50
58
UpdateBrush ( e . mousePosition ) ;
51
- ApplyBrush ( ) ;
59
+ ApplyBrush ( e . pressure , e . control ) ;
52
60
break ;
53
61
54
62
case EventType . MouseUp :
@@ -82,13 +90,16 @@ static bool SceneViewInUse(Event e)
82
90
void UpdateBrush ( Vector2 mousePosition )
83
91
{
84
92
Ray mouseRay = HandleUtility . GUIPointToWorldRay ( mousePosition ) ;
85
- m_Hovering = Raycast ( mouseRay , out var hitPosition ) ;
93
+ m_Hovering = Raycast ( mouseRay , out var hitPosition , out var hitNormal ) ;
86
94
if ( m_Hovering )
95
+ {
87
96
m_Position = hitPosition ;
97
+ m_Normal = hitNormal ;
98
+ }
88
99
}
89
100
90
101
RaycastHit [ ] raycastBuffer ;
91
- bool Raycast ( Ray ray , out Vector3 hitPosition )
102
+ bool Raycast ( Ray ray , out Vector3 hitPosition , out Vector3 hitNormal )
92
103
{
93
104
if ( MeshCollidersOnly )
94
105
{
@@ -97,21 +108,23 @@ bool Raycast(Ray ray, out Vector3 hitPosition)
97
108
var hitCount = Physics . RaycastNonAlloc ( ray , raycastBuffer , float . MaxValue , PhysicsLayerMask , QueryTriggerInteraction . Ignore ) ;
98
109
99
110
var minDistance = float . MaxValue ;
100
- var nearestPosition = Vector3 . zero ;
111
+ var nearestHit = - 1 ;
101
112
102
113
for ( int i = 0 ; i < hitCount ; i ++ )
103
114
{
104
115
var hit = raycastBuffer [ i ] ;
105
116
if ( hit . collider is MeshCollider && hit . distance < minDistance )
106
117
{
107
118
minDistance = hit . distance ;
108
- nearestPosition = hit . point ;
119
+ nearestHit = i ;
109
120
}
110
121
}
111
122
112
- if ( minDistance != float . MaxValue )
123
+ if ( nearestHit != - 1 )
113
124
{
114
- hitPosition = nearestPosition ;
125
+ var hit = raycastBuffer [ nearestHit ] ;
126
+ hitPosition = hit . point ;
127
+ hitNormal = hit . normal ;
115
128
return true ;
116
129
}
117
130
}
@@ -120,41 +133,50 @@ bool Raycast(Ray ray, out Vector3 hitPosition)
120
133
if ( Physics . Raycast ( ray , out var hit , float . MaxValue , PhysicsLayerMask , QueryTriggerInteraction . Ignore ) )
121
134
{
122
135
hitPosition = hit . point ;
136
+ hitNormal = hit . normal ;
123
137
return true ;
124
138
}
125
139
}
126
140
127
141
hitPosition = default ;
142
+ hitNormal = default ;
128
143
return false ;
129
144
}
130
145
131
146
/// <summary>
132
147
/// Apply brush.
133
148
/// </summary>
134
- void ApplyBrush ( )
149
+ void ApplyBrush ( float pressure , bool control )
135
150
{
136
151
if ( m_Hovering )
137
152
{
138
153
if ( ! m_Applying )
139
154
{
140
155
m_Applying = true ;
141
- OnApply ? . Invoke ( m_Position ) ;
156
+ OnApply ? . Invoke ( m_Position , m_Normal , pressure , control ) ;
142
157
m_LastApplyPosition = m_Position ;
158
+ m_LastApplyNormal = m_Normal ;
159
+ m_LastApplyPressure = pressure ;
143
160
}
144
161
else
145
162
{
146
163
var moveDistance = Vector3 . Distance ( m_Position , m_LastApplyPosition ) ;
147
164
148
165
// If mouse moved too far due to low framerate or high movement speed, fill the gap with more stamps
149
- var maxStep = Radius * k_Stepping ;
166
+ var maxStep = OuterRadius * k_Stepping ;
150
167
var steps = ( int ) ( moveDistance / maxStep ) ;
151
168
152
169
var maxTime = Time . realtimeSinceStartup + k_MaxTimeSpentPerEvent ;
153
170
var startPosition = m_LastApplyPosition ;
171
+ var startNormal = m_LastApplyNormal ;
172
+ var startPressure = m_LastApplyPressure ;
154
173
for ( int i = 1 ; i <= steps ; i ++ )
155
174
{
156
- m_LastApplyPosition = Vector3 . Lerp ( startPosition , m_Position , ( float ) i / steps ) ;
157
- OnApply ? . Invoke ( m_LastApplyPosition ) ;
175
+ var time = ( float ) i / steps ;
176
+ m_LastApplyPosition = Vector3 . Lerp ( startPosition , m_Position , time ) ;
177
+ m_LastApplyNormal = Vector3 . Lerp ( startNormal , m_Normal , time ) ;
178
+ m_LastApplyPressure = Mathf . Lerp ( startPressure , pressure , time ) ;
179
+ OnApply ? . Invoke ( m_LastApplyPosition , m_LastApplyNormal , m_LastApplyPressure , control ) ;
158
180
if ( Time . realtimeSinceStartup > maxTime )
159
181
break ;
160
182
}
@@ -165,7 +187,28 @@ void ApplyBrush()
165
187
void DrawGizmo ( SceneView sceneView )
166
188
{
167
189
if ( m_Hovering )
168
- Handles . DrawWireDisc ( m_Position , ( sceneView . camera . transform . position - m_Position ) . normalized , Radius ) ;
190
+ {
191
+ var oldHandleColor = Handles . color ;
192
+
193
+ var discNormal = ( sceneView . camera . transform . position - m_Position ) . normalized ;
194
+
195
+ if ( InnerRadius != 1f )
196
+ {
197
+ Handles . color = new Color ( 1f , 1f , 1f , 0.5f ) ;
198
+ Handles . DrawWireDisc ( m_Position , discNormal , OuterRadius ) ;
199
+ }
200
+
201
+ Handles . color = Color . white ;
202
+ Handles . DrawWireDisc ( m_Position , discNormal , OuterRadius * InnerRadius ) ;
203
+
204
+ if ( NormalBias != 0f )
205
+ {
206
+ Handles . color = new Color ( Mathf . Abs ( m_Normal . x ) , Mathf . Abs ( m_Normal . y ) , Mathf . Abs ( m_Normal . z ) ) ;
207
+ Handles . DrawLine ( m_Position , m_Position + m_Normal * NormalBias ) ;
208
+ }
209
+
210
+ Handles . color = oldHandleColor ;
211
+ }
169
212
}
170
213
171
214
public void StopIfApplying ( )
0 commit comments