205 lines
7.5 KiB
C#
205 lines
7.5 KiB
C#
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT License.
|
|
|
|
using Microsoft.MixedReality.Toolkit.Utilities;
|
|
using UnityEngine;
|
|
|
|
namespace Microsoft.MixedReality.Toolkit.Input
|
|
{
|
|
/// <summary>
|
|
/// Utilities for accessing position, rotation of rays.
|
|
/// </summary>
|
|
public static class InputRayUtils
|
|
{
|
|
/// <summary>
|
|
/// Gets the ray representing the position and direction of the user's head.
|
|
/// </summary>
|
|
/// <returns>The ray the head gaze</returns>
|
|
public static Ray GetHeadGazeRay()
|
|
{
|
|
return new Ray(CameraCache.Main.transform.position, CameraCache.Main.transform.forward);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the ray representing the position and direction of the user's eyes.
|
|
/// </summary>
|
|
/// <param name="ray">The ray being returned</param>
|
|
/// <returns>
|
|
/// True if the ray is being returned, false otherwise.
|
|
/// </returns>
|
|
public static bool TryGetEyeGazeRay(out Ray ray)
|
|
{
|
|
ray = new Ray();
|
|
|
|
IMixedRealityEyeGazeProvider eyeGazeProvider = CoreServices.InputSystem?.EyeGazeProvider;
|
|
if ((eyeGazeProvider == null) ||
|
|
!eyeGazeProvider.IsEyeTrackingDataValid)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
ray = eyeGazeProvider.LatestEyeGaze;
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the ray associated with the user's hand.
|
|
/// </summary>
|
|
/// <param name="hand">The handedness of the hand</param>
|
|
/// <param name="ray">The ray being returned</param>
|
|
/// <returns>
|
|
/// True if the ray is being returned, false otherwise.
|
|
/// </returns>
|
|
public static bool TryGetHandRay(Handedness hand, out Ray ray)
|
|
{
|
|
ray = new Ray();
|
|
|
|
IMixedRealityController controller;
|
|
if (TryGetControllerInstance(InputSourceType.Hand, hand, out controller))
|
|
{
|
|
MixedRealityInteractionMapping mapping;
|
|
if (TryGetInteractionMapping(controller, DeviceInputType.SpatialPointer, out mapping))
|
|
{
|
|
ray.origin = mapping.PositionData;
|
|
ray.direction = MathUtilities.GetDirection(mapping.RotationData);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the ray associated with the motion controller.
|
|
/// </summary>
|
|
/// <param name="hand">The handedness of the motion controller</param>
|
|
/// <param name="ray">The ray being returned</param>
|
|
/// <returns>
|
|
/// True if the ray is being returned, false otherwise.
|
|
/// </returns>
|
|
public static bool TryGetMotionControllerRay(Handedness hand, out Ray ray)
|
|
{
|
|
ray = new Ray();
|
|
|
|
IMixedRealityController controller;
|
|
if (TryGetControllerInstance(InputSourceType.Controller, hand, out controller))
|
|
{
|
|
MixedRealityInteractionMapping mapping;
|
|
if (TryGetInteractionMapping(controller, DeviceInputType.SpatialPointer, out mapping))
|
|
{
|
|
ray.origin = mapping.PositionData;
|
|
ray.direction = MathUtilities.GetDirection(mapping.RotationData);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the first <seealso cref="IMixedRealityController"/> instance matching the specified source type and hand.
|
|
/// </summary>
|
|
/// <param name="sourceType">Type of the input source</param>
|
|
/// <param name="hand">The handedness of the controller</param>
|
|
/// <param name="controller">The <seealso cref="IMixedRealityController"/> instance being returned</param>
|
|
/// <returns>
|
|
/// True if the controller instance is being returned, false otherwise.
|
|
/// </returns>
|
|
private static bool TryGetControllerInstance(InputSourceType sourceType, Handedness hand, out IMixedRealityController controller)
|
|
{
|
|
controller = null;
|
|
|
|
System.Collections.Generic.HashSet<IMixedRealityController> controllers = CoreServices.InputSystem?.DetectedControllers;
|
|
|
|
if (controllers == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
foreach (IMixedRealityController c in controllers)
|
|
{
|
|
if ((c.InputSource?.SourceType == sourceType) &&
|
|
(c.ControllerHandedness == hand))
|
|
{
|
|
controller = c;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the <seealso cref="MixedRealityInteractionMapping"/> matching the <seealso cref="DeviceInputType"/> for
|
|
/// the specified controller.
|
|
/// </summary>
|
|
/// <param name="controller">The <seealso cref="IMixedRealityController"/> instance</param>
|
|
/// <param name="inputType">The type of device input</param>
|
|
/// <param name="mapping">The <seealso cref="MixedRealityInteractionMapping"/> being returned</param>
|
|
/// <returns>
|
|
/// True if the interaction mapping is being returned, false otherwise.
|
|
/// </returns>
|
|
private static bool TryGetInteractionMapping(IMixedRealityController controller, DeviceInputType inputType, out MixedRealityInteractionMapping mapping)
|
|
{
|
|
mapping = null;
|
|
|
|
MixedRealityInteractionMapping[] mappings = controller.Interactions;
|
|
for (int i = 0; i < mappings.Length; i++)
|
|
{
|
|
if (mappings[i].InputType == inputType)
|
|
{
|
|
mapping = mappings[i];
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the ray associated with the desired input source type
|
|
/// and hand.
|
|
/// </summary>
|
|
/// <param name="sourceType">The type of input source</param>
|
|
/// <param name="hand">The handedness of the input source</param>
|
|
/// <param name="ray">The ray being returned</param>
|
|
/// <returns>
|
|
/// True if the ray is being returned, false otherwise.
|
|
/// </returns>
|
|
public static bool TryGetRay(InputSourceType sourceType, Handedness hand, out Ray ray)
|
|
{
|
|
bool success = false;
|
|
|
|
switch (sourceType)
|
|
{
|
|
case InputSourceType.Head:
|
|
// The head does not have a handedness, so we ignore the hand parameter.
|
|
ray = GetHeadGazeRay();
|
|
success = true;
|
|
break;
|
|
|
|
case InputSourceType.Eyes:
|
|
// The eyes do not have a handedness, so we ignore the hand parameter.
|
|
success = TryGetEyeGazeRay(out ray);
|
|
break;
|
|
|
|
case InputSourceType.Hand:
|
|
success = TryGetHandRay(hand, out ray);
|
|
break;
|
|
|
|
case InputSourceType.Controller:
|
|
success = TryGetMotionControllerRay(hand, out ray);
|
|
break;
|
|
|
|
default:
|
|
Debug.Log($"It is not supported to get the ray for {sourceType} sources.");
|
|
ray = new Ray();
|
|
success = false;
|
|
break;
|
|
}
|
|
return success;
|
|
}
|
|
}
|
|
}
|