Skip to content

Commit 88de6f9

Browse files
RogPodgekeveleigh
authored andcommitted
Fixed objects drifting during Near Manipulation (#10294)
* Fixed objects drifting during Near Manipulation * Updated unit tests, made near manipulation consistent to avoid weird offset behaviors * missing changes * reverted manipulation handler changes due to it being obsolete, fixed CI * removed debug
1 parent 8769d61 commit 88de6f9

File tree

4 files changed

+177
-105
lines changed

4 files changed

+177
-105
lines changed

Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationHandler.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,9 @@ private void HandleTwoHandManipulationUpdated()
684684
// the initial pointer pose; if far manipulation, a more complex
685685
// look-rotation-based pointer pose is used.
686686
MixedRealityPose pose = IsNearManipulation() ? new MixedRealityPose(GetPointersCentroid()) : GetAveragePointerPose();
687-
targetTransform.Position = moveLogic.Update(pose, targetTransform.Rotation, targetTransform.Scale, true);
687+
688+
// The manipulation handler is not built to handle near manipulation properly, please use the object manipulator
689+
targetTransform.Position = moveLogic.UpdateTransform(pose, targetTransform, true, false);
688690
if (constraintOnMovement == MovementConstraintType.FixDistanceFromHead && moveConstraint != null)
689691
{
690692
moveConstraint.ApplyConstraint(ref targetTransform);
@@ -748,7 +750,9 @@ private void HandleOneHandMoveUpdated()
748750
}
749751

750752
MixedRealityPose pointerPose = new MixedRealityPose(pointer.Position, pointer.Rotation);
751-
targetTransform.Position = moveLogic.Update(pointerPose, targetTransform.Rotation, targetTransform.Scale, rotateInOneHandType != RotateInOneHandType.RotateAboutObjectCenter);
753+
754+
// The manipulation handler is not built to handle near manipulation properly, please use the object manipulator
755+
targetTransform.Position = moveLogic.UpdateTransform(pointerPose, targetTransform, rotateInOneHandType != RotateInOneHandType.RotateAboutObjectCenter, false);
752756
if (constraintOnMovement == MovementConstraintType.FixDistanceFromHead && moveConstraint != null)
753757
{
754758
moveConstraint.ApplyConstraint(ref targetTransform);

Assets/MRTK/SDK/Features/Input/Handlers/Manipulation/ManipulationMoveLogic.cs

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT License.
33

44
using Microsoft.MixedReality.Toolkit.Utilities;
5+
using System;
56
using UnityEngine;
67

78
namespace Microsoft.MixedReality.Toolkit.Physics
@@ -25,6 +26,9 @@ internal class ManipulationMoveLogic
2526
private Vector3 objectLocalGrabPoint;
2627
private Vector3 grabToObject;
2728

29+
private Vector3 objectLocalAttachPoint;
30+
private Vector3 attachToObject;
31+
2832
/// <summary>
2933
/// Setup function
3034
/// </summary>
@@ -37,17 +41,57 @@ public void Setup(MixedRealityPose pointerCentroidPose, Vector3 grabCentroid, Mi
3741
Quaternion worldToPointerRotation = Quaternion.Inverse(pointerCentroidPose.Rotation);
3842
pointerLocalGrabPoint = worldToPointerRotation * (grabCentroid - pointerCentroidPose.Position);
3943

40-
objectLocalGrabPoint = Quaternion.Inverse(objectPose.Rotation) * (grabCentroid - objectPose.Position);
41-
objectLocalGrabPoint = objectLocalGrabPoint.Div(objectScale);
44+
attachToObject = objectPose.Position - pointerCentroidPose.Position;
45+
objectLocalAttachPoint = Quaternion.Inverse(objectPose.Rotation) * (pointerCentroidPose.Position - objectPose.Position);
46+
objectLocalAttachPoint = objectLocalAttachPoint.Div(objectScale);
4247

4348
grabToObject = objectPose.Position - grabCentroid;
49+
objectLocalGrabPoint = Quaternion.Inverse(objectPose.Rotation) * (grabCentroid - objectPose.Position);
50+
objectLocalGrabPoint = objectLocalGrabPoint.Div(objectScale);
4451
}
4552

4653
/// <summary>
4754
/// Update the position based on input.
4855
/// </summary>
4956
/// <returns>A Vector3 describing the desired position</returns>
57+
[Obsolete("This update function is out of date and does not properly support Near Manipulation. Use UpdateTransform instead")]
5058
public Vector3 Update(MixedRealityPose pointerCentroidPose, Quaternion objectRotation, Vector3 objectScale, bool usePointerRotation)
59+
{
60+
return FarManipulationUpdate(pointerCentroidPose, objectRotation, objectScale, usePointerRotation);
61+
}
62+
63+
/// <summary>
64+
/// Update the position based on input.
65+
/// </summary>
66+
/// <returns>A Vector3 describing the desired position</returns>
67+
public Vector3 UpdateTransform(MixedRealityPose pointerCentroidPose, MixedRealityTransform currentTarget, bool isPointerAnchor, bool isNearManipulation)
68+
{
69+
if (isNearManipulation)
70+
{
71+
return NearManipulationUpdate(pointerCentroidPose, currentTarget);
72+
}
73+
else
74+
{
75+
return FarManipulationUpdate(pointerCentroidPose, currentTarget.Rotation, currentTarget.Scale, isPointerAnchor);
76+
}
77+
}
78+
79+
/// <summary>
80+
/// Updates the position during near manipulation
81+
/// </summary>
82+
/// <returns>A Vector3 describing the desired position during near manipulation</returns>
83+
private Vector3 NearManipulationUpdate(MixedRealityPose pointerCentroidPose, MixedRealityTransform currentTarget)
84+
{
85+
Vector3 scaledLocalAttach = Vector3.Scale(objectLocalAttachPoint, currentTarget.Scale);
86+
Vector3 worldAttachPoint = currentTarget.Rotation * scaledLocalAttach + currentTarget.Position;
87+
return currentTarget.Position + (pointerCentroidPose.Position - worldAttachPoint);
88+
}
89+
90+
/// <summary>
91+
/// Updates the position during far manipulation
92+
/// </summary>
93+
/// <returns>A Vector3 describing the desired position during far manipulation</returns>
94+
private Vector3 FarManipulationUpdate(MixedRealityPose pointerCentroidPose, Quaternion objectRotation, Vector3 objectScale, bool isPointerAnchor)
5195
{
5296
float distanceRatio = 1.0f;
5397

@@ -58,7 +102,7 @@ public Vector3 Update(MixedRealityPose pointerCentroidPose, Quaternion objectRot
58102
distanceRatio = currentHandDistance / pointerRefDistance;
59103
}
60104

61-
if (usePointerRotation)
105+
if (isPointerAnchor)
62106
{
63107
Vector3 scaledGrabToObject = Vector3.Scale(objectLocalGrabPoint, objectScale);
64108
Vector3 adjustedPointerToGrab = (pointerLocalGrabPoint * distanceRatio);

Assets/MRTK/SDK/Features/Input/Handlers/ObjectManipulator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,7 @@ private void HandleTwoHandManipulationUpdated()
727727
// the pointer pose; if far manipulation, a more complex
728728
// look-rotation-based pointer pose is used.
729729
MixedRealityPose pose = IsNearManipulation() ? new MixedRealityPose(GetPointersGrabPoint()) : GetPointersPose();
730-
targetTransform.Position = moveLogic.Update(pose, targetTransform.Rotation, targetTransform.Scale, true);
730+
targetTransform.Position = moveLogic.UpdateTransform(pose, targetTransform, true, IsNearManipulation());
731731
if (EnableConstraints && constraintsManager != null)
732732
{
733733
constraintsManager.ApplyTranslationConstraints(ref targetTransform, false, IsNearManipulation());
@@ -778,7 +778,7 @@ private void HandleOneHandMoveUpdated()
778778

779779
RotateInOneHandType rotateInOneHandType = isNearManipulation ? oneHandRotationModeNear : oneHandRotationModeFar;
780780
MixedRealityPose pointerPose = new MixedRealityPose(pointer.Position, pointer.Rotation);
781-
targetTransform.Position = moveLogic.Update(pointerPose, targetTransform.Rotation, targetTransform.Scale, rotateInOneHandType != RotateInOneHandType.RotateAboutObjectCenter);
781+
targetTransform.Position = moveLogic.UpdateTransform(pointerPose, targetTransform, rotateInOneHandType != RotateInOneHandType.RotateAboutObjectCenter, IsNearManipulation());
782782

783783
if (EnableConstraints && constraintsManager != null)
784784
{

0 commit comments

Comments
 (0)