version 2.0.0

This commit is contained in:
srl87
2023-09-14 18:17:47 +08:00
parent 13e9d00b37
commit ca21423a06
953 changed files with 125887 additions and 21229 deletions

View File

@@ -0,0 +1,193 @@
// Copyright HTC Corporation All Rights Reserved.
using System;
using System.Collections.Generic;
using UnityEngine;
using VIVE.OpenXR.Hand;
namespace VIVE.OpenXR.Samples
{
public class ViveRenderHand : MonoBehaviour
{
const string LOG_TAG = "HTC.VIVE.OPENXR.SAMPLE.ViveRenderHand";
void DEBUG(string msg) { Debug.Log(LOG_TAG + (isLeft ? " Left" : " Right") + ", " + msg); }
void INTERVAL(string msg) { if (printIntervalLog) { DEBUG(msg); } }
// Links between keypoints, 2*i & 2*i+1 forms a link.
// keypoint index: 1: palm, 2-5: thumb, 6-10: index, 11-15: middle, 16-20: ring, 21-25: pinky
// fingers are counted from bottom to top
private static int[] Connections = new int[] {
1, 2, 1, 6, 1, 11, 1, 16, 1, 21, // palm and finger starts
3, 6, 6, 11, 11, 16, 16, 21, // finger starts
2, 3, 3, 4, 4, 5, // thumb
6, 7, 7, 8, 8, 9, 9, 10, // index
11, 12, 12, 13, 13, 14, 14, 15, // middle
16, 17, 17, 18, 18, 19, 19, 20, // ring
21, 22, 22, 23, 23, 24, 24, 25 // pinky
};
[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("Default color of hand points")]
public Color pointColor = Color.green;
[Tooltip("Default color of links between keypoints in skeleton mode")]
public Color linkColor = Color.white;
[Tooltip("Material for hand points and links")]
[SerializeField]
private Material material = null;
private List<GameObject> points = new List<GameObject>();
// list of links created (only for skeleton)
private List<GameObject> links = new List<GameObject>();
// Start is called before the first frame update
private XrHandJointLocationEXT[] HandjointLocations = new XrHandJointLocationEXT[(int)XrHandJointEXT.XR_HAND_JOINT_MAX_ENUM_EXT];
// shared material for all point objects
private Material pointMat = null;
// shared material for all link objects
private Material linkMat = null;
private void Start()
{
pointMat = new Material(material);
if (isLeft)
{
pointColor = Color.blue;
}
else
{
pointColor = Color.red;
}
pointMat.color = pointColor;
linkMat = new Material(material);
linkMat.color = linkColor;
for (int i = 0; i < (int)XrHandJointEXT.XR_HAND_JOINT_MAX_ENUM_EXT; i++)
{
var go = GameObject.CreatePrimitive(PrimitiveType.Sphere);
go.name = ((XrHandJointEXT)i).ToString();
go.transform.parent = transform;
go.transform.localScale = Vector3.one * 0.012f;
go.SetActive(false);
points.Add(go);
go.transform.position = new Vector3((float)i * 0.1f, 0, 0);
// handle layer
go.layer = gameObject.layer;
// handle material
go.GetComponent<Renderer>().sharedMaterial = pointMat;
}
// create game objects for links between keypoints, only used in skeleton mode
for (int i = 0; i < Connections.Length; i += 2)
{
var go = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
go.name = "link" + i;
go.transform.parent = transform;
go.transform.localScale = Vector3.one * 0.005f;
go.SetActive(false);
links.Add(go);
// handle layer
go.layer = gameObject.layer;
// handle material
go.GetComponent<Renderer>().sharedMaterial = linkMat;
}
}
int printFrame = 0;
private bool printIntervalLog = false;
private void Update()
{
printFrame++;
printFrame %= 300;
printIntervalLog = (printFrame == 0);
if (XR_EXT_hand_tracking.Interop.GetJointLocations(isLeft, out HandjointLocations))
{
UpdateJointLocation();
}
else
{
for (int i = 0; i < points.Count; i++)
{
var go = points[i];
go.SetActive(false);
}
for (int i = 0; i < links.Count; i++)
{
var link = links[i];
link.SetActive(false);
}
}
}
public void UpdateJointLocation()
{
for (int i = 0; i < points.Count && i < HandjointLocations.Length; i++)
{
var go = points[i];
XrQuaternionf orientation;
XrVector3f position;
go.GetComponent<SphereCollider>().radius = HandjointLocations[i].radius;
INTERVAL(go.name + " radius: " + go.GetComponent<SphereCollider>().radius);
if (allowUntrackedPose) //Use inferred or last-known pose when lost tracking
{
orientation = HandjointLocations[i].pose.orientation;
position = HandjointLocations[i].pose.position;
go.transform.localPosition = new Vector3(position.x, position.y, -position.z);
go.SetActive(true);
}
else
{
if (((UInt64)HandjointLocations[i].locationFlags & (UInt64)XrSpaceLocationFlags.XR_SPACE_LOCATION_ORIENTATION_TRACKED_BIT) != 0)
{
orientation = HandjointLocations[i].pose.orientation;
}
if (((UInt64)HandjointLocations[i].locationFlags & (UInt64)XrSpaceLocationFlags.XR_SPACE_LOCATION_POSITION_TRACKED_BIT) != 0)
{
position = HandjointLocations[i].pose.position;
go.transform.localPosition = new Vector3(position.x, position.y, -position.z);
go.SetActive(true);
}
else
{
INTERVAL("Lost tracking");
go.SetActive(false);
}
/*if (i == 1 && isLeft)
{
DEBUG("points[1]: " + go.name + " active? " + go.activeSelf
+ ", locationFlags: " + HandjointLocations[i].locationFlags
+ ", position (" + go.transform.localPosition.x.ToString() + ", " + go.transform.localPosition.y.ToString() + ", " + go.transform.localPosition.z.ToString() + ")");
}*/
}
}
for (int i = 0; i < links.Count; i++)
{
var link = links[i];
if (!points[Connections[i * 2]].activeSelf || !points[Connections[i * 2 + 1]].activeSelf)
{
link.SetActive(false);
continue;
}
var pose1 = points[Connections[i * 2]].transform.position;
var pose2 = points[Connections[i * 2 + 1]].transform.position;
// calculate link position and rotation based on points on both end
link.SetActive(true);
link.transform.position = (pose1 + pose2) / 2;
var direction = pose2 - pose1;
link.transform.rotation = Quaternion.FromToRotation(Vector3.up, direction);
link.transform.localScale = new Vector3(0.006f, direction.magnitude / 2f - 0.0051f, 0.006f);
}
}
public void OnDestroy()
{
DEBUG("OnDestroy");
}
}
}