@@ -110,7 +110,7 @@ public class UxrGrabbableObject : UxrComponent<UxrGrabbableObject>, IUxrGrabbabl
110
110
// Grab points
111
111
112
112
[ SerializeField ] private bool _firstGrabPointIsMain = true ;
113
- [ SerializeField ] private UxrGrabPointInfo _grabPoint ;
113
+ [ SerializeField ] private UxrGrabPointInfo _grabPoint = new UxrGrabPointInfo ( ) ;
114
114
[ SerializeField ] private List < UxrGrabPointInfo > _additionalGrabPoints ;
115
115
116
116
// Placement
@@ -1110,6 +1110,94 @@ public void CheckAndApplyLockHand(UxrGrabber grabber, int grabPoint)
1110
1110
}
1111
1111
}
1112
1112
1113
+ /// <summary>
1114
+ /// Tries to get the longitudinal rotation axis of the grabbable object. If it hasn't been defined by the user (on
1115
+ /// objects where <see cref="RangeOfMotionRotationAxisCount" /> is less than 2.
1116
+ /// </summary>
1117
+ /// <returns>Longitudinal rotation axis</returns>
1118
+ public UxrAxis GetMostProbableLongitudinalRotationAxis ( )
1119
+ {
1120
+ if ( RangeOfMotionRotationAxisCount > 1 )
1121
+ {
1122
+ // Longitudinal axis is user defined for constrained rotation with more than one axis
1123
+ return _rotationLongitudinalAxis ;
1124
+ }
1125
+
1126
+ // We have an object with a single rotation axis. First compute bounds and see if the rotation pivot is not centered.
1127
+
1128
+ Bounds localBounds = gameObject . GetLocalBounds ( true ) ;
1129
+ int maxUncenteredComponent = - 1 ;
1130
+ float maxUncenteredDistance = 0.0f ;
1131
+
1132
+ for ( int i = 0 ; i < 3 ; ++ i )
1133
+ {
1134
+ float centerOffset = Mathf . Abs ( localBounds . center [ i ] ) ;
1135
+
1136
+ if ( centerOffset > localBounds . size [ i ] * 0.25f && centerOffset > maxUncenteredDistance )
1137
+ {
1138
+ maxUncenteredComponent = i ;
1139
+ maxUncenteredDistance = centerOffset ;
1140
+ }
1141
+ }
1142
+
1143
+ // Found an axis that is significantly larger than others?
1144
+
1145
+ if ( maxUncenteredComponent != - 1 )
1146
+ {
1147
+ return maxUncenteredComponent ;
1148
+ }
1149
+
1150
+ // At this point the best bet is the single rotation axis
1151
+
1152
+ int singleRotationAxisIndex = SingleRotationAxisIndex ;
1153
+
1154
+ if ( singleRotationAxisIndex != - 1 )
1155
+ {
1156
+ return singleRotationAxisIndex ;
1157
+ }
1158
+
1159
+ return UxrAxis . Z ;
1160
+ }
1161
+
1162
+ /// <summary>
1163
+ /// Tries to infer the most appropriate <see cref="UxrRotationProvider" /> to rotate the object based on the shape and
1164
+ /// size of the object, and the grip.
1165
+ /// </summary>
1166
+ /// <param name="gripPos">The grip snap position</param>
1167
+ /// <returns>Most appropriate <see cref="UxrRotationProvider" /></returns>
1168
+ public UxrRotationProvider GetAutoRotationProvider ( Vector3 gripPos )
1169
+ {
1170
+ if ( ! ( HasTranslationConstraint && LimitedRangeOfMotionRotationAxes . Any ( ) ) )
1171
+ {
1172
+ // No constraint
1173
+ return UxrRotationProvider . HandOrientation ;
1174
+ }
1175
+
1176
+ UxrAxis longitudinalAxis = GetMostProbableLongitudinalRotationAxis ( ) ;
1177
+ int singleRotationAxisIndex = SingleRotationAxisIndex ;
1178
+ float leverageDistance = 0.0f ;
1179
+
1180
+ if ( singleRotationAxisIndex != - 1 )
1181
+ {
1182
+ // Object with a single rotation axis
1183
+
1184
+ if ( longitudinalAxis != singleRotationAxisIndex )
1185
+ {
1186
+ // Lever action
1187
+ return UxrRotationProvider . HandPositionAroundPivot ;
1188
+ }
1189
+
1190
+ // Lever action will depend on grabber distance to rotation axis. Smaller than a hand distance will use rotation while larger will use leverage.
1191
+ leverageDistance = Vector3 . ProjectOnPlane ( gripPos - transform . position , transform . TransformDirection ( longitudinalAxis ) ) . magnitude ;
1192
+ return leverageDistance > UxrConstants . Hand . HandWidth ? UxrRotationProvider . HandPositionAroundPivot : UxrRotationProvider . HandOrientation ;
1193
+ }
1194
+
1195
+ // Object with more than one rotation axis
1196
+
1197
+ leverageDistance = Mathf . Abs ( gripPos . DistanceToPlane ( transform . position , transform . TransformDirection ( longitudinalAxis ) ) ) ;
1198
+ return leverageDistance > UxrConstants . Hand . HandWidth ? UxrRotationProvider . HandPositionAroundPivot : UxrRotationProvider . HandOrientation ;
1199
+ }
1200
+
1113
1201
#endregion
1114
1202
1115
1203
#region Internal Methods
@@ -1621,7 +1709,7 @@ internal void NotifyBeginGrab(UxrGrabber grabber, int grabPoint)
1621
1709
1622
1710
if ( _autoRotationProvider )
1623
1711
{
1624
- _rotationProvider = Editor_GetAutoRotationProvider ( snapPosition ) ;
1712
+ _rotationProvider = GetAutoRotationProvider ( snapPosition ) ;
1625
1713
}
1626
1714
1627
1715
if ( RotationProvider == UxrRotationProvider . HandPositionAroundPivot && GetGrabPointSnapModeAffectsRotation ( grabPoint ) )
@@ -1782,7 +1870,7 @@ protected override void OnDisable()
1782
1870
private void Reset ( )
1783
1871
{
1784
1872
_grabPoint = new UxrGrabPointInfo ( ) ;
1785
- _rotationLongitudinalAxis = Editor_GetMostProbableLongitudinalRotationAxis ( ) ;
1873
+ _rotationLongitudinalAxis = GetMostProbableLongitudinalRotationAxis ( ) ;
1786
1874
}
1787
1875
1788
1876
/// <summary>
@@ -2584,94 +2672,6 @@ public bool Editor_HasGrabPointWithGrabAlignTransform(Transform snapTransform, G
2584
2672
return false ;
2585
2673
}
2586
2674
2587
- /// <summary>
2588
- /// Tries to get the longitudinal rotation axis of the grabbable object. If it hasn't been defined by the user (on
2589
- /// objects where <see cref="RangeOfMotionRotationAxisCount" /> is less than 2.
2590
- /// </summary>
2591
- /// <returns>Longitudinal rotation axis</returns>
2592
- public UxrAxis Editor_GetMostProbableLongitudinalRotationAxis ( )
2593
- {
2594
- if ( RangeOfMotionRotationAxisCount > 1 )
2595
- {
2596
- // Longitudinal axis is user defined for constrained rotation with more than one axis
2597
- return _rotationLongitudinalAxis ;
2598
- }
2599
-
2600
- // We have an object with a single rotation axis. First compute bounds and see if the rotation pivot is not centered.
2601
-
2602
- Bounds localBounds = gameObject . GetLocalBounds ( true ) ;
2603
- int maxUncenteredComponent = - 1 ;
2604
- float maxUncenteredDistance = 0.0f ;
2605
-
2606
- for ( int i = 0 ; i < 3 ; ++ i )
2607
- {
2608
- float centerOffset = Mathf . Abs ( localBounds . center [ i ] ) ;
2609
-
2610
- if ( centerOffset > localBounds . size [ i ] * 0.25f && centerOffset > maxUncenteredDistance )
2611
- {
2612
- maxUncenteredComponent = i ;
2613
- maxUncenteredDistance = centerOffset ;
2614
- }
2615
- }
2616
-
2617
- // Found an axis that is significantly larger than others?
2618
-
2619
- if ( maxUncenteredComponent != - 1 )
2620
- {
2621
- return maxUncenteredComponent ;
2622
- }
2623
-
2624
- // At this point the best bet is the single rotation axis
2625
-
2626
- int singleRotationAxisIndex = SingleRotationAxisIndex ;
2627
-
2628
- if ( singleRotationAxisIndex != - 1 )
2629
- {
2630
- return singleRotationAxisIndex ;
2631
- }
2632
-
2633
- return UxrAxis . Z ;
2634
- }
2635
-
2636
- /// <summary>
2637
- /// Tries to infer the most appropriate <see cref="UxrRotationProvider" /> to rotate the object based on the shape and
2638
- /// size of the object, and the grip.
2639
- /// </summary>
2640
- /// <param name="gripPos">The grip snap position</param>
2641
- /// <returns>Most appropriate <see cref="UxrRotationProvider" /></returns>
2642
- public UxrRotationProvider Editor_GetAutoRotationProvider ( Vector3 gripPos )
2643
- {
2644
- if ( ! ( HasTranslationConstraint && LimitedRangeOfMotionRotationAxes . Any ( ) ) )
2645
- {
2646
- // No constraint
2647
- return UxrRotationProvider . HandOrientation ;
2648
- }
2649
-
2650
- UxrAxis longitudinalAxis = Editor_GetMostProbableLongitudinalRotationAxis ( ) ;
2651
- int singleRotationAxisIndex = SingleRotationAxisIndex ;
2652
- float leverageDistance = 0.0f ;
2653
-
2654
- if ( singleRotationAxisIndex != - 1 )
2655
- {
2656
- // Object with a single rotation axis
2657
-
2658
- if ( longitudinalAxis != singleRotationAxisIndex )
2659
- {
2660
- // Lever action
2661
- return UxrRotationProvider . HandPositionAroundPivot ;
2662
- }
2663
-
2664
- // Lever action will depend on grabber distance to rotation axis. Smaller than a hand distance will use rotation while larger will use leverage.
2665
- leverageDistance = Vector3 . ProjectOnPlane ( gripPos - transform . position , transform . TransformDirection ( longitudinalAxis ) ) . magnitude ;
2666
- return leverageDistance > UxrConstants . Hand . HandWidth ? UxrRotationProvider . HandPositionAroundPivot : UxrRotationProvider . HandOrientation ;
2667
- }
2668
-
2669
- // Object with more than one rotation axis
2670
-
2671
- leverageDistance = Mathf . Abs ( gripPos . DistanceToPlane ( transform . position , transform . TransformDirection ( longitudinalAxis ) ) ) ;
2672
- return leverageDistance > UxrConstants . Hand . HandWidth ? UxrRotationProvider . HandPositionAroundPivot : UxrRotationProvider . HandOrientation ;
2673
- }
2674
-
2675
2675
#endif
2676
2676
}
2677
2677
}
0 commit comments