/** 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);
        }
        /// <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);
        }