Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@
"source": "local",
"dependencies": {
"org.mixedrealitytoolkit.core": "4.0.0",
"org.mixedrealitytoolkit.input": "4.0.0",
"org.mixedrealitytoolkit.uxcore": "4.0.0",
"com.unity.inputsystem": "1.6.1",
"com.unity.xr.interaction.toolkit": "3.0.4"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public class MRTKBaseInteractable : XRBaseInteractable
/// <summary>
/// Is this object selected by a gaze-pinch interactor?
/// </summary>
public TimedFlag IsGazePinchSelected { get => isGazePinchSelected; }
public TimedFlag IsGazePinchSelected => isGazePinchSelected;

[SerializeField]
[Tooltip("Is this object selected by a non-gaze ray interactor?")]
Expand All @@ -104,7 +104,7 @@ public class MRTKBaseInteractable : XRBaseInteractable
/// <summary>
/// Is this object selected by a non-gaze ray interactor?
/// </summary>
public TimedFlag IsRaySelected { get => isRaySelected; }
public TimedFlag IsRaySelected => isRaySelected;

[SerializeField]
[Tooltip("Is this object selected by a poke interactor?")]
Expand All @@ -113,7 +113,7 @@ public class MRTKBaseInteractable : XRBaseInteractable
/// <summary>
/// Is this object selected by a poke interactor?
/// </summary>
public TimedFlag IsPokeSelected { get => isPokeSelected; }
public TimedFlag IsPokeSelected => isPokeSelected;

[SerializeField]
[Tooltip("Is this object selected by a grab interactor?")]
Expand All @@ -122,7 +122,7 @@ public class MRTKBaseInteractable : XRBaseInteractable
/// <summary>
/// Is this object selected by a grab interactor?
/// </summary>
public TimedFlag IsGrabSelected { get => isGrabSelected; }
public TimedFlag IsGrabSelected => isGrabSelected;

[SerializeField]
[Tooltip("Is this object hovered by any gaze interactor?")]
Expand All @@ -131,7 +131,7 @@ public class MRTKBaseInteractable : XRBaseInteractable
/// <summary>
/// Is this object hovered by any gaze interactor?
/// </summary>
public TimedFlag IsGazeHovered { get => isGazeHovered; }
public TimedFlag IsGazeHovered => isGazeHovered;

[SerializeField]
[Tooltip("Is this object hovered by a gaze-pinch interactor?")]
Expand All @@ -140,7 +140,7 @@ public class MRTKBaseInteractable : XRBaseInteractable
/// <summary>
/// Is this object hovered by a gaze-pinch interactor?
/// </summary>
public TimedFlag IsGazePinchHovered { get => isGazePinchHovered; }
public TimedFlag IsGazePinchHovered => isGazePinchHovered;

[SerializeField]
[Tooltip("Is this object hovered by a non-gaze ray interactor?")]
Expand All @@ -149,7 +149,7 @@ public class MRTKBaseInteractable : XRBaseInteractable
/// <summary>
/// Is this object hovered by a non-gaze ray interactor?
/// </summary>
public TimedFlag IsRayHovered { get => isRayHovered; }
public TimedFlag IsRayHovered => isRayHovered;

[SerializeField]
[Tooltip("Is this object hovered by a grab interactor?")]
Expand All @@ -158,7 +158,7 @@ public class MRTKBaseInteractable : XRBaseInteractable
/// <summary>
/// Is this object hovered by a grab interactor?
/// </summary>
public TimedFlag IsGrabHovered { get => isGrabHovered; }
public TimedFlag IsGrabHovered => isGrabHovered;

[SerializeField]
[Tooltip("Is this object hovered by a near touch/poke interactor?")]
Expand All @@ -168,12 +168,12 @@ public class MRTKBaseInteractable : XRBaseInteractable
/// <summary>
/// Is this object hovered by a near touch/poke interactor?
/// </summary>
public TimedFlag IsPokeHovered { get => isPokeHovered; }
public TimedFlag IsPokeHovered => isPokeHovered;

/// <summary>
/// Is this object hovered by any interactor other than passive targeting interactors?
/// </summary>
public TimedFlag IsActiveHovered { get => isActiveHovered; }
public TimedFlag IsActiveHovered => isActiveHovered;

[SerializeField]
[Tooltip("Is this object hovered by any interactor other than only passive targeting interactors?")]
Expand Down
3 changes: 1 addition & 2 deletions org.mixedrealitytoolkit.core/MRTK.Core.asmdef
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
"references": [
"Unity.XR.CoreUtils",
"Unity.XR.Interaction.Toolkit",
"Unity.XR.Management",
"Unity.InputSystem"
"Unity.XR.Management"
],
"includePlatforms": [],
"excludePlatforms": [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Collections.Generic;
using Unity.Profiling;
using UnityEngine;
using UnityEngine.InputSystem;

namespace MixedReality.Toolkit.Subsystems
{
Expand All @@ -19,9 +18,6 @@ public class MRTKLifecycleManager :
MonoBehaviour,
IDisposable
{
[SerializeField, Tooltip("A set of input actions to enable/disable according to the app's focus state.")]
private InputActionReference[] inputActionReferences;

private List<IMRTKManagedSubsystem> managedSubsystems = new List<IMRTKManagedSubsystem>();

/// <summary>
Expand Down Expand Up @@ -191,17 +187,7 @@ protected void OnApplicationFocus(bool focus)
// and applications should react to an inactive input action by skipping rendering of that action's input avatar
// (depictions of hands or other tracked objects controlled by the user)."

foreach (InputActionReference reference in inputActionReferences)
{
if (focus)
{
reference.action.Enable();
}
else
{
reference.action.Disable();
}
}

}

#endregion MonoBehaviour
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ private void OnValidate()
{
if (FindObjectsByType<TrackedPoseDriverLookup>(FindObjectsSortMode.None).Length > 1)
{
Debug.LogWarning("Found more than one instance of the ControllerLookup class in the hierarchy. There should only be one");
Debug.LogWarning($"Found more than one instance of the {nameof(TrackedPoseDriverLookup)} class in the hierarchy. There should only be one.");
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
{
"name": "MixedReality.Toolkit.SpatialManipulation",
"rootNamespace": "MixedReality.Toolkit.SpatialManipulation",
"references": [
"MixedReality.Toolkit.Core",
"Unity.InputSystem",
"Unity.XR.CoreUtils",
"Unity.XR.Interaction.Toolkit"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
"name": "MixedReality.Toolkit.SpatialManipulation",
"rootNamespace": "MixedReality.Toolkit.SpatialManipulation",
"references": [
"MixedReality.Toolkit.Core",
"MixedReality.Toolkit.Input",
"Unity.InputSystem",
"Unity.XR.CoreUtils",
"Unity.XR.Interaction.Toolkit"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public float HeadGazeProximityThreshold
new ProfilerMarker("[MRTK] HandConstraintPalmUp.IsValidController");

/// <summary>
/// Determines if a hand meets the requirements for use with constraining the
/// Determines if a hand meets the requirements for use with constraining the
/// tracked object and determines if the palm is currently facing the user.
/// </summary>
/// <param name="hand">XRNode representing the hand to validate.</param>
Expand Down Expand Up @@ -258,15 +258,15 @@ private bool IsPalmMeetingThresholdRequirements(
new ProfilerMarker("[MRTK] HandConstraintPalmUp.IsUserGazeMeetingThresholdRequirements");

/// <summary>
/// Checks to see if the user is currently gazing at the activation point; it first attempts to do so
/// Checks to see if the user is currently gazing at the activation point; it first attempts to do so
/// using eye gaze, and then falls back to head-based gaze if eye gaze isn't available for use.
/// </summary>
/// <param name="hand">
/// The XRNode representing the user's hand that is used to determine if user gaze meets the gaze threshold.
/// </param>
/// <returns>
/// <see langword="true"/> if the user's gaze is within the proximity threshold of the activation point (both relative to the
/// hand plane), or <see langword="fapse"/>.
/// hand plane), or <see langword="false"/>.
/// </returns>
private bool IsUserGazeMeetingThresholdRequirements(XRNode hand)
{
Expand All @@ -275,16 +275,16 @@ private bool IsUserGazeMeetingThresholdRequirements(XRNode hand)
Ray? gazeRay = null;
bool usedEyeGaze = false;

#pragma warning disable CS0618 // Type or member is obsolete
#pragma warning disable CS0618 // Type or member is obsolete
if (ControllerLookup != null)
{
if (ControllerLookup.GazeController != null &&
(ControllerLookup.GazeController.currentControllerState.inputTrackingState &
(InputTrackingState.Position | InputTrackingState.Rotation)) > 0)
{
gazeRay = new Ray(
ControllerLookup.GazeController.transform.position,
ControllerLookup.GazeController.transform.forward);
ControllerLookup.GazeController.transform.position,
ControllerLookup.GazeController.transform.forward);
usedEyeGaze = true;
}
else
Expand All @@ -294,7 +294,7 @@ private bool IsUserGazeMeetingThresholdRequirements(XRNode hand)
Camera.main.transform.forward);
}
}
#pragma warning restore CS0618
#pragma warning restore CS0618
else if (TrackedPoseDriverLookup != null)
{
InputTrackingState gazeTrackingStateInput = GetGazeInputTrackingState(TrackedPoseDriverLookup.GazeTrackedPoseDriver);
Expand All @@ -315,35 +315,31 @@ private bool IsUserGazeMeetingThresholdRequirements(XRNode hand)
}
else
{
Debug.LogWarning("Neither ControllerLookup nor TrackedPoseDriverLookup are set, unable to determine whether user gaze meets threashold requirements or not.");
Debug.LogWarning("Neither ControllerLookup nor TrackedPoseDriverLookup are set, unable to determine whether user gaze meets threshold requirements or not.");
return false;
}

if (gazeRay.HasValue)
// Define the activation point as a vector between the wrist and pinky knuckle; then cast it against the plane to get a smooth location
// If we can generate the hand plane or are able to set an activation point on it, and then are able to raycast against it
if (gazeRay.HasValue &&
TryGenerateHandPlaneAndActivationPoint(hand, out Plane handPlane, out Vector3 activationPoint) &&
handPlane.Raycast(gazeRay.Value, out float distanceToHandPlane))
{
// Define the activation point as a vector between the wrist and pinky knuckle; then cast it against the plane to get a smooth location
// If we can generate the hand plane or are able to set an activation point on it, and then are able to raycast against it
if (TryGenerateHandPlaneAndActivationPoint(hand, out Plane handPlane, out Vector3 activationPoint) &&
handPlane.Raycast(gazeRay.Value, out float distanceToHandPlane))
{
// Now that we know the dist to the plane, create a vector at that point
Vector3 gazePosOnPlane = gazeRay.Value.origin + gazeRay.Value.direction.normalized * distanceToHandPlane;
Vector3 planePos = handPlane.ClosestPointOnPlane(gazePosOnPlane);
float gazePosDistToActivationPosition = (activationPoint - planePos).sqrMagnitude;
float gazeActivationThreshold = usedEyeGaze ? eyeGazeProximityThreshold : headGazeProximityThreshold;
gazeActivationAlreadyTriggered = (gazePosDistToActivationPosition < gazeActivationThreshold);

return gazeActivationAlreadyTriggered;
}
// Now that we know the distance to the plane, create a vector at that point
Vector3 gazePosOnPlane = gazeRay.Value.origin + gazeRay.Value.direction.normalized * distanceToHandPlane;
Vector3 planePos = handPlane.ClosestPointOnPlane(gazePosOnPlane);
float gazePosDistToActivationPosition = (activationPoint - planePos).sqrMagnitude;
float gazeActivationThreshold = usedEyeGaze ? eyeGazeProximityThreshold : headGazeProximityThreshold;
return gazeActivationAlreadyTriggered = gazePosDistToActivationPosition < gazeActivationThreshold;
}

return false;
}
}

/// <summary>
/// Coroutine function called by the ObjectManipulator of the attached object whenever the object is done
/// being manipulated by the user. This triggers a coroutine that checks to see whether the object should
/// Coroutine function called by the ObjectManipulator of the attached object whenever the object is done
/// being manipulated by the user. This triggers a coroutine that checks to see whether the object should
/// reattach to the hand.
/// </summary>
public void StartWorldLockReattachCheckCoroutine()
Expand Down Expand Up @@ -521,7 +517,7 @@ private bool TryGenerateActivationPoint(
}

/// <summary>
/// Coroutine function that's invoked when the attached object becomes world-locked. It uses the
/// Coroutine function that's invoked when the attached object becomes world-locked. It uses the
/// logical checks invoked during IsValidController to determine whether the menu should reattach
/// to the hand or not.
/// </summary>
Expand All @@ -531,19 +527,14 @@ private IEnumerator WorldLockedReattachCheck()
{
XRNode? hand = SolverHandler.CurrentTrackedHandedness.ToXRNode();

if (hand.HasValue)
if (hand.HasValue &&
XRSubsystemHelpers.HandsAggregator != null &&
XRSubsystemHelpers.HandsAggregator.TryGetJoint(TrackedHandJoint.Palm, hand.Value, out HandJointPose palmPose) &&
IsPalmMeetingThresholdRequirements(hand.Value, palmPose, Vector3.Angle(palmPose.Up, Camera.main.transform.forward)) &&
IsUserGazeMeetingThresholdRequirements(hand.Value))
{
if (XRSubsystemHelpers.HandsAggregator != null &&
XRSubsystemHelpers.HandsAggregator.TryGetJoint(TrackedHandJoint.Palm, hand.Value, out HandJointPose palmPose))
{
float palmCameraAngle = Vector3.Angle(palmPose.Up, Camera.main.transform.forward);
if (IsPalmMeetingThresholdRequirements(hand.Value, palmPose, palmCameraAngle) &&
IsUserGazeMeetingThresholdRequirements(hand.Value))
{
gazeActivationAlreadyTriggered = false;
SolverHandler.UpdateSolvers = true;
}
}
gazeActivationAlreadyTriggered = false;
SolverHandler.UpdateSolvers = true;
}

yield return null;
Expand All @@ -556,8 +547,8 @@ private IEnumerator WorldLockedReattachCheck()
/// A Unity event function that is called when the script component has been enabled.
/// </summary>
/// <remarks>
/// When enabled, ensure that there are no outlying status changes that would prevent HandConstraintPalmUp from
/// properly working (like gazeActivationAlreadyTriggered being set to true previously)
/// When enabled, ensure that there are no outlying status changes that would prevent HandConstraintPalmUp from
/// properly working (like gazeActivationAlreadyTriggered being set to true previously).
/// </remarks>
protected override void OnEnable()
{
Expand Down
11 changes: 5 additions & 6 deletions org.mixedrealitytoolkit.spatialmanipulation/Solvers/Solver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ public abstract class Solver : MonoBehaviour
private static ControllerLookup controllerLookup;

/// <summary>
/// Get the <see cref="Toolkit.ControllerLookup">ControllerLookup</see> that will be used all application <see cref="Solver"/> objects.
/// Get the <see cref="Toolkit.ControllerLookup"/> that will be used all application <see cref="Solver"/> objects.
/// </summary>
[Obsolete("This property has been deprecated in version 4.0.0. Please use MixedReality.Toolkit.Input.TrackedPoseDriverLookup instead.")]
protected static ControllerLookup ControllerLookup => controllerLookup;

private static TrackedPoseDriverLookup trackedPoseDriverLookup;

/// <summary>
/// Get the <see cref="Toolkit.TrackedPoseDriverLookup">TrackedPoseDriverLookup</see> that will be used by all application <see cref="Solver"/> objects.
/// Get the <see cref="Toolkit.TrackedPoseDriverLookup"/> that will be used by all application <see cref="Solver"/> objects.
/// </summary>
protected static TrackedPoseDriverLookup TrackedPoseDriverLookup => trackedPoseDriverLookup;

Expand Down Expand Up @@ -272,7 +272,7 @@ protected virtual void Start()
{
// Find the controller lookup class in the hierarchy. Solvers that require access to the
// left, right or gaze controllers will use the references stored in this class.
#pragma warning disable CS0618 // Type or member is obsolete
#pragma warning disable CS0618 // Type or member is obsolete
if (controllerLookup == null)
{
controllerLookup = ComponentCache<ControllerLookup>.FindFirstActiveInstance();
Expand All @@ -284,7 +284,7 @@ protected virtual void Start()
{
trackedPoseDriverLookup = ComponentCache<TrackedPoseDriverLookup>.FindFirstActiveInstance();
}
#pragma warning restore CS0618
#pragma warning restore CS0618
}

#endregion MonoBehaviour Implementation
Expand Down Expand Up @@ -370,8 +370,7 @@ protected void UpdateTransformToGoal()
{
if (smoothing)
{
Vector3 pos = transform.position;
Quaternion rot = transform.rotation;
transform.GetPositionAndRotation(out Vector3 pos, out Quaternion rot);
Vector3 scale = transform.localScale;

pos = SmoothTo(pos, GoalPosition, SolverHandler.DeltaTime, moveLerpTime);
Expand Down
Loading