Files
VIVE-OpenXR-Unity/com.htc.upm.vive.openxr/OpenXRHandTracking/Samples~/Scripts/RenderModel.cs
2023-06-15 10:10:25 +08:00

79 lines
3.4 KiB
C#

using UnityEngine;
using VIVE.HandTracking;
namespace VIVE.HandTracking.Sample
{
public class RenderModel : MonoBehaviour
{
private readonly Quaternion zBackModelRotFix = Quaternion.AngleAxis(180f, Vector3.up);
public Transform[] nodes = new Transform[(int)XrHandJointEXT.XR_HAND_JOINT_MAX_ENUM_EXT];
[Tooltip("Draw left hand if true, right hand otherwise")]
public bool isLeft = false;
[Tooltip("Use inferred or last-known posed when hand loses tracking if true.")]
public bool allowUntrackedPose = false;
[Tooltip("Root object of skinned mesh")]
public GameObject Hand = null;
private XrHandJointsMotionRangeEXT MotionType = XrHandJointsMotionRangeEXT.XR_HAND_JOINTS_MOTION_RANGE_MAX_ENUM_EXT;
[Tooltip("Type of hand joints range of motion")]
[ReadOnly]public string HandJointsMotionRange;
// Start is called before the first frame update
private void Start()
{
HandManager.StartFrameWork(isLeft);
}
// Update is called once per frame
private void Update()
{
if (HandManager.GetJointLocation(isLeft, out var joints, ref MotionType))
{
setHandVisible(true);
for (int i = (int)XrHandJointEXT.XR_HAND_JOINT_PALM_EXT; i < (int)XrHandJointEXT.XR_HAND_JOINT_MAX_ENUM_EXT; i++)
{
var posValid = (joints[i].locationFlags & (ulong)XrSpaceLocationFlags.XR_SPACE_LOCATION_POSITION_VALID_BIT) != 0;
var posTracked = (joints[i].locationFlags & (ulong)XrSpaceLocationFlags.XR_SPACE_LOCATION_POSITION_TRACKED_BIT) != 0;
var rotValid = (joints[i].locationFlags & (ulong)XrSpaceLocationFlags.XR_SPACE_LOCATION_ORIENTATION_VALID_BIT) != 0;
var rotTracked = (joints[i].locationFlags & (ulong)XrSpaceLocationFlags.XR_SPACE_LOCATION_ORIENTATION_TRACKED_BIT) != 0;
var pos = new Vector3(joints[i].pose.position.x, joints[i].pose.position.y, -joints[i].pose.position.z);
var rot = new Quaternion(-joints[i].pose.orientation.x, -joints[i].pose.orientation.y, joints[i].pose.orientation.z, joints[i].pose.orientation.w) * zBackModelRotFix;
if (posValid && (allowUntrackedPose || posTracked)) { nodes[i].position = transform.TransformPoint(pos); }
if (rotValid && (allowUntrackedPose || rotTracked)) { nodes[i].rotation = transform.rotation * rot; }
}
switch (MotionType)
{
case XrHandJointsMotionRangeEXT.XR_HAND_JOINTS_MOTION_RANGE_UNOBSTRUCTED_EXT:
HandJointsMotionRange = "UNOBSTRUCTED";
break;
case XrHandJointsMotionRangeEXT.XR_HAND_JOINTS_MOTION_RANGE_CONFORMING_TO_CONTROLLER_EXT:
HandJointsMotionRange = "CONTROLLER";
break;
default:
HandJointsMotionRange = "";
break;
}
}
else
{
setHandVisible(false);
}
}
private void OnDestroy()
{
HandManager.StopFrameWork(isLeft);
}
public void setHandVisible(bool isVisible)
{
Hand.SetActive(isVisible);
}
}
}