private void UpdateLatestVelocitiesAndPoseValues(Pose referencePose, float delta)
        {
            (_linearVelocity, _angularVelocity) = GetLatestLinearAndAngularVelocities(
                referencePose, delta);
            _linearVelocity = _linearVelocityFilter.Step(_linearVelocity);

            var newReleaseVelocInfo = new ReleaseVelocityInformation(_linearVelocity, _angularVelocity,
                                                                     referencePose.position);

            WhenNewSampleAvailable(newReleaseVelocInfo);

            _previousReferencePosition = referencePose.position;
            _previousReferenceRotation = referencePose.rotation;
        }
        public ReleaseVelocityInformation CalculateThrowVelocity(Transform objectThrown)
        {
            Vector3 linearVelocity  = Vector3.zero,
                    angularVelocity = Vector3.zero;

            IncludeInstantVelocities(ref linearVelocity, ref angularVelocity);

            IncludeTrendVelocities(ref linearVelocity, ref angularVelocity);

            IncludeTangentialInfluence(ref linearVelocity, objectThrown.position);

            IncludeExternalVelocities(ref linearVelocity, ref angularVelocity);

            _currentThrowVelocities.Clear();
            // queue items in order from lastWritePos to earliest sample
            int numPoses = _bufferedPoses.Count;

            for (int readPos = _lastWritePos, itemsRead = 0;
                 itemsRead < numPoses; readPos--, itemsRead++)
            {
                if (readPos < 0)
                {
                    readPos = numPoses - 1;
                }
                var item = _bufferedPoses[readPos];
                ReleaseVelocityInformation newSample = new ReleaseVelocityInformation(
                    item.LinearVelocity,
                    item.AngularVelocity,
                    item.TransformPose.position,
                    false);
                _currentThrowVelocities.Add(newSample);
            }
            ReleaseVelocityInformation newVelocity = new ReleaseVelocityInformation(linearVelocity,
                                                                                    angularVelocity,
                                                                                    _previousReferencePosition.HasValue ? _previousReferencePosition.Value : Vector3.zero,
                                                                                    true);

            _currentThrowVelocities.Add(newVelocity);
            WhenThrowVelocitiesChanged(_currentThrowVelocities);

            _bufferedPoses.Clear();
            _lastWritePos = -1;

            _linearVelocityFilter.Reset();

            return(newVelocity);
        }