protected IEnumerator DoRangeOfMotionBlend(EVRSkeletalMotionRange oldRangeOfMotion, EVRSkeletalMotionRange newRangeOfMotion, float overTime)
        {
            float startTime = Time.time;
            float endTime   = startTime + overTime;

            Vector3[]    oldBonePositions;
            Quaternion[] oldBoneRotations;

            Vector3[]    newBonePositions;
            Quaternion[] newBoneRotations;

            while (Time.time < endTime)
            {
                yield return(null);

                float lerp = (Time.time - startTime) / overTime;

                if (skeletonBlend > 0)
                {
                    skeletonAction.SetRangeOfMotion(inputSource, oldRangeOfMotion);
                    skeletonAction.UpdateValue(inputSource, true);
                    oldBonePositions = (Vector3[])GetBonePositions(inputSource).Clone();
                    oldBoneRotations = (Quaternion[])GetBoneRotations(inputSource).Clone();

                    skeletonAction.SetRangeOfMotion(inputSource, newRangeOfMotion);
                    skeletonAction.UpdateValue(inputSource, true);
                    newBonePositions = GetBonePositions(inputSource);
                    newBoneRotations = GetBoneRotations(inputSource);

                    for (int boneIndex = 0; boneIndex < bones.Length; boneIndex++)
                    {
                        if (bones[boneIndex] == null)
                        {
                            continue;
                        }

                        if (SteamVR_Utils.IsValid(newBoneRotations[boneIndex]) == false || SteamVR_Utils.IsValid(oldBoneRotations[boneIndex]) == false)
                        {
                            continue;
                        }

                        Vector3    blendedRangeOfMotionPosition = Vector3.Lerp(oldBonePositions[boneIndex], newBonePositions[boneIndex], lerp);
                        Quaternion blendedRangeOfMotionRotation = Quaternion.Lerp(oldBoneRotations[boneIndex], newBoneRotations[boneIndex], lerp);

                        if (skeletonBlend < 1)
                        {
                            SetBonePosition(boneIndex, Vector3.Lerp(bones[boneIndex].localPosition, blendedRangeOfMotionPosition, skeletonBlend));
                            SetBoneRotation(boneIndex, Quaternion.Lerp(bones[boneIndex].localRotation, blendedRangeOfMotionRotation, skeletonBlend));
                        }
                        else
                        {
                            SetBonePosition(boneIndex, blendedRangeOfMotionPosition);
                            SetBoneRotation(boneIndex, blendedRangeOfMotionRotation);
                        }
                    }
                }
            }


            rangeOfMotionBlendRoutine = null;
        }
        protected IEnumerator DoRangeOfMotionBlend(EVRSkeletalMotionRange oldRangeOfMotion, EVRSkeletalMotionRange newRangeOfMotion, float overTime)
        {
            float startTime = Time.time;
            float endTime   = startTime + overTime;

            while (Time.time < endTime)
            {
                yield return(null);

                float lerp = (Time.time - startTime) / overTime;

                if (skeletonBlend > 0)
                {
                    skeletonAction.SetRangeOfMotion(oldRangeOfMotion);
                    skeletonAction.UpdateValueWithoutEvents();
                    CopyBonePositions(oldROMPositionBuffer);
                    CopyBoneRotations(oldROMRotationBuffer);

                    skeletonAction.SetRangeOfMotion(newRangeOfMotion);
                    skeletonAction.UpdateValueWithoutEvents();
                    CopyBonePositions(newROMPositionBuffer);
                    CopyBoneRotations(newROMRotationBuffer);

                    for (int boneIndex = 0; boneIndex < bones.Length; boneIndex++)
                    {
                        if (bones[boneIndex] == null)
                        {
                            continue;
                        }

                        if (SteamVR_Utils.IsValid(newROMRotationBuffer[boneIndex]) == false || SteamVR_Utils.IsValid(oldROMRotationBuffer[boneIndex]) == false)
                        {
                            continue;
                        }

                        Vector3    blendedRangeOfMotionPosition = Vector3.Lerp(oldROMPositionBuffer[boneIndex], newROMPositionBuffer[boneIndex], lerp);
                        Quaternion blendedRangeOfMotionRotation = Quaternion.Lerp(oldROMRotationBuffer[boneIndex], newROMRotationBuffer[boneIndex], lerp);

                        if (skeletonBlend < 1)
                        {
                            if (blendPoser != null)
                            {
                                SetBonePosition(boneIndex, Vector3.Lerp(blendSnapshot.bonePositions[boneIndex], blendedRangeOfMotionPosition, skeletonBlend));
                                SetBoneRotation(boneIndex, Quaternion.Lerp(blendSnapshot.boneRotations[boneIndex], blendedRangeOfMotionRotation, skeletonBlend));
                            }
                            else
                            {
                                SetBonePosition(boneIndex, Vector3.Lerp(bones[boneIndex].localPosition, blendedRangeOfMotionPosition, skeletonBlend));
                                SetBoneRotation(boneIndex, Quaternion.Lerp(bones[boneIndex].localRotation, blendedRangeOfMotionRotation, skeletonBlend));
                            }
                        }
                        else
                        {
                            SetBonePosition(boneIndex, blendedRangeOfMotionPosition);
                            SetBoneRotation(boneIndex, blendedRangeOfMotionRotation);
                        }
                    }
                }

                if (onBoneTransformsUpdated != null)
                {
                    onBoneTransformsUpdated.Invoke(this, inputSource);
                }
                if (onBoneTransformsUpdatedEvent != null)
                {
                    onBoneTransformsUpdatedEvent.Invoke(this, inputSource);
                }
            }

            rangeOfMotionBlendRoutine = null;
        }