@@ -23,19 +23,21 @@ namespace Microsoft.MixedReality.Toolkit.Experimental.UI
2323 public class ObjectManipulator : MonoBehaviour , IMixedRealityPointerHandler , IMixedRealityFocusChangedHandler
2424 {
2525 #region Public Enums
26- [ System . Flags ]
27- public enum HandMovementType
28- {
29- OneHanded = 1 << 0 ,
30- TwoHanded = 1 << 1 ,
31- }
26+
27+ /// <summary>
28+ /// Describes what pivot the manipulated object will rotate about when
29+ /// you rotate your hand. This is not a description of any limits or
30+ /// additional rotation logic. If no other factors (such as constraints)
31+ /// are involved, rotating your hand by an amount should rotate the object
32+ /// by the same amount.
33+ /// For example a possible future value here is RotateAboutUserDefinedPoint
34+ /// where the user could specify a pivot that the object is to rotate
35+ /// around.
36+ /// An example of a value that should not be found here is MaintainRotationToUser
37+ /// as this restricts rotation of the object when we rotate the hand.
38+ /// </summary>
3239 public enum RotateInOneHandType
3340 {
34- MaintainRotationToUser ,
35- GravityAlignedMaintainRotationToUser ,
36- FaceUser ,
37- FaceAwayFromUser ,
38- MaintainOriginalRotation ,
3941 RotateAboutObjectCenter ,
4042 RotateAboutGrabPoint
4143 } ;
@@ -73,12 +75,12 @@ public Transform HostTransform
7375 [ SerializeField ]
7476 [ EnumFlags ]
7577 [ Tooltip ( "Can manipulation be done only with one hand, only with two hands, or with both?" ) ]
76- private HandMovementType manipulationType = HandMovementType . OneHanded | HandMovementType . TwoHanded ;
78+ private ManipulationHandFlags manipulationType = ManipulationHandFlags . OneHanded | ManipulationHandFlags . TwoHanded ;
7779
7880 /// <summary>
7981 /// Can manipulation be done only with one hand, only with two hands, or with both?
8082 /// </summary>
81- public HandMovementType ManipulationType
83+ public ManipulationHandFlags ManipulationType
8284 {
8385 get => manipulationType ;
8486 set => manipulationType = value ;
@@ -291,22 +293,17 @@ public PointerData(IMixedRealityPointer pointer, Vector3 worldGrabPoint) : this(
291293 }
292294
293295 private Dictionary < uint , PointerData > pointerIdToPointerMap = new Dictionary < uint , PointerData > ( ) ;
294- private Quaternion objectToHandRotation ;
295296 private Quaternion objectToGripRotation ;
296297 private bool isNearManipulation ;
297298 private bool isManipulationStarted ;
298299
299300 private Rigidbody rigidBody ;
300301 private bool wasKinematic = false ;
301302
302- private Quaternion startObjectRotationCameraSpace ;
303- private Quaternion startObjectRotationFlatCameraSpace ;
304- private Quaternion hostWorldRotationOnManipulationStart ;
305-
306303 private ConstraintManager constraints ;
307304
308- private bool IsOneHandedManipulationEnabled => manipulationType . HasFlag ( HandMovementType . OneHanded ) && pointerIdToPointerMap . Count == 1 ;
309- private bool IsTwoHandedManipulationEnabled => manipulationType . HasFlag ( HandMovementType . TwoHanded ) && pointerIdToPointerMap . Count > 1 ;
305+ private bool IsOneHandedManipulationEnabled => manipulationType . HasFlag ( ManipulationHandFlags . OneHanded ) && pointerIdToPointerMap . Count == 1 ;
306+ private bool IsTwoHandedManipulationEnabled => manipulationType . HasFlag ( ManipulationHandFlags . TwoHanded ) && pointerIdToPointerMap . Count > 1 ;
310307
311308 #endregion
312309
@@ -442,7 +439,7 @@ public void OnPointerDown(MixedRealityPointerEventData eventData)
442439 }
443440
444441 // If we only allow one handed manipulations, check there is no hand interacting yet.
445- if ( manipulationType != HandMovementType . OneHanded || pointerIdToPointerMap . Count == 0 )
442+ if ( manipulationType != ManipulationHandFlags . OneHanded || pointerIdToPointerMap . Count == 0 )
446443 {
447444 uint id = eventData . Pointer . PointerId ;
448445 // Ignore poke pointer events
@@ -509,9 +506,9 @@ public void OnPointerUp(MixedRealityPointerEventData eventData)
509506
510507 // Call manipulation ended handlers
511508 var handsPressedCount = pointerIdToPointerMap . Count ;
512- if ( manipulationType . HasFlag ( HandMovementType . TwoHanded ) && handsPressedCount == 1 )
509+ if ( manipulationType . HasFlag ( ManipulationHandFlags . TwoHanded ) && handsPressedCount == 1 )
513510 {
514- if ( manipulationType . HasFlag ( HandMovementType . OneHanded ) )
511+ if ( manipulationType . HasFlag ( ManipulationHandFlags . OneHanded ) )
515512 {
516513 HandleOneHandMoveStarted ( ) ;
517514 }
@@ -560,18 +557,18 @@ private void HandleTwoHandManipulationUpdated()
560557 if ( twoHandedManipulationType . HasFlag ( TransformFlags . Scale ) )
561558 {
562559 targetTransform . Scale = scaleLogic . UpdateMap ( handPositionArray ) ;
563- constraints . ApplyScaleConstraints ( ref targetTransform ) ;
560+ constraints . ApplyScaleConstraints ( ref targetTransform , false , IsNearManipulation ( ) ) ;
564561 }
565562 if ( twoHandedManipulationType . HasFlag ( TransformFlags . Rotate ) )
566563 {
567564 targetTransform . Rotation = rotateLogic . Update ( handPositionArray , targetTransform . Rotation ) ;
568- constraints . ApplyRotationConstraints ( ref targetTransform ) ;
565+ constraints . ApplyRotationConstraints ( ref targetTransform , false , IsNearManipulation ( ) ) ;
569566 }
570567 if ( twoHandedManipulationType . HasFlag ( TransformFlags . Move ) )
571568 {
572569 MixedRealityPose pose = GetPointersPose ( ) ;
573570 targetTransform . Position = moveLogic . Update ( pose , targetTransform . Rotation , targetTransform . Scale , true ) ;
574- constraints . ApplyTranslationConstraints ( ref targetTransform ) ;
571+ constraints . ApplyTranslationConstraints ( ref targetTransform , false , IsNearManipulation ( ) ) ;
575572 }
576573
577574 ApplyTargetTransform ( targetTransform ) ;
@@ -583,15 +580,6 @@ private void HandleOneHandMoveStarted()
583580 PointerData pointerData = GetFirstPointer ( ) ;
584581 IMixedRealityPointer pointer = pointerData . pointer ;
585582
586- // cache objects rotation on start to have a reference for constraint calculations
587- // if we don't cache this on manipulation start the near rotation might drift off the hand
588- // over time
589- hostWorldRotationOnManipulationStart = HostTransform . rotation ;
590-
591- // Calculate relative transform from object to hand.
592- Quaternion worldToPalmRotation = Quaternion . Inverse ( pointer . Rotation ) ;
593- objectToHandRotation = worldToPalmRotation * HostTransform . rotation ;
594-
595583 // Calculate relative transform from object to grip.
596584 Quaternion gripRotation ;
597585 TryGetGripRotation ( pointer , out gripRotation ) ;
@@ -600,15 +588,7 @@ private void HandleOneHandMoveStarted()
600588
601589 MixedRealityPose pointerPose = new MixedRealityPose ( pointer . Position , pointer . Rotation ) ;
602590 MixedRealityPose hostPose = new MixedRealityPose ( HostTransform . position , HostTransform . rotation ) ;
603- moveLogic . Setup ( pointerPose , pointerData . GrabPoint , hostPose , HostTransform . localScale ) ;
604-
605- startObjectRotationCameraSpace = Quaternion . Inverse ( CameraCache . Main . transform . rotation ) * HostTransform . rotation ;
606- var cameraFlat = CameraCache . Main . transform . forward ;
607- cameraFlat . y = 0 ;
608- var hostForwardFlat = HostTransform . forward ;
609- hostForwardFlat . y = 0 ;
610- var hostRotFlat = Quaternion . LookRotation ( hostForwardFlat , Vector3 . up ) ;
611- startObjectRotationFlatCameraSpace = Quaternion . Inverse ( Quaternion . LookRotation ( cameraFlat , Vector3 . up ) ) * hostRotFlat ;
591+ moveLogic . Setup ( pointerPose , pointerData . GrabPoint , hostPose , HostTransform . localScale ) ;
612592 }
613593
614594 private void HandleOneHandMoveUpdated ( )
@@ -619,49 +599,19 @@ private void HandleOneHandMoveUpdated()
619599
620600 var targetTransform = new MixedRealityTransform ( HostTransform . position , HostTransform . rotation , HostTransform . localScale ) ;
621601
622- constraints . ApplyScaleConstraints ( ref targetTransform ) ;
602+ constraints . ApplyScaleConstraints ( ref targetTransform , true , IsNearManipulation ( ) ) ;
623603
624- RotateInOneHandType rotateInOneHandType = isNearManipulation ? oneHandRotationModeNear : oneHandRotationModeFar ;
625- switch ( rotateInOneHandType )
626- {
627- case RotateInOneHandType . MaintainOriginalRotation :
628- targetTransform . Rotation = HostTransform . rotation ;
629- break ;
630- case RotateInOneHandType . MaintainRotationToUser :
631- Vector3 euler = CameraCache . Main . transform . rotation . eulerAngles ;
632- // don't use roll (feels awkward) - just maintain yaw / pitch angle
633- targetTransform . Rotation = Quaternion . Euler ( euler . x , euler . y , 0 ) * startObjectRotationCameraSpace ;
634- break ;
635- case RotateInOneHandType . GravityAlignedMaintainRotationToUser :
636- var cameraForwardFlat = CameraCache . Main . transform . forward ;
637- cameraForwardFlat . y = 0 ;
638- targetTransform . Rotation = Quaternion . LookRotation ( cameraForwardFlat , Vector3 . up ) * startObjectRotationFlatCameraSpace ;
639- break ;
640- case RotateInOneHandType . FaceUser :
641- {
642- Vector3 directionToTarget = pointerData . GrabPoint - CameraCache . Main . transform . position ;
643- // Vector3 directionToTarget = HostTransform.position - CameraCache.Main.transform.position;
644- targetTransform . Rotation = Quaternion . LookRotation ( - directionToTarget ) ;
645- break ;
646- }
647- case RotateInOneHandType . FaceAwayFromUser :
648- {
649- Vector3 directionToTarget = pointerData . GrabPoint - CameraCache . Main . transform . position ;
650- targetTransform . Rotation = Quaternion . LookRotation ( directionToTarget ) ;
651- break ;
652- }
653- case RotateInOneHandType . RotateAboutObjectCenter :
654- case RotateInOneHandType . RotateAboutGrabPoint :
655- Quaternion gripRotation ;
656- TryGetGripRotation ( pointer , out gripRotation ) ;
657- targetTransform . Rotation = gripRotation * objectToGripRotation ;
658- break ;
659- }
660- constraints . ApplyRotationConstraints ( ref targetTransform ) ;
604+ Quaternion gripRotation ;
605+ TryGetGripRotation ( pointer , out gripRotation ) ;
606+ targetTransform . Rotation = gripRotation * objectToGripRotation ;
607+
608+ constraints . ApplyRotationConstraints ( ref targetTransform , true , IsNearManipulation ( ) ) ;
661609
610+ RotateInOneHandType rotateInOneHandType = isNearManipulation ? oneHandRotationModeNear : oneHandRotationModeFar ;
662611 MixedRealityPose pointerPose = new MixedRealityPose ( pointer . Position , pointer . Rotation ) ;
663612 targetTransform . Position = moveLogic . Update ( pointerPose , targetTransform . Rotation , targetTransform . Scale , rotateInOneHandType != RotateInOneHandType . RotateAboutObjectCenter ) ;
664- constraints . ApplyTranslationConstraints ( ref targetTransform ) ;
613+
614+ constraints . ApplyTranslationConstraints ( ref targetTransform , true , IsNearManipulation ( ) ) ;
665615
666616 ApplyTargetTransform ( targetTransform ) ;
667617 }
@@ -834,7 +784,6 @@ private PointerData GetFirstPointer()
834784
835785 private bool TryGetGripRotation ( IMixedRealityPointer pointer , out Quaternion rotation )
836786 {
837-
838787 for ( int i = 0 ; i < pointer . Controller . Interactions . Length ; i ++ )
839788 {
840789 if ( pointer . Controller . Interactions [ i ] . InputType == DeviceInputType . SpatialGrip )
0 commit comments