Skip to content

Commit 05a71e1

Browse files
Remove MaintainRotationToUser
Also removed GravityAlignedMaintainRotationToUser as this can be achieved with an additional RotationAxisConstraint. Also added options to configure what manipulation type a constraint should work for.
1 parent 8ff6698 commit 05a71e1

File tree

13 files changed

+504
-167
lines changed

13 files changed

+504
-167
lines changed

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

Lines changed: 15 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,8 @@ 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-
}
3226
public enum RotateInOneHandType
3327
{
34-
MaintainRotationToUser,
35-
GravityAlignedMaintainRotationToUser,
3628
FaceUser,
3729
FaceAwayFromUser,
3830
MaintainOriginalRotation,
@@ -73,12 +65,12 @@ public Transform HostTransform
7365
[SerializeField]
7466
[EnumFlags]
7567
[Tooltip("Can manipulation be done only with one hand, only with two hands, or with both?")]
76-
private HandMovementType manipulationType = HandMovementType.OneHanded | HandMovementType.TwoHanded;
68+
private ManipulationHandFlags manipulationType = ManipulationHandFlags.OneHanded | ManipulationHandFlags.TwoHanded;
7769

7870
/// <summary>
7971
/// Can manipulation be done only with one hand, only with two hands, or with both?
8072
/// </summary>
81-
public HandMovementType ManipulationType
73+
public ManipulationHandFlags ManipulationType
8274
{
8375
get => manipulationType;
8476
set => manipulationType = value;
@@ -298,15 +290,13 @@ public PointerData(IMixedRealityPointer pointer, Vector3 worldGrabPoint) : this(
298290

299291
private Rigidbody rigidBody;
300292
private bool wasKinematic = false;
301-
302-
private Quaternion startObjectRotationCameraSpace;
303-
private Quaternion startObjectRotationFlatCameraSpace;
293+
304294
private Quaternion hostWorldRotationOnManipulationStart;
305295

306296
private ConstraintManager constraints;
307297

308-
private bool IsOneHandedManipulationEnabled => manipulationType.HasFlag(HandMovementType.OneHanded) && pointerIdToPointerMap.Count == 1;
309-
private bool IsTwoHandedManipulationEnabled => manipulationType.HasFlag(HandMovementType.TwoHanded) && pointerIdToPointerMap.Count > 1;
298+
private bool IsOneHandedManipulationEnabled => manipulationType.HasFlag(ManipulationHandFlags.OneHanded) && pointerIdToPointerMap.Count == 1;
299+
private bool IsTwoHandedManipulationEnabled => manipulationType.HasFlag(ManipulationHandFlags.TwoHanded) && pointerIdToPointerMap.Count > 1;
310300

311301
#endregion
312302

@@ -442,7 +432,7 @@ public void OnPointerDown(MixedRealityPointerEventData eventData)
442432
}
443433

444434
// If we only allow one handed manipulations, check there is no hand interacting yet.
445-
if (manipulationType != HandMovementType.OneHanded || pointerIdToPointerMap.Count == 0)
435+
if (manipulationType != ManipulationHandFlags.OneHanded || pointerIdToPointerMap.Count == 0)
446436
{
447437
uint id = eventData.Pointer.PointerId;
448438
// Ignore poke pointer events
@@ -509,9 +499,9 @@ public void OnPointerUp(MixedRealityPointerEventData eventData)
509499

510500
// Call manipulation ended handlers
511501
var handsPressedCount = pointerIdToPointerMap.Count;
512-
if (manipulationType.HasFlag(HandMovementType.TwoHanded) && handsPressedCount == 1)
502+
if (manipulationType.HasFlag(ManipulationHandFlags.TwoHanded) && handsPressedCount == 1)
513503
{
514-
if (manipulationType.HasFlag(HandMovementType.OneHanded))
504+
if (manipulationType.HasFlag(ManipulationHandFlags.OneHanded))
515505
{
516506
HandleOneHandMoveStarted();
517507
}
@@ -560,18 +550,18 @@ private void HandleTwoHandManipulationUpdated()
560550
if (twoHandedManipulationType.HasFlag(TransformFlags.Scale))
561551
{
562552
targetTransform.Scale = scaleLogic.UpdateMap(handPositionArray);
563-
constraints.ApplyScaleConstraints(ref targetTransform);
553+
constraints.ApplyScaleConstraints(ref targetTransform, false, IsNearManipulation());
564554
}
565555
if (twoHandedManipulationType.HasFlag(TransformFlags.Rotate))
566556
{
567557
targetTransform.Rotation = rotateLogic.Update(handPositionArray, targetTransform.Rotation);
568-
constraints.ApplyRotationConstraints(ref targetTransform);
558+
constraints.ApplyRotationConstraints(ref targetTransform, false, IsNearManipulation());
569559
}
570560
if (twoHandedManipulationType.HasFlag(TransformFlags.Move))
571561
{
572562
MixedRealityPose pose = GetPointersPose();
573563
targetTransform.Position = moveLogic.Update(pose, targetTransform.Rotation, targetTransform.Scale, true);
574-
constraints.ApplyTranslationConstraints(ref targetTransform);
564+
constraints.ApplyTranslationConstraints(ref targetTransform, false, IsNearManipulation());
575565
}
576566

577567
ApplyTargetTransform(targetTransform);
@@ -600,15 +590,7 @@ private void HandleOneHandMoveStarted()
600590

601591
MixedRealityPose pointerPose = new MixedRealityPose(pointer.Position, pointer.Rotation);
602592
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;
593+
moveLogic.Setup(pointerPose, pointerData.GrabPoint, hostPose, HostTransform.localScale);
612594
}
613595

614596
private void HandleOneHandMoveUpdated()
@@ -619,24 +601,14 @@ private void HandleOneHandMoveUpdated()
619601

620602
var targetTransform = new MixedRealityTransform(HostTransform.position, HostTransform.rotation, HostTransform.localScale);
621603

622-
constraints.ApplyScaleConstraints(ref targetTransform);
604+
constraints.ApplyScaleConstraints(ref targetTransform, true, IsNearManipulation());
623605

624606
RotateInOneHandType rotateInOneHandType = isNearManipulation ? oneHandRotationModeNear : oneHandRotationModeFar;
625607
switch (rotateInOneHandType)
626608
{
627609
case RotateInOneHandType.MaintainOriginalRotation:
628610
targetTransform.Rotation = HostTransform.rotation;
629611
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;
640612
case RotateInOneHandType.FaceUser:
641613
{
642614
Vector3 directionToTarget = pointerData.GrabPoint - CameraCache.Main.transform.position;
@@ -657,11 +629,11 @@ private void HandleOneHandMoveUpdated()
657629
targetTransform.Rotation = gripRotation * objectToGripRotation;
658630
break;
659631
}
660-
constraints.ApplyRotationConstraints(ref targetTransform);
632+
constraints.ApplyRotationConstraints(ref targetTransform, true, IsNearManipulation());
661633

662634
MixedRealityPose pointerPose = new MixedRealityPose(pointer.Position, pointer.Rotation);
663635
targetTransform.Position = moveLogic.Update(pointerPose, targetTransform.Rotation, targetTransform.Scale, rotateInOneHandType != RotateInOneHandType.RotateAboutObjectCenter);
664-
constraints.ApplyTranslationConstraints(ref targetTransform);
636+
constraints.ApplyTranslationConstraints(ref targetTransform, true, IsNearManipulation());
665637

666638
ApplyTargetTransform(targetTransform);
667639
}

Assets/MixedRealityToolkit.SDK/Experimental/Features/Utilities/Migration/ObjectManipulatorMigrationHandler.cs

Lines changed: 102 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -23,82 +23,149 @@ public bool CanMigrate(GameObject gameObject)
2323
/// <inheritdoc />
2424
public void Migrate(GameObject gameObject)
2525
{
26-
var mh1 = gameObject.GetComponent<ManipulationHandler>();
27-
var mh2 = gameObject.AddComponent<ObjectManipulator>();
26+
var manipHandler = gameObject.GetComponent<ManipulationHandler>();
27+
var objManip = gameObject.AddComponent<ObjectManipulator>();
2828

29-
mh2.HostTransform = mh1.HostTransform;
29+
objManip.HostTransform = manipHandler.HostTransform;
3030

31-
switch (mh1.ManipulationType)
31+
switch (manipHandler.ManipulationType)
3232
{
3333
case ManipulationHandler.HandMovementType.OneHandedOnly:
34-
mh2.ManipulationType = ObjectManipulator.HandMovementType.OneHanded;
34+
objManip.ManipulationType = ManipulationHandFlags.OneHanded;
3535
break;
3636
case ManipulationHandler.HandMovementType.TwoHandedOnly:
37-
mh2.ManipulationType = ObjectManipulator.HandMovementType.TwoHanded;
37+
objManip.ManipulationType = ManipulationHandFlags.TwoHanded;
3838
break;
3939
case ManipulationHandler.HandMovementType.OneAndTwoHanded:
40-
mh2.ManipulationType = ObjectManipulator.HandMovementType.OneHanded |
41-
ObjectManipulator.HandMovementType.TwoHanded;
40+
objManip.ManipulationType = ManipulationHandFlags.OneHanded |
41+
ManipulationHandFlags.TwoHanded;
4242
break;
4343
}
4444

45-
mh2.AllowFarManipulation = mh1.AllowFarManipulation;
46-
mh2.OneHandRotationModeNear = (ObjectManipulator.RotateInOneHandType)mh1.OneHandRotationModeNear;
47-
mh2.OneHandRotationModeFar = (ObjectManipulator.RotateInOneHandType)mh1.OneHandRotationModeFar;
45+
objManip.AllowFarManipulation = manipHandler.AllowFarManipulation;
4846

49-
switch (mh1.TwoHandedManipulationType)
47+
if (manipHandler.OneHandRotationModeNear == manipHandler.OneHandRotationModeFar)
48+
{
49+
MigrateOneHandRotationModes(ref objManip, manipHandler.OneHandRotationModeNear, ManipulationProximityFlags.Near | ManipulationProximityFlags.Far);
50+
}
51+
else
52+
{
53+
MigrateOneHandRotationModes(ref objManip, manipHandler.OneHandRotationModeNear, ManipulationProximityFlags.Near);
54+
MigrateOneHandRotationModes(ref objManip, manipHandler.OneHandRotationModeFar, ManipulationProximityFlags.Far);
55+
}
56+
57+
switch (manipHandler.TwoHandedManipulationType)
5058
{
5159
case ManipulationHandler.TwoHandedManipulation.Scale:
52-
mh2.TwoHandedManipulationType = TransformFlags.Scale;
60+
objManip.TwoHandedManipulationType = TransformFlags.Scale;
5361
break;
5462
case ManipulationHandler.TwoHandedManipulation.Rotate:
55-
mh2.TwoHandedManipulationType = TransformFlags.Rotate;
63+
objManip.TwoHandedManipulationType = TransformFlags.Rotate;
5664
break;
5765
case ManipulationHandler.TwoHandedManipulation.MoveScale:
58-
mh2.TwoHandedManipulationType = TransformFlags.Move |
66+
objManip.TwoHandedManipulationType = TransformFlags.Move |
5967
TransformFlags.Scale;
6068
break;
6169
case ManipulationHandler.TwoHandedManipulation.MoveRotate:
62-
mh2.TwoHandedManipulationType = TransformFlags.Move |
70+
objManip.TwoHandedManipulationType = TransformFlags.Move |
6371
TransformFlags.Rotate;
6472
break;
6573
case ManipulationHandler.TwoHandedManipulation.RotateScale:
66-
mh2.TwoHandedManipulationType = TransformFlags.Rotate |
74+
objManip.TwoHandedManipulationType = TransformFlags.Rotate |
6775
TransformFlags.Scale;
6876
break;
6977
case ManipulationHandler.TwoHandedManipulation.MoveRotateScale:
70-
mh2.TwoHandedManipulationType = TransformFlags.Move |
78+
objManip.TwoHandedManipulationType = TransformFlags.Move |
7179
TransformFlags.Rotate |
7280
TransformFlags.Scale;
7381
break;
7482
}
7583

76-
mh2.ReleaseBehavior = (ObjectManipulator.ReleaseBehaviorType)mh1.ReleaseBehavior;
84+
objManip.ReleaseBehavior = (ObjectManipulator.ReleaseBehaviorType)manipHandler.ReleaseBehavior;
7785

78-
if (mh1.ConstraintOnRotation != RotationConstraintType.None)
86+
if (manipHandler.ConstraintOnRotation != RotationConstraintType.None)
7987
{
80-
var rotateConstraint = mh2.gameObject.AddComponent<RotationAxisConstraint>();
81-
rotateConstraint.TargetTransform = mh1.HostTransform;
82-
rotateConstraint.ConstraintOnRotation = RotationConstraintHelper.ConvertToAxisFlags(mh1.ConstraintOnRotation);
88+
var rotateConstraint = objManip.EnsureComponent<RotationAxisConstraint>();
89+
rotateConstraint.TargetTransform = manipHandler.HostTransform;
90+
rotateConstraint.ConstraintOnRotation = RotationConstraintHelper.ConvertToAxisFlags(manipHandler.ConstraintOnRotation);
8391
}
8492

85-
if (mh1.ConstraintOnMovement == MovementConstraintType.FixDistanceFromHead)
93+
if (manipHandler.ConstraintOnMovement == MovementConstraintType.FixDistanceFromHead)
8694
{
87-
var moveConstraint = mh2.gameObject.AddComponent<FixedDistanceConstraint>();
88-
moveConstraint.TargetTransform = mh1.HostTransform;
95+
var moveConstraint = objManip.EnsureComponent<FixedDistanceConstraint>();
96+
moveConstraint.TargetTransform = manipHandler.HostTransform;
8997
moveConstraint.ConstraintTransform = CameraCache.Main.transform;
9098
}
9199

92-
mh2.SmoothingActive = mh1.SmoothingActive;
93-
mh2.MoveLerpTime = mh1.SmoothingAmoutOneHandManip;
94-
mh2.RotateLerpTime = mh1.SmoothingAmoutOneHandManip;
95-
mh2.ScaleLerpTime = mh1.SmoothingAmoutOneHandManip;
96-
mh2.OnManipulationStarted = mh1.OnManipulationStarted;
97-
mh2.OnManipulationEnded = mh1.OnManipulationEnded;
98-
mh2.OnHoverEntered = mh1.OnHoverEntered;
99-
mh2.OnHoverExited = mh1.OnHoverExited;
100+
objManip.SmoothingActive = manipHandler.SmoothingActive;
101+
objManip.MoveLerpTime = manipHandler.SmoothingAmoutOneHandManip;
102+
objManip.RotateLerpTime = manipHandler.SmoothingAmoutOneHandManip;
103+
objManip.ScaleLerpTime = manipHandler.SmoothingAmoutOneHandManip;
104+
objManip.OnManipulationStarted = manipHandler.OnManipulationStarted;
105+
objManip.OnManipulationEnded = manipHandler.OnManipulationEnded;
106+
objManip.OnHoverEntered = manipHandler.OnHoverEntered;
107+
objManip.OnHoverExited = manipHandler.OnHoverExited;
108+
109+
Object.DestroyImmediate(manipHandler);
110+
}
111+
112+
private void MigrateOneHandRotationModes(ref ObjectManipulator objManip, ManipulationHandler.RotateInOneHandType mode, ManipulationProximityFlags proximity)
113+
{
114+
ObjectManipulator.RotateInOneHandType newMode = ObjectManipulator.RotateInOneHandType.RotateAboutGrabPoint;
115+
116+
switch (mode)
117+
{
118+
case ManipulationHandler.RotateInOneHandType.MaintainRotationToUser:
119+
{
120+
newMode = ObjectManipulator.RotateInOneHandType.RotateAboutGrabPoint;
121+
122+
var constraint = objManip.EnsureComponent<FixedRotationToUserConstraint>();
123+
constraint.TargetTransform = objManip.HostTransform;
124+
constraint.HandType = ManipulationHandFlags.OneHanded;
125+
constraint.ProximityType = proximity;
126+
break;
127+
}
128+
case ManipulationHandler.RotateInOneHandType.GravityAlignedMaintainRotationToUser:
129+
{
130+
newMode = ObjectManipulator.RotateInOneHandType.RotateAboutGrabPoint;
100131

101-
Object.DestroyImmediate(mh1);
132+
var rotConstraint = objManip.EnsureComponent<FixedRotationToUserConstraint>();
133+
rotConstraint.TargetTransform = objManip.HostTransform;
134+
rotConstraint.HandType = ManipulationHandFlags.OneHanded;
135+
rotConstraint.ProximityType = proximity;
136+
137+
var axisConstraint = objManip.EnsureComponent<RotationAxisConstraint>();
138+
axisConstraint.TargetTransform = objManip.HostTransform;
139+
axisConstraint.HandType = ManipulationHandFlags.OneHanded;
140+
axisConstraint.ProximityType = proximity;
141+
axisConstraint.ConstraintOnRotation = AxisFlags.XAxis | AxisFlags.ZAxis;
142+
break;
143+
}
144+
case ManipulationHandler.RotateInOneHandType.FaceUser:
145+
newMode = ObjectManipulator.RotateInOneHandType.FaceUser;
146+
break;
147+
case ManipulationHandler.RotateInOneHandType.FaceAwayFromUser:
148+
newMode = ObjectManipulator.RotateInOneHandType.FaceAwayFromUser;
149+
break;
150+
case ManipulationHandler.RotateInOneHandType.MaintainOriginalRotation:
151+
newMode = ObjectManipulator.RotateInOneHandType.MaintainOriginalRotation;
152+
break;
153+
case ManipulationHandler.RotateInOneHandType.RotateAboutObjectCenter:
154+
newMode = ObjectManipulator.RotateInOneHandType.RotateAboutObjectCenter;
155+
break;
156+
case ManipulationHandler.RotateInOneHandType.RotateAboutGrabPoint:
157+
newMode = ObjectManipulator.RotateInOneHandType.RotateAboutGrabPoint;
158+
break;
159+
}
160+
161+
if (proximity.HasFlag(ManipulationProximityFlags.Near))
162+
{
163+
objManip.OneHandRotationModeNear = newMode;
164+
}
165+
if (proximity.HasFlag(ManipulationProximityFlags.Far))
166+
{
167+
objManip.OneHandRotationModeFar = newMode;
168+
}
102169
}
103170
}
104171
}

0 commit comments

Comments
 (0)