AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
GazeManager.cs
Go to the documentation of this file.
1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 // Licensed under the MIT License. See LICENSE in the project root for license information.
3 
4 using System;
5 using UnityEngine;
6 using UnityEngine.EventSystems;
7 
8 namespace HoloToolkit.Unity.InputModule
9 {
13  public class GazeManager : Singleton<GazeManager>, IPointingSource
14  {
15  [Obsolete("Use FocusManager.PointerSpecificFocusChangedMethod")]
16  public delegate void FocusedChangedDelegate(GameObject previousObject, GameObject newObject);
17 
21  [Obsolete("Use FocusManager.TryGetFocusDetails")]
22  public bool IsGazingAtObject { get; private set; }
23 
28  [Obsolete("Use FocusManager.PointerSpecificFocusChanged")]
29 #pragma warning disable 618
30 #pragma warning disable 67
31  public event FocusedChangedDelegate FocusedObjectChanged;
32 #pragma warning restore 67
33 #pragma warning restore 618
34 
38  [Obsolete("Use FocusManager.UnityUIPointerEvent")]
39  public PointerEventData UnityUIPointerEvent { get; private set; }
40 
44  public RaycastHit HitInfo { get; private set; }
45 
49  public GameObject HitObject { get; private set; }
50 
55  public Vector3 HitPosition { get; private set; }
56 
61  public Vector3 HitNormal { get; private set; }
62 
66  public Vector3 GazeOrigin
67  {
68  get { return Rays[0].Origin; }
69  }
70 
74  public Vector3 GazeNormal
75  {
76  get { return Rays[0].Direction; }
77  }
78 
82  [Tooltip("Maximum distance at which the gaze can collide with an object.")]
83  public float MaxGazeCollisionDistance = 10.0f;
84 
96  [Tooltip("The LayerMasks, in prioritized order, that are used to determine the HitObject when raycasting.\n\nExample Usage:\n\n// Allow the cursor to hit SR, but first prioritize any DefaultRaycastLayers (potentially behind SR)\n\nint sr = LayerMask.GetMask(\"SR\");\nint nonSR = Physics.DefaultRaycastLayers & ~sr;\nGazeManager.Instance.RaycastLayerMasks = new LayerMask[] { nonSR, sr };")]
97  public LayerMask[] RaycastLayerMasks = { Physics.DefaultRaycastLayers };
98 
103  [Tooltip("Stabilizer, if any, used to smooth out the gaze ray data.")]
104  public BaseRayStabilizer Stabilizer = null;
105 
110  [Tooltip("Transform that should be used to represent the gaze position and rotation. Defaults to CameraCache.Main")]
111  public Transform GazeTransform;
112 
113  [Tooltip("True to draw a debug view of the ray.")]
114  public bool DebugDrawRay;
115  public PointerResult Result { get; set; }
116 
117  [Obsolete("Will be removed in a later version. Use Rays instead.")]
118  public Ray Ray { get { return Rays[0]; } }
119 
120  public RayStep[] Rays { get { return rays; } }
121 
122  private RayStep[] rays = new RayStep[1] { new RayStep(Vector3.zero, Vector3.zero) };
123 
124  public float? ExtentOverride
125  {
126  get { return MaxGazeCollisionDistance; }
127  }
128 
129  public LayerMask[] PrioritizedLayerMasksOverride
130  {
131  get { return RaycastLayerMasks; }
132  }
133 
134  public bool InteractionEnabled
135  {
136  get { return true; }
137  }
138 
139  public bool FocusLocked { get; set; }
140 
141  private float lastHitDistance = 2.0f;
142 
143  protected override void Awake()
144  {
145  base.Awake();
146 
147  // Add default RaycastLayers as first layerPriority
148  if (RaycastLayerMasks == null || RaycastLayerMasks.Length == 0)
149  {
150  RaycastLayerMasks = new LayerMask[] { Physics.DefaultRaycastLayers };
151  }
152 
153  FindGazeTransform();
154  }
155 
156  private void Update()
157  {
158  if (!FindGazeTransform())
159  {
160  return;
161  }
162 
163  if (DebugDrawRay)
164  {
165  Debug.DrawRay(GazeOrigin, (HitPosition - GazeOrigin), Color.white);
166  }
167  }
168 
169  private bool FindGazeTransform()
170  {
171  if (GazeTransform != null) { return true; }
172 
173  if (CameraCache.Main != null)
174  {
175  GazeTransform = CameraCache.Main.transform;
176  return true;
177  }
178 
179  Debug.LogError("Gaze Manager was not given a GazeTransform and no main camera exists to default to.");
180  return false;
181  }
182 
186  private void UpdateGazeInfo()
187  {
188  if (GazeTransform == null)
189  {
190  Rays[0] = default(RayStep);
191  }
192  else
193  {
194  Vector3 newGazeOrigin = GazeTransform.position;
195  Vector3 newGazeNormal = GazeTransform.forward;
196 
197  // Update gaze info from stabilizer
198  if (Stabilizer != null)
199  {
200  Stabilizer.UpdateStability(newGazeOrigin, GazeTransform.rotation);
201  newGazeOrigin = Stabilizer.StablePosition;
202  newGazeNormal = Stabilizer.StableRay.direction;
203  }
204 
205  Rays[0].UpdateRayStep(newGazeOrigin, newGazeOrigin + (newGazeNormal * FocusManager.Instance.GetPointingExtent(this)));
206  }
207 
208  UpdateHitPosition();
209  }
210 
211  [Obsolete("Will be removed in a later version. Use OnPreRaycast / OnPostRaycast instead.")]
212  public void UpdatePointer()
213  {
214  }
215 
216  public virtual void OnPreRaycast()
217  {
218  UpdateGazeInfo();
219  }
220 
221  public virtual void OnPostRaycast()
222  {
223  // Nothing needed
224  }
225 
226  public bool OwnsInput(BaseEventData eventData)
227  {
228  // NOTE: This is a simple pointer and not meant to be used simultaneously with others.
229  return true;
230  }
231 
238  public void UpdateHitDetails(FocusDetails focusDetails, RaycastHit hitInfo, bool isRegisteredForFocus)
239  {
240  HitInfo = hitInfo;
241  HitObject = isRegisteredForFocus
242  ? focusDetails.Object
243  : null; // If we're not actually registered for focus, we keep HitObject as null so we don't mislead anyone.
244 
245  if (focusDetails.Object != null)
246  {
247  lastHitDistance = (focusDetails.Point - Rays[0].Origin).magnitude;
248  UpdateHitPosition();
249  HitNormal = focusDetails.Normal;
250  }
251  }
252 
253  private void UpdateHitPosition()
254  {
255  HitPosition = (Rays[0].Origin + (lastHitDistance * Rays[0].Direction));
256  }
257  }
258 }
The gaze manager manages everything related to a gaze ray that can interact with other objects...
Definition: GazeManager.cs:13
FocusDetails struct contains information about which game object has the focus currently. Also contains information about the normal of that point.
Definition: FocusDetails.cs:14
A base class for a stabilizer that takes an input position and rotation, and performs operations on t...
void UpdateHitDetails(FocusDetails focusDetails, RaycastHit hitInfo, bool isRegisteredForFocus)
Notifies this gaze manager of its new hit details.
Definition: GazeManager.cs:238
abstract Ray StableRay
A ray representing the stable position and rotation
Transform GazeTransform
Transform that should be used as the source of the gaze position and rotation. Defaults to the main c...
Definition: GazeManager.cs:111
override void Awake()
Base Awake method that sets the Singleton&#39;s unique instance. Called by Unity when initializing a Mono...
Definition: GazeManager.cs:143
The purpose of this class is to provide a cached reference to the main camera. Calling Camera...
Definition: CameraCache.cs:12
static T Instance
Returns the Singleton instance of the classes type. If no instance is found, then we search for an in...
Definition: Singleton.cs:26
static Camera Main
Returns a cached reference to the main camera and uses Camera.main if it hasn&#39;t been cached yet...
Definition: CameraCache.cs:20
virtual void UpdateStability(Vector3 position, Quaternion rotation)
Call this each frame to smooth out changes to a position and rotation, if supported.
Focus manager is the bridge that handles different types of pointing sources like gaze cursor or poin...
Definition: FocusManager.cs:16
abstract Vector3 StablePosition
The stabilized position.
Implement this interface to register your pointer as a pointing source. This could be gaze based or m...
bool OwnsInput(BaseEventData eventData)
Definition: GazeManager.cs:226
FocusedChangedDelegate FocusedObjectChanged
Dispatched when focus shifts to a new object, or focus on current object is lost. ...
Definition: GazeManager.cs:31
Singleton behaviour class, used for components that should only have one instance.
Definition: Singleton.cs:14