1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033 |
-
- using System;
- using System.Collections;
- using UnityEngine;
- using UnityEngine.Events;
- using Valve.VR;
- namespace Valve.VR
- {
- public class SteamVR_Behaviour_Skeleton : MonoBehaviour
- {
- [Tooltip("If not set, will try to auto assign this based on 'Skeleton' + inputSource")]
-
- public SteamVR_Action_Skeleton skeletonAction;
-
- [Tooltip("The device this action should apply to. Any if the action is not device specific.")]
- public SteamVR_Input_Sources inputSource;
-
- [Tooltip("The range of motion you'd like the hand to move in. With controller is the best estimate of the fingers wrapped around a controller. Without is from a flat hand to a fist.")]
- public EVRSkeletalMotionRange rangeOfMotion = EVRSkeletalMotionRange.WithoutController;
-
- [Tooltip("This needs to be in the order of: root -> wrist -> thumb, index, middle, ring, pinky")]
- public Transform skeletonRoot;
-
- [Tooltip("If not set, relative to parent")]
- public Transform origin;
-
- [Tooltip("Set to true if you want this script to update its position and rotation. False if this will be handled elsewhere")]
- public bool updatePose = true;
-
- [Tooltip("Check this to not set the positions of the bones. This is helpful for differently scaled skeletons.")]
- public bool onlySetRotations = false;
-
-
-
-
-
- [Range(0, 1)]
- [Tooltip("Modify this to blend between animations setup on the hand")]
- public float skeletonBlend = 1f;
-
- public SteamVR_Behaviour_SkeletonEvent onBoneTransformsUpdated;
-
- public SteamVR_Behaviour_SkeletonEvent onTransformUpdated;
-
- public SteamVR_Behaviour_SkeletonEvent onTransformChanged;
-
- public SteamVR_Behaviour_Skeleton_ConnectedChangedEvent onConnectedChanged;
-
- public SteamVR_Behaviour_Skeleton_TrackingChangedEvent onTrackingChanged;
-
- public UpdateHandler onBoneTransformsUpdatedEvent;
-
- public UpdateHandler onTransformUpdatedEvent;
-
- public ChangeHandler onTransformChangedEvent;
-
- public DeviceConnectedChangeHandler onConnectedChangedEvent;
-
- public TrackingChangeHandler onTrackingChangedEvent;
-
- [Tooltip("Is this rendermodel a mirror of another one?")]
- public MirrorType mirroring;
- [Header("No Skeleton - Fallback")]
- [Tooltip("The fallback SkeletonPoser to drive hand animation when no skeleton data is available")]
-
- public SteamVR_Skeleton_Poser fallbackPoser;
- [Tooltip("The fallback action to drive finger curl values when no skeleton data is available")]
-
- public SteamVR_Action_Single fallbackCurlAction;
-
-
-
- public bool skeletonAvailable { get { return skeletonAction.activeBinding; } }
-
- protected SteamVR_Skeleton_Poser blendPoser;
-
- protected SteamVR_Skeleton_PoseSnapshot blendSnapshot = null;
-
- public bool isActive { get { return skeletonAction.GetActive(); } }
-
- public float[] fingerCurls
- {
- get
- {
- if (skeletonAvailable)
- {
- return skeletonAction.GetFingerCurls();
- }
- else
- {
-
- float[] curls = new float[5];
- for (int i = 0; i < 5; i++)
- {
- curls[i] = fallbackCurlAction.GetAxis(inputSource);
- }
- return curls;
- }
- }
- }
-
- public float thumbCurl
- {
- get
- {
- if (skeletonAvailable)
- return skeletonAction.GetFingerCurl(SteamVR_Skeleton_FingerIndexEnum.thumb);
- else
- return fallbackCurlAction.GetAxis(inputSource);
- }
- }
-
- public float indexCurl
- {
- get
- {
- if (skeletonAvailable)
- return skeletonAction.GetFingerCurl(SteamVR_Skeleton_FingerIndexEnum.index);
- else
- return fallbackCurlAction.GetAxis(inputSource);
- }
- }
-
- public float middleCurl
- {
- get
- {
- if (skeletonAvailable)
- return skeletonAction.GetFingerCurl(SteamVR_Skeleton_FingerIndexEnum.middle);
- else
- return fallbackCurlAction.GetAxis(inputSource);
- }
- }
-
- public float ringCurl
- {
- get
- {
- if (skeletonAvailable)
- return skeletonAction.GetFingerCurl(SteamVR_Skeleton_FingerIndexEnum.ring);
- else
- return fallbackCurlAction.GetAxis(inputSource);
- }
- }
-
- public float pinkyCurl
- {
- get
- {
- if (skeletonAvailable)
- return skeletonAction.GetFingerCurl(SteamVR_Skeleton_FingerIndexEnum.pinky);
- else
- return fallbackCurlAction.GetAxis(inputSource);
- }
- }
- public Transform root { get { return bones[SteamVR_Skeleton_JointIndexes.root]; } }
- public Transform wrist { get { return bones[SteamVR_Skeleton_JointIndexes.wrist]; } }
- public Transform indexMetacarpal { get { return bones[SteamVR_Skeleton_JointIndexes.indexMetacarpal]; } }
- public Transform indexProximal { get { return bones[SteamVR_Skeleton_JointIndexes.indexProximal]; } }
- public Transform indexMiddle { get { return bones[SteamVR_Skeleton_JointIndexes.indexMiddle]; } }
- public Transform indexDistal { get { return bones[SteamVR_Skeleton_JointIndexes.indexDistal]; } }
- public Transform indexTip { get { return bones[SteamVR_Skeleton_JointIndexes.indexTip]; } }
- public Transform middleMetacarpal { get { return bones[SteamVR_Skeleton_JointIndexes.middleMetacarpal]; } }
- public Transform middleProximal { get { return bones[SteamVR_Skeleton_JointIndexes.middleProximal]; } }
- public Transform middleMiddle { get { return bones[SteamVR_Skeleton_JointIndexes.middleMiddle]; } }
- public Transform middleDistal { get { return bones[SteamVR_Skeleton_JointIndexes.middleDistal]; } }
- public Transform middleTip { get { return bones[SteamVR_Skeleton_JointIndexes.middleTip]; } }
- public Transform pinkyMetacarpal { get { return bones[SteamVR_Skeleton_JointIndexes.pinkyMetacarpal]; } }
- public Transform pinkyProximal { get { return bones[SteamVR_Skeleton_JointIndexes.pinkyProximal]; } }
- public Transform pinkyMiddle { get { return bones[SteamVR_Skeleton_JointIndexes.pinkyMiddle]; } }
- public Transform pinkyDistal { get { return bones[SteamVR_Skeleton_JointIndexes.pinkyDistal]; } }
- public Transform pinkyTip { get { return bones[SteamVR_Skeleton_JointIndexes.pinkyTip]; } }
- public Transform ringMetacarpal { get { return bones[SteamVR_Skeleton_JointIndexes.ringMetacarpal]; } }
- public Transform ringProximal { get { return bones[SteamVR_Skeleton_JointIndexes.ringProximal]; } }
- public Transform ringMiddle { get { return bones[SteamVR_Skeleton_JointIndexes.ringMiddle]; } }
- public Transform ringDistal { get { return bones[SteamVR_Skeleton_JointIndexes.ringDistal]; } }
- public Transform ringTip { get { return bones[SteamVR_Skeleton_JointIndexes.ringTip]; } }
- public Transform thumbMetacarpal { get { return bones[SteamVR_Skeleton_JointIndexes.thumbMetacarpal]; } }
- public Transform thumbProximal { get { return bones[SteamVR_Skeleton_JointIndexes.thumbProximal]; } }
- public Transform thumbMiddle { get { return bones[SteamVR_Skeleton_JointIndexes.thumbMiddle]; } }
- public Transform thumbDistal { get { return bones[SteamVR_Skeleton_JointIndexes.thumbDistal]; } }
- public Transform thumbTip { get { return bones[SteamVR_Skeleton_JointIndexes.thumbTip]; } }
- public Transform thumbAux { get { return bones[SteamVR_Skeleton_JointIndexes.thumbAux]; } }
- public Transform indexAux { get { return bones[SteamVR_Skeleton_JointIndexes.indexAux]; } }
- public Transform middleAux { get { return bones[SteamVR_Skeleton_JointIndexes.middleAux]; } }
- public Transform ringAux { get { return bones[SteamVR_Skeleton_JointIndexes.ringAux]; } }
- public Transform pinkyAux { get { return bones[SteamVR_Skeleton_JointIndexes.pinkyAux]; } }
-
- public Transform[] proximals { get; protected set; }
-
- public Transform[] middles { get; protected set; }
-
- public Transform[] distals { get; protected set; }
-
- public Transform[] tips { get; protected set; }
-
- public Transform[] auxs { get; protected set; }
- protected Coroutine blendRoutine;
- protected Coroutine rangeOfMotionBlendRoutine;
- protected Coroutine attachRoutine;
- protected Transform[] bones;
-
- protected EVRSkeletalMotionRange? temporaryRangeOfMotion = null;
-
-
-
-
-
-
- public EVRSkeletalTrackingLevel skeletalTrackingLevel
- {
- get
- {
- if (skeletonAvailable)
- {
- return skeletonAction.skeletalTrackingLevel;
- }
- else
- {
- return EVRSkeletalTrackingLevel.VRSkeletalTracking_Estimated;
- }
- }
- }
-
- public bool isBlending
- {
- get
- {
- return blendRoutine != null;
- }
- }
-
- public SteamVR_ActionSet actionSet
- {
- get
- {
- return skeletonAction.actionSet;
- }
- }
- public SteamVR_ActionDirections direction
- {
- get
- {
- return skeletonAction.direction;
- }
- }
- protected virtual void Awake()
- {
- SteamVR.Initialize();
- AssignBonesArray();
- proximals = new Transform[] { thumbProximal, indexProximal, middleProximal, ringProximal, pinkyProximal };
- middles = new Transform[] { thumbMiddle, indexMiddle, middleMiddle, ringMiddle, pinkyMiddle };
- distals = new Transform[] { thumbDistal, indexDistal, middleDistal, ringDistal, pinkyDistal };
- tips = new Transform[] { thumbTip, indexTip, middleTip, ringTip, pinkyTip };
- auxs = new Transform[] { thumbAux, indexAux, middleAux, ringAux, pinkyAux };
- CheckSkeletonAction();
- }
- protected virtual void CheckSkeletonAction()
- {
- if (skeletonAction == null)
- skeletonAction = SteamVR_Input.GetAction<SteamVR_Action_Skeleton>("Skeleton" + inputSource.ToString());
- }
- protected virtual void AssignBonesArray()
- {
- bones = skeletonRoot.GetComponentsInChildren<Transform>();
- }
- protected virtual void OnEnable()
- {
- CheckSkeletonAction();
- SteamVR_Input.onSkeletonsUpdated += SteamVR_Input_OnSkeletonsUpdated;
- if (skeletonAction != null)
- {
- skeletonAction.onDeviceConnectedChanged += OnDeviceConnectedChanged;
- skeletonAction.onTrackingChanged += OnTrackingChanged;
- }
- }
- protected virtual void OnDisable()
- {
- SteamVR_Input.onSkeletonsUpdated -= SteamVR_Input_OnSkeletonsUpdated;
- if (skeletonAction != null)
- {
- skeletonAction.onDeviceConnectedChanged -= OnDeviceConnectedChanged;
- skeletonAction.onTrackingChanged -= OnTrackingChanged;
- }
- }
- private void OnDeviceConnectedChanged(SteamVR_Action_Skeleton fromAction, bool deviceConnected)
- {
- if (onConnectedChanged != null)
- onConnectedChanged.Invoke(this, inputSource, deviceConnected);
- if (onConnectedChangedEvent != null)
- onConnectedChangedEvent.Invoke(this, inputSource, deviceConnected);
- }
- private void OnTrackingChanged(SteamVR_Action_Skeleton fromAction, ETrackingResult trackingState)
- {
- if (onTrackingChanged != null)
- onTrackingChanged.Invoke(this, inputSource, trackingState);
- if (onTrackingChangedEvent != null)
- onTrackingChangedEvent.Invoke(this, inputSource, trackingState);
- }
- protected virtual void SteamVR_Input_OnSkeletonsUpdated(bool skipSendingEvents)
- {
- UpdateSkeleton();
- }
- protected virtual void UpdateSkeleton()
- {
- if (skeletonAction == null)
- return;
- if (updatePose)
- UpdatePose();
- if (blendPoser != null && skeletonBlend < 1)
- {
- if (blendSnapshot == null) blendSnapshot = blendPoser.GetBlendedPose(this);
- blendSnapshot = blendPoser.GetBlendedPose(this);
- }
- if (rangeOfMotionBlendRoutine == null)
- {
- if (temporaryRangeOfMotion != null)
- skeletonAction.SetRangeOfMotion(temporaryRangeOfMotion.Value);
- else
- skeletonAction.SetRangeOfMotion(rangeOfMotion);
- UpdateSkeletonTransforms();
- }
- }
-
-
-
-
-
-
- public void SetTemporaryRangeOfMotion(EVRSkeletalMotionRange newRangeOfMotion, float blendOverSeconds = 0.1f)
- {
- if (rangeOfMotion != newRangeOfMotion || temporaryRangeOfMotion != newRangeOfMotion)
- {
- TemporaryRangeOfMotionBlend(newRangeOfMotion, blendOverSeconds);
- }
- }
-
-
-
-
-
- public void ResetTemporaryRangeOfMotion(float blendOverSeconds = 0.1f)
- {
- ResetTemporaryRangeOfMotionBlend(blendOverSeconds);
- }
-
-
-
-
-
-
-
-
- public void SetRangeOfMotion(EVRSkeletalMotionRange newRangeOfMotion, float blendOverSeconds = 0.1f)
- {
- if (rangeOfMotion != newRangeOfMotion)
- {
- RangeOfMotionBlend(newRangeOfMotion, blendOverSeconds);
- }
- }
-
-
-
-
- public void BlendToSkeleton(float overTime = 0.1f)
- {
- if (blendPoser != null)
- blendSnapshot = blendPoser.GetBlendedPose(this);
- blendPoser = null;
- BlendTo(1, overTime);
- }
-
-
-
-
-
- public void BlendToPoser(SteamVR_Skeleton_Poser poser, float overTime = 0.1f)
- {
- if (poser == null)
- return;
- blendPoser = poser;
- BlendTo(0, overTime);
- }
-
-
-
-
- public void BlendToAnimation(float overTime = 0.1f)
- {
- BlendTo(0, overTime);
- }
-
-
-
-
-
-
- public void BlendTo(float blendToAmount, float overTime)
- {
- if (blendRoutine != null)
- StopCoroutine(blendRoutine);
- if (this.gameObject.activeInHierarchy)
- blendRoutine = StartCoroutine(DoBlendRoutine(blendToAmount, overTime));
- }
- protected IEnumerator DoBlendRoutine(float blendToAmount, float overTime)
- {
- float startTime = Time.time;
- float endTime = startTime + overTime;
- float startAmount = skeletonBlend;
- while (Time.time < endTime)
- {
- yield return null;
- skeletonBlend = Mathf.Lerp(startAmount, blendToAmount, (Time.time - startTime) / overTime);
- }
- skeletonBlend = blendToAmount;
- blendRoutine = null;
- }
- protected void RangeOfMotionBlend(EVRSkeletalMotionRange newRangeOfMotion, float blendOverSeconds)
- {
- if (rangeOfMotionBlendRoutine != null)
- StopCoroutine(rangeOfMotionBlendRoutine);
- EVRSkeletalMotionRange oldRangeOfMotion = rangeOfMotion;
- rangeOfMotion = newRangeOfMotion;
- if (this.gameObject.activeInHierarchy)
- {
- rangeOfMotionBlendRoutine = StartCoroutine(DoRangeOfMotionBlend(oldRangeOfMotion, newRangeOfMotion, blendOverSeconds));
- }
- }
- protected void TemporaryRangeOfMotionBlend(EVRSkeletalMotionRange newRangeOfMotion, float blendOverSeconds)
- {
- if (rangeOfMotionBlendRoutine != null)
- StopCoroutine(rangeOfMotionBlendRoutine);
- EVRSkeletalMotionRange oldRangeOfMotion = rangeOfMotion;
- if (temporaryRangeOfMotion != null)
- oldRangeOfMotion = temporaryRangeOfMotion.Value;
- temporaryRangeOfMotion = newRangeOfMotion;
- if (this.gameObject.activeInHierarchy)
- {
- rangeOfMotionBlendRoutine = StartCoroutine(DoRangeOfMotionBlend(oldRangeOfMotion, newRangeOfMotion, blendOverSeconds));
- }
- }
- protected void ResetTemporaryRangeOfMotionBlend(float blendOverSeconds)
- {
- if (temporaryRangeOfMotion != null)
- {
- if (rangeOfMotionBlendRoutine != null)
- StopCoroutine(rangeOfMotionBlendRoutine);
- EVRSkeletalMotionRange oldRangeOfMotion = temporaryRangeOfMotion.Value;
- EVRSkeletalMotionRange newRangeOfMotion = rangeOfMotion;
- temporaryRangeOfMotion = null;
- if (this.gameObject.activeInHierarchy)
- {
- rangeOfMotionBlendRoutine = StartCoroutine(DoRangeOfMotionBlend(oldRangeOfMotion, newRangeOfMotion, blendOverSeconds));
- }
- }
- }
- 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(oldRangeOfMotion);
- skeletonAction.UpdateValueWithoutEvents();
- oldBonePositions = (Vector3[])GetBonePositions().Clone();
- oldBoneRotations = (Quaternion[])GetBoneRotations().Clone();
- skeletonAction.SetRangeOfMotion(newRangeOfMotion);
- skeletonAction.UpdateValueWithoutEvents();
- newBonePositions = GetBonePositions();
- newBoneRotations = GetBoneRotations();
- 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)
- {
- if (blendPoser != null)
- {
- SetBonePosition(boneIndex, Vector3.Lerp(blendSnapshot.bonePositions[boneIndex], blendedRangeOfMotionPosition, skeletonBlend));
- SetBoneRotation(boneIndex, Quaternion.Lerp(GetBlendPoseForBone(boneIndex, blendedRangeOfMotionRotation), 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;
- }
-
- protected virtual Quaternion GetBlendPoseForBone(int boneIndex, Quaternion skeletonRotation)
- {
- Quaternion poseRotation = blendSnapshot.boneRotations[boneIndex];
- return poseRotation;
- }
- public virtual void UpdateSkeletonTransforms()
- {
- Vector3[] bonePositions = GetBonePositions();
- Quaternion[] boneRotations = GetBoneRotations();
- if (skeletonBlend <= 0)
- {
- if (blendPoser != null)
- {
- SteamVR_Skeleton_Pose_Hand mainPose = blendPoser.skeletonMainPose.GetHand(inputSource);
- for (int boneIndex = 0; boneIndex < bones.Length; boneIndex++)
- {
- if (bones[boneIndex] == null)
- continue;
- if ((boneIndex == SteamVR_Skeleton_JointIndexes.wrist && mainPose.ignoreWristPoseData) ||
- (boneIndex == SteamVR_Skeleton_JointIndexes.root && mainPose.ignoreRootPoseData))
- {
- SetBonePosition(boneIndex, bonePositions[boneIndex]);
- SetBoneRotation(boneIndex, boneRotations[boneIndex]);
- }
- else
- {
- Quaternion poseRotation = GetBlendPoseForBone(boneIndex, boneRotations[boneIndex]);
- SetBonePosition(boneIndex, blendSnapshot.bonePositions[boneIndex]);
- SetBoneRotation(boneIndex, poseRotation);
- }
- }
- }
- else
- {
- for (int boneIndex = 0; boneIndex < bones.Length; boneIndex++)
- {
- Quaternion poseRotation = GetBlendPoseForBone(boneIndex, boneRotations[boneIndex]);
- SetBonePosition(boneIndex, blendSnapshot.bonePositions[boneIndex]);
- SetBoneRotation(boneIndex, poseRotation);
- }
- }
- }
- else if (skeletonBlend >= 1)
- {
- for (int boneIndex = 0; boneIndex < bones.Length; boneIndex++)
- {
- if (bones[boneIndex] == null)
- continue;
- SetBonePosition(boneIndex, bonePositions[boneIndex]);
- SetBoneRotation(boneIndex, boneRotations[boneIndex]);
- }
- }
- else
- {
- for (int boneIndex = 0; boneIndex < bones.Length; boneIndex++)
- {
- if (bones[boneIndex] == null)
- continue;
- if (blendPoser != null)
- {
- SteamVR_Skeleton_Pose_Hand mainPose = blendPoser.skeletonMainPose.GetHand(inputSource);
- if ((boneIndex == SteamVR_Skeleton_JointIndexes.wrist && mainPose.ignoreWristPoseData) ||
- (boneIndex == SteamVR_Skeleton_JointIndexes.root && mainPose.ignoreRootPoseData))
- {
- SetBonePosition(boneIndex, bonePositions[boneIndex]);
- SetBoneRotation(boneIndex, boneRotations[boneIndex]);
- }
- else
- {
-
- SetBonePosition(boneIndex, Vector3.Lerp(blendSnapshot.bonePositions[boneIndex], bonePositions[boneIndex], skeletonBlend));
- SetBoneRotation(boneIndex, Quaternion.Lerp(blendSnapshot.boneRotations[boneIndex], boneRotations[boneIndex], skeletonBlend));
-
- }
- }
- else
- {
- if (blendSnapshot == null)
- {
- SetBonePosition(boneIndex, Vector3.Lerp(bones[boneIndex].localPosition, bonePositions[boneIndex], skeletonBlend));
- SetBoneRotation(boneIndex, Quaternion.Lerp(bones[boneIndex].localRotation, boneRotations[boneIndex], skeletonBlend));
- }
- else
- {
- SetBonePosition(boneIndex, Vector3.Lerp(blendSnapshot.bonePositions[boneIndex], bonePositions[boneIndex], skeletonBlend));
- SetBoneRotation(boneIndex, Quaternion.Lerp(blendSnapshot.boneRotations[boneIndex], boneRotations[boneIndex], skeletonBlend));
- }
- }
- }
- }
- if (onBoneTransformsUpdated != null)
- onBoneTransformsUpdated.Invoke(this, inputSource);
- if (onBoneTransformsUpdatedEvent != null)
- onBoneTransformsUpdatedEvent.Invoke(this, inputSource);
- }
- public virtual void SetBonePosition(int boneIndex, Vector3 localPosition)
- {
- if (onlySetRotations == false)
- bones[boneIndex].localPosition = localPosition;
- }
- public virtual void SetBoneRotation(int boneIndex, Quaternion localRotation)
- {
- bones[boneIndex].localRotation = localRotation;
- }
-
-
-
-
- public virtual Transform GetBone(int joint)
- {
- if (bones == null || bones.Length == 0)
- Awake();
- return bones[joint];
- }
-
-
-
-
-
- public Vector3 GetBonePosition(int joint, bool local = false)
- {
- if (local)
- return bones[joint].localPosition;
- else
- return bones[joint].position;
- }
-
-
-
-
-
- public Quaternion GetBoneRotation(int joint, bool local = false)
- {
- if (local)
- return bones[joint].localRotation;
- else
- return bones[joint].rotation;
- }
- protected Vector3[] GetBonePositions()
- {
- if (skeletonAvailable)
- {
- Vector3[] rawSkeleton = skeletonAction.GetBonePositions();
- if (mirroring == MirrorType.LeftToRight || mirroring == MirrorType.RightToLeft)
- {
- for (int boneIndex = 0; boneIndex < rawSkeleton.Length; boneIndex++)
- {
- rawSkeleton[boneIndex] = MirrorPosition(boneIndex, rawSkeleton[boneIndex]);
- }
- }
- return rawSkeleton;
- }
- else
- {
-
- if (fallbackPoser != null)
- {
- return fallbackPoser.GetBlendedPose(skeletonAction, inputSource).bonePositions;
- }
- else
- {
- Debug.LogError("Skeleton Action is not bound, and you have not provided a fallback SkeletonPoser. Please create one to drive hand animation when no skeleton data is available.", this);
- return null;
- }
- }
- }
- protected static readonly Quaternion rightFlipAngle = Quaternion.AngleAxis(180, Vector3.right);
- protected Quaternion[] GetBoneRotations()
- {
- if (skeletonAvailable)
- {
- Quaternion[] rawSkeleton = skeletonAction.GetBoneRotations();
- if (mirroring == MirrorType.LeftToRight || mirroring == MirrorType.RightToLeft)
- {
- for (int boneIndex = 0; boneIndex < rawSkeleton.Length; boneIndex++)
- {
- rawSkeleton[boneIndex] = MirrorRotation(boneIndex, rawSkeleton[boneIndex]);
- }
- }
- return rawSkeleton;
- }
- else
- {
-
- if (fallbackPoser != null)
- {
- return fallbackPoser.GetBlendedPose(skeletonAction, inputSource).boneRotations;
- }
- else
- {
- Debug.LogError("Skeleton Action is not bound, and you have not provided a fallback SkeletonPoser. Please create one to drive hand animation when no skeleton data is available.", this);
- return null;
- }
- }
- }
- public static Vector3 MirrorPosition(int boneIndex, Vector3 rawPosition)
- {
- if (boneIndex == SteamVR_Skeleton_JointIndexes.wrist || IsMetacarpal(boneIndex))
- {
- rawPosition.Scale(new Vector3(-1, 1, 1));
- }
- else if (boneIndex != SteamVR_Skeleton_JointIndexes.root)
- {
- rawPosition = rawPosition * -1;
- }
- return rawPosition;
- }
- public static Quaternion MirrorRotation(int boneIndex, Quaternion rawRotation)
- {
- if (boneIndex == SteamVR_Skeleton_JointIndexes.wrist)
- {
- rawRotation.y = rawRotation.y * -1;
- rawRotation.z = rawRotation.z * -1;
- }
- if (IsMetacarpal(boneIndex))
- {
- rawRotation = rightFlipAngle * rawRotation;
- }
- return rawRotation;
- }
- protected virtual void UpdatePose()
- {
- if (skeletonAction == null)
- return;
- Vector3 skeletonPosition = skeletonAction.GetLocalPosition();
- Quaternion skeletonRotation = skeletonAction.GetLocalRotation();
- if (origin == null)
- {
- if (this.transform.parent != null)
- {
- skeletonPosition = this.transform.parent.TransformPoint(skeletonPosition);
- skeletonRotation = this.transform.parent.rotation * skeletonRotation;
- }
- }
- else
- {
- skeletonPosition = origin.TransformPoint(skeletonPosition);
- skeletonRotation = origin.rotation * skeletonRotation;
- }
- if (skeletonAction.poseChanged)
- {
- if (onTransformChanged != null)
- onTransformChanged.Invoke(this, inputSource);
- if (onTransformChangedEvent != null)
- onTransformChangedEvent.Invoke(this, inputSource);
- }
- this.transform.position = skeletonPosition;
- this.transform.rotation = skeletonRotation;
- if (onTransformUpdated != null)
- onTransformUpdated.Invoke(this, inputSource);
- }
-
-
-
-
- public void ForceToReferencePose(EVRSkeletalReferencePose referencePose)
- {
- bool temporarySession = false;
- if (Application.isEditor && Application.isPlaying == false)
- {
- temporarySession = SteamVR.InitializeTemporarySession(true);
- Awake();
- #if UNITY_EDITOR
-
- string title = "SteamVR";
- string text = "Getting reference pose...";
- float msToWait = 3000;
- float increment = 100;
- for (float timer = 0; timer < msToWait; timer += increment)
- {
- bool cancel = UnityEditor.EditorUtility.DisplayCancelableProgressBar(title, text, timer / msToWait);
- if (cancel)
- {
- UnityEditor.EditorUtility.ClearProgressBar();
- if (temporarySession)
- SteamVR.ExitTemporarySession();
- return;
- }
- System.Threading.Thread.Sleep((int)increment);
- }
- UnityEditor.EditorUtility.ClearProgressBar();
- #endif
- skeletonAction.actionSet.Activate();
- SteamVR_ActionSet_Manager.UpdateActionStates(true);
- skeletonAction.UpdateValueWithoutEvents();
- }
- if (skeletonAction.active == false)
- {
- Debug.LogError("<b>[SteamVR Input]</b> Please turn on your " + inputSource.ToString() + " controller and ensure SteamVR is open.", this);
- return;
- }
- SteamVR_Utils.RigidTransform[] transforms = skeletonAction.GetReferenceTransforms(EVRSkeletalTransformSpace.Parent, referencePose);
- if (transforms == null || transforms.Length == 0)
- {
- Debug.LogError("<b>[SteamVR Input]</b> Unable to get the reference transform for " + inputSource.ToString() + ". Please make sure SteamVR is open and both controllers are connected.", this);
- }
- if (mirroring == MirrorType.LeftToRight || mirroring == MirrorType.RightToLeft)
- {
- for (int boneIndex = 0; boneIndex < transforms.Length; boneIndex++)
- {
- bones[boneIndex].localPosition = MirrorPosition(boneIndex, transforms[boneIndex].pos);
- bones[boneIndex].localRotation = MirrorRotation(boneIndex, transforms[boneIndex].rot);
- }
- }
- else
- {
- for (int boneIndex = 0; boneIndex < transforms.Length; boneIndex++)
- {
- bones[boneIndex].localPosition = transforms[boneIndex].pos;
- bones[boneIndex].localRotation = transforms[boneIndex].rot;
- }
- }
- if (temporarySession)
- SteamVR.ExitTemporarySession();
- }
- protected static bool IsMetacarpal(int boneIndex)
- {
- return (boneIndex == SteamVR_Skeleton_JointIndexes.indexMetacarpal ||
- boneIndex == SteamVR_Skeleton_JointIndexes.middleMetacarpal ||
- boneIndex == SteamVR_Skeleton_JointIndexes.ringMetacarpal ||
- boneIndex == SteamVR_Skeleton_JointIndexes.pinkyMetacarpal ||
- boneIndex == SteamVR_Skeleton_JointIndexes.thumbMetacarpal);
- }
- public enum MirrorType
- {
- None,
- LeftToRight,
- RightToLeft
- }
- public delegate void ActiveChangeHandler(SteamVR_Behaviour_Skeleton fromAction, SteamVR_Input_Sources inputSource, bool active);
- public delegate void ChangeHandler(SteamVR_Behaviour_Skeleton fromAction, SteamVR_Input_Sources inputSource);
- public delegate void UpdateHandler(SteamVR_Behaviour_Skeleton fromAction, SteamVR_Input_Sources inputSource);
- public delegate void TrackingChangeHandler(SteamVR_Behaviour_Skeleton fromAction, SteamVR_Input_Sources inputSource, ETrackingResult trackingState);
- public delegate void ValidPoseChangeHandler(SteamVR_Behaviour_Skeleton fromAction, SteamVR_Input_Sources inputSource, bool validPose);
- public delegate void DeviceConnectedChangeHandler(SteamVR_Behaviour_Skeleton fromAction, SteamVR_Input_Sources inputSource, bool deviceConnected);
- }
- }
|