Skip to content

Commit 26de4b6

Browse files
Merge pull request #6875 from MenelvagorMilsom/ux/move-options-to-constraints
Move RotateInOneHand options to constraint components
2 parents 8ff6698 + d15851d commit 26de4b6

File tree

19 files changed

+799
-235
lines changed

19 files changed

+799
-235
lines changed

Assets/MixedRealityToolkit.SDK/Experimental/Features/Input/Handlers/ObjectManipulator.cs

Lines changed: 33 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)