Skip to content

Commit b20aa92

Browse files
Move MaintainOriginalRotation to a TransformConstraint
Also updated and implemented new tests.
1 parent dde0dc2 commit b20aa92

File tree

6 files changed

+106
-23
lines changed

6 files changed

+106
-23
lines changed

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

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ public class ObjectManipulator : MonoBehaviour, IMixedRealityPointerHandler, IMi
2525
#region Public Enums
2626
public enum RotateInOneHandType
2727
{
28-
MaintainOriginalRotation,
2928
RotateAboutObjectCenter,
3029
RotateAboutGrabPoint
3130
};
@@ -589,23 +588,16 @@ private void HandleOneHandMoveUpdated()
589588

590589
constraints.ApplyScaleConstraints(ref targetTransform, true, IsNearManipulation());
591590

592-
RotateInOneHandType rotateInOneHandType = isNearManipulation ? oneHandRotationModeNear : oneHandRotationModeFar;
593-
switch (rotateInOneHandType)
594-
{
595-
case RotateInOneHandType.MaintainOriginalRotation:
596-
targetTransform.Rotation = HostTransform.rotation;
597-
break;
598-
case RotateInOneHandType.RotateAboutObjectCenter:
599-
case RotateInOneHandType.RotateAboutGrabPoint:
600-
Quaternion gripRotation;
601-
TryGetGripRotation(pointer, out gripRotation);
602-
targetTransform.Rotation = gripRotation * objectToGripRotation;
603-
break;
604-
}
591+
Quaternion gripRotation;
592+
TryGetGripRotation(pointer, out gripRotation);
593+
targetTransform.Rotation = gripRotation * objectToGripRotation;
594+
605595
constraints.ApplyRotationConstraints(ref targetTransform, true, IsNearManipulation());
606596

597+
RotateInOneHandType rotateInOneHandType = isNearManipulation ? oneHandRotationModeNear : oneHandRotationModeFar;
607598
MixedRealityPose pointerPose = new MixedRealityPose(pointer.Position, pointer.Rotation);
608599
targetTransform.Position = moveLogic.Update(pointerPose, targetTransform.Rotation, targetTransform.Scale, rotateInOneHandType != RotateInOneHandType.RotateAboutObjectCenter);
600+
609601
constraints.ApplyTranslationConstraints(ref targetTransform, true, IsNearManipulation());
610602

611603
ApplyTargetTransform(targetTransform);
@@ -779,7 +771,6 @@ private PointerData GetFirstPointer()
779771

780772
private bool TryGetGripRotation(IMixedRealityPointer pointer, out Quaternion rotation)
781773
{
782-
783774
for (int i = 0; i < pointer.Controller.Interactions.Length; i++)
784775
{
785776
if (pointer.Controller.Interactions[i].InputType == DeviceInputType.SpatialGrip)

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,15 @@ private void MigrateOneHandRotationModes(ref ObjectManipulator objManip, Manipul
164164
break;
165165
}
166166
case ManipulationHandler.RotateInOneHandType.MaintainOriginalRotation:
167-
newMode = ObjectManipulator.RotateInOneHandType.MaintainOriginalRotation;
168-
break;
167+
{
168+
newMode = ObjectManipulator.RotateInOneHandType.RotateAboutGrabPoint;
169+
170+
var rotConstraint = objManip.EnsureComponent<FixedRotationToWorldConstraint>();
171+
rotConstraint.TargetTransform = objManip.HostTransform;
172+
rotConstraint.HandType = ManipulationHandFlags.OneHanded;
173+
rotConstraint.ProximityType = proximity;
174+
break;
175+
}
169176
case ManipulationHandler.RotateInOneHandType.RotateAboutObjectCenter:
170177
newMode = ObjectManipulator.RotateInOneHandType.RotateAboutObjectCenter;
171178
break;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License. See LICENSE in the project root for license information.
3+
4+
using Microsoft.MixedReality.Toolkit.Utilities;
5+
using UnityEngine;
6+
7+
namespace Microsoft.MixedReality.Toolkit.UI
8+
{
9+
/// <summary>
10+
/// Component for fixing the rotation of a manipulated object relative to the world
11+
/// </summary>
12+
public class FixedRotationToWorldConstraint : TransformConstraint
13+
{
14+
#region Properties
15+
16+
public override TransformFlags ConstraintType => TransformFlags.Rotate;
17+
18+
#endregion Properties
19+
20+
#region Public Methods
21+
22+
/// <summary>
23+
/// Fix rotation to the rotation from manipulation start
24+
/// </summary>
25+
public override void ApplyConstraint(ref MixedRealityTransform transform)
26+
{
27+
transform.Rotation = this.worldPoseOnManipulationStart.Rotation;
28+
}
29+
30+
#endregion Public Methods
31+
}
32+
}

Assets/MixedRealityToolkit.SDK/Features/Input/Handlers/Constraints/FixedRotationToWorldConstraint.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/MixedRealityToolkit.Tests/PlayModeTests/ConstraintTests.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,54 @@ public IEnumerator ConstrainRotationFaceUser()
813813
TestUtilities.AssertAboutEqual(checkCollinear(), Vector3.zero, "Object not facing camera", 0.002f);
814814
Assert.Less(checkNegative(), 0, "Object facing away");
815815
}
816+
817+
/// <summary>
818+
/// Tests that FixedRotationToWorldConstraint maintains the original rotation of the manipulated object
819+
/// </summary>
820+
[UnityTest]
821+
public IEnumerator ConstrainRotationFixToWorld()
822+
{
823+
TestUtilities.PlayspaceToOriginLookingForward();
824+
825+
var testObject = GameObject.CreatePrimitive(PrimitiveType.Cube);
826+
testObject.transform.localScale = Vector3.one * 0.2f;
827+
testObject.transform.position = Vector3.forward;
828+
var manipHandler = testObject.AddComponent<ObjectManipulator>();
829+
manipHandler.HostTransform = testObject.transform;
830+
manipHandler.SmoothingActive = false;
831+
manipHandler.ManipulationType = ManipulationHandFlags.OneHanded;
832+
manipHandler.OneHandRotationModeNear = ObjectManipulator.RotateInOneHandType.RotateAboutGrabPoint;
833+
834+
var rotConstraint = manipHandler.EnsureComponent<FixedRotationToWorldConstraint>();
835+
rotConstraint.TargetTransform = manipHandler.HostTransform;
836+
837+
// Face user first
838+
const int numHandSteps = 1;
839+
TestHand hand = new TestHand(Handedness.Right);
840+
841+
yield return hand.Show(new Vector3(0.05f, -0.1f, 0.45f));
842+
yield return hand.SetGesture(ArticulatedHandPose.GestureId.Pinch);
843+
yield return null;
844+
845+
// rotate the hand
846+
yield return hand.SetRotation(Quaternion.Euler(45, 45, 45), numHandSteps);
847+
yield return null;
848+
849+
Assert.AreEqual(Quaternion.identity, testObject.transform.rotation);
850+
851+
// move the hand
852+
yield return hand.Move(Vector3.right * 0.2f, numHandSteps);
853+
yield return null;
854+
855+
Assert.AreEqual(Quaternion.identity, testObject.transform.rotation);
856+
857+
// rotate the head
858+
CameraCache.Main.transform.Rotate(new Vector3(0, 10, 0));
859+
yield return new WaitForFixedUpdate();
860+
yield return null;
861+
862+
Assert.AreEqual(Quaternion.identity, testObject.transform.rotation);
863+
}
816864
}
817865
}
818866
#endif

Assets/MixedRealityToolkit.Tests/PlayModeTests/Experimental/ObjectManipulatorTests.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -356,12 +356,6 @@ public IEnumerator ObjectManipulatorOneHandMoveFar()
356356
// do this test for every one hand rotation mode
357357
foreach (ObjectManipulator.RotateInOneHandType type in Enum.GetValues(typeof(ObjectManipulator.RotateInOneHandType)))
358358
{
359-
// Some rotation modes move the object on grab, don't test those
360-
if (type == ObjectManipulator.RotateInOneHandType.MaintainOriginalRotation)
361-
{
362-
continue;
363-
}
364-
365359
manipHandler.OneHandRotationModeFar = type;
366360

367361
TestUtilities.PlayspaceToOriginLookingForward();

0 commit comments

Comments
 (0)