version 2.4.0
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
|
||||
{
|
||||
public abstract class HandPose : MonoBehaviour
|
||||
{
|
||||
#region Log
|
||||
private const string LOG_TAG = "Wave.Essence.Hand.Interaction.HandPose";
|
||||
private static StringBuilder m_sb = null;
|
||||
protected static StringBuilder sb
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_sb == null) { m_sb = new StringBuilder(); }
|
||||
return m_sb;
|
||||
}
|
||||
}
|
||||
protected void DEBUG(string msg) { Debug.Log($"{LOG_TAG}.{m_PoseType}, {msg}"); }
|
||||
protected void WARNING(string msg) { Debug.LogWarning($"{LOG_TAG}.{m_PoseType}, {msg}"); }
|
||||
protected void ERROR(string msg) { Debug.LogError($"{LOG_TAG}.{m_PoseType}, {msg}"); }
|
||||
#endregion
|
||||
|
||||
protected HandPoseType m_PoseType = HandPoseType.UNKNOWN;
|
||||
protected bool m_Initialized = false;
|
||||
protected bool m_IsTracked = false;
|
||||
protected const int poseCount = (int)JointType.Count;
|
||||
protected Vector3[] m_Position = Enumerable.Repeat(Vector3.zero, poseCount).ToArray();
|
||||
protected Vector3[] m_LocalPosition = Enumerable.Repeat(Vector3.zero, poseCount).ToArray();
|
||||
protected Quaternion[] m_Rotation = Enumerable.Repeat(Quaternion.identity, poseCount).ToArray();
|
||||
protected Quaternion[] m_LocalRotation = Enumerable.Repeat(Quaternion.identity, poseCount).ToArray();
|
||||
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
HandPoseProvider.RegisterHandPose(m_PoseType, this);
|
||||
}
|
||||
protected virtual void OnDisable()
|
||||
{
|
||||
HandPoseProvider.UnregisterHandPose(m_PoseType);
|
||||
}
|
||||
|
||||
public virtual void SetType(HandPoseType poseType)
|
||||
{
|
||||
m_PoseType = poseType;
|
||||
m_Initialized = true;
|
||||
}
|
||||
|
||||
public virtual bool IsTracked()
|
||||
{
|
||||
return m_IsTracked;
|
||||
}
|
||||
|
||||
public virtual bool GetRotation(JointType joint, out Quaternion value, bool local = false)
|
||||
{
|
||||
value = Quaternion.identity;
|
||||
if (joint != JointType.Count)
|
||||
{
|
||||
value = local ? m_LocalRotation[(int)joint] : m_Rotation[(int)joint];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool GetPosition(JointType joint, out Vector3 value, bool local = false)
|
||||
{
|
||||
value = Vector3.zero;
|
||||
if (joint != JointType.Count)
|
||||
{
|
||||
value = local ? m_LocalPosition[(int)joint] : m_Position[(int)joint];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1ced5448f0990b040b82475106e1b1d3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,95 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
|
||||
{
|
||||
public enum HandPoseType : UInt32
|
||||
{
|
||||
UNKNOWN = 0x7FFFFFFF,
|
||||
|
||||
HAND_LEFT = 100,
|
||||
HAND_RIGHT = 101,
|
||||
|
||||
MESH_LEFT = 200,
|
||||
MESH_RIGHT = 201,
|
||||
}
|
||||
|
||||
public static class HandPoseProvider
|
||||
{
|
||||
private static Dictionary<HandPoseType, HandPose> m_HandPoseMap = new Dictionary<HandPoseType, HandPose>();
|
||||
public static Dictionary<HandPoseType, HandPose> HandPoseMap
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_HandPoseMap == null) { m_HandPoseMap = new Dictionary<HandPoseType, HandPose>(); }
|
||||
return m_HandPoseMap;
|
||||
}
|
||||
private set { m_HandPoseMap = value; }
|
||||
}
|
||||
|
||||
public static bool RegisterHandPose(in HandPoseType poseType, in HandPose handPose)
|
||||
{
|
||||
if (!HandPoseMap.ContainsKey(poseType))
|
||||
{
|
||||
HandPoseMap.Add(poseType, handPose);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool UnregisterHandPose(in HandPoseType poseType)
|
||||
{
|
||||
if (HandPoseMap.ContainsKey(poseType))
|
||||
{
|
||||
HandPoseMap.Remove(poseType);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static HandPose GetHandPose(in HandPoseType poseType)
|
||||
{
|
||||
if (HandPoseMap.ContainsKey(poseType))
|
||||
{
|
||||
return HandPoseMap[poseType];
|
||||
}
|
||||
if (poseType == HandPoseType.HAND_LEFT || poseType == HandPoseType.MESH_LEFT)
|
||||
{
|
||||
return GetDefaultHandPose("LeftHandPose", HandPoseType.HAND_LEFT);
|
||||
}
|
||||
else if (poseType == HandPoseType.HAND_RIGHT || poseType == HandPoseType.MESH_RIGHT)
|
||||
{
|
||||
return GetDefaultHandPose("RightHandPose", HandPoseType.HAND_RIGHT);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string Name(this HandPoseType poseType)
|
||||
{
|
||||
string name = "";
|
||||
switch (poseType)
|
||||
{
|
||||
case HandPoseType.HAND_LEFT: name = "HAND_LEFT"; break;
|
||||
case HandPoseType.HAND_RIGHT: name = "HAND_LEFT"; break;
|
||||
case HandPoseType.MESH_LEFT: name = "MESH_LEFT"; break;
|
||||
case HandPoseType.MESH_RIGHT: name = "MESH_RIGHT"; break;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private static HandPose GetDefaultHandPose(string poseName, HandPoseType poseType)
|
||||
{
|
||||
if (!HandPoseMap.ContainsKey(poseType))
|
||||
{
|
||||
GameObject handPoseObject = new GameObject(poseName);
|
||||
RealHandPose realHandPose = handPoseObject.AddComponent<RealHandPose>();
|
||||
realHandPose.SetType(poseType);
|
||||
RegisterHandPose(poseType, realHandPose);
|
||||
return realHandPose;
|
||||
}
|
||||
return HandPoseMap[poseType];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 059d07a57fa09e543bf2f2b6d5788bb7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,84 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
|
||||
{
|
||||
public class MeshHandPose : HandPose
|
||||
{
|
||||
[SerializeField]
|
||||
private HandMeshManager m_HandMesh;
|
||||
|
||||
private bool keepUpdate = false;
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
StartCoroutine(WaitInit());
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
base.OnDisable();
|
||||
if (keepUpdate)
|
||||
{
|
||||
keepUpdate = false;
|
||||
StopCoroutine(UpdatePose());
|
||||
}
|
||||
}
|
||||
|
||||
public void SetHandMeshRenderer(HandMeshManager handMeshRenderer)
|
||||
{
|
||||
m_HandMesh = handMeshRenderer;
|
||||
SetType(handMeshRenderer.isLeft ? HandPoseType.MESH_LEFT : HandPoseType.MESH_RIGHT);
|
||||
}
|
||||
|
||||
public bool SetJointPose(JointType joint, Pose jointPose, bool local = false)
|
||||
{
|
||||
if (m_HandMesh != null)
|
||||
{
|
||||
return m_HandMesh.SetJointPositionAndRotation(joint, jointPose.position, jointPose.rotation, local);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private IEnumerator WaitInit()
|
||||
{
|
||||
yield return new WaitUntil(() => m_Initialized);
|
||||
base.OnEnable();
|
||||
if (!keepUpdate)
|
||||
{
|
||||
keepUpdate = true;
|
||||
StartCoroutine(UpdatePose());
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator UpdatePose()
|
||||
{
|
||||
while (keepUpdate)
|
||||
{
|
||||
yield return new WaitForFixedUpdate();
|
||||
|
||||
HandPose handPose = HandPoseProvider.GetHandPose(m_HandMesh.isLeft ? HandPoseType.HAND_LEFT : HandPoseType.HAND_RIGHT);
|
||||
m_IsTracked = handPose.IsTracked();
|
||||
|
||||
for (int i = 0; i < poseCount; i++)
|
||||
{
|
||||
if (m_HandMesh.GetJointPositionAndRotation((JointType)i, out Vector3 position, out Quaternion rotation) &&
|
||||
m_HandMesh.GetJointPositionAndRotation((JointType)i, out Vector3 localPosition, out Quaternion localRotation, local: true))
|
||||
{
|
||||
m_Position[i] = position;
|
||||
m_Rotation[i] = rotation;
|
||||
m_LocalPosition[i] = localPosition;
|
||||
m_LocalRotation[i] = localRotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Position[i] = Vector3.zero;
|
||||
m_Rotation[i] = Quaternion.identity;
|
||||
m_LocalPosition[i] = Vector3.zero;
|
||||
m_LocalRotation[i] = Quaternion.identity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5e78e2d8c82d5584faaf4b66d40d1057
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,85 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
|
||||
{
|
||||
public class RealHandPose : HandPose
|
||||
{
|
||||
[SerializeField]
|
||||
private Handedness m_Handedness;
|
||||
private bool isLeft => m_Handedness == Handedness.Left;
|
||||
private bool keepUpdate = false;
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
StartCoroutine(WaitInit());
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
base.OnDisable();
|
||||
if (keepUpdate)
|
||||
{
|
||||
keepUpdate = false;
|
||||
StopCoroutine(UpdatePose());
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetType(HandPoseType poseType)
|
||||
{
|
||||
if (poseType == HandPoseType.HAND_LEFT)
|
||||
{
|
||||
m_Handedness = Handedness.Left;
|
||||
}
|
||||
else if (poseType == HandPoseType.HAND_RIGHT)
|
||||
{
|
||||
m_Handedness = Handedness.Right;
|
||||
}
|
||||
|
||||
base.SetType(poseType);
|
||||
}
|
||||
|
||||
private IEnumerator WaitInit()
|
||||
{
|
||||
yield return new WaitUntil(() => m_Initialized);
|
||||
base.OnEnable();
|
||||
if (!keepUpdate)
|
||||
{
|
||||
keepUpdate = true;
|
||||
StartCoroutine(UpdatePose());
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator UpdatePose()
|
||||
{
|
||||
Vector3 position = Vector3.zero;
|
||||
Quaternion rotation = Quaternion.identity;
|
||||
while (keepUpdate)
|
||||
{
|
||||
yield return new WaitForEndOfFrame();
|
||||
|
||||
HandData handData = CachedHand.Get(isLeft);
|
||||
m_IsTracked = handData.isTracked;
|
||||
if (!m_IsTracked) { continue; }
|
||||
|
||||
for (int i = 0; i < poseCount; i++)
|
||||
{
|
||||
if (handData.GetJointPosition((JointType)i, ref position) && handData.GetJointRotation((JointType)i, ref rotation))
|
||||
{
|
||||
m_Position[i] = position;
|
||||
m_Rotation[i] = rotation;
|
||||
m_LocalPosition[i] = position;
|
||||
m_LocalRotation[i] = rotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Position[i] = Vector3.zero;
|
||||
m_Rotation[i] = Quaternion.identity;
|
||||
m_LocalPosition[i] = Vector3.zero;
|
||||
m_LocalRotation[i] = Quaternion.identity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 52790aba0e3d55f4fb27aded6c698d8b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user