AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
GazeStabilizer.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 UnityEngine;
5 
6 namespace HoloToolkit.Unity.InputModule
7 {
13  {
14  [Tooltip("Number of samples that you want to iterate on.")]
15  [Range(40, 120)]
16  public int StoredStabilitySamples = 60;
17 
18  private Vector3 stablePosition;
19  public override Vector3 StablePosition
20  {
21  get { return stablePosition; }
22  }
23 
24  private Quaternion stableRotation;
25  public override Quaternion StableRotation
26  {
27  get { return stableRotation; }
28  }
29 
30  private Ray stableRay;
31  public override Ray StableRay
32  {
33  get { return stableRay; }
34  }
35 
39  private readonly VectorRollingStatistics positionRollingStats = new VectorRollingStatistics();
40 
44  private readonly VectorRollingStatistics directionRollingStats = new VectorRollingStatistics();
45 
50  private const float PositionStandardDeviationReset = 0.2f;
51 
56  private const float DirectionStandardDeviationReset = 0.1f;
57 
61  private const int MinimumSamplesRequiredToStabalize = 30;
62 
66  private const float UnstabalizedLerpFactor = 0.3f;
67 
72  private const float StabalizedLerpBoost = 10.0f;
73 
74  private void Awake()
75  {
76  directionRollingStats.Init(StoredStabilitySamples);
77  positionRollingStats.Init(StoredStabilitySamples);
78  }
79 
86  public override void UpdateStability(Vector3 gazePosition, Vector3 gazeDirection)
87  {
88  positionRollingStats.AddSample(gazePosition);
89  directionRollingStats.AddSample(gazeDirection);
90 
91  float lerpPower = UnstabalizedLerpFactor;
92  if (positionRollingStats.ActualSampleCount > MinimumSamplesRequiredToStabalize && // we have enough samples and...
93  (positionRollingStats.CurrentStandardDeviation > PositionStandardDeviationReset || // the standard deviation of positions is high or...
94  directionRollingStats.CurrentStandardDeviation > DirectionStandardDeviationReset)) // the standard deviation of directions is high
95  {
96  // We've detected that the user's gaze is no longer fixed, so stop stabilizing so that gaze is responsive.
97  //Debug.LogFormat("Reset {0} {1} {2} {3}", positionRollingStats.standardDeviation, positionRollingStats.standardDeviationsAway, directionRollignStats.standardDeviation, directionRollignStats.standardDeviationsAway);
98  positionRollingStats.Reset();
99  directionRollingStats.Reset();
100  }
101  else if (positionRollingStats.ActualSampleCount > MinimumSamplesRequiredToStabalize)
102  {
103  // We've detected that the user's gaze is fairly fixed, so start stabilizing. The more fixed the gaze the less the cursor will move.
104  lerpPower = StabalizedLerpBoost * (positionRollingStats.CurrentStandardDeviation + directionRollingStats.CurrentStandardDeviation);
105  }
106 
107  stablePosition = Vector3.Lerp(stablePosition, gazePosition, lerpPower);
108  stableRotation = Quaternion.LookRotation(Vector3.Lerp(stableRotation * Vector3.forward, gazeDirection, lerpPower));
109  stableRay = new Ray(stablePosition, stableRotation * Vector3.forward);
110  }
111  }
112 }
A base class for a stabilizer that takes an input position and rotation, and performs operations on t...
override void UpdateStability(Vector3 gazePosition, Vector3 gazeDirection)
Updates the StablePosition and StableRotation based on GazeSample values. Call this method with Rayca...
Vector Statistics used in gaze stabilization.
GazeStabilizer iterates over samples of Raycast data and helps stabilize the user's gaze for precisio...