Skip to content

Commit 6a77ffd

Browse files
updated controller attachment and pointers.
Removed some of the core physics raycasting logic in the FocusProvider and moved it to a more accessible place for other scripts to use. Renamed a few classes for clarity.
1 parent b61eca8 commit 6a77ffd

22 files changed

+508
-1479
lines changed

Assets/MixedRealityToolkit/InputSystem/Focus/FocusProvider.cs

Lines changed: 46 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Microsoft.MixedReality.Toolkit.Internal.Utilities;
1010
using System;
1111
using System.Collections.Generic;
12+
using Microsoft.MixedReality.Toolkit.Internal.Utilities.Physics;
1213
using UnityEngine;
1314
using UnityEngine.EventSystems;
1415

@@ -530,6 +531,8 @@ private void UpdatePointers()
530531

531532
if (debugDrawPointingRays)
532533
{
534+
MixedRealityRaycaster.DebugEnabled = debugDrawPointingRays;
535+
533536
Color rayColor;
534537

535538
if ((debugDrawPointingRayColors != null) && (debugDrawPointingRayColors.Length > 0))
@@ -581,7 +584,7 @@ private void UpdatePointer(PointerData pointer)
581584
}
582585

583586
// Set the pointer's result last
584-
pointer.Pointer.Result = pointer as IPointerResult;
587+
pointer.Pointer.Result = pointer;
585588
}
586589
}
587590

@@ -591,12 +594,14 @@ private void UpdatePointer(PointerData pointer)
591594
pointer.Pointer.OnPostRaycast();
592595
}
593596

597+
#region Physics Raycasting
598+
594599
/// <summary>
595600
/// Perform a Unity physics Raycast to determine which scene objects with a collider is currently being gazed at, if any.
596601
/// </summary>
597602
/// <param name="pointer"></param>
598603
/// <param name="prioritizedLayerMasks"></param>
599-
private void RaycastPhysics(PointerData pointer, LayerMask[] prioritizedLayerMasks)
604+
private static void RaycastPhysics(PointerData pointer, LayerMask[] prioritizedLayerMasks)
600605
{
601606
bool isHit = false;
602607
int rayStepIndex = 0;
@@ -609,15 +614,34 @@ private void RaycastPhysics(PointerData pointer, LayerMask[] prioritizedLayerMas
609614
// Check raycast for each step in the pointing source
610615
for (int i = 0; i < pointer.Pointer.Rays.Length; i++)
611616
{
612-
if (RaycastPhysicsStep(pointer.Pointer.Rays[i], prioritizedLayerMasks, out physicsHit))
617+
switch (pointer.Pointer.RaycastMode)
613618
{
614-
// Set the pointer source's origin ray to this step
615-
isHit = true;
616-
rayStep = pointer.Pointer.Rays[i];
617-
rayStepIndex = i;
618-
// No need to continue once we've hit something
619-
break;
619+
case RaycastModeType.Simple:
620+
if (MixedRealityRaycaster.RaycastSimplePhysicsStep(pointer.Pointer.Rays[i], prioritizedLayerMasks, out physicsHit))
621+
{
622+
// Set the pointer source's origin ray to this step
623+
isHit = true;
624+
rayStep = pointer.Pointer.Rays[i];
625+
rayStepIndex = i;
626+
}
627+
break;
628+
case RaycastModeType.Box:
629+
Debug.LogWarning("Box Raycasting Mode not supported for pointers.");
630+
break;
631+
case RaycastModeType.Sphere:
632+
if (MixedRealityRaycaster.RaycastSpherePhysicsStep(pointer.Pointer.Rays[i], pointer.Pointer.SphereCastRadius, prioritizedLayerMasks, out physicsHit))
633+
{
634+
// Set the pointer source's origin ray to this step
635+
isHit = true;
636+
rayStep = pointer.Pointer.Rays[i];
637+
rayStepIndex = i;
638+
}
639+
break;
640+
default:
641+
throw new ArgumentOutOfRangeException();
620642
}
643+
644+
if (isHit) { break; }
621645
}
622646

623647
if (isHit)
@@ -630,62 +654,9 @@ private void RaycastPhysics(PointerData pointer, LayerMask[] prioritizedLayerMas
630654
}
631655
}
632656

633-
/// <summary>
634-
/// Raycasts each physics <see cref="RayStep"/>
635-
/// </summary>
636-
/// <param name="step"></param>
637-
/// <param name="prioritizedLayerMasks"></param>
638-
/// <param name="physicsHit"></param>
639-
/// <returns></returns>
640-
private bool RaycastPhysicsStep(RayStep step, LayerMask[] prioritizedLayerMasks, out RaycastHit physicsHit)
641-
{
642-
return prioritizedLayerMasks.Length == 1
643-
// If there is only one priority, don't prioritize
644-
? Physics.Raycast(step.Origin, step.Direction, out physicsHit, step.Length, prioritizedLayerMasks[0])
645-
// Raycast across all layers and prioritize
646-
: TryGetPrioritizedHit(Physics.RaycastAll(step.Origin, step.Direction, step.Length, Physics.AllLayers), prioritizedLayerMasks, out physicsHit);
647-
}
648-
649-
/// <summary>
650-
/// Tries to ge the prioritized raycast hit based on the prioritized layer masks.
651-
/// <para><remarks>Sorts all hit objects first by layerMask, then by distance.</remarks></para>
652-
/// </summary>
653-
/// <param name="hits"></param>
654-
/// <param name="priorityLayers"></param>
655-
/// <param name="raycastHit"></param>
656-
/// <returns>The minimum distance hit within the first layer that has hits</returns>
657-
private static bool TryGetPrioritizedHit(RaycastHit[] hits, LayerMask[] priorityLayers, out RaycastHit raycastHit)
658-
{
659-
raycastHit = default(RaycastHit);
660-
661-
if (hits.Length == 0)
662-
{
663-
return false;
664-
}
665-
666-
for (int layerMaskIdx = 0; layerMaskIdx < priorityLayers.Length; layerMaskIdx++)
667-
{
668-
RaycastHit? minHit = null;
669-
670-
for (int hitIdx = 0; hitIdx < hits.Length; hitIdx++)
671-
{
672-
RaycastHit hit = hits[hitIdx];
673-
if (hit.transform.gameObject.layer.IsInLayerMask(priorityLayers[layerMaskIdx]) &&
674-
(minHit == null || hit.distance < minHit.Value.distance))
675-
{
676-
minHit = hit;
677-
}
678-
}
679-
680-
if (minHit != null)
681-
{
682-
raycastHit = minHit.Value;
683-
return true;
684-
}
685-
}
657+
#endregion Physics Raycasting
686658

687-
return false;
688-
}
659+
#region uGUI Graphics Raycasting
689660

690661
/// <summary>
691662
/// Perform a Unity Graphics Raycast to determine which uGUI element is currently being gazed at, if any.
@@ -736,6 +707,15 @@ private void RaycastGraphics(PointerData pointer, LayerMask[] prioritizedLayerMa
736707
}
737708
}
738709

710+
/// <summary>
711+
/// Raycasts each graphic <see cref="RayStep"/>
712+
/// </summary>
713+
/// <param name="pointer"></param>
714+
/// <param name="step"></param>
715+
/// <param name="prioritizedLayerMasks"></param>
716+
/// <param name="overridePhysicsRaycast"></param>
717+
/// <param name="uiRaycastResult"></param>
718+
/// <returns></returns>
739719
private bool RaycastGraphicsStep(PointerData pointer, RayStep step, LayerMask[] prioritizedLayerMasks, out bool overridePhysicsRaycast, out RaycastResult uiRaycastResult)
740720
{
741721
// Move the uiRaycast camera to the current pointer's position.
@@ -790,6 +770,8 @@ private bool RaycastGraphicsStep(PointerData pointer, RayStep step, LayerMask[]
790770
return false;
791771
}
792772

773+
#endregion uGUI Graphics Raycasting
774+
793775
/// <summary>
794776
/// Raises the Focus Events to the Input Manger if needed.
795777
/// </summary>

Assets/MixedRealityToolkit/InputSystem/Gaze/GazeProvider.cs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ namespace Microsoft.MixedReality.Toolkit.InputSystem.Gaze
1818
[DisallowMultipleComponent]
1919
public class GazeProvider : MonoBehaviour, IMixedRealityGazeProvider
2020
{
21+
private const float VelocityThreshold = 0.1f;
22+
23+
private const float MovementThreshold = 0.01f;
24+
2125
[SerializeField]
2226
[Tooltip("Optional Cursor Prefab to use if you don't wish to reference a cursor in the scene.")]
2327
private GameObject cursorPrefab = null;
@@ -60,6 +64,14 @@ public class GazeProvider : MonoBehaviour, IMixedRealityGazeProvider
6064
[Tooltip("Transform that should be used to represent the gaze position and rotation. Defaults to CameraCache.Main")]
6165
private Transform gazeTransform = null;
6266

67+
[SerializeField]
68+
[Tooltip("Minimum velocity threshold")]
69+
private float idleHeadVelocityThresh = 0.5f;
70+
71+
[SerializeField]
72+
[Tooltip("Maximum velocity threshold")]
73+
private float movementHeadVelocityThresh = 2f;
74+
6375
[SerializeField]
6476
[Tooltip("True to draw a debug view of the ray.")]
6577
private bool debugDrawRay = false;
@@ -103,10 +115,18 @@ public IMixedRealityInputSource GazeInputSource
103115
/// <inheritdoc />
104116
public Vector3 GazeDirection => GazePointer.Rays[0].Direction;
105117

118+
/// <inheritdoc />
119+
public Vector3 HeadVelocity { get; private set; }
120+
121+
/// <inheritdoc />
122+
public Vector3 HeadMovementDirection { get; private set; }
123+
106124
private float lastHitDistance = 2.0f;
107125

108126
private bool delayInitialization = true;
109127

128+
private Vector3 lastHeadPosition = Vector3.zero;
129+
110130
private IMixedRealityInputSystem inputSystem = null;
111131
private IMixedRealityInputSystem InputSystem => inputSystem ?? (inputSystem = MixedRealityManager.Instance.GetManager<IMixedRealityInputSystem>());
112132

@@ -241,6 +261,44 @@ private void Update()
241261
}
242262
}
243263

264+
private void LateUpdate()
265+
{
266+
// Update head velocity.
267+
Vector3 headPosition = GazeOrigin;
268+
Vector3 headDelta = headPosition - lastHeadPosition;
269+
270+
if (headDelta.sqrMagnitude < MovementThreshold * MovementThreshold)
271+
{
272+
headDelta = Vector3.zero;
273+
}
274+
275+
if (Time.fixedDeltaTime > 0)
276+
{
277+
float velAdjustRate = 3f * Time.fixedDeltaTime;
278+
HeadVelocity = HeadVelocity * (1f - velAdjustRate) + headDelta * velAdjustRate / Time.fixedDeltaTime;
279+
280+
if (HeadVelocity.sqrMagnitude < VelocityThreshold * VelocityThreshold)
281+
{
282+
HeadVelocity = Vector3.zero;
283+
}
284+
}
285+
286+
// Update Head Movement Direction
287+
float multiplier = Mathf.Clamp01(Mathf.InverseLerp(idleHeadVelocityThresh, movementHeadVelocityThresh, HeadVelocity.magnitude));
288+
289+
Vector3 newHeadMoveDirection = Vector3.Lerp(headPosition, HeadVelocity, multiplier).normalized;
290+
lastHeadPosition = headPosition;
291+
float dirAdjustRate = Mathf.Clamp01(5f * Time.fixedDeltaTime);
292+
293+
HeadMovementDirection = Vector3.Slerp(HeadMovementDirection, newHeadMoveDirection, dirAdjustRate);
294+
295+
if (debugDrawRay)
296+
{
297+
Debug.DrawLine(lastHeadPosition, lastHeadPosition + HeadMovementDirection * 10f, Color.Lerp(Color.red, Color.green, multiplier));
298+
Debug.DrawLine(lastHeadPosition, lastHeadPosition + HeadVelocity, Color.yellow);
299+
}
300+
}
301+
244302
private void OnDisable()
245303
{
246304
GazePointer.BaseCursor?.SetVisibility(false);

0 commit comments

Comments
 (0)