From d4b54e1e2ea024f45a5cb6bfaab4496a8dfc68c2 Mon Sep 17 00:00:00 2001 From: RogPodge Date: Wed, 3 Nov 2021 15:54:32 -0700 Subject: [PATCH 1/5] Fixed objects drifting during Near Manipulation --- .../Manipulation/ManipulationHandler.cs | 4 +- .../Manipulation/ManipulationMoveLogic.cs | 59 ++++++++++++++++++- .../Input/Handlers/ObjectManipulator.cs | 4 +- 3 files changed, 60 insertions(+), 7 deletions(-) diff --git a/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationHandler.cs b/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationHandler.cs index b0204d2b109..a109b9313ae 100644 --- a/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationHandler.cs +++ b/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationHandler.cs @@ -684,7 +684,7 @@ private void HandleTwoHandManipulationUpdated() // the initial pointer pose; if far manipulation, a more complex // look-rotation-based pointer pose is used. MixedRealityPose pose = IsNearManipulation() ? new MixedRealityPose(GetPointersCentroid()) : GetAveragePointerPose(); - targetTransform.Position = moveLogic.Update(pose, targetTransform.Rotation, targetTransform.Scale, true); + targetTransform.Position = moveLogic.UpdateTransform(pose, targetTransform, true, IsNearManipulation()); if (constraintOnMovement == MovementConstraintType.FixDistanceFromHead && moveConstraint != null) { moveConstraint.ApplyConstraint(ref targetTransform); @@ -748,7 +748,7 @@ private void HandleOneHandMoveUpdated() } MixedRealityPose pointerPose = new MixedRealityPose(pointer.Position, pointer.Rotation); - targetTransform.Position = moveLogic.Update(pointerPose, targetTransform.Rotation, targetTransform.Scale, rotateInOneHandType != RotateInOneHandType.RotateAboutObjectCenter); + targetTransform.Position = moveLogic.UpdateTransform(pointerPose, targetTransform, rotateInOneHandType != RotateInOneHandType.RotateAboutObjectCenter, IsNearManipulation()); if (constraintOnMovement == MovementConstraintType.FixDistanceFromHead && moveConstraint != null) { moveConstraint.ApplyConstraint(ref targetTransform); diff --git a/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationMoveLogic.cs b/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationMoveLogic.cs index 4554b2d618d..8bf5d682e65 100644 --- a/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationMoveLogic.cs +++ b/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationMoveLogic.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using Microsoft.MixedReality.Toolkit.Utilities; +using System; using UnityEngine; namespace Microsoft.MixedReality.Toolkit.Physics @@ -25,6 +26,9 @@ internal class ManipulationMoveLogic private Vector3 objectLocalGrabPoint; private Vector3 grabToObject; + private Vector3 objectLocalAttachPoint; + private Vector3 attachToObject; + /// /// Setup function /// @@ -37,17 +41,66 @@ public void Setup(MixedRealityPose pointerCentroidPose, Vector3 grabCentroid, Mi Quaternion worldToPointerRotation = Quaternion.Inverse(pointerCentroidPose.Rotation); pointerLocalGrabPoint = worldToPointerRotation * (grabCentroid - pointerCentroidPose.Position); - objectLocalGrabPoint = Quaternion.Inverse(objectPose.Rotation) * (grabCentroid - objectPose.Position); - objectLocalGrabPoint = objectLocalGrabPoint.Div(objectScale); + attachToObject = objectPose.Position - pointerCentroidPose.Position; + objectLocalAttachPoint = Quaternion.Inverse(objectPose.Rotation) * (pointerCentroidPose.Position - objectPose.Position); + objectLocalAttachPoint = objectLocalAttachPoint.Div(objectScale); grabToObject = objectPose.Position - grabCentroid; + objectLocalGrabPoint = Quaternion.Inverse(objectPose.Rotation) * (grabCentroid - objectPose.Position); + objectLocalGrabPoint = objectLocalGrabPoint.Div(objectScale); } /// /// Update the position based on input. /// /// A Vector3 describing the desired position + [Obsolete("This update function is out of date and does not properly support Near Manipulation. Use UpdateTransform instead")] public Vector3 Update(MixedRealityPose pointerCentroidPose, Quaternion objectRotation, Vector3 objectScale, bool usePointerRotation) + { + return FarManipulationUpdate(pointerCentroidPose, objectRotation, objectScale, usePointerRotation); + } + + /// + /// Update the position based on input. + /// + /// A Vector3 describing the desired position + public Vector3 UpdateTransform(MixedRealityPose pointerCentroidPose, MixedRealityTransform currentTarget, bool isPointerAnchor, bool isNearManipulation) + { + if (isNearManipulation) + { + return NearManipulationUpdate(pointerCentroidPose, currentTarget, isPointerAnchor); + } + else + { + return FarManipulationUpdate(pointerCentroidPose, currentTarget.Rotation, currentTarget.Scale, isPointerAnchor); + } + } + + /// + /// Updates the position during near manipulation + /// + /// A Vector3 describing the desired position during near manipulation + /// + private Vector3 NearManipulationUpdate(MixedRealityPose pointerCentroidPose, MixedRealityTransform currentTarget, bool isPointerAnchor) + { + if (isPointerAnchor) + { + Vector3 scaledLocalAttach = Vector3.Scale(objectLocalAttachPoint, currentTarget.Scale); + Vector3 worldAttachPoint = currentTarget.Rotation * scaledLocalAttach + currentTarget.Position; + return currentTarget.Position + (pointerCentroidPose.Position - worldAttachPoint); + } + else + { + return pointerCentroidPose.Position + attachToObject; + } + } + + /// + /// Updates the position during far manipulation + /// + /// A Vector3 describing the desired position during far manipulation + /// + private Vector3 FarManipulationUpdate(MixedRealityPose pointerCentroidPose, Quaternion objectRotation, Vector3 objectScale, bool isPointerAnchor) { float distanceRatio = 1.0f; @@ -58,7 +111,7 @@ public Vector3 Update(MixedRealityPose pointerCentroidPose, Quaternion objectRot distanceRatio = currentHandDistance / pointerRefDistance; } - if (usePointerRotation) + if (isPointerAnchor) { Vector3 scaledGrabToObject = Vector3.Scale(objectLocalGrabPoint, objectScale); Vector3 adjustedPointerToGrab = (pointerLocalGrabPoint * distanceRatio); diff --git a/Assets/MRTK/SDK/Features/Input/Handlers/ObjectManipulator.cs b/Assets/MRTK/SDK/Features/Input/Handlers/ObjectManipulator.cs index a6d8fd45c48..126a1c106cf 100644 --- a/Assets/MRTK/SDK/Features/Input/Handlers/ObjectManipulator.cs +++ b/Assets/MRTK/SDK/Features/Input/Handlers/ObjectManipulator.cs @@ -727,7 +727,7 @@ private void HandleTwoHandManipulationUpdated() // the pointer pose; if far manipulation, a more complex // look-rotation-based pointer pose is used. MixedRealityPose pose = IsNearManipulation() ? new MixedRealityPose(GetPointersGrabPoint()) : GetPointersPose(); - targetTransform.Position = moveLogic.Update(pose, targetTransform.Rotation, targetTransform.Scale, true); + targetTransform.Position = moveLogic.UpdateTransform(pose, targetTransform, true, IsNearManipulation()); if (EnableConstraints && constraintsManager != null) { constraintsManager.ApplyTranslationConstraints(ref targetTransform, false, IsNearManipulation()); @@ -778,7 +778,7 @@ private void HandleOneHandMoveUpdated() RotateInOneHandType rotateInOneHandType = isNearManipulation ? oneHandRotationModeNear : oneHandRotationModeFar; MixedRealityPose pointerPose = new MixedRealityPose(pointer.Position, pointer.Rotation); - targetTransform.Position = moveLogic.Update(pointerPose, targetTransform.Rotation, targetTransform.Scale, rotateInOneHandType != RotateInOneHandType.RotateAboutObjectCenter); + targetTransform.Position = moveLogic.UpdateTransform(pointerPose, targetTransform, rotateInOneHandType != RotateInOneHandType.RotateAboutObjectCenter, IsNearManipulation()); if (EnableConstraints && constraintsManager != null) { From ef69db66a02f488892ce1854b92eb5ce9154b9e8 Mon Sep 17 00:00:00 2001 From: RogPodge Date: Wed, 3 Nov 2021 16:56:47 -0700 Subject: [PATCH 2/5] Updated unit tests, made near manipulation consistent to avoid weird offset behaviors --- .../Manipulation/ManipulationMoveLogic.cs | 17 +- .../PlayModeTests/ObjectManipulatorTests.cs | 220 ++++++++++-------- 2 files changed, 127 insertions(+), 110 deletions(-) diff --git a/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationMoveLogic.cs b/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationMoveLogic.cs index 8bf5d682e65..4f8c372bf64 100644 --- a/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationMoveLogic.cs +++ b/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationMoveLogic.cs @@ -68,7 +68,7 @@ public Vector3 UpdateTransform(MixedRealityPose pointerCentroidPose, MixedRealit { if (isNearManipulation) { - return NearManipulationUpdate(pointerCentroidPose, currentTarget, isPointerAnchor); + return NearManipulationUpdate(pointerCentroidPose, currentTarget); } else { @@ -81,18 +81,11 @@ public Vector3 UpdateTransform(MixedRealityPose pointerCentroidPose, MixedRealit /// /// A Vector3 describing the desired position during near manipulation /// - private Vector3 NearManipulationUpdate(MixedRealityPose pointerCentroidPose, MixedRealityTransform currentTarget, bool isPointerAnchor) + private Vector3 NearManipulationUpdate(MixedRealityPose pointerCentroidPose, MixedRealityTransform currentTarget) { - if (isPointerAnchor) - { - Vector3 scaledLocalAttach = Vector3.Scale(objectLocalAttachPoint, currentTarget.Scale); - Vector3 worldAttachPoint = currentTarget.Rotation * scaledLocalAttach + currentTarget.Position; - return currentTarget.Position + (pointerCentroidPose.Position - worldAttachPoint); - } - else - { - return pointerCentroidPose.Position + attachToObject; - } + Vector3 scaledLocalAttach = Vector3.Scale(objectLocalAttachPoint, currentTarget.Scale); + Vector3 worldAttachPoint = currentTarget.Rotation * scaledLocalAttach + currentTarget.Position; + return currentTarget.Position + (pointerCentroidPose.Position - worldAttachPoint); } /// diff --git a/Assets/MRTK/Tests/PlayModeTests/ObjectManipulatorTests.cs b/Assets/MRTK/Tests/PlayModeTests/ObjectManipulatorTests.cs index c9fa43da748..2c22e88a558 100644 --- a/Assets/MRTK/Tests/PlayModeTests/ObjectManipulatorTests.cs +++ b/Assets/MRTK/Tests/PlayModeTests/ObjectManipulatorTests.cs @@ -281,13 +281,13 @@ public IEnumerator ObjectManipulatorFarThrow() /// This tests the one hand near movement while camera (character) is moving around. /// The test will check the offset between object pivot and grab point and make sure we're not drifting /// out of the object on pointer rotation - this test should be the same in all rotation setups + /// This test also has a santity check to ensure behavior is still the same for objects of different scale /// [UnityTest] public IEnumerator ObjectManipulatorOneHandMoveNear() { // set up cube with manipulation handler var testObject = GameObject.CreatePrimitive(PrimitiveType.Cube); - testObject.transform.localScale = Vector3.one * 0.2f; Vector3 initialObjectPosition = new Vector3(0f, 0f, 1f); testObject.transform.position = initialObjectPosition; var manipHandler = testObject.AddComponent(); @@ -309,74 +309,94 @@ public IEnumerator ObjectManipulatorOneHandMoveNear() Vector3 initialGrabPosition = new Vector3(-0.1f, -0.1f, 1f); // grab the left bottom corner of the cube TestHand hand = new TestHand(Handedness.Right); - // do this test for every one hand rotation mode - foreach (ObjectManipulator.RotateInOneHandType type in Enum.GetValues(typeof(ObjectManipulator.RotateInOneHandType))) - { - manipHandler.OneHandRotationModeNear = type; - - TestUtilities.PlayspaceToOriginLookingForward(); + Vector3[] objectScales = new Vector3[] { Vector3.one * 0.2f, new Vector3(0.2f, 0.4f, 0.3f) }; - yield return hand.Show(initialHandPosition); - var pointer = hand.GetPointer(); - Assert.IsNotNull(pointer); + foreach (var objectScale in objectScales) + { + testObject.transform.localScale = objectScale; - yield return hand.MoveTo(initialGrabPosition, numHandSteps); + // do this test for every one hand rotation mode + foreach (ObjectManipulator.RotateInOneHandType type in Enum.GetValues(typeof(ObjectManipulator.RotateInOneHandType))) + { + manipHandler.OneHandRotationModeNear = type; - Vector3 initialPosition = testObject.transform.position; - yield return hand.SetGesture(ArticulatedHandPose.GestureId.Pinch); + TestUtilities.PlayspaceToOriginLookingForward(); - yield return PlayModeTestUtilities.WaitForInputSystemUpdate(); + yield return hand.Show(initialHandPosition); + var pointer = hand.GetPointer(); + Assert.IsNotNull(pointer); - // Ensure the object didn't move after pinching - TestUtilities.AssertAboutEqual(initialPosition, testObject.transform.position, "object shifted during pinch", 0.001f); + yield return hand.MoveTo(initialGrabPosition, numHandSteps); - // save relative pos grab point to object - Vector3 initialGrabPoint = manipHandler.GetPointerGrabPoint(pointer.PointerId); - Vector3 initialOffsetGrabToObjPivot = initialGrabPoint - testObject.transform.position; - Vector3 initialGrabPointInObject = testObject.transform.InverseTransformPoint(initialGrabPoint); + Vector3 initialPosition = testObject.transform.position; + yield return hand.SetGesture(ArticulatedHandPose.GestureId.Pinch); - // full circle - const int degreeStep = 360 / numCircleSteps; + yield return PlayModeTestUtilities.WaitForInputSystemUpdate(); - // rotating the pointer in a circle around "the user" - for (int i = 1; i <= numCircleSteps; ++i) - { - // rotate main camera (user) - MixedRealityPlayspace.PerformTransformation( - p => - { - p.position = MixedRealityPlayspace.Position; - Vector3 rotatedFwd = Quaternion.AngleAxis(degreeStep * i, Vector3.up) * Vector3.forward; - p.LookAt(rotatedFwd); - }); + // Ensure the object didn't move after pinching + TestUtilities.AssertAboutEqual(initialPosition, testObject.transform.position, "object shifted during pinch", 0.001f); - yield return null; + // save relative pos grab point to object + Vector3 initialGrabPoint = manipHandler.GetPointerGrabPoint(pointer.PointerId); + Vector3 initialOffsetGrabToObjPivot = initialGrabPoint - testObject.transform.position; + Vector3 initialGrabPointInObject = testObject.transform.InverseTransformPoint(initialGrabPoint); - // move hand with the camera - Vector3 newHandPosition = Quaternion.AngleAxis(degreeStep * i, Vector3.up) * initialGrabPosition; - yield return hand.MoveTo(newHandPosition, numHandSteps); + // full circle + const int degreeStep = 360 / numCircleSteps; - if (type == ObjectManipulator.RotateInOneHandType.RotateAboutObjectCenter) + // rotating the pointer in a circle around "the user" + for (int i = 1; i <= numCircleSteps; ++i) { - // make sure that the offset between grab and object centre hasn't changed while rotating - Vector3 grabPoint = manipHandler.GetPointerGrabPoint(pointer.PointerId); - Vector3 offsetRotated = grabPoint - testObject.transform.position; - TestUtilities.AssertAboutEqual(offsetRotated, initialOffsetGrabToObjPivot, $"Object offset changed during rotation using {type}"); + // rotate main camera (user) + MixedRealityPlayspace.PerformTransformation( + p => + { + p.position = MixedRealityPlayspace.Position; + Vector3 rotatedFwd = Quaternion.AngleAxis(degreeStep * i, Vector3.up) * Vector3.forward; + p.LookAt(rotatedFwd); + }); + + yield return null; + + // move hand with the camera + Vector3 newHandPosition = Quaternion.AngleAxis(degreeStep * i, Vector3.up) * initialGrabPosition; + yield return hand.MoveTo(newHandPosition, numHandSteps); + + if (type == ObjectManipulator.RotateInOneHandType.RotateAboutObjectCenter) + { + // make sure that the offset between grab and object centre hasn't changed while rotating + Vector3 grabPoint = manipHandler.GetPointerGrabPoint(pointer.PointerId); + Vector3 offsetRotated = MixedRealityPlayspace.InverseTransformPoint(grabPoint) - MixedRealityPlayspace.InverseTransformPoint(testObject.transform.position); + TestUtilities.AssertAboutEqual(offsetRotated, initialOffsetGrabToObjPivot, $"Object offset changed during rotation using {type}"); + } + else + { + // make sure that the offset between grab point and object pivot hasn't changed while rotating + Vector3 grabPoint = manipHandler.GetPointerGrabPoint(pointer.PointerId); + Vector3 cornerRotated = testObject.transform.TransformPoint(initialGrabPointInObject); + TestUtilities.AssertAboutEqual(cornerRotated, grabPoint, $"Grab point on object changed during rotation using {type}"); + } } - else - { - // make sure that the offset between grab point and object pivot hasn't changed while rotating - Vector3 grabPoint = manipHandler.GetPointerGrabPoint(pointer.PointerId); - Vector3 cornerRotated = testObject.transform.TransformPoint(initialGrabPointInObject); - TestUtilities.AssertAboutEqual(cornerRotated, grabPoint, $"Grab point on object changed during rotation using {type}"); - } - } - yield return hand.SetGesture(ArticulatedHandPose.GestureId.Open); - yield return hand.Hide(); + //Move the object forward and back + yield return hand.MoveTo(initialGrabPosition + Vector3.forward, numHandSteps); + // make sure that the offset between grab and object centre hasn't changed while rotating + Vector3 currentGrabPoint = manipHandler.GetPointerGrabPoint(pointer.PointerId); + Vector3 currentOffset = MixedRealityPlayspace.InverseTransformPoint(currentGrabPoint) - MixedRealityPlayspace.InverseTransformPoint(testObject.transform.position); + TestUtilities.AssertAboutEqual(currentOffset, initialOffsetGrabToObjPivot, $"Object offset changed during move forward"); - } + yield return hand.MoveTo(initialGrabPosition + Vector3.back, numHandSteps); + // make sure that the offset between grab and object centre hasn't changed while rotating + currentGrabPoint = manipHandler.GetPointerGrabPoint(pointer.PointerId); + currentOffset = MixedRealityPlayspace.InverseTransformPoint(currentGrabPoint) - MixedRealityPlayspace.InverseTransformPoint(testObject.transform.position); + TestUtilities.AssertAboutEqual(currentOffset, initialOffsetGrabToObjPivot, $"Object offset changed during move backward"); + yield return hand.MoveTo(initialGrabPosition, numHandSteps); + + yield return hand.SetGesture(ArticulatedHandPose.GestureId.Open); + yield return hand.Hide(); + } + } } /// @@ -384,6 +404,7 @@ public IEnumerator ObjectManipulatorOneHandMoveNear() /// The test will check the offset between object pivot and grab point and make sure we're not drifting /// out of the object on pointer rotation - this test is the same for all objects that won't change /// their orientation to camera while camera / pointer rotates as this will modify the far interaction grab point + /// This test also has a santity check to ensure behavior is still the same for objects of different scale /// [UnityTest] public IEnumerator ObjectManipulatorOneHandMoveFar() @@ -412,67 +433,70 @@ public IEnumerator ObjectManipulatorOneHandMoveFar() Vector3 initialHandPosition = new Vector3(0.044f, -0.1f, 0.45f); TestHand hand = new TestHand(Handedness.Right); - // do this test for every one hand rotation mode - foreach (ObjectManipulator.RotateInOneHandType type in Enum.GetValues(typeof(ObjectManipulator.RotateInOneHandType))) + Vector3[] objectScales = new Vector3[] { Vector3.one * 0.2f, new Vector3(0.2f, 0.4f, 0.3f) }; + foreach (var objectScale in objectScales) { - manipHandler.OneHandRotationModeFar = type; + // do this test for every one hand rotation mode + foreach (ObjectManipulator.RotateInOneHandType type in Enum.GetValues(typeof(ObjectManipulator.RotateInOneHandType))) + { + manipHandler.OneHandRotationModeFar = type; - TestUtilities.PlayspaceToOriginLookingForward(); + TestUtilities.PlayspaceToOriginLookingForward(); - yield return hand.Show(initialHandPosition); - yield return PlayModeTestUtilities.WaitForInputSystemUpdate(); + yield return hand.Show(initialHandPosition); + yield return PlayModeTestUtilities.WaitForInputSystemUpdate(); - Vector3 initialPosition = testObject.transform.position; - yield return hand.SetGesture(ArticulatedHandPose.GestureId.Pinch); + Vector3 initialPosition = testObject.transform.position; + yield return hand.SetGesture(ArticulatedHandPose.GestureId.Pinch); - yield return PlayModeTestUtilities.WaitForInputSystemUpdate(); + yield return PlayModeTestUtilities.WaitForInputSystemUpdate(); - // Ensure the object didn't move after pinching - TestUtilities.AssertAboutEqual(initialPosition, testObject.transform.position, "object shifted during pinch", 0.0001f); + // Ensure the object didn't move after pinching + TestUtilities.AssertAboutEqual(initialPosition, testObject.transform.position, "object shifted during pinch", 0.0001f); - // save relative pos grab point to object - for far interaction we need to check the grab point where the pointer ray hits the manipulated object - InputSimulationService simulationService = PlayModeTestUtilities.GetInputSimulationService(); - IMixedRealityController[] inputControllers = simulationService.GetActiveControllers(); - // assume hand is first controller and pointer for this test - IMixedRealityController handController = inputControllers[0]; - IMixedRealityPointer handPointer = handController.InputSource.Pointers[0]; - Vector3 initialGrabPosition = handPointer.Result.Details.Point; - Vector3 initialOffsetGrabToObjPivot = MixedRealityPlayspace.InverseTransformPoint(initialGrabPosition) - MixedRealityPlayspace.InverseTransformPoint(testObject.transform.position); + // save relative pos grab point to object - for far interaction we need to check the grab point where the pointer ray hits the manipulated object + InputSimulationService simulationService = PlayModeTestUtilities.GetInputSimulationService(); + IMixedRealityController[] inputControllers = simulationService.GetActiveControllers(); + // assume hand is first controller and pointer for this test + IMixedRealityController handController = inputControllers[0]; + IMixedRealityPointer handPointer = handController.InputSource.Pointers[0]; + Vector3 initialGrabPosition = handPointer.Result.Details.Point; + Vector3 initialOffsetGrabToObjPivot = MixedRealityPlayspace.InverseTransformPoint(initialGrabPosition) - MixedRealityPlayspace.InverseTransformPoint(testObject.transform.position); - // full circle - const int degreeStep = 360 / numCircleSteps; + // full circle + const int degreeStep = 360 / numCircleSteps; - // rotating the pointer in a circle around "the user" - for (int i = 1; i <= numCircleSteps; ++i) - { - - // rotate main camera (user) - MixedRealityPlayspace.PerformTransformation( - p => + // rotating the pointer in a circle around "the user" + for (int i = 1; i <= numCircleSteps; ++i) { - p.position = MixedRealityPlayspace.Position; - Vector3 rotatedFwd = Quaternion.AngleAxis(degreeStep * i, Vector3.up) * Vector3.forward; - p.LookAt(rotatedFwd); - }); - yield return null; + // rotate main camera (user) + MixedRealityPlayspace.PerformTransformation( + p => + { + p.position = MixedRealityPlayspace.Position; + Vector3 rotatedFwd = Quaternion.AngleAxis(degreeStep * i, Vector3.up) * Vector3.forward; + p.LookAt(rotatedFwd); + }); - // move hand with the camera - Vector3 newHandPosition = Quaternion.AngleAxis(degreeStep * i, Vector3.up) * initialHandPosition; - yield return hand.MoveTo(newHandPosition, numHandSteps); - yield return new WaitForFixedUpdate(); - yield return null; + yield return null; + // move hand with the camera + Vector3 newHandPosition = Quaternion.AngleAxis(degreeStep * i, Vector3.up) * initialHandPosition; + yield return hand.MoveTo(newHandPosition, numHandSteps); + yield return new WaitForFixedUpdate(); + yield return null; - // make sure that the offset between grab point and object pivot hasn't changed while rotating - Vector3 newGrabPosition = handPointer.Result.Details.Point; - Vector3 offsetRotated = MixedRealityPlayspace.InverseTransformPoint(newGrabPosition) - MixedRealityPlayspace.InverseTransformPoint(testObject.transform.position); - TestUtilities.AssertAboutEqual(offsetRotated, initialOffsetGrabToObjPivot, "Grab point on object changed during rotation"); - } - yield return hand.SetGesture(ArticulatedHandPose.GestureId.Open); - yield return hand.Hide(); + // make sure that the offset between grab point and object pivot hasn't changed while rotating + Vector3 newGrabPosition = handPointer.Result.Details.Point; + Vector3 offsetRotated = MixedRealityPlayspace.InverseTransformPoint(newGrabPosition) - MixedRealityPlayspace.InverseTransformPoint(testObject.transform.position); + TestUtilities.AssertAboutEqual(offsetRotated, initialOffsetGrabToObjPivot, "Grab point on object changed during rotation"); + } + yield return hand.SetGesture(ArticulatedHandPose.GestureId.Open); + yield return hand.Hide(); + } } } From 689bd0eb9d8253f24677ad13ab2c6f98e060704f Mon Sep 17 00:00:00 2001 From: RogPodge Date: Wed, 3 Nov 2021 17:00:07 -0700 Subject: [PATCH 3/5] missing changes --- .../Input/Handlers/Manipulation/ManipulationMoveLogic.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationMoveLogic.cs b/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationMoveLogic.cs index 4f8c372bf64..363d939b619 100644 --- a/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationMoveLogic.cs +++ b/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationMoveLogic.cs @@ -80,7 +80,6 @@ public Vector3 UpdateTransform(MixedRealityPose pointerCentroidPose, MixedRealit /// Updates the position during near manipulation /// /// A Vector3 describing the desired position during near manipulation - /// private Vector3 NearManipulationUpdate(MixedRealityPose pointerCentroidPose, MixedRealityTransform currentTarget) { Vector3 scaledLocalAttach = Vector3.Scale(objectLocalAttachPoint, currentTarget.Scale); @@ -92,7 +91,6 @@ private Vector3 NearManipulationUpdate(MixedRealityPose pointerCentroidPose, Mix /// Updates the position during far manipulation /// /// A Vector3 describing the desired position during far manipulation - /// private Vector3 FarManipulationUpdate(MixedRealityPose pointerCentroidPose, Quaternion objectRotation, Vector3 objectScale, bool isPointerAnchor) { float distanceRatio = 1.0f; From e1a81a80173eefbf41dc31bd9c6ec022a3b50b01 Mon Sep 17 00:00:00 2001 From: RogPodge Date: Wed, 3 Nov 2021 21:38:09 -0700 Subject: [PATCH 4/5] reverted manipulation handler changes due to it being obsolete, fixed CI --- .../Input/Handlers/Manipulation/ManipulationHandler.cs | 9 +++++++-- .../MRTK/Tests/PlayModeTests/ObjectManipulatorTests.cs | 6 +++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationHandler.cs b/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationHandler.cs index a109b9313ae..34d10746672 100644 --- a/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationHandler.cs +++ b/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationHandler.cs @@ -684,7 +684,9 @@ private void HandleTwoHandManipulationUpdated() // the initial pointer pose; if far manipulation, a more complex // look-rotation-based pointer pose is used. MixedRealityPose pose = IsNearManipulation() ? new MixedRealityPose(GetPointersCentroid()) : GetAveragePointerPose(); - targetTransform.Position = moveLogic.UpdateTransform(pose, targetTransform, true, IsNearManipulation()); + + // The manipulation handler is not built to handle near manipulation properly, please use the object manipulator + targetTransform.Position = moveLogic.UpdateTransform(pose, targetTransform, true, false); if (constraintOnMovement == MovementConstraintType.FixDistanceFromHead && moveConstraint != null) { moveConstraint.ApplyConstraint(ref targetTransform); @@ -748,13 +750,16 @@ private void HandleOneHandMoveUpdated() } MixedRealityPose pointerPose = new MixedRealityPose(pointer.Position, pointer.Rotation); - targetTransform.Position = moveLogic.UpdateTransform(pointerPose, targetTransform, rotateInOneHandType != RotateInOneHandType.RotateAboutObjectCenter, IsNearManipulation()); + + // The manipulation handler is not built to handle near manipulation properly, please use the object manipulator + targetTransform.Position = moveLogic.UpdateTransform(pointerPose, targetTransform, rotateInOneHandType != RotateInOneHandType.RotateAboutObjectCenter, false); if (constraintOnMovement == MovementConstraintType.FixDistanceFromHead && moveConstraint != null) { moveConstraint.ApplyConstraint(ref targetTransform); } float lerpAmount = GetLerpAmount(); + Debug.Log(lerpAmount); Quaternion smoothedRotation = Quaternion.Lerp(hostTransform.rotation, targetTransform.Rotation, lerpAmount); Vector3 smoothedPosition = Vector3.Lerp(hostTransform.position, targetTransform.Position, lerpAmount); diff --git a/Assets/MRTK/Tests/PlayModeTests/ObjectManipulatorTests.cs b/Assets/MRTK/Tests/PlayModeTests/ObjectManipulatorTests.cs index 2c22e88a558..e2af4bc5e9e 100644 --- a/Assets/MRTK/Tests/PlayModeTests/ObjectManipulatorTests.cs +++ b/Assets/MRTK/Tests/PlayModeTests/ObjectManipulatorTests.cs @@ -373,12 +373,12 @@ public IEnumerator ObjectManipulatorOneHandMoveNear() { // make sure that the offset between grab point and object pivot hasn't changed while rotating Vector3 grabPoint = manipHandler.GetPointerGrabPoint(pointer.PointerId); - Vector3 cornerRotated = testObject.transform.TransformPoint(initialGrabPointInObject); - TestUtilities.AssertAboutEqual(cornerRotated, grabPoint, $"Grab point on object changed during rotation using {type}"); + Vector3 offsetRotated = testObject.transform.TransformPoint(initialGrabPointInObject); + TestUtilities.AssertAboutEqual(offsetRotated, grabPoint, $"Grab point on object changed during rotation using {type}"); } } - //Move the object forward and back + // Move the object forward and back yield return hand.MoveTo(initialGrabPosition + Vector3.forward, numHandSteps); // make sure that the offset between grab and object centre hasn't changed while rotating Vector3 currentGrabPoint = manipHandler.GetPointerGrabPoint(pointer.PointerId); From fcca4a910b611b92f0562b70956caaff1bf6980d Mon Sep 17 00:00:00 2001 From: RogPodge Date: Fri, 5 Nov 2021 10:21:45 -0700 Subject: [PATCH 5/5] removed debug --- .../Features/Input/Handlers/Manipulation/ManipulationHandler.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationHandler.cs b/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationHandler.cs index 34d10746672..3d41a728c00 100644 --- a/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationHandler.cs +++ b/Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationHandler.cs @@ -759,7 +759,6 @@ private void HandleOneHandMoveUpdated() } float lerpAmount = GetLerpAmount(); - Debug.Log(lerpAmount); Quaternion smoothedRotation = Quaternion.Lerp(hostTransform.rotation, targetTransform.Rotation, lerpAmount); Vector3 smoothedPosition = Vector3.Lerp(hostTransform.position, targetTransform.Position, lerpAmount);