version 2.5.0
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user