9
9
namespace Microsoft . MixedReality . Toolkit . UI . BoundsControl
10
10
{
11
11
/// <summary>
12
- /// Rotation handles for <see cref="BoundsControl"/> that are used for rotating the
12
+ /// Handles for <see cref="BoundsControl"/> that are used for manipulating the
13
13
/// Gameobject BoundsControl is attached to with near or far interaction
14
14
/// </summary>
15
15
public abstract class PerAxisHandles : HandlesBase
@@ -75,6 +75,9 @@ private void UpdateColliderType()
75
75
// remove old colliders
76
76
bool shouldCreateNewCollider = false ;
77
77
var oldBoxCollider = handle . GetComponent < BoxCollider > ( ) ;
78
+
79
+ // Caution, Destroy() will destroy one frame later.
80
+ // Do not check later for presence this frame!
78
81
if ( oldBoxCollider != null && config . HandlePrefabColliderType == HandlePrefabCollider . Sphere )
79
82
{
80
83
shouldCreateNewCollider = true ;
@@ -92,7 +95,8 @@ private void UpdateColliderType()
92
95
{
93
96
// attach new collider
94
97
var handleBounds = VisualUtils . GetMaxBounds ( GetVisual ( handle ) . gameObject ) ;
95
- var invScale = handleBounds . size . x == 0.0f ? 0.0f : config . HandleSize / handleBounds . size . x ;
98
+ float maxDim = VisualUtils . GetMaxComponent ( handleBounds . size ) ;
99
+ float invScale = maxDim == 0.0f ? 0.0f : config . HandleSize / maxDim ;
96
100
Vector3 colliderSizeScaled = handleBounds . size * invScale ;
97
101
Vector3 colliderCenterScaled = handleBounds . center * invScale ;
98
102
if ( config . HandlePrefabColliderType == HandlePrefabCollider . Box )
@@ -106,7 +110,7 @@ private void UpdateColliderType()
106
110
{
107
111
SphereCollider sphere = handle . gameObject . AddComponent < SphereCollider > ( ) ;
108
112
sphere . center = colliderCenterScaled ;
109
- sphere . radius = colliderSizeScaled . x * 0.5f ;
113
+ sphere . radius = VisualUtils . GetMaxComponent ( colliderSizeScaled ) * 0.5f ;
110
114
sphere . radius += VisualUtils . GetMaxComponent ( config . ColliderPadding ) ;
111
115
}
112
116
}
@@ -185,10 +189,12 @@ private void CreateHandles(Transform parent)
185
189
handle . transform . position = HandlePositions [ i ] ;
186
190
handle . transform . parent = parent ;
187
191
188
- Bounds midpointBounds = CreateVisual ( i , handle ) ;
189
- float maxDim = VisualUtils . GetMaxComponent ( midpointBounds . size ) ;
192
+ Bounds handleVisualBounds = CreateVisual ( i , handle ) ;
193
+ float maxDim = VisualUtils . GetMaxComponent ( handleVisualBounds . size ) ;
190
194
float invScale = maxDim == 0.0f ? 0.0f : config . HandleSize / maxDim ;
191
- VisualUtils . AddComponentsToAffordance ( handle , new Bounds ( midpointBounds . center * invScale , midpointBounds . size * invScale ) ,
195
+
196
+ // TODO: Some subclasses of PerAxisHandles shouldn't use CursorContextInfo.CursorAction.Rotate
197
+ VisualUtils . AddComponentsToAffordance ( handle , new Bounds ( handleVisualBounds . center * invScale , handleVisualBounds . size * invScale ) ,
192
198
config . HandlePrefabColliderType , CursorContextInfo . CursorAction . Rotate , config . ColliderPadding , parent , config . DrawTetherWhenManipulating ) ;
193
199
194
200
handles . Add ( handle . transform ) ;
@@ -209,11 +215,14 @@ protected override void RecreateVisuals()
209
215
{
210
216
// get old child and remove it
211
217
obsoleteChild . parent = null ;
218
+
219
+ // Caution, Destroy() will destroy one frame later.
220
+ // Do not check later for presence this frame!
212
221
Object . Destroy ( obsoleteChild . gameObject ) ;
213
222
}
214
223
else
215
224
{
216
- Debug . LogError ( "couldn 't find rotation visual on recreating visuals" ) ;
225
+ Debug . LogError ( "Couldn 't find handle visual on recreating visuals" ) ;
217
226
}
218
227
219
228
// create new visual
@@ -228,7 +237,8 @@ protected override void RecreateVisuals()
228
237
229
238
protected override void UpdateColliderBounds ( Transform handle , Vector3 visualSize )
230
239
{
231
- var invScale = visualSize . x == 0.0f ? 0.0f : config . HandleSize / visualSize . x ;
240
+ float maxDim = VisualUtils . GetMaxComponent ( visualSize ) ;
241
+ float invScale = maxDim == 0.0f ? 0.0f : config . HandleSize / maxDim ;
232
242
GetVisual ( handle ) . transform . localScale = new Vector3 ( invScale , invScale , invScale ) ;
233
243
Vector3 colliderSizeScaled = visualSize * invScale ;
234
244
if ( config . HandlePrefabColliderType == HandlePrefabCollider . Box )
@@ -240,47 +250,53 @@ protected override void UpdateColliderBounds(Transform handle, Vector3 visualSiz
240
250
else
241
251
{
242
252
SphereCollider collider = handle . gameObject . GetComponent < SphereCollider > ( ) ;
243
- collider . radius = colliderSizeScaled . x * 0.5f ;
253
+ collider . radius = VisualUtils . GetMaxComponent ( colliderSizeScaled ) * 0.5f ;
244
254
collider . radius += VisualUtils . GetMaxComponent ( config . ColliderPadding ) ;
245
255
}
246
256
}
247
257
248
258
private Bounds CreateVisual ( int handleIndex , GameObject parent )
249
259
{
250
- GameObject midpointVisual ;
260
+ GameObject handleVisual ;
251
261
GameObject prefabType = config . HandlePrefab ;
252
262
if ( prefabType != null )
253
263
{
254
- midpointVisual = Object . Instantiate ( prefabType ) ;
264
+ handleVisual = Object . Instantiate ( prefabType ) ;
255
265
}
256
266
else
257
267
{
258
- midpointVisual = GameObject . CreatePrimitive ( PrimitiveType . Sphere ) ;
259
- // deactivate collider on visuals and register for deletion - actual collider
260
- // of handle is attached to the handle gameobject, not the visual
261
- var collider = midpointVisual . GetComponent < SphereCollider > ( ) ;
268
+ handleVisual = GameObject . CreatePrimitive ( PrimitiveType . Sphere ) ;
269
+ // We only want the Primitive sphere mesh, but CreatePrimitive will
270
+ // give us a sphere collider too. Remove the sphere collider here
271
+ // so we can manually add our own properly configured collider later.
272
+ var collider = handleVisual . GetComponent < SphereCollider > ( ) ;
262
273
collider . enabled = false ;
263
- Object . Destroy ( collider ) ;
264
- }
265
274
266
- Quaternion realignment = GetRotationRealignment ( handleIndex ) ;
267
- midpointVisual . transform . localRotation = realignment * midpointVisual . transform . localRotation ;
275
+ // Caution, Destroy() will destroy one frame later.
276
+ // Do not check later for presence this frame!
277
+ Object . Destroy ( collider ) ;
278
+ }
268
279
269
- Bounds midpointBounds = VisualUtils . GetMaxBounds ( midpointVisual ) ;
270
- float maxDim = VisualUtils . GetMaxComponent ( midpointBounds . size ) ;
280
+ // handleVisualBounds are returned in handleVisual-local space.
281
+ Bounds handleVisualBounds = VisualUtils . GetMaxBounds ( handleVisual ) ;
282
+ float maxDim = VisualUtils . GetMaxComponent ( handleVisualBounds . size ) ;
271
283
float invScale = maxDim == 0.0f ? 0.0f : config . HandleSize / maxDim ;
272
284
273
- midpointVisual . name = visualsName ;
274
- midpointVisual . transform . parent = parent . transform ;
275
- midpointVisual . transform . localScale = new Vector3 ( invScale , invScale , invScale ) ;
276
- midpointVisual . transform . localPosition = Vector3 . zero ;
285
+ handleVisual . name = visualsName ;
286
+ handleVisual . transform . parent = parent . transform ;
287
+ handleVisual . transform . localScale = new Vector3 ( invScale , invScale , invScale ) ;
288
+ handleVisual . transform . localPosition = Vector3 . zero ;
289
+ handleVisual . transform . localRotation = Quaternion . identity ;
290
+
291
+ Quaternion realignment = GetRotationRealignment ( handleIndex ) ;
292
+ parent . transform . localRotation = realignment ;
277
293
278
294
if ( config . HandleMaterial != null )
279
295
{
280
- VisualUtils . ApplyMaterialToAllRenderers ( midpointVisual , config . HandleMaterial ) ;
296
+ VisualUtils . ApplyMaterialToAllRenderers ( handleVisual , config . HandleMaterial ) ;
281
297
}
282
298
283
- return midpointBounds ;
299
+ return handleVisualBounds ;
284
300
}
285
301
286
302
#region BoundsControlHandlerBase
0 commit comments