AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
SolverMomentumizer.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
7 {
11  public class SolverMomentumizer : Solver
12  {
13  [Tooltip("Friction to slow down the current velocity")]
14  public float resistance = 0.99f;
15  [Tooltip("Apply more resistance when going faster- applied resistance is resistance * (velocity ^ reisistanceVelPower)")]
16  public float resistanceVelPower = 1.5f;
17  [Tooltip("Accelerate to goal position at this rate")]
18  public float accelRate = 10f;
19  [Tooltip("Apply more acceleration if farther from target- applied acceleration is accelRate + springiness * distance")]
20  public float springiness = 0;
21 
22  [Tooltip("Instantly maintain a constant depth from the view point instead of simulating Z-velocity")]
23  public bool SnapZ = true;
24 
25  private Vector3 velocity;
26 
27  public override void SolverUpdate()
28  {
29  CalculateMomentum();
30  }
31 
32  public override void SnapTo(Vector3 position, Quaternion rotation)
33  {
34  base.SnapTo(position, rotation);
35  velocity = Vector3.zero;
36  }
37 
38  protected override void OnEnable()
39  {
40  base.OnEnable();
41 
42  velocity = Vector3.zero;
43  }
44 
45  private void CalculateMomentum()
46  {
47  // Start with SnapZ
48  if (SnapZ)
49  {
50  // Snap the current depth to the goal depth
51  var refPos = getRefPos();
52  float goalDepth = (solverHandler.GoalPosition - refPos).magnitude;
53  Vector3 currentDelta = transform.position - refPos;
54  float currentDeltaLen = currentDelta.magnitude;
55  if (!Mathf.Approximately(currentDeltaLen, 0))
56  {
57  Vector3 currentDeltaNorm = currentDelta / currentDeltaLen;
58  transform.position += currentDeltaNorm * (goalDepth - currentDeltaLen);
59  }
60  }
61 
62  // Determine and apply accel
63  Vector3 delta = solverHandler.GoalPosition - transform.position;
64  float deltaLen = delta.magnitude;
65  if (deltaLen > 0.01f)
66  {
67  Vector3 deltaNorm = delta / deltaLen;
68 
69  velocity += deltaNorm * (solverHandler.DeltaTime * (accelRate + springiness * deltaLen));
70  }
71 
72  // Resistance
73  float velMag = velocity.magnitude;
74  if (!Mathf.Approximately(velMag, 0))
75  {
76  Vector3 velNormal = velocity / velMag;
77  float powFactor = velMag > 1f ? Mathf.Pow(velMag, resistanceVelPower) : velMag;
78  velocity -= velNormal * (powFactor * resistance * solverHandler.DeltaTime);
79  }
80 
81  if (velocity.sqrMagnitude < 0.001f)
82  {
83  velocity = Vector3.zero;
84  }
85 
86  // Apply vel to the solver... no wait, the actual transform
87  transform.position += velocity * solverHandler.DeltaTime;
88  }
89 
90  private Vector3 getRefPos()
91  {
92  if (solverHandler.TransformTarget == null)
93  {
94  return Vector3.zero;
95  }
96  return solverHandler.TransformTarget.position;
97  }
98  }
99 }
SolverBase is the base abstract class for all Solvers to derive from. It provides state tracking...
Definition: Solver.cs:15
override void SnapTo(Vector3 position, Quaternion rotation)
SnapTo may be used to bypass smoothing to a certain position if the object is teleported or spawned ...
override void OnEnable()
Typically when a solver becomes enabled, it should update its internal state to the system...
Momentumizer solver applies acceleration/velocity/friction to simulate momentum for an object being m...