AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
Solver.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 
5 using UnityEngine;
6 
7 namespace HoloToolkit.Unity
8 {
14  [RequireComponent(typeof(SolverHandler))]
15  public abstract class Solver : MonoBehaviour
16  {
17  #region public members
18  [Tooltip("If true, the position and orientation will be calculated, but not applied, for other components to use")]
19  public bool UpdateLinkedTransform = false;
20 
21  [Tooltip("Position lerp multiplier")]
22  public float MoveLerpTime = 0.1f;
23  [Tooltip("Rotation lerp multiplier")]
24  public float RotateLerpTime = 0.1f;
25  [Tooltip("Scale lerp multiplier")]
26  public float ScaleLerpTime = 0;
27 
28  [Tooltip("If true, the Solver will respect the object's original scale values")]
29  public bool MaintainScale = true;
30 
31  // Field that may be used to represent final position to be smoothly attained
32  [HideInInspector]
33  public Vector3 GoalPosition;
34  // Field that may be used to represent final rotation to be smoothly attained
35  [HideInInspector]
36  public Quaternion GoalRotation;
37  // Field that may be used to represent final scale to be smoothly attained
38  [HideInInspector]
39  public Vector3 GoalScale;
40 
41  [Tooltip("Working output is smoothed if true. Otherwise snapped")]
42  public bool Smoothing = true;
43 
44  [Tooltip("If > 0, this solver will deactivate after this much time, even if the state is still active")]
45  public float Lifetime = 0;
46  #endregion
47 
48  #region private members
50  private float lifetime;
51  #endregion
52 
53  protected virtual void Awake()
54  {
55  solverHandler = GetComponent<SolverHandler>();
56 
57  if (UpdateLinkedTransform && solverHandler == null)
58  {
59  Debug.LogError("No SolverHandler component found on " + name + " when UpdateLinkedTransform was set to true! Disabling UpdateLinkedTransform");
60  UpdateLinkedTransform = false;
61  }
62 
63  GoalScale = MaintainScale == true ? this.transform.localScale : Vector3.one;
64  }
65 
69  protected virtual void OnEnable()
70  {
71  //Ensure the Camera helper component exists
72  CameraCache.Main.gameObject.EnsureComponent<CameraMotionInfo>();
73 
74  if (solverHandler != null)
75  {
76  SnapGoalTo(solverHandler.GoalPosition, solverHandler.GoalRotation);
77  }
78 
79  lifetime = 0;
80  }
81 
82  // SolverLink will pass transform through
83  // Should be implemented in derived classes, but SolverBase can be used to flush shared transform to real transform
84  public abstract void SolverUpdate();
85 
89  public void SolverUpdateEntry()
90  {
91  lifetime += solverHandler.DeltaTime;
92  if (Lifetime > 0 && lifetime >= Lifetime)
93  {
94  enabled = false;
95  return;
96  }
97 
98  SolverUpdate();
99  }
100 
106  public virtual void SnapTo(Vector3 position, Quaternion rotation)
107  {
108  SnapGoalTo(position, rotation);
109 
110  WorkingPos = position;
111  WorkingRot = rotation;
112  }
113 
119  public virtual void SnapGoalTo(Vector3 position, Quaternion rotation)
120  {
121  GoalPosition = position;
122  GoalRotation = rotation;
123  }
124 
125  public virtual void AddOffset(Vector3 offset)
126  {
127  GoalPosition += offset;
128  }
129 
135  public Vector3 WorkingPos
136  {
137  get
138  {
139  if (UpdateLinkedTransform)
140  {
141  return solverHandler.GoalPosition;
142  }
143  else
144  {
145  return transform.position;
146  }
147  }
148 
149  set
150  {
151  if (UpdateLinkedTransform)
152  {
153  solverHandler.GoalPosition = value;
154  }
155  else
156  {
157  this.transform.position = value;
158  }
159  }
160  }
161 
165  public Quaternion WorkingRot
166  {
167  get
168  {
169  if (UpdateLinkedTransform)
170  {
171  return solverHandler.GoalRotation;
172  }
173  else
174  {
175  return transform.rotation;
176  }
177  }
178 
179  set
180  {
181  if (UpdateLinkedTransform)
182  {
183  solverHandler.GoalRotation = value;
184  }
185  else
186  {
187  this.transform.rotation = value;
188  }
189  }
190  }
191 
195  public Vector3 WorkingScale
196  {
197  get
198  {
199  if (UpdateLinkedTransform)
200  {
201  return solverHandler.GoalScale;
202  }
203  else
204  {
205  return transform.localScale;
206  }
207  }
208 
209  set
210  {
211  if (UpdateLinkedTransform)
212  {
213  solverHandler.GoalScale = value;
214  }
215  else
216  {
217  this.transform.localScale = value;
218  }
219  }
220  }
221 
230  public static Vector3 SmoothTo(Vector3 source, Vector3 goal, float deltaTime, float lerpTime)
231  {
232  return Vector3.Lerp(source, goal, lerpTime == 0 ? 1f : deltaTime / lerpTime);
233  }
234 
243  public static Quaternion SmoothTo(Quaternion source, Quaternion goal, float deltaTime, float lerpTime)
244  {
245  return Quaternion.Slerp(source, goal, lerpTime == 0 ? 1f : deltaTime / lerpTime);
246  }
247 
251  protected void UpdateTransformToGoal()
252  {
253  if (Smoothing)
254  {
255  Vector3 pos = this.transform.position;
256  Quaternion rot = this.transform.rotation;
257  Vector3 scale = this.transform.localScale;
258 
259  float dt = solverHandler.DeltaTime;
260  pos = SmoothTo(pos, GoalPosition, dt, MoveLerpTime);
261  rot = SmoothTo(rot, GoalRotation, dt, RotateLerpTime);
262  scale = SmoothTo(scale, GoalScale, dt, ScaleLerpTime);
263 
264  this.transform.position = pos;
265  this.transform.rotation = rot;
266  this.transform.localScale = scale;
267  }
268  else
269  {
270  this.transform.position = GoalPosition;
271  this.transform.rotation = GoalRotation;
272  this.transform.localScale = GoalScale;
273  }
274  }
275 
279  public void UpdateWorkingToGoal()
280  {
281  if (Smoothing)
282  {
283  float dt = solverHandler.DeltaTime;
284  WorkingPos = SmoothTo(WorkingPos, GoalPosition, dt, MoveLerpTime);
285  WorkingRot = SmoothTo(WorkingRot, GoalRotation, dt, RotateLerpTime);
286  WorkingScale = SmoothTo(WorkingScale, GoalScale, dt, ScaleLerpTime);
287  }
288  else
289  {
290  WorkingPos = GoalPosition;
291  WorkingRot = GoalRotation;
292  WorkingScale = GoalScale;
293  }
294  }
295 
300  {
301  if (Smoothing)
302  {
303  WorkingPos = SmoothTo(WorkingPos, GoalPosition, solverHandler.DeltaTime, MoveLerpTime);
304  }
305  else
306  {
307  WorkingPos = GoalPosition;
308  }
309  }
310 
315  {
316  if (Smoothing)
317  {
318  WorkingRot = SmoothTo(WorkingRot, GoalRotation, solverHandler.DeltaTime, RotateLerpTime);
319  }
320  else
321  {
322  WorkingRot = GoalRotation;
323  }
324  }
325 
330  {
331  if (Smoothing)
332  {
333  WorkingScale = SmoothTo(WorkingScale, GoalScale, solverHandler.DeltaTime, ScaleLerpTime);
334  }
335  else
336  {
337  WorkingScale = GoalScale;
338  }
339  }
340  }
341 
342 }
SolverBase is the base abstract class for all Solvers to derive from. It provides state tracking...
Definition: Solver.cs:15
static Vector3 SmoothTo(Vector3 source, Vector3 goal, float deltaTime, float lerpTime)
Lerps Vector3 source to goal, handles lerpTime of 0
Definition: Solver.cs:230
void UpdateWorkingRotToGoal()
Updates only the working rotation to goal with smoothing
Definition: Solver.cs:314
virtual void OnEnable()
Typically when a solver becomes enabled, it should update its internal state to the system...
Definition: Solver.cs:69
static Quaternion SmoothTo(Quaternion source, Quaternion goal, float deltaTime, float lerpTime)
Slerps Quaternion source to goal, handles lerpTime of 0
Definition: Solver.cs:243
SolverHandler solverHandler
Definition: Solver.cs:49
void UpdateWorkingScaleToGoal()
Updates only the working scale to goal with smoothing
Definition: Solver.cs:329
void UpdateWorkingToGoal()
Updates the Working orientation (which may be the object, or the shared orientation) to the goal...
Definition: Solver.cs:279
virtual void SnapTo(Vector3 position, Quaternion rotation)
SnapTo may be used to bypass smoothing to a certain position if the object is teleported or spawned ...
Definition: Solver.cs:106
virtual void Awake()
Definition: Solver.cs:53
The purpose of this class is to provide a cached reference to the main camera. Calling Camera...
Definition: CameraCache.cs:12
void UpdateTransformToGoal()
Updates all object orientations to the goal orientation for this solver, with smoothing accounted for...
Definition: Solver.cs:251
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
Quaternion GoalRotation
Definition: Solver.cs:36
CameraMotionInfo calculates the velocity and direction of the camera.
void SolverUpdateEntry()
Tracks lifetime of the solver, disabling it when expired, and finally runs the orientation update log...
Definition: Solver.cs:89
virtual void AddOffset(Vector3 offset)
Definition: Solver.cs:125
virtual void SnapGoalTo(Vector3 position, Quaternion rotation)
SnapGoalTo only sets the goal orientation. Not really useful.
Definition: Solver.cs:119
void UpdateWorkingPosToGoal()
Updates only the working position to goal with smoothing
Definition: Solver.cs:299