123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using Ximmerse.XR.Utils;
- namespace Ximmerse.XR.InputSystems
- {
- /// <summary>
- /// Virtual hand renderer, for hand tracking.
- /// </summary>
- public class VirtualHandRenderer : MonoBehaviour
- {
- /// <summary>
- /// If true, colliders are disabled when start the behaviour.
- /// </summary>
- public bool DisableCollidersAtStartup = true;
- /// <summary>
- /// The game object prefab of palm.
- /// </summary>
- public GameObject palm;
- /// <summary>
- /// Joints of thumb finger
- /// </summary>
- public GameObject[] thumbJoints;
- public GameObject[] thumbConnections;
- /// <summary>
- /// Joints of index finger
- /// </summary>
- public GameObject[] indexJoints;
- public GameObject[] indexConnections;
- /// <summary>
- /// Joints of middle finger
- /// </summary>
- public GameObject[] middleJoints;
- public GameObject[] middleConnections;
- /// <summary>
- /// Joints of ring finger
- /// </summary>
- public GameObject[] ringJoints;
- public GameObject[] ringConnections;
- /// <summary>
- /// Joints of little finger
- /// </summary>
- public GameObject[] littleJoints;
- public GameObject[] littleConnections;
- /// <summary>
- /// Deactivate model time valve.
- /// </summary>
- const float kDeactiveTimeValve = 0.10f;
- float deactiveTimeCounter = 0;
- private bool isHandModelActive = false;
- Collider[] subColliders = null;
- private void Awake()
- {
- subColliders = GetComponentsInChildren<Collider>(true);
- }
- private void Start()
- {
- EnableHandModel(false);
- if(DisableCollidersAtStartup)
- {
- this.EnableSubColliders(false);
- }
- }
- // Update is called once per frame
- void LateUpdate()
- {
- if (HandTracking.IsHandTrackingEnable)
- {
- if (isHandModelActive)
- {
- UpdateHandTransforms();
- }
- var trackedInfo = HandTracking.HandTrackingInfo;
- if (!trackedInfo.IsValid)
- {
- deactiveTimeCounter += Time.deltaTime;
- if (deactiveTimeCounter >= kDeactiveTimeValve && isHandModelActive)
- {
- EnableHandModel(false);
- }
- }
- else
- {
- if (!isHandModelActive)
- {
- EnableHandModel(true);
- }
- deactiveTimeCounter = 0;//reset time counter on valid hand case.
- }
- }
- }
- /// <summary>
- /// update transforms of each finger's joint and connection.
- /// </summary>
- private void UpdateHandTransforms()
- {
- var trackedInfo = HandTracking.HandTrackingInfo;
- this.palm.transform.SetPositionAndRotation(trackedInfo.PalmPosition, trackedInfo.PalmRotation);
- this.palm.transform.localScale = trackedInfo.PalmScale;
- UpdateFingerJoints(this.thumbJoints, this.thumbConnections, trackedInfo.ThumbFinger);
- UpdateFingerJoints(this.indexJoints, this.indexConnections, trackedInfo.IndexFinger);
- UpdateFingerJoints(this.middleJoints, this.middleConnections, trackedInfo.MiddleFinger);
- UpdateFingerJoints(this.ringJoints, this.ringConnections, trackedInfo.RingFinger);
- UpdateFingerJoints(this.littleJoints, this.littleConnections, trackedInfo.LittleFinger);
- }
- private void UpdateFingerJoints(GameObject[] joints, GameObject[] connections, RawFingerTrackingInfo fingerTrackInfo)
- {
- for (int i = 0, iMax = joints.Length; i < iMax; i++)
- {
- joints[i].transform.position = fingerTrackInfo.Positions[i];
- }
- for (int i = 0, iMax = connections.Length; i < iMax; i++)
- {
- connections[i].transform.position = (fingerTrackInfo.Positions[i + 1] + fingerTrackInfo.Positions[i]) / 2;
- connections[i].transform.up = (fingerTrackInfo.Positions[i + 1] - fingerTrackInfo.Positions[i]).normalized;
- }
- }
- /// <summary>
- /// Activate / Deactivate hand model
- /// </summary>
- /// <param name="enabled"></param>
- void EnableHandModel(bool enabled)
- {
- isHandModelActive = enabled;
- palm.gameObject.SetActive(enabled);
- foreach (var g in thumbJoints)
- {
- g.gameObject.SetActive(enabled);
- }
- foreach (var g in indexJoints)
- {
- g.gameObject.SetActive(enabled);
- }
- foreach (var g in middleJoints)
- {
- g.gameObject.SetActive(enabled);
- }
- foreach (var g in ringJoints)
- {
- g.gameObject.SetActive(enabled);
- }
- foreach (var g in littleJoints)
- {
- g.gameObject.SetActive(enabled);
- }
- foreach (var g in thumbConnections)
- {
- g.gameObject.SetActive(enabled);
- }
- foreach (var g in indexConnections)
- {
- g.gameObject.SetActive(enabled);
- }
- foreach (var g in middleConnections)
- {
- g.gameObject.SetActive(enabled);
- }
- foreach (var g in ringConnections)
- {
- g.gameObject.SetActive(enabled);
- }
- foreach (var g in littleConnections)
- {
- g.gameObject.SetActive(enabled);
- }
- }
- /// <summary>
- /// Enable/disable sub colliders
- /// </summary>
- public void EnableSubColliders(bool enable)
- {
- foreach(var c in subColliders)
- {
- c.enabled = enable;
- }
- }
- }
- }
|