You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			565 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C#
		
	
			
		
		
	
	
			565 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C#
		
	
//======= Copyright (c) Valve Corporation, All rights reserved. ===============
 | 
						|
 | 
						|
using System;
 | 
						|
using System.Collections;
 | 
						|
using UnityEngine;
 | 
						|
using Valve.VR;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.Linq;
 | 
						|
 | 
						|
namespace Valve.VR
 | 
						|
{
 | 
						|
    public class SteamVR_Skeleton_Poser : MonoBehaviour
 | 
						|
    {
 | 
						|
        #region Editor Storage
 | 
						|
        public bool poseEditorExpanded = true;
 | 
						|
        public bool blendEditorExpanded = true;
 | 
						|
        public string[] poseNames;
 | 
						|
        #endregion
 | 
						|
 | 
						|
        public GameObject overridePreviewLeftHandPrefab;
 | 
						|
        public GameObject overridePreviewRightHandPrefab;
 | 
						|
 | 
						|
        public SteamVR_Skeleton_Pose skeletonMainPose;
 | 
						|
        public List<SteamVR_Skeleton_Pose> skeletonAdditionalPoses = new List<SteamVR_Skeleton_Pose>();
 | 
						|
 | 
						|
        [SerializeField]
 | 
						|
        protected bool showLeftPreview = false;
 | 
						|
 | 
						|
        [SerializeField]
 | 
						|
        protected bool showRightPreview = true; //show the right hand by default
 | 
						|
 | 
						|
        [SerializeField]
 | 
						|
        protected GameObject previewLeftInstance;
 | 
						|
 | 
						|
        [SerializeField]
 | 
						|
        protected GameObject previewRightInstance;
 | 
						|
 | 
						|
        [SerializeField]
 | 
						|
        protected int previewPoseSelection = 0;
 | 
						|
 | 
						|
        public int blendPoseCount { get { return blendPoses.Length; } }
 | 
						|
 | 
						|
        public List<PoseBlendingBehaviour> blendingBehaviours = new List<PoseBlendingBehaviour>();
 | 
						|
 | 
						|
        public SteamVR_Skeleton_PoseSnapshot blendedSnapshotL;
 | 
						|
        public SteamVR_Skeleton_PoseSnapshot blendedSnapshotR;
 | 
						|
 | 
						|
        private SkeletonBlendablePose[] blendPoses;
 | 
						|
 | 
						|
        private int boneCount;
 | 
						|
 | 
						|
        private bool poseUpdatedThisFrame;
 | 
						|
 | 
						|
        public float scale;
 | 
						|
 | 
						|
 | 
						|
        protected void Awake()
 | 
						|
        {
 | 
						|
            if (previewLeftInstance != null)
 | 
						|
                DestroyImmediate(previewLeftInstance);
 | 
						|
            if (previewRightInstance != null)
 | 
						|
                DestroyImmediate(previewRightInstance);
 | 
						|
 | 
						|
            blendPoses = new SkeletonBlendablePose[skeletonAdditionalPoses.Count + 1];
 | 
						|
            for (int i = 0; i < blendPoseCount; i++)
 | 
						|
            {
 | 
						|
                blendPoses[i] = new SkeletonBlendablePose(GetPoseByIndex(i));
 | 
						|
                blendPoses[i].PoseToSnapshots();
 | 
						|
            }
 | 
						|
 | 
						|
            boneCount = skeletonMainPose.leftHand.bonePositions.Length;
 | 
						|
            // NOTE: Is there a better way to get the bone count? idk
 | 
						|
            blendedSnapshotL = new SteamVR_Skeleton_PoseSnapshot(boneCount, SteamVR_Input_Sources.LeftHand);
 | 
						|
            blendedSnapshotR = new SteamVR_Skeleton_PoseSnapshot(boneCount, SteamVR_Input_Sources.RightHand);
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Set the blending value of a blendingBehaviour. Works best on Manual type behaviours.
 | 
						|
        /// </summary>
 | 
						|
        public void SetBlendingBehaviourValue(string behaviourName, float value)
 | 
						|
        {
 | 
						|
            PoseBlendingBehaviour behaviour = FindBlendingBehaviour(behaviourName);
 | 
						|
            if (behaviour != null)
 | 
						|
            {
 | 
						|
                behaviour.value = value;
 | 
						|
 | 
						|
                if (behaviour.type != PoseBlendingBehaviour.BlenderTypes.Manual)
 | 
						|
                {
 | 
						|
                    Debug.LogWarning("[SteamVR] Blending Behaviour: " + behaviourName + " is not a manual behaviour. Its value will likely be overriden.", this);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        /// <summary>
 | 
						|
        /// Get the blending value of a blendingBehaviour.
 | 
						|
        /// </summary>
 | 
						|
        public float GetBlendingBehaviourValue(string behaviourName)
 | 
						|
        {
 | 
						|
            PoseBlendingBehaviour behaviour = FindBlendingBehaviour(behaviourName);
 | 
						|
            if (behaviour != null)
 | 
						|
            {
 | 
						|
                return behaviour.value;
 | 
						|
            }
 | 
						|
            return 0;
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Enable or disable a blending behaviour.
 | 
						|
        /// </summary>
 | 
						|
        public void SetBlendingBehaviourEnabled(string behaviourName, bool value)
 | 
						|
        {
 | 
						|
            PoseBlendingBehaviour behaviour = FindBlendingBehaviour(behaviourName);
 | 
						|
            if (behaviour != null)
 | 
						|
            {
 | 
						|
                behaviour.enabled = value;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        /// <summary>
 | 
						|
        /// Check if a blending behaviour is enabled.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="behaviourName"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        public bool GetBlendingBehaviourEnabled(string behaviourName)
 | 
						|
        {
 | 
						|
            PoseBlendingBehaviour behaviour = FindBlendingBehaviour(behaviourName);
 | 
						|
            if (behaviour != null)
 | 
						|
            {
 | 
						|
                return behaviour.enabled;
 | 
						|
            }
 | 
						|
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
        /// <summary>
 | 
						|
        /// Get a blending behaviour by name.
 | 
						|
        /// </summary>
 | 
						|
        public PoseBlendingBehaviour GetBlendingBehaviour(string behaviourName)
 | 
						|
        {
 | 
						|
            return FindBlendingBehaviour(behaviourName);
 | 
						|
        }
 | 
						|
 | 
						|
        protected PoseBlendingBehaviour FindBlendingBehaviour(string behaviourName, bool throwErrors = true)
 | 
						|
        {
 | 
						|
            PoseBlendingBehaviour behaviour = blendingBehaviours.Find(b => b.name == behaviourName);
 | 
						|
 | 
						|
            if (behaviour == null)
 | 
						|
            {
 | 
						|
                if (throwErrors)
 | 
						|
                    Debug.LogError("[SteamVR] Blending Behaviour: " + behaviourName + " not found on Skeleton Poser: " + gameObject.name, this);
 | 
						|
 | 
						|
                return null;
 | 
						|
            }
 | 
						|
 | 
						|
            return behaviour;
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        public SteamVR_Skeleton_Pose GetPoseByIndex(int index)
 | 
						|
        {
 | 
						|
            if (index == 0) { return skeletonMainPose; }
 | 
						|
            else { return skeletonAdditionalPoses[index - 1]; }
 | 
						|
        }
 | 
						|
 | 
						|
        private SteamVR_Skeleton_PoseSnapshot GetHandSnapshot(SteamVR_Input_Sources inputSource)
 | 
						|
        {
 | 
						|
            if (inputSource == SteamVR_Input_Sources.LeftHand)
 | 
						|
                return blendedSnapshotL;
 | 
						|
            else
 | 
						|
                return blendedSnapshotR;
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Retrieve the final animated pose, to be applied to a hand skeleton
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="forAction">The skeleton action you want to blend between</param>
 | 
						|
        /// <param name="handType">If this is for the left or right hand</param>
 | 
						|
        public SteamVR_Skeleton_PoseSnapshot GetBlendedPose(SteamVR_Action_Skeleton skeletonAction, SteamVR_Input_Sources handType)
 | 
						|
        {
 | 
						|
            UpdatePose(skeletonAction, handType);
 | 
						|
            return GetHandSnapshot(handType);
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Retrieve the final animated pose, to be applied to a hand skeleton
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="skeletonBehaviour">The skeleton behaviour you want to get the action/input source from to blend between</param>
 | 
						|
        public SteamVR_Skeleton_PoseSnapshot GetBlendedPose(SteamVR_Behaviour_Skeleton skeletonBehaviour)
 | 
						|
        {
 | 
						|
            return GetBlendedPose(skeletonBehaviour.skeletonAction, skeletonBehaviour.inputSource);
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Updates all pose animation and blending. Can be called from different places without performance concerns, as it will only let itself run once per frame.
 | 
						|
        /// </summary>
 | 
						|
        public void UpdatePose(SteamVR_Action_Skeleton skeletonAction, SteamVR_Input_Sources inputSource)
 | 
						|
        {
 | 
						|
            // only allow this function to run once per frame
 | 
						|
            if (poseUpdatedThisFrame) return;
 | 
						|
 | 
						|
            poseUpdatedThisFrame = true;
 | 
						|
 | 
						|
            if (skeletonAction.activeBinding)
 | 
						|
            {
 | 
						|
                // always do additive animation on main pose
 | 
						|
                blendPoses[0].UpdateAdditiveAnimation(skeletonAction, inputSource);
 | 
						|
            }
 | 
						|
 | 
						|
            //copy from main pose as a base
 | 
						|
            SteamVR_Skeleton_PoseSnapshot snap = GetHandSnapshot(inputSource);
 | 
						|
            snap.CopyFrom(blendPoses[0].GetHandSnapshot(inputSource));
 | 
						|
 | 
						|
            ApplyBlenderBehaviours(skeletonAction, inputSource, snap);
 | 
						|
 | 
						|
 | 
						|
            if (inputSource == SteamVR_Input_Sources.RightHand)
 | 
						|
                blendedSnapshotR = snap;
 | 
						|
            if (inputSource == SteamVR_Input_Sources.LeftHand)
 | 
						|
                blendedSnapshotL = snap;
 | 
						|
        }
 | 
						|
 | 
						|
        protected void ApplyBlenderBehaviours(SteamVR_Action_Skeleton skeletonAction, SteamVR_Input_Sources inputSource, SteamVR_Skeleton_PoseSnapshot snapshot)
 | 
						|
        {
 | 
						|
 | 
						|
            // apply blending for each behaviour
 | 
						|
            for (int behaviourIndex = 0; behaviourIndex < blendingBehaviours.Count; behaviourIndex++)
 | 
						|
            {
 | 
						|
                blendingBehaviours[behaviourIndex].Update(Time.deltaTime, inputSource);
 | 
						|
                // if disabled or very low influence, skip for perf
 | 
						|
                if (blendingBehaviours[behaviourIndex].enabled && blendingBehaviours[behaviourIndex].influence * blendingBehaviours[behaviourIndex].value > 0.01f)
 | 
						|
                {
 | 
						|
                    if (blendingBehaviours[behaviourIndex].pose != 0 && skeletonAction.activeBinding)
 | 
						|
                    {
 | 
						|
                        // update additive animation only as needed
 | 
						|
                        blendPoses[blendingBehaviours[behaviourIndex].pose].UpdateAdditiveAnimation(skeletonAction, inputSource);
 | 
						|
                    }
 | 
						|
 | 
						|
                    blendingBehaviours[behaviourIndex].ApplyBlending(snapshot, blendPoses, inputSource);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
        }
 | 
						|
 | 
						|
        protected void LateUpdate()
 | 
						|
        {
 | 
						|
            // let the pose be updated again the next frame
 | 
						|
            poseUpdatedThisFrame = false;
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>Weighted average of n vector3s</summary>
 | 
						|
        protected Vector3 BlendVectors(Vector3[] vectors, float[] weights)
 | 
						|
        {
 | 
						|
            Vector3 blendedVector = Vector3.zero;
 | 
						|
            for (int i = 0; i < vectors.Length; i++)
 | 
						|
            {
 | 
						|
                blendedVector += vectors[i] * weights[i];
 | 
						|
            }
 | 
						|
            return blendedVector;
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>Weighted average of n quaternions</summary>
 | 
						|
        protected Quaternion BlendQuaternions(Quaternion[] quaternions, float[] weights)
 | 
						|
        {
 | 
						|
            Quaternion outquat = Quaternion.identity;
 | 
						|
            for (int i = 0; i < quaternions.Length; i++)
 | 
						|
            {
 | 
						|
                outquat *= Quaternion.Slerp(Quaternion.identity, quaternions[i], weights[i]);
 | 
						|
            }
 | 
						|
            return outquat;
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// A SkeletonBlendablePose holds a reference to a Skeleton_Pose scriptableObject, and also contains some helper functions.
 | 
						|
        /// Also handles pose-specific animation like additive finger motion.
 | 
						|
        /// </summary>
 | 
						|
        public class SkeletonBlendablePose
 | 
						|
        {
 | 
						|
            public SteamVR_Skeleton_Pose pose;
 | 
						|
            public SteamVR_Skeleton_PoseSnapshot snapshotR;
 | 
						|
            public SteamVR_Skeleton_PoseSnapshot snapshotL;
 | 
						|
 | 
						|
            /// <summary>
 | 
						|
            /// Get the snapshot of this pose with effects such as additive finger animation applied.
 | 
						|
            /// </summary>
 | 
						|
            public SteamVR_Skeleton_PoseSnapshot GetHandSnapshot(SteamVR_Input_Sources inputSource)
 | 
						|
            {
 | 
						|
                if (inputSource == SteamVR_Input_Sources.LeftHand)
 | 
						|
                {
 | 
						|
                    return snapshotL;
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    return snapshotR;
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            public void UpdateAdditiveAnimation(SteamVR_Action_Skeleton skeletonAction, SteamVR_Input_Sources inputSource)
 | 
						|
            {
 | 
						|
                if (skeletonAction.GetSkeletalTrackingLevel() == EVRSkeletalTrackingLevel.VRSkeletalTracking_Estimated)
 | 
						|
                {
 | 
						|
                    //do not apply additive animation on low fidelity controllers, eg. Vive Wands and Touch
 | 
						|
                    return;
 | 
						|
                }
 | 
						|
 | 
						|
                SteamVR_Skeleton_PoseSnapshot snapshot = GetHandSnapshot(inputSource);
 | 
						|
                SteamVR_Skeleton_Pose_Hand poseHand = pose.GetHand(inputSource);
 | 
						|
 | 
						|
                for (int boneIndex = 0; boneIndex < snapshotL.bonePositions.Length; boneIndex++)
 | 
						|
                {
 | 
						|
                    int fingerIndex = SteamVR_Skeleton_JointIndexes.GetFingerForBone(boneIndex);
 | 
						|
                    SteamVR_Skeleton_FingerExtensionTypes extensionType = poseHand.GetMovementTypeForBone(boneIndex);
 | 
						|
 | 
						|
                    if (extensionType == SteamVR_Skeleton_FingerExtensionTypes.Free)
 | 
						|
                    {
 | 
						|
                        snapshot.bonePositions[boneIndex] = skeletonAction.bonePositions[boneIndex];
 | 
						|
                        snapshot.boneRotations[boneIndex] = skeletonAction.boneRotations[boneIndex];
 | 
						|
                    }
 | 
						|
                    if (extensionType == SteamVR_Skeleton_FingerExtensionTypes.Extend)
 | 
						|
                    {
 | 
						|
                        // lerp to open pose by fingercurl
 | 
						|
                        snapshot.bonePositions[boneIndex] = Vector3.Lerp(poseHand.bonePositions[boneIndex], skeletonAction.bonePositions[boneIndex], 1 - skeletonAction.fingerCurls[fingerIndex]);
 | 
						|
                        snapshot.boneRotations[boneIndex] = Quaternion.Lerp(poseHand.boneRotations[boneIndex], skeletonAction.boneRotations[boneIndex], 1 - skeletonAction.fingerCurls[fingerIndex]);
 | 
						|
                    }
 | 
						|
                    if (extensionType == SteamVR_Skeleton_FingerExtensionTypes.Contract)
 | 
						|
                    {
 | 
						|
                        // lerp to closed pose by fingercurl
 | 
						|
                        snapshot.bonePositions[boneIndex] = Vector3.Lerp(poseHand.bonePositions[boneIndex], skeletonAction.bonePositions[boneIndex], skeletonAction.fingerCurls[fingerIndex]);
 | 
						|
                        snapshot.boneRotations[boneIndex] = Quaternion.Lerp(poseHand.boneRotations[boneIndex], skeletonAction.boneRotations[boneIndex], skeletonAction.fingerCurls[fingerIndex]);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            /// <summary>
 | 
						|
            /// Init based on an existing Skeleton_Pose
 | 
						|
            /// </summary>
 | 
						|
            public SkeletonBlendablePose(SteamVR_Skeleton_Pose p)
 | 
						|
            {
 | 
						|
                pose = p;
 | 
						|
                snapshotR = new SteamVR_Skeleton_PoseSnapshot(p.rightHand.bonePositions.Length, SteamVR_Input_Sources.RightHand);
 | 
						|
                snapshotL = new SteamVR_Skeleton_PoseSnapshot(p.leftHand.bonePositions.Length, SteamVR_Input_Sources.LeftHand);
 | 
						|
            }
 | 
						|
 | 
						|
            /// <summary>
 | 
						|
            /// Copy the base pose into the snapshots.
 | 
						|
            /// </summary>
 | 
						|
            public void PoseToSnapshots()
 | 
						|
            {
 | 
						|
                snapshotR.position = pose.rightHand.position;
 | 
						|
                snapshotR.rotation = pose.rightHand.rotation;
 | 
						|
                pose.rightHand.bonePositions.CopyTo(snapshotR.bonePositions, 0);
 | 
						|
                pose.rightHand.boneRotations.CopyTo(snapshotR.boneRotations, 0);
 | 
						|
 | 
						|
                snapshotL.position = pose.leftHand.position;
 | 
						|
                snapshotL.rotation = pose.leftHand.rotation;
 | 
						|
                pose.leftHand.bonePositions.CopyTo(snapshotL.bonePositions, 0);
 | 
						|
                pose.leftHand.boneRotations.CopyTo(snapshotL.boneRotations, 0);
 | 
						|
            }
 | 
						|
 | 
						|
            public SkeletonBlendablePose() { }
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// A filter applied to the base pose. Blends to a secondary pose by a certain weight. Can be masked per-finger
 | 
						|
        /// </summary>
 | 
						|
        [System.Serializable]
 | 
						|
        public class PoseBlendingBehaviour
 | 
						|
        {
 | 
						|
            public string name;
 | 
						|
            public bool enabled = true;
 | 
						|
            public float influence = 1;
 | 
						|
            public int pose = 1;
 | 
						|
            public float value = 0;
 | 
						|
            public SteamVR_Action_Single action_single;
 | 
						|
            public SteamVR_Action_Boolean action_bool;
 | 
						|
            public float smoothingSpeed = 0;
 | 
						|
            public BlenderTypes type;
 | 
						|
            public bool useMask;
 | 
						|
            public SteamVR_Skeleton_HandMask mask = new SteamVR_Skeleton_HandMask();
 | 
						|
 | 
						|
            public bool previewEnabled;
 | 
						|
 | 
						|
            /// <summary>
 | 
						|
            /// Performs smoothing based on deltaTime parameter.
 | 
						|
            /// </summary>
 | 
						|
            public void Update(float deltaTime, SteamVR_Input_Sources inputSource)
 | 
						|
            {
 | 
						|
                if (type == BlenderTypes.AnalogAction)
 | 
						|
                {
 | 
						|
                    if (smoothingSpeed == 0)
 | 
						|
                        value = action_single.GetAxis(inputSource);
 | 
						|
                    else
 | 
						|
                        value = Mathf.Lerp(value, action_single.GetAxis(inputSource), deltaTime * smoothingSpeed);
 | 
						|
                }
 | 
						|
                if (type == BlenderTypes.BooleanAction)
 | 
						|
                {
 | 
						|
                    if (smoothingSpeed == 0)
 | 
						|
                        value = action_bool.GetState(inputSource) ? 1 : 0;
 | 
						|
                    else
 | 
						|
                        value = Mathf.Lerp(value, action_bool.GetState(inputSource) ? 1 : 0, deltaTime * smoothingSpeed);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            /// <summary>
 | 
						|
            /// Apply blending to this behaviour's pose to an existing snapshot.
 | 
						|
            /// </summary>
 | 
						|
            /// <param name="snapshot">Snapshot to modify</param>
 | 
						|
            /// <param name="blendPoses">List of blend poses to get the target pose</param>
 | 
						|
            /// <param name="inputSource">Which hand to receive input from</param>
 | 
						|
            public void ApplyBlending(SteamVR_Skeleton_PoseSnapshot snapshot, SkeletonBlendablePose[] blendPoses, SteamVR_Input_Sources inputSource)
 | 
						|
            {
 | 
						|
                SteamVR_Skeleton_PoseSnapshot targetSnapshot = blendPoses[pose].GetHandSnapshot(inputSource);
 | 
						|
                if (mask.GetFinger(0) || useMask == false)
 | 
						|
                {
 | 
						|
                    snapshot.position = Vector3.Lerp(snapshot.position, targetSnapshot.position, influence * value);
 | 
						|
                    snapshot.rotation = Quaternion.Slerp(snapshot.rotation, targetSnapshot.rotation, influence * value);
 | 
						|
                }
 | 
						|
 | 
						|
                for (int boneIndex = 0; boneIndex < snapshot.bonePositions.Length; boneIndex++)
 | 
						|
                {
 | 
						|
                    // verify the current finger is enabled in the mask, or if no mask is used.
 | 
						|
                    if (mask.GetFinger(SteamVR_Skeleton_JointIndexes.GetFingerForBone(boneIndex) + 1) || useMask == false)
 | 
						|
                    {
 | 
						|
                        snapshot.bonePositions[boneIndex] = Vector3.Lerp(snapshot.bonePositions[boneIndex], targetSnapshot.bonePositions[boneIndex], influence * value);
 | 
						|
                        snapshot.boneRotations[boneIndex] = Quaternion.Slerp(snapshot.boneRotations[boneIndex], targetSnapshot.boneRotations[boneIndex], influence * value);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            public PoseBlendingBehaviour()
 | 
						|
            {
 | 
						|
                enabled = true;
 | 
						|
                influence = 1;
 | 
						|
            }
 | 
						|
 | 
						|
            public enum BlenderTypes
 | 
						|
            {
 | 
						|
                Manual, AnalogAction, BooleanAction
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        //this is broken
 | 
						|
        public Vector3 GetTargetHandPosition(SteamVR_Behaviour_Skeleton hand, Transform origin)
 | 
						|
        {
 | 
						|
            Vector3 oldOrigin = origin.position;
 | 
						|
            Quaternion oldHand = hand.transform.rotation;
 | 
						|
            hand.transform.rotation = GetBlendedPose(hand).rotation;
 | 
						|
            origin.position = hand.transform.TransformPoint(GetBlendedPose(hand).position);
 | 
						|
            Vector3 offset = origin.InverseTransformPoint(hand.transform.position);
 | 
						|
            origin.position = oldOrigin;
 | 
						|
            hand.transform.rotation = oldHand;
 | 
						|
            return origin.TransformPoint(offset);
 | 
						|
        }
 | 
						|
 | 
						|
        public Quaternion GetTargetHandRotation(SteamVR_Behaviour_Skeleton hand, Transform origin)
 | 
						|
        {
 | 
						|
            Quaternion oldOrigin = origin.rotation;
 | 
						|
            origin.rotation = hand.transform.rotation * GetBlendedPose(hand).rotation;
 | 
						|
            Quaternion offsetRot = Quaternion.Inverse(origin.rotation) * hand.transform.rotation;
 | 
						|
            origin.rotation = oldOrigin;
 | 
						|
            return origin.rotation * offsetRot;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /// <summary>
 | 
						|
    /// PoseSnapshots hold a skeleton pose for one hand, as well as storing which hand they contain.
 | 
						|
    /// They have several functions for combining BlendablePoses.
 | 
						|
    /// </summary>
 | 
						|
    public class SteamVR_Skeleton_PoseSnapshot
 | 
						|
    {
 | 
						|
        public SteamVR_Input_Sources inputSource;
 | 
						|
 | 
						|
        public Vector3 position;
 | 
						|
        public Quaternion rotation;
 | 
						|
 | 
						|
        public Vector3[] bonePositions;
 | 
						|
        public Quaternion[] boneRotations;
 | 
						|
 | 
						|
        public SteamVR_Skeleton_PoseSnapshot(int boneCount, SteamVR_Input_Sources source)
 | 
						|
        {
 | 
						|
            inputSource = source;
 | 
						|
            bonePositions = new Vector3[boneCount];
 | 
						|
            boneRotations = new Quaternion[boneCount];
 | 
						|
            position = Vector3.zero;
 | 
						|
            rotation = Quaternion.identity;
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Perform a deep copy from one poseSnapshot to another.
 | 
						|
        /// </summary>
 | 
						|
        public void CopyFrom(SteamVR_Skeleton_PoseSnapshot source)
 | 
						|
        {
 | 
						|
            inputSource = source.inputSource;
 | 
						|
            position = source.position;
 | 
						|
            rotation = source.rotation;
 | 
						|
            for (int i = 0; i < bonePositions.Length; i++)
 | 
						|
            {
 | 
						|
                bonePositions[i] = source.bonePositions[i];
 | 
						|
                boneRotations[i] = source.boneRotations[i];
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    /// <summary>
 | 
						|
    /// Simple mask for fingers
 | 
						|
    /// </summary>
 | 
						|
    [System.Serializable]
 | 
						|
    public class SteamVR_Skeleton_HandMask
 | 
						|
    {
 | 
						|
        public bool palm;
 | 
						|
        public bool thumb;
 | 
						|
        public bool index;
 | 
						|
        public bool middle;
 | 
						|
        public bool ring;
 | 
						|
        public bool pinky;
 | 
						|
        public bool[] values = new bool[6];
 | 
						|
 | 
						|
        public void SetFinger(int i, bool value)
 | 
						|
        {
 | 
						|
            values[i] = value;
 | 
						|
            Apply();
 | 
						|
        }
 | 
						|
 | 
						|
        public bool GetFinger(int i)
 | 
						|
        {
 | 
						|
            return values[i];
 | 
						|
        }
 | 
						|
 | 
						|
        public SteamVR_Skeleton_HandMask()
 | 
						|
        {
 | 
						|
            values = new bool[6];
 | 
						|
            Reset();
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// All elements on
 | 
						|
        /// </summary>
 | 
						|
        public void Reset()
 | 
						|
        {
 | 
						|
            values = new bool[6];
 | 
						|
            for (int i = 0; i < 6; i++)
 | 
						|
            {
 | 
						|
                values[i] = true;
 | 
						|
            }
 | 
						|
            Apply();
 | 
						|
        }
 | 
						|
 | 
						|
        protected void Apply()
 | 
						|
        {
 | 
						|
            palm = values[0];
 | 
						|
            thumb = values[1];
 | 
						|
            index = values[2];
 | 
						|
            middle = values[3];
 | 
						|
            ring = values[4];
 | 
						|
            pinky = values[5];
 | 
						|
        }
 | 
						|
 | 
						|
        public static readonly SteamVR_Skeleton_HandMask fullMask = new SteamVR_Skeleton_HandMask();
 | 
						|
    };
 | 
						|
 | 
						|
}
 |