8 using System.Collections;
10 namespace Valve.VR.InteractionSystem
15 [Tooltip(
"How many frames to average over for computing velocity" )]
16 public int velocityAverageFrames = 5;
17 [Tooltip(
"How many frames to average over for computing angular velocity" )]
18 public int angularVelocityAverageFrames = 11;
20 public bool estimateOnAwake =
false;
22 private Coroutine routine;
23 private int sampleCount;
24 private Vector3[] velocitySamples;
25 private Vector3[] angularVelocitySamples;
29 public void BeginEstimatingVelocity()
31 FinishEstimatingVelocity();
33 routine = StartCoroutine( EstimateVelocityCoroutine() );
38 public void FinishEstimatingVelocity()
40 if ( routine != null )
42 StopCoroutine( routine );
49 public Vector3 GetVelocityEstimate()
52 Vector3 velocity = Vector3.zero;
53 int velocitySampleCount = Mathf.Min( sampleCount, velocitySamples.Length );
54 if ( velocitySampleCount != 0 )
56 for (
int i = 0; i < velocitySampleCount; i++ )
58 velocity += velocitySamples[i];
60 velocity *= ( 1.0f / velocitySampleCount );
68 public Vector3 GetAngularVelocityEstimate()
71 Vector3 angularVelocity = Vector3.zero;
72 int angularVelocitySampleCount = Mathf.Min( sampleCount, angularVelocitySamples.Length );
73 if ( angularVelocitySampleCount != 0 )
75 for (
int i = 0; i < angularVelocitySampleCount; i++ )
77 angularVelocity += angularVelocitySamples[i];
79 angularVelocity *= ( 1.0f / angularVelocitySampleCount );
82 return angularVelocity;
87 public Vector3 GetAccelerationEstimate()
89 Vector3 average = Vector3.zero;
90 for (
int i = 2 + sampleCount - velocitySamples.Length; i < sampleCount; i++ )
98 Vector3 v1 = velocitySamples[first % velocitySamples.Length];
99 Vector3 v2 = velocitySamples[second % velocitySamples.Length];
102 average *= ( 1.0f / Time.deltaTime );
110 velocitySamples =
new Vector3[velocityAverageFrames];
111 angularVelocitySamples =
new Vector3[angularVelocityAverageFrames];
113 if ( estimateOnAwake )
115 BeginEstimatingVelocity();
121 private IEnumerator EstimateVelocityCoroutine()
125 Vector3 previousPosition = transform.position;
126 Quaternion previousRotation = transform.rotation;
129 yield
return new WaitForEndOfFrame();
131 float velocityFactor = 1.0f / Time.deltaTime;
133 int v = sampleCount % velocitySamples.Length;
134 int w = sampleCount % angularVelocitySamples.Length;
138 velocitySamples[v] = velocityFactor * ( transform.position - previousPosition );
141 Quaternion deltaRotation = transform.rotation * Quaternion.Inverse( previousRotation );
143 float theta = 2.0f * Mathf.Acos( Mathf.Clamp( deltaRotation.w, -1.0f, 1.0f ) );
144 if ( theta > Mathf.PI )
146 theta -= 2.0f * Mathf.PI;
149 Vector3 angularVelocity =
new Vector3( deltaRotation.x, deltaRotation.y, deltaRotation.z );
150 if ( angularVelocity.sqrMagnitude > 0.0f )
152 angularVelocity = theta * velocityFactor * angularVelocity.normalized;
155 angularVelocitySamples[w] = angularVelocity;
157 previousPosition = transform.position;
158 previousRotation = transform.rotation;