sdraw_mods_cvr/ml_bft/HandHandlerXR.cs
SDraw 85925a7072
Custom event classes for patched methods
Update to LeapCSharp 6.15.0
2024-04-27 00:23:03 +03:00

229 lines
13 KiB
C#

using UnityEngine;
using UnityEngine.XR.OpenXR;
using UnityEngine.XR.Hands;
using UnityEngine.XR;
namespace ml_bft
{
class HandHandlerXR : HandHandler
{
// 26 bones, get in XRHandJointID enum
const int c_fingerBonesCount = (int)XRHandJointID.EndMarker - 1;
public HandHandlerXR(Transform p_root, bool p_left) : base(p_left)
{
for(int i = 0; i < c_fingerBonesCount; i++)
{
m_bones.Add(null);
m_localRotations.Add(Quaternion.identity);
}
m_prefabRoot = AssetsHandler.GetAsset(string.Format("Assets/OpenXR/Models/{0}Hand_IK.prefab", m_left ? "Left" : "Right")).transform;
m_prefabRoot.name = "[FingersTracking_XR]";
m_prefabRoot.parent = p_root;
m_prefabRoot.localPosition = Vector3.zero;
m_prefabRoot.localRotation = Quaternion.identity;
m_prefabRoot.GetComponentsInChildren(true, m_renderers);
// Ah yes, the stupid code
char l_side = (m_left ? 'L' : 'R');
m_bones[(int)XRHandJointID.Wrist - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist", l_side));
m_bones[(int)XRHandJointID.Palm - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_Palm", l_side));
m_bones[(int)XRHandJointID.ThumbMetacarpal - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_ThumbMetacarpal", l_side));
m_bones[(int)XRHandJointID.ThumbProximal - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_ThumbMetacarpal/{0}_Wrist/{0}_ThumbProximal", l_side));
m_bones[(int)XRHandJointID.ThumbDistal - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_ThumbMetacarpal/{0}_Wrist/{0}_ThumbProximal/{0}_ThumbDistal", l_side));
m_bones[(int)XRHandJointID.ThumbTip - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_ThumbMetacarpal/{0}_Wrist/{0}_ThumbProximal/{0}_ThumbDistal/{0}_ThumbTip", l_side));
m_bones[(int)XRHandJointID.IndexMetacarpal - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_IndexMetacarpal", l_side));
m_bones[(int)XRHandJointID.IndexProximal - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_IndexMetacarpal/{0}_IndexProximal", l_side));
m_bones[(int)XRHandJointID.IndexIntermediate - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_IndexMetacarpal/{0}_IndexProximal/{0}_IndexIntermediate", l_side));
m_bones[(int)XRHandJointID.IndexDistal - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_IndexMetacarpal/{0}_IndexProximal/{0}_IndexIntermediate/{0}_IndexDistal", l_side));
m_bones[(int)XRHandJointID.IndexTip - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_IndexMetacarpal/{0}_IndexProximal/{0}_IndexIntermediate/{0}_IndexDistal/{0}_IndexTip", l_side));
m_bones[(int)XRHandJointID.MiddleMetacarpal - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_MiddleMetacarpal", l_side));
m_bones[(int)XRHandJointID.MiddleProximal - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_MiddleMetacarpal/{0}_MiddleProximal", l_side));
m_bones[(int)XRHandJointID.MiddleIntermediate - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_MiddleMetacarpal/{0}_MiddleProximal/{0}_MiddleIntermediate", l_side));
m_bones[(int)XRHandJointID.MiddleDistal - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_MiddleMetacarpal/{0}_MiddleProximal/{0}_MiddleIntermediate/{0}_MiddleDistal", l_side));
m_bones[(int)XRHandJointID.MiddleTip - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_MiddleMetacarpal/{0}_MiddleProximal/{0}_MiddleIntermediate/{0}_MiddleDistal/{0}_MiddleTip", l_side));
m_bones[(int)XRHandJointID.RingMetacarpal - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_RingMetacarpal", l_side));
m_bones[(int)XRHandJointID.RingProximal - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_RingMetacarpal/{0}_RingProximal", l_side));
m_bones[(int)XRHandJointID.RingIntermediate - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_RingMetacarpal/{0}_RingProximal/{0}_RingIntermediate", l_side));
m_bones[(int)XRHandJointID.RingDistal - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_RingMetacarpal/{0}_RingProximal/{0}_RingIntermediate/{0}_RingDistal", l_side));
m_bones[(int)XRHandJointID.RingTip - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_RingMetacarpal/{0}_RingProximal/{0}_RingIntermediate/{0}_RingDistal/{0}_RingTip", l_side));
m_bones[(int)XRHandJointID.LittleMetacarpal - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_LittleMetacarpal", l_side));
m_bones[(int)XRHandJointID.LittleProximal - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_LittleMetacarpal/{0}_LittleProximal", l_side));
m_bones[(int)XRHandJointID.LittleIntermediate - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_LittleMetacarpal/{0}_LittleProximal/{0}_LittleIntermediate", l_side));
m_bones[(int)XRHandJointID.LittleDistal - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_LittleMetacarpal/{0}_LittleProximal/{0}_LittleIntermediate/{0}_LittleDistal", l_side));
m_bones[(int)XRHandJointID.LittleTip - 1] = m_prefabRoot.Find(string.Format("{0}_Wrist/{0}_LittleMetacarpal/{0}_LittleProximal/{0}_LittleIntermediate/{0}_LittleDistal/{0}_LittleTip", l_side));
for(int i = 0; i < c_fingerBonesCount; i++)
{
if(m_bones[i] != null)
m_localRotations[i] = m_bones[i].localRotation;
}
base.OnShowHandsChanged(Settings.ShowHands);
}
public override Transform GetSourceForBone(HumanBodyBones p_bone)
{
Transform l_result = null;
if(m_left)
{
switch(p_bone)
{
case HumanBodyBones.LeftHand:
l_result = m_bones[(int)XRHandJointID.Wrist - 1];
break;
case HumanBodyBones.LeftThumbProximal:
l_result = m_bones[(int)XRHandJointID.ThumbMetacarpal - 1];
break;
case HumanBodyBones.LeftThumbIntermediate:
l_result = m_bones[(int)XRHandJointID.ThumbProximal - 1];
break;
case HumanBodyBones.LeftThumbDistal:
l_result = m_bones[(int)XRHandJointID.ThumbDistal - 1];
break;
case HumanBodyBones.LeftIndexProximal:
l_result = m_bones[(int)XRHandJointID.IndexProximal - 1];
break;
case HumanBodyBones.LeftIndexIntermediate:
l_result = m_bones[(int)XRHandJointID.IndexIntermediate - 1];
break;
case HumanBodyBones.LeftIndexDistal:
l_result = m_bones[(int)XRHandJointID.IndexDistal - 1];
break;
case HumanBodyBones.LeftMiddleProximal:
l_result = m_bones[(int)XRHandJointID.MiddleProximal - 1];
break;
case HumanBodyBones.LeftMiddleIntermediate:
l_result = m_bones[(int)XRHandJointID.MiddleIntermediate - 1];
break;
case HumanBodyBones.LeftMiddleDistal:
l_result = m_bones[(int)XRHandJointID.MiddleDistal - 1];
break;
case HumanBodyBones.LeftRingProximal:
l_result = m_bones[(int)XRHandJointID.RingProximal - 1];
break;
case HumanBodyBones.LeftRingIntermediate:
l_result = m_bones[(int)XRHandJointID.RingIntermediate - 1];
break;
case HumanBodyBones.LeftRingDistal:
l_result = m_bones[(int)XRHandJointID.RingDistal - 1];
break;
case HumanBodyBones.LeftLittleProximal:
l_result = m_bones[(int)XRHandJointID.LittleProximal - 1];
break;
case HumanBodyBones.LeftLittleIntermediate:
l_result = m_bones[(int)XRHandJointID.LittleIntermediate - 1];
break;
case HumanBodyBones.LeftLittleDistal:
l_result = m_bones[(int)XRHandJointID.LittleDistal - 1];
break;
}
}
else
{
switch(p_bone)
{
case HumanBodyBones.RightHand:
l_result = m_bones[(int)XRHandJointID.Wrist - 1];
break;
case HumanBodyBones.RightThumbProximal:
l_result = m_bones[(int)XRHandJointID.ThumbMetacarpal - 1];
break;
case HumanBodyBones.RightThumbIntermediate:
l_result = m_bones[(int)XRHandJointID.ThumbProximal - 1];
break;
case HumanBodyBones.RightThumbDistal:
l_result = m_bones[(int)XRHandJointID.ThumbDistal - 1];
break;
case HumanBodyBones.RightIndexProximal:
l_result = m_bones[(int)XRHandJointID.IndexProximal - 1];
break;
case HumanBodyBones.RightIndexIntermediate:
l_result = m_bones[(int)XRHandJointID.IndexIntermediate - 1];
break;
case HumanBodyBones.RightIndexDistal:
l_result = m_bones[(int)XRHandJointID.IndexDistal - 1];
break;
case HumanBodyBones.RightMiddleProximal:
l_result = m_bones[(int)XRHandJointID.MiddleProximal - 1];
break;
case HumanBodyBones.RightMiddleIntermediate:
l_result = m_bones[(int)XRHandJointID.MiddleIntermediate - 1];
break;
case HumanBodyBones.RightMiddleDistal:
l_result = m_bones[(int)XRHandJointID.MiddleDistal - 1];
break;
case HumanBodyBones.RightRingProximal:
l_result = m_bones[(int)XRHandJointID.RingProximal - 1];
break;
case HumanBodyBones.RightRingIntermediate:
l_result = m_bones[(int)XRHandJointID.RingIntermediate - 1];
break;
case HumanBodyBones.RightRingDistal:
l_result = m_bones[(int)XRHandJointID.RingDistal - 1];
break;
case HumanBodyBones.RightLittleProximal:
l_result = m_bones[(int)XRHandJointID.LittleProximal - 1];
break;
case HumanBodyBones.RightLittleIntermediate:
l_result = m_bones[(int)XRHandJointID.LittleIntermediate - 1];
break;
case HumanBodyBones.RightLittleDistal:
l_result = m_bones[(int)XRHandJointID.LittleDistal - 1];
break;
}
}
return l_result;
}
public override void Update()
{
var l_tracking = OpenXRSettings.Instance.GetFeature<HandTrackingFeature>();
var l_device = InputDevices.GetDeviceAtXRNode(m_left ? XRNode.LeftHand : XRNode.RightHand);
if((l_device != null) && l_device.TryGetFeatureValue(CommonUsages.deviceRotation, out Quaternion l_deviceRot) && (l_tracking != null))
{
Quaternion l_handInv = Quaternion.Inverse(l_deviceRot);
l_tracking.GetHandJoints(m_left ? HandTrackingFeature.Hand_Index.L : HandTrackingFeature.Hand_Index.R, out var l_positions, out var l_rotations, out _);
if(l_positions.Length >= c_fingerBonesCount)
{
// Joints rotations are in global space, locations are in ... space??? ... wth is wrong with OpenXR?
Quaternion l_prefabRot = m_prefabRoot.rotation;
for(int i = 0; i < c_fingerBonesCount; i++)
{
if(m_bones[i] != null)
{
//m_bones[i].localPosition = l_positions[i];
m_bones[i].rotation = l_prefabRot * (l_handInv * l_rotations[i]);
}
}
}
}
}
public override void Rebind(Quaternion p_base)
{
for(int i = 0; i < c_fingerBonesCount; i++)
{
if(m_bones[i] != null)
m_bones[i].localRotation = m_localRotations[i];
}
if(m_bones[(int)XRHandJointID.Wrist - 1] != null)
m_bones[(int)XRHandJointID.Wrist - 1].rotation = p_base * (m_left ? Quaternion.Euler(0f, -90f, 0f) : Quaternion.Euler(0f, 90f, 0f));
}
}
}