version 2.5.0

This commit is contained in:
Sean Lu
2024-12-06 15:44:37 +08:00
parent dfdcd0fd7f
commit 2bfa2ad4c7
966 changed files with 238216 additions and 77239 deletions

View File

@@ -5,7 +5,7 @@ using UnityEditor;
namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
{
[CustomEditor(typeof(HandMeshManager))]
public class HandMeshManagerEditor : Editor
public class HandMeshManagerEditor : UnityEditor.Editor
{
private HandMeshManager m_HandMesh;
private SerializedProperty m_Handedness, m_EnableCollider, m_HandJoints;

View File

@@ -67,7 +67,9 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
[SerializeField]
private Rigidbody m_Rigidbody = null;
public new Rigidbody rigidbody => m_Rigidbody;
#pragma warning disable
public Rigidbody rigidbody => m_Rigidbody;
#pragma warning enable
[SerializeField]
private List<GrabPose> m_GrabPoses = new List<GrabPose>();
@@ -82,15 +84,17 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
private bool m_ShowAllIndicator = false;
private List<Collider> allColliders = new List<Collider>();
private HandGrabInteractor closestGrabber = null;
private OnBeginGrabbed beginGrabbed;
private OnEndGrabbed endGrabbed;
[SerializeField]
private IOneHandContraintMovement m_OneHandContraintMovement;
public bool isContraint => m_OneHandContraintMovement != null;
public IOneHandContraintMovement oneHandContraintMovement { get { return m_OneHandContraintMovement; } set { m_OneHandContraintMovement = value; } }
public bool isContraint => m_OneHandContraintMovement != null;
#pragma warning disable
[SerializeField]
private int m_PreviewIndex = -1;
#pragma warning enable
private RaycastHit[] hitResults = new RaycastHit[10];
#region MonoBehaviour
private void Awake()
@@ -124,7 +128,6 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
handPose.GetPosition(JointType.Wrist, out Vector3 wristPos);
handPose.GetRotation(JointType.Wrist, out Quaternion wristRot);
UpdateBestGrabPose(handGrabber.isLeft, new Pose(wristPos, wristRot));
beginGrabbed?.Invoke(this);
m_OnBeginGrabbed?.Invoke(this);
DEBUG($"{transform.name} is grabbed by {handGrabber.name}");
}
@@ -132,7 +135,6 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
{
m_Grabber = null;
m_BestGrabPose = GrabPose.Identity;
endGrabbed?.Invoke(this);
m_OnEndGrabbed?.Invoke(this);
DEBUG($"{transform.name} is released.");
}
@@ -185,46 +187,6 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
return distacne > grabDistance ? 0 : 1 - (distacne / grabDistance);
}
/// <summary>
/// Add a listener for the event triggered when the grabbable object is grabbed.
/// </summary>
/// <param name="handler">The method to be called when the grabbable object is grabbed.</param>
[Obsolete("Please use onBeginGrabbed instead.")]
public void AddBeginGrabbedListener(OnBeginGrabbed handler)
{
beginGrabbed += handler;
}
/// <summary>
/// Remove a listener for the event triggered when the grabbable object is grabbed.
/// </summary>
/// <param name="handler">The method to be removed from the event listeners.</param>
[Obsolete("Please use onBeginGrabbed instead.")]
public void RemoveBeginGrabbedListener(OnBeginGrabbed handler)
{
beginGrabbed -= handler;
}
/// <summary>
/// Add a listener for the event triggered when the grabbable object is released.
/// </summary>
/// <param name="handler">The method to be called when the grabbable object is released.</param>
[Obsolete("Please use onEndGrabbed instead.")]
public void AddEndGrabbedListener(OnEndGrabbed handler)
{
endGrabbed += handler;
}
/// <summary>
/// Remove a listener for the event triggered when the grabbable object is released.
/// </summary>
/// <param name="handler">The method to be removed from the event listeners.</param>
[Obsolete("Please use onEndGrabbed instead.")]
public void RemoveEndGrabbedListener(OnEndGrabbed handler)
{
endGrabbed -= handler;
}
/// <summary>
/// Update the position and rotation of the self with the pose of the hand that is grabbing it.
/// </summary>
@@ -302,16 +264,19 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
{
Vector3 closestPoint = Vector3.zero;
float shortDistance = float.MaxValue;
foreach (var collider in allColliders)
for (int i = 0; i < allColliders.Count; i++)
{
Collider collider = allColliders[i];
Vector3 closePoint = collider.ClosestPointOnBounds(sourcePos);
float distance = Vector3.Distance(sourcePos, closePoint);
if (collider.bounds.Contains(closePoint))
{
Vector3 direction = (closePoint - sourcePos).normalized;
RaycastHit[] hits = Physics.RaycastAll(sourcePos, direction, distance);
foreach (var hit in hits)
Vector3 direction = closePoint - sourcePos;
direction.Normalize();
int hitCount = Physics.RaycastNonAlloc(sourcePos, direction, hitResults, distance);
for (int j = 0; j < hitCount; j++)
{
RaycastHit hit = hitResults[j];
if (hit.collider == collider)
{
float hitDistance = Vector3.Distance(sourcePos, hit.point);

View File

@@ -9,6 +9,7 @@
// specifications, and documentation provided by HTC to You."
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
@@ -34,8 +35,6 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
private void DEBUG(string msg) { Debug.Log($"{LOG_TAG}, {msg}"); }
private void WARNING(string msg) { Debug.LogWarning($"{LOG_TAG}, {msg}"); }
private void ERROR(string msg) { Debug.LogError($"{LOG_TAG}, {msg}"); }
int logFrame = 0;
bool printIntervalLog => logFrame == 0;
#endregion
@@ -79,8 +78,6 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
private GrabState m_State = GrabState.None;
private Pose wristPose = Pose.identity;
private Vector3[] fingerTipPosition = new Vector3[(int)FingerId.Count];
private OnBeginGrab beginGrabHandler;
private OnEndGrab endGrabHandler;
#region MonoBehaviour
private void Awake()
@@ -155,46 +152,6 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
}
return false;
}
/// <summary>
/// Add a listener for the event triggered when the grabber begins grabbing.
/// </summary>
/// <param name="handler">The method to be called when the grabber begins grabbing.</param>
[Obsolete("Please use onBeginGrab instead.")]
public void AddBeginGrabListener(OnBeginGrab handler)
{
beginGrabHandler += handler;
}
/// <summary>
/// Remove a listener for the event triggered when the grabber begins grabbing.
/// </summary>
/// <param name="handler">The method to be removed from the event listeners.</param>
[Obsolete("Please use onBeginGrab instead.")]
public void RemoveBeginGrabListener(OnBeginGrab handler)
{
beginGrabHandler -= handler;
}
/// <summary>
/// Add a listener for the event triggered when the grabber ends grabbing.
/// </summary>
/// <param name="handler">The method to be called when the grabber ends grabbing.</param>
[Obsolete("Please use onEndGrab instead.")]
public void AddEndGrabListener(OnEndGrab handler)
{
endGrabHandler += handler;
}
/// <summary>
/// Remove a listener for the event triggered when the grabber ends grabbing.
/// </summary>
/// <param name="handler">The method to be removed from the event listeners.</param>
[Obsolete("Please use onEndGrab instead.")]
public void RemoveEndGrabListener(OnEndGrab handler)
{
endGrabHandler -= handler;
}
#endregion
/// <summary>
@@ -231,13 +188,32 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
{
grabbable = null;
maxScore = 0f;
foreach (HandGrabInteractable interactable in GrabManager.handGrabbables)
{
interactable.ShowIndicator(false, this);
foreach (Vector3 tipPos in fingerTipPosition)
Collider[] nearColliders = Physics.OverlapSphere(wristPose.position, 0.5f);
List<HandGrabInteractable> nearHandGrabInteractables = new List<HandGrabInteractable>();
for (int i = 0; i < nearColliders.Length; i++)
{
HandGrabInteractable interactable = nearColliders[i].GetComponentInParent<HandGrabInteractable>();
if (interactable && !nearHandGrabInteractables.Contains(interactable))
{
float distanceScore = interactable.CalculateDistanceScore(tipPos, grabDistance);
nearHandGrabInteractables.Add(interactable);
continue;
}
interactable = nearColliders[i].GetComponentInChildren<HandGrabInteractable>();
if (interactable && !nearHandGrabInteractables.Contains(interactable))
{
nearHandGrabInteractables.Add(interactable);
continue;
}
}
for (int i = 0; i < nearHandGrabInteractables.Count; i++)
{
HandGrabInteractable interactable = nearHandGrabInteractables[i];
interactable.ShowIndicator(false, this);
for (int j = 0; j < fingerTipPosition.Length; j++)
{
float distanceScore = interactable.CalculateDistanceScore(fingerTipPosition[j], grabDistance);
if (distanceScore > maxScore)
{
maxScore = distanceScore;
@@ -280,7 +256,6 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
m_Grabbable = currentCandidate;
m_Grabbable.SetGrabber(this);
m_Grabbable.ShowIndicator(false, this);
beginGrabHandler?.Invoke(this);
onBeginGrab?.Invoke(this);
DEBUG($"The {(m_Handedness == Handedness.Left ? "left" : "right")} hand begins to grab the {m_Grabbable.name}");
@@ -296,7 +271,6 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
{
DEBUG($"The {(m_Handedness == Handedness.Left ? "left" : "right")} hand ends to grab the {m_Grabbable.name}");
endGrabHandler?.Invoke(this);
onEndGrab?.Invoke(this);
m_Grabbable.SetGrabber(null);
m_Grabbable = null;

View File

@@ -1,7 +1,7 @@
using System.Text;
using UnityEngine;
namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
{
public class OneGrabMoveConstraint : IOneHandContraintMovement
{
@@ -30,21 +30,28 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
[SerializeField]
private ConstraintInfo m_NegativeXMove = ConstraintInfo.Identity;
private float defaultNegativeXPos = 0.0f;
public float xNegativeBoundary => defaultNegativeXPos;
[SerializeField]
private ConstraintInfo m_PositiveXMove = ConstraintInfo.Identity;
private float defaultPositiveXPos = 0.0f;
public float xPositiveBoundary => defaultPositiveXPos;
[SerializeField]
private ConstraintInfo m_NegativeYMove = ConstraintInfo.Identity;
private float defaultNegativeYPos = 0.0f;
public float yNegativeBoundary => defaultNegativeYPos;
[SerializeField]
private ConstraintInfo m_PositiveYMove = ConstraintInfo.Identity;
private float defaultPositiveYPos = 0.0f;
public float yPositiveBoundary => defaultPositiveYPos;
[SerializeField]
private ConstraintInfo m_NegativeZMove = ConstraintInfo.Identity;
private float defaultNegativeZPos = 0.0f;
public float zNegativeBoundary => defaultNegativeZPos;
[SerializeField]
private ConstraintInfo m_PositiveZMove = ConstraintInfo.Identity;
private float defaultPositiveZPos = 0.0f;
public float zPositiveBoundary => defaultPositiveZPos;
private Pose previousHandPose = Pose.identity;
private GrabPose currentGrabPose = GrabPose.Identity;

View File

@@ -40,9 +40,12 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
private RotationAxis m_RotationAxis = RotationAxis.XAxis;
[SerializeField]
private ConstraintInfo m_ClockwiseAngle = ConstraintInfo.Identity;
public float clockwiseAngle => m_ClockwiseAngle.value;
[SerializeField]
private ConstraintInfo m_CounterclockwiseAngle = ConstraintInfo.Identity;
private float totalRotationAngle = 0.0f;
public float counterclockwiseAngle => m_CounterclockwiseAngle.value;
private float m_TotalDegrees = 0.0f;
public float totalDegrees => m_TotalDegrees;
private Pose previousHandPose = Pose.identity;
public override void Initialize(IGrabbable grabbable)
@@ -99,17 +102,17 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
float angleDelta = Vector3.Angle(previousVector, targetVector);
angleDelta *= Vector3.Dot(Vector3.Cross(previousVector, targetVector), worldAxis) > 0.0f ? 1.0f : -1.0f;
float previousAngle = totalRotationAngle;
totalRotationAngle += angleDelta;
float previousAngle = m_TotalDegrees;
m_TotalDegrees += angleDelta;
if (m_CounterclockwiseAngle.enableConstraint)
{
totalRotationAngle = Mathf.Max(totalRotationAngle, -m_CounterclockwiseAngle.value);
m_TotalDegrees = Mathf.Max(m_TotalDegrees, -m_CounterclockwiseAngle.value);
}
if (m_ClockwiseAngle.enableConstraint)
{
totalRotationAngle = Mathf.Min(totalRotationAngle, m_ClockwiseAngle.value);
m_TotalDegrees = Mathf.Min(m_TotalDegrees, m_ClockwiseAngle.value);
}
angleDelta = totalRotationAngle - previousAngle;
angleDelta = m_TotalDegrees - previousAngle;
m_Constraint.RotateAround(m_Pivot.position, worldAxis, angleDelta);
previousHandPose = handPose;

View File

@@ -13,11 +13,7 @@ using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.Events;
#if UNITY_XR_HANDS
using UnityEngine.XR.Hands;
#endif
using VIVE.OpenXR.Toolkits.Common;
namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
{
@@ -60,31 +56,15 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
/// <summary>
/// This class is designed to update hand tracking data.
/// </summary>
#if UNITY_XR_HANDS
public static class DataWrapper
{
private static XRHandSubsystem handSubsystem = null;
private static List<XRHandSubsystem> s_XRHandSubsystems = new List<XRHandSubsystem>();
/// <summary>
/// Validate whether the hand tracking is active.
/// </summary>
/// <returns>True if the hand tracking is active; otherwise, false.</returns>
public static bool Validate()
{
if (handSubsystem == null || !handSubsystem.running)
{
SubsystemManager.GetSubsystems(s_XRHandSubsystems);
for (int i = 0; i < s_XRHandSubsystems.Count; i++)
{
if (handSubsystem != null)
{
handSubsystem = null;
}
handSubsystem = s_XRHandSubsystems[i];
}
}
return handSubsystem != null && handSubsystem.running;
return VIVEInput.IsHandValidate();
}
/// <summary>
@@ -94,11 +74,8 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
/// <returns>True if the hand tracking is successfully tracking; otherwise, false.</returns>
public static bool IsHandTracked(bool isLeft)
{
if (handSubsystem != null)
{
return isLeft ? handSubsystem.leftHand.isTracked : handSubsystem.rightHand.isTracked;
}
return false;
Common.Handedness handedness = isLeft ? Common.Handedness.Left : Common.Handedness.Right;
return VIVEInput.IsHandTracked(handedness);
}
/// <summary>
@@ -111,53 +88,17 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
/// <returns></returns>
public static bool GetJointPose(JointType jointType, ref Vector3 position, ref Quaternion rotation, bool isLeft)
{
if (IsHandTracked(isLeft))
Common.Handedness handedness = isLeft ? Common.Handedness.Left : Common.Handedness.Right;
if (IsHandTracked(isLeft) &&
VIVEInput.GetJointPose(handedness, (HandJointType)jointType, out Pose jointPose))
{
XRHand hand = isLeft ? handSubsystem.leftHand : handSubsystem.rightHand;
XRHandJoint xrHandJoint = hand.GetJoint(ConvertToXRHandJointID(jointType));
if (xrHandJoint.TryGetPose(out Pose pose))
{
position = pose.position;
rotation = pose.rotation;
return true;
}
position = jointPose.position;
rotation = jointPose.rotation;
return true;
}
return false;
}
private static XRHandJointID ConvertToXRHandJointID(JointType jointType)
{
int id = (int)jointType;
switch (id)
{
case 0:
return XRHandJointID.Palm;
case 1:
return XRHandJointID.Wrist;
default:
return (XRHandJointID)(id + 1);
}
}
}
#else
public static class DataWrapper
{
public static bool Validate()
{
return false;
}
public static bool IsHandTracked(bool isLeft)
{
return false;
}
public static bool GetJointPose(JointType jointType, ref Vector3 position, ref Quaternion rotation, bool isLeft)
{
return false;
}
}
#endif
/// <summary>
/// The enum is designed to define the IDs of joints.
@@ -242,28 +183,38 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
{
public Vector3 direction = Vector3.zero;
public JointData[] joints = null;
public JointData joint0 {
get {
public JointData joint0
{
get
{
return joints[(Int32)JointId.Joint0];
}
}
public JointData joint1 {
get {
public JointData joint1
{
get
{
return joints[(Int32)JointId.Joint1];
}
}
public JointData joint2 {
get {
public JointData joint2
{
get
{
return joints[(Int32)JointId.Joint2];
}
}
public JointData joint3 {
get {
public JointData joint3
{
get
{
return joints[(Int32)JointId.Joint3];
}
}
public JointData tip {
get {
public JointData tip
{
get
{
return joints[(Int32)JointId.Tip];
}
}
@@ -692,28 +643,38 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
public JointData palm;
public JointData wrist;
public FingerData[] fingers = null; // size: FingerId.Count
public FingerData thumb {
get {
public FingerData thumb
{
get
{
return fingers[(Int32)FingerId.Thumb];
}
}
public FingerData index {
get {
public FingerData index
{
get
{
return fingers[(Int32)FingerId.Index];
}
}
public FingerData middle {
get {
public FingerData middle
{
get
{
return fingers[(Int32)FingerId.Middle];
}
}
public FingerData ring {
get {
public FingerData ring
{
get
{
return fingers[(Int32)FingerId.Ring];
}
}
public FingerData pinky {
get {
public FingerData pinky
{
get
{
return fingers[(Int32)FingerId.Pinky];
}
}
@@ -1026,13 +987,17 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
const string LOG_TAG = "VIVE.OpenXR.Toolkits.RealisticHandInteraction.HandGrabState.FingerPinchState ";
StringBuilder m_sb = null;
StringBuilder sb {
get {
StringBuilder sb
{
get
{
if (m_sb == null) { m_sb = new StringBuilder(); }
return m_sb;
}
}
void DEBUG(StringBuilder msg) { Debug.Log(msg); }
void DEBUG(string msg) { Debug.Log($"{LOG_TAG}, {msg}"); }
bool printIntervalLog = false;
int logFrame = 0;
private bool isLeft = false;
private FingerData thumbData;
@@ -1107,10 +1072,10 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
fingerData.joint2.position};
float distance = float.PositiveInfinity;
foreach (var fingerJointPos in fingerPos)
for (int i = 0; i < fingerPos.Length; i++)
{
distance = Mathf.Min(distance, CalculateShortestDistance(fingerJointPos, thumbTip, thumbJoint2));
distance = Mathf.Min(distance, CalculateShortestDistance(fingerJointPos, thumbJoint2, thumbJoint1));
distance = Mathf.Min(distance, CalculateShortestDistance(fingerPos[i], thumbTip, thumbJoint2));
distance = Mathf.Min(distance, CalculateShortestDistance(fingerPos[i], thumbJoint2, thumbJoint1));
}
return distance;
}
@@ -1169,12 +1134,14 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
m_isPinching = true;
minDistance = distance;
sb.Clear().Append(LOG_TAG).Append(isLeft ? "Left " : "Right ").Append(m_finger.Name())
.Append(" UpdateState() pinch strength: ").Append(m_pinchStrength)
.Append(", pinch on threshold: ").Append(kPinchStrengthOnThreshold)
.Append(", is pinching: ").Append(m_isPinching)
.Append(", pinch distance: ").Append(minDistance);
DEBUG(sb);
if (printIntervalLog)
{
DEBUG($"{(isLeft ? "Left " : "Right ")} {finger.Name()}" +
$" UpdateState() pinch strength: {m_pinchStrength}" +
$", pinch on threshold: {kPinchStrengthOnThreshold}" +
$", is pinching: {m_isPinching}" +
$", pinch distance: {minDistance}");
}
updated = true;
}
@@ -1187,12 +1154,14 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
{
m_isPinching = false;
sb.Clear().Append(LOG_TAG).Append(isLeft ? "Left " : "Right ").Append(m_finger.Name())
.Append(" UpdateState() pinch strength: ").Append(m_pinchStrength)
.Append(", pinch off threshold: ").Append(kPinchStrengthOffThreshold)
.Append(", is pinching: ").Append(m_isPinching)
.Append(", pinch distance: ").Append(minDistance);
DEBUG(sb);
if (printIntervalLog)
{
DEBUG($"{(isLeft ? "Left " : "Right ")} {finger.Name()}" +
$" UpdateState() pinch strength: {m_pinchStrength}" +
$", pinch off threshold: {kPinchStrengthOffThreshold}" +
$", is pinching: {m_isPinching}" +
$", pinch distance: {minDistance}");
}
updated = true;
}
@@ -1207,6 +1176,9 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
/// <param name="finger">The FingerData of the finger.</param>
public void Update(FingerData thumb, FingerData finger)
{
logFrame++;
logFrame %= 300;
printIntervalLog = logFrame == 0;
if (!Validate()) { return; }
this.thumbData = thumb;
@@ -1901,15 +1873,6 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
[Serializable]
public class HandGrabbableEvent : UnityEvent<IGrabbable> { };
[Obsolete("Please use HandGrabberEvent instead.")]
public delegate void OnBeginGrab(IGrabber grabber);
[Obsolete("Please use HandGrabberEvent instead.")]
public delegate void OnEndGrab(IGrabber grabber);
[Obsolete("Please use HandGrabbableEvent instead.")]
public delegate void OnBeginGrabbed(IGrabbable grabbable);
[Obsolete("Please use HandGrabbableEvent instead.")]
public delegate void OnEndGrabbed(IGrabbable grabbable);
/// <summary>
/// Interface for objects capable of grabbing.
/// </summary>
@@ -1919,15 +1882,6 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
bool isGrabbing { get; }
HandGrabberEvent onBeginGrab { get; }
HandGrabberEvent onEndGrab { get; }
[Obsolete("Please use onBeginGrab instead.")]
void AddBeginGrabListener(OnBeginGrab handler);
[Obsolete("Please use onBeginGrab instead.")]
void RemoveBeginGrabListener(OnBeginGrab handler);
[Obsolete("Please use onEndGrab instead.")]
void AddEndGrabListener(OnEndGrab handler);
[Obsolete("Please use onEndGrab instead.")]
void RemoveEndGrabListener(OnEndGrab handler);
}
/// <summary>
@@ -1950,15 +1904,6 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
HandGrabbableEvent onBeginGrabbed { get; }
HandGrabbableEvent onEndGrabbed { get; }
void SetGrabber(IGrabber grabber);
[Obsolete("Please use onBeginGrabbed instead.")]
void AddBeginGrabbedListener(OnBeginGrabbed handler);
[Obsolete("Please use onBeginGrabbed instead.")]
void RemoveBeginGrabbedListener(OnBeginGrabbed handler);
[Obsolete("Please use onEndGrabbed instead.")]
void AddEndGrabbedListener(OnEndGrabbed handler);
[Obsolete("Please use onEndGrabbed instead.")]
void RemoveEndGrabbedListener(OnEndGrabbed handler);
}
/// <summary>

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using VIVE.OpenXR.Toolkits.Common;
namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
{
@@ -50,6 +51,7 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
[SerializeField]
private Transform[] m_HandJoints = new Transform[k_JointCount];
private SkinnedMeshRenderer skinnedMeshRenderer = null;
private const int k_JointCount = (int)JointType.Count;
private const int k_RootId = (int)JointType.Wrist;
private bool updateRoot = false;
@@ -77,6 +79,8 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
MeshHandPose meshHandPose = transform.gameObject.AddComponent<MeshHandPose>();
meshHandPose.SetHandMeshRenderer(this);
skinnedMeshRenderer = transform.GetComponentInChildren<SkinnedMeshRenderer>();
}
private void OnDisable()
@@ -95,9 +99,9 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
private void Update()
{
HandData handData = CachedHand.Get(isLeft);
EnableHandModel(handData.isTracked);
if (!handData.isTracked) { return; }
bool isTracked = VIVEInput.IsHandTracked(isLeft ? Common.Handedness.Left : Common.Handedness.Right);
EnableHandModel(isTracked);
if (!isTracked) { return; }
//if (m_UseRuntimeModel || (!m_UseRuntimeModel && m_UseScale))
//{
@@ -118,22 +122,23 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
}
if (!updateRoot)
{
Vector3 rootPosition = Vector3.zero;
Quaternion rootRotation = Quaternion.identity;
handData.GetJointPosition((JointType)k_RootId, ref rootPosition);
handData.GetJointRotation((JointType)k_RootId, ref rootRotation);
m_HandJoints[k_RootId].position = m_HandJoints[k_RootId].parent.position + rootPosition;
m_HandJoints[k_RootId].rotation = m_HandJoints[k_RootId].parent.rotation * rootRotation;
VIVEInput.GetJointPose(isLeft ? Common.Handedness.Left : Common.Handedness.Right, HandJointType.Wrist, out Pose jointPose);
m_HandJoints[k_RootId].localPosition = jointPose.position;
m_HandJoints[k_RootId].localRotation = jointPose.rotation;
}
for (int i = 0; i < m_HandJoints.Length; i++)
{
if (m_HandJoints[i] == null || i == k_RootId) { continue; }
Quaternion jointRotation = Quaternion.identity;
handData.GetJointRotation((JointType)i, ref jointRotation);
m_HandJoints[i].rotation = m_HandJoints[k_RootId].parent.rotation * jointRotation;
VIVEInput.GetJointPose(isLeft ? Common.Handedness.Left : Common.Handedness.Right, (HandJointType)i, out Pose jointPose);
m_HandJoints[i].rotation = m_HandJoints[k_RootId].parent.rotation * jointPose.rotation;
}
if (VIVERig.Instance)
{
m_HandJoints[k_RootId].rotation = VIVERig.Instance.transform.rotation * m_HandJoints[k_RootId].localRotation;
m_HandJoints[k_RootId].position = VIVERig.Instance.transform.position + VIVERig.Instance.transform.rotation * m_HandJoints[k_RootId].localPosition;
}
if (isGrabbing)
@@ -343,6 +348,11 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
if (m_HandJoints[k_RootId].gameObject.activeSelf != enable)
{
m_HandJoints[k_RootId].gameObject.SetActive(enable);
if (skinnedMeshRenderer)
{
skinnedMeshRenderer.enabled = enable;
}
}
}

View File

@@ -83,11 +83,25 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
{
if (!HandPoseMap.ContainsKey(poseType))
{
UnityEngine.Object[] handObjects = UnityEngine.Object.FindObjectsOfType(typeof(RealHandPose));
for (int i = 0; i < handObjects.Length; i++)
{
UnityEngine.Object handObject = handObjects[i];
if (handObject is RealHandPose realHand &&
(realHand.isLeft ? poseType == HandPoseType.HAND_LEFT : poseType == HandPoseType.HAND_RIGHT))
{
realHand.SetType(poseType);
RegisterHandPose(poseType, realHand);
return realHand;
}
}
GameObject handPoseObject = new GameObject(poseName);
RealHandPose realHandPose = handPoseObject.AddComponent<RealHandPose>();
realHandPose.SetType(poseType);
RegisterHandPose(poseType, realHandPose);
return realHandPose;
RealHandPose newRealHand = handPoseObject.AddComponent<RealHandPose>();
newRealHand.SetType(poseType);
RegisterHandPose(poseType, newRealHand);
return newRealHand;
}
return HandPoseMap[poseType];
}

View File

@@ -7,7 +7,7 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
{
[SerializeField]
private Handedness m_Handedness;
private bool isLeft => m_Handedness == Handedness.Left;
public bool isLeft => m_Handedness == Handedness.Left;
private bool keepUpdate = false;
protected override void OnEnable()
@@ -66,8 +66,8 @@ namespace VIVE.OpenXR.Toolkits.RealisticHandInteraction
{
if (handData.GetJointPosition((JointType)i, ref position) && handData.GetJointRotation((JointType)i, ref rotation))
{
m_Position[i] = position;
m_Rotation[i] = rotation;
m_Position[i] = transform.position + transform.rotation * position;
m_Rotation[i] = transform.rotation * rotation;
m_LocalPosition[i] = position;
m_LocalRotation[i] = rotation;
}