/// <summary> /// Samples the current velocity and adds it to a rolling average. /// </summary> public void OnHold(InteractionBehaviour intObj, ReadonlyList <InteractionController> controllers) { _velocityQueue.Enqueue(new VelocitySample(intObj.rigidbody.position, intObj.rigidbody.rotation, Time.fixedTime)); while (true) { VelocitySample oldestVelocity = _velocityQueue.Peek(); // Dequeue conservatively if the oldest velocity is more than 4 frames later // than the start of the window. if (oldestVelocity.time + (Time.fixedDeltaTime * 4) < Time.fixedTime - _windowLength - _windowDelay) { _velocityQueue.Dequeue(); } else { break; } } }
/** Transfers the averaged velocity to the released object. */ public override void OnThrow(Hand throwingHand) { if (_velocityQueue.Count < 2) { _obj.rigidbody.velocity = Vector3.zero; _obj.rigidbody.angularVelocity = Vector3.zero; return; } float windowEnd = Time.fixedTime - _windowDelay; float windowStart = windowEnd - _windowLength; //0 occurs before 1 //start occurs before end VelocitySample start0, start1; VelocitySample end0, end1; VelocitySample s0, s1; s0 = s1 = start0 = start1 = end0 = end1 = _velocityQueue.Dequeue(); while (_velocityQueue.Count != 0) { s0 = s1; s1 = _velocityQueue.Dequeue(); if (s0.time < windowStart && s1.time >= windowStart) { start0 = s0; start1 = s1; } if (s0.time < windowEnd && s1.time >= windowEnd) { end0 = s0; end1 = s1; //We have assigned both start and end and can break out of loop _velocityQueue.Clear(); break; } } VelocitySample start = VelocitySample.Interpolate(start0, start1, windowStart); VelocitySample end = VelocitySample.Interpolate(end0, end1, windowEnd); Vector3 interpolatedVelocity = PhysicsUtility.ToLinearVelocity(start.position, end.position, _windowLength); //If trying to throw the object backwards into the hand Vector3 relativeVelocity = interpolatedVelocity - throwingHand.PalmVelocity.ToVector3(); if (Vector3.Dot(relativeVelocity, throwingHand.PalmNormal.ToVector3()) < 0) { interpolatedVelocity -= Vector3.Project(relativeVelocity, throwingHand.PalmNormal.ToVector3()); } _obj.rigidbody.velocity = interpolatedVelocity; _obj.rigidbody.angularVelocity = PhysicsUtility.ToAngularVelocity(start.rotation, end.rotation, _windowLength); _obj.rigidbody.velocity *= _velocityMultiplierCurve.Evaluate(_obj.rigidbody.velocity.magnitude); }
public static VelocitySample Interpolate(VelocitySample a, VelocitySample b, float time) { float alpha = Mathf.Clamp01(Mathf.InverseLerp(a.time, b.time, time)); return(new VelocitySample(Vector3.Lerp(a.position, b.position, alpha), Quaternion.Slerp(a.rotation, b.rotation, alpha), time)); }
/// <summary> /// Transfers the averaged velocity to the released object. /// </summary> public void OnThrow(InteractionBehaviour intObj, InteractionController throwingController) { if (_velocityQueue.Count < 2) { intObj.rigidbody.velocity = Vector3.zero; intObj.rigidbody.angularVelocity = Vector3.zero; return; } float windowEnd = Time.fixedTime - _windowDelay; float windowStart = windowEnd - _windowLength; // 0 occurs before 1, // start occurs before end. VelocitySample start0, start1; VelocitySample end0, end1; VelocitySample s0, s1; s0 = s1 = start0 = start1 = end0 = end1 = _velocityQueue.Dequeue(); while (_velocityQueue.Count != 0) { s0 = s1; s1 = _velocityQueue.Dequeue(); if (s0.time < windowStart && s1.time >= windowStart) { start0 = s0; start1 = s1; } if (s0.time < windowEnd && s1.time >= windowEnd) { end0 = s0; end1 = s1; // We have assigned both start and end and can break out of the loop. _velocityQueue.Clear(); break; } } VelocitySample start = VelocitySample.Interpolate(start0, start1, windowStart); VelocitySample end = VelocitySample.Interpolate(end0, end1, windowEnd); Vector3 interpolatedVelocity = PhysicsUtility.ToLinearVelocity(start.position, end.position, _windowLength); intObj.rigidbody.velocity = interpolatedVelocity; intObj.rigidbody.angularVelocity = PhysicsUtility.ToAngularVelocity(start.rotation, end.rotation, _windowLength); intObj.rigidbody.velocity *= _velocityMultiplierCurve.Evaluate(intObj.rigidbody.velocity.magnitude); }
/** Samples the current velocity and adds it to the rolling average. */ public override void OnHold(ReadonlyList <Hand> hands) { _velocityQueue.Enqueue(new VelocitySample(_obj.warper.RigidbodyPosition, _obj.warper.RigidbodyRotation, Time.fixedTime)); while (true) { VelocitySample oldest = _velocityQueue.Peek(); //Dequeue conservatively if the oldest is more than 4 frames later than the start of the window if (oldest.time + Time.fixedDeltaTime * 4 < Time.fixedTime - _windowLength - _windowDelay) { _velocityQueue.Dequeue(); } else { break; } } }
public static VelocitySample Interpolate(VelocitySample a, VelocitySample b, float time) { float alpha = Mathf.Clamp01(Mathf.InverseLerp(a.time, b.time, time)); return new VelocitySample(Vector3.Lerp(a.position, b.position, alpha), Quaternion.Slerp(a.rotation, b.rotation, alpha), time); }