修改
This commit is contained in:
@@ -1,150 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Rokid.UXR.Interaction;
|
||||
|
||||
namespace Stary.Evo.RKTools
|
||||
{
|
||||
public abstract class GestureBase : MonoBehaviour
|
||||
{
|
||||
private GestureBean leftBean = null;
|
||||
private GestureBean rightBean = null;
|
||||
|
||||
protected void OnEnable()
|
||||
{
|
||||
GesEventInput.OnTrackedSuccess += OnTrackedSuccess;
|
||||
GesEventInput.OnTrackedFailed += OnTrackedFailed;
|
||||
GesEventInput.OnRenderHand += OnRenderHand;
|
||||
}
|
||||
|
||||
protected void OnDisable()
|
||||
{
|
||||
GesEventInput.OnTrackedSuccess -= OnTrackedSuccess;
|
||||
GesEventInput.OnTrackedFailed -= OnTrackedFailed;
|
||||
GesEventInput.OnRenderHand -= OnRenderHand;
|
||||
}
|
||||
|
||||
protected void FixedUpdate()
|
||||
{
|
||||
if (leftBean != null)
|
||||
{
|
||||
GestureType type = GesEventInput.Instance.GetGestureType(HandType.LeftHand);
|
||||
Vector3 handForward = GetSkeletonPose(SkeletonIndexFlag.PALM, HandType.LeftHand).forward;
|
||||
GestureLeftSuccess(type, handForward);
|
||||
}
|
||||
else
|
||||
{
|
||||
GestureLeftFail();
|
||||
}
|
||||
|
||||
if (rightBean != null)
|
||||
{
|
||||
GestureType type = GesEventInput.Instance.GetGestureType(HandType.RightHand);
|
||||
Vector3 handForward = GetSkeletonPose(SkeletonIndexFlag.PALM, HandType.RightHand).forward;
|
||||
GestureRightSuccess(type, handForward);
|
||||
}
|
||||
else
|
||||
{
|
||||
GestureRightFail();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTrackedSuccess(HandType handType)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void OnTrackedFailed(HandType handType)
|
||||
{
|
||||
if (handType == HandType.None)
|
||||
{
|
||||
leftBean = null;
|
||||
rightBean = null;
|
||||
}
|
||||
|
||||
if (handType == HandType.RightHand)
|
||||
{
|
||||
rightBean = null;
|
||||
}
|
||||
|
||||
if (handType == HandType.LeftHand)
|
||||
{
|
||||
leftBean = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRenderHand(HandType handType, GestureBean gestureBean)
|
||||
{
|
||||
if (handType == HandType.RightHand)
|
||||
{
|
||||
rightBean = gestureBean;
|
||||
}
|
||||
|
||||
if (handType == HandType.LeftHand)
|
||||
{
|
||||
leftBean = gestureBean;
|
||||
}
|
||||
|
||||
if (handType == HandType.None)
|
||||
{
|
||||
rightBean = null;
|
||||
leftBean = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取骨架点位置
|
||||
/// </summary>
|
||||
/// <param name="index">骨架序号</param>
|
||||
/// <param name="hand">哪只手</param>
|
||||
/// <returns></returns>
|
||||
public Pose GetSkeletonPose(SkeletonIndexFlag index, HandType hand)
|
||||
{
|
||||
return GesEventInput.Instance.GetSkeletonPose(index, hand);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取手地朝向
|
||||
/// </summary>
|
||||
/// <param name="handType">哪只手</param>
|
||||
/// <returns></returns>
|
||||
public Vector3 GetHandForward(HandType handType)
|
||||
{
|
||||
Vector3 handForward = (GetSkeletonPose(SkeletonIndexFlag.MIDDLE_FINGER_MCP, handType).position -
|
||||
GetSkeletonPose(SkeletonIndexFlag.WRIST, handType).position);
|
||||
return handForward;
|
||||
}
|
||||
|
||||
|
||||
#region 需要被重写的方法
|
||||
|
||||
/// <summary>
|
||||
/// 左手成功识别到手势不断执行操作
|
||||
/// </summary>
|
||||
/// <param name="gestureType">左手手势类型</param>
|
||||
/// <param name="handForward">左手掌心朝向</param>
|
||||
public abstract void GestureLeftSuccess(GestureType gestureType, Vector3 handForward);
|
||||
|
||||
/// <summary>
|
||||
/// 右手成功识别到手势不断执行操作
|
||||
/// </summary>
|
||||
/// <param name="gestureType">右手手势类型</param>
|
||||
/// <param name="handForward">右手掌心朝向</param>
|
||||
public abstract void GestureRightSuccess(GestureType gestureType, Vector3 handForward);
|
||||
|
||||
/// <summary>
|
||||
/// 左手未识别到手势执行操作
|
||||
/// </summary>
|
||||
public abstract void GestureLeftFail();
|
||||
|
||||
/// <summary>
|
||||
/// 右手未识别到手势执行操作
|
||||
/// </summary>
|
||||
public abstract void GestureRightFail();
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
153
Assets/07.RKTools/RunTime/GestureRecognition/GestureRokidBase.cs
Normal file
153
Assets/07.RKTools/RunTime/GestureRecognition/GestureRokidBase.cs
Normal file
@@ -0,0 +1,153 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Stary.Evo.RKTools
|
||||
{
|
||||
#if Evo_Rokid
|
||||
public abstract class GestureRokidBase : MonoBehaviour
|
||||
{
|
||||
private Rokid.UXR.Interaction.GestureBean leftBean = null;
|
||||
private Rokid.UXR.Interaction.GestureBean rightBean = null;
|
||||
protected void OnEnable()
|
||||
{
|
||||
Rokid.UXR.Interaction.GesEventInput.OnTrackedSuccess += OnTrackedSuccess;
|
||||
Rokid.UXR.Interaction.GesEventInput.OnTrackedFailed += OnTrackedFailed;
|
||||
Rokid.UXR.Interaction.GesEventInput.OnRenderHand += OnRenderHand;
|
||||
}
|
||||
|
||||
protected void OnDisable()
|
||||
{
|
||||
Rokid.UXR.Interaction.GesEventInput.OnTrackedSuccess -= OnTrackedSuccess;
|
||||
Rokid.UXR.Interaction.GesEventInput.OnTrackedFailed -= OnTrackedFailed;
|
||||
Rokid.UXR.Interaction.GesEventInput.OnRenderHand -= OnRenderHand;
|
||||
}
|
||||
|
||||
protected void FixedUpdate()
|
||||
{
|
||||
if (leftBean != null)
|
||||
{
|
||||
Rokid.UXR.Interaction.GestureType type =
|
||||
Rokid.UXR.Interaction.GesEventInput.Instance.GetGestureType(Rokid.UXR.Interaction.HandType.LeftHand);
|
||||
Vector3 handForward =
|
||||
GetSkeletonPose(Rokid.UXR.Interaction.SkeletonIndexFlag.PALM, Rokid.UXR.Interaction.HandType.LeftHand).forward;
|
||||
GestureLeftSuccess(type, handForward);
|
||||
}
|
||||
else
|
||||
{
|
||||
GestureLeftFail();
|
||||
}
|
||||
|
||||
if (rightBean != null)
|
||||
{
|
||||
Rokid.UXR.Interaction.GestureType type =
|
||||
Rokid.UXR.Interaction.GesEventInput.Instance.GetGestureType(Rokid.UXR.Interaction.HandType.RightHand);
|
||||
Vector3 handForward =
|
||||
GetSkeletonPose(Rokid.UXR.Interaction.SkeletonIndexFlag.PALM, Rokid.UXR.Interaction.HandType.RightHand).forward;
|
||||
GestureRightSuccess(type, handForward);
|
||||
}
|
||||
else
|
||||
{
|
||||
GestureRightFail();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTrackedSuccess(Rokid.UXR.Interaction.HandType handType)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void OnTrackedFailed(Rokid.UXR.Interaction.HandType handType)
|
||||
{
|
||||
if (handType == Rokid.UXR.Interaction.HandType.None)
|
||||
{
|
||||
leftBean = null;
|
||||
rightBean = null;
|
||||
}
|
||||
|
||||
if (handType == Rokid.UXR.Interaction.HandType.RightHand)
|
||||
{
|
||||
rightBean = null;
|
||||
}
|
||||
|
||||
if (handType == Rokid.UXR.Interaction.HandType.LeftHand)
|
||||
{
|
||||
leftBean = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRenderHand(Rokid.UXR.Interaction.HandType handType, Rokid.UXR.Interaction.GestureBean gestureBean)
|
||||
{
|
||||
if (handType == Rokid.UXR.Interaction.HandType.RightHand)
|
||||
{
|
||||
rightBean = gestureBean;
|
||||
}
|
||||
|
||||
if (handType == Rokid.UXR.Interaction.HandType.LeftHand)
|
||||
{
|
||||
leftBean = gestureBean;
|
||||
}
|
||||
|
||||
if (handType == Rokid.UXR.Interaction.HandType.None)
|
||||
{
|
||||
rightBean = null;
|
||||
leftBean = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取骨架点位置
|
||||
/// </summary>
|
||||
/// <param name="index">骨架序号</param>
|
||||
/// <param name="hand">哪只手</param>
|
||||
/// <returns></returns>
|
||||
public Pose GetSkeletonPose(Rokid.UXR.Interaction.SkeletonIndexFlag index, Rokid.UXR.Interaction.HandType hand)
|
||||
{
|
||||
return Rokid.UXR.Interaction.GesEventInput.Instance.GetSkeletonPose(index, hand);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取手地朝向
|
||||
/// </summary>
|
||||
/// <param name="handType">哪只手</param>
|
||||
/// <returns></returns>
|
||||
public Vector3 GetHandForward(Rokid.UXR.Interaction.HandType handType)
|
||||
{
|
||||
Vector3 handForward =
|
||||
(GetSkeletonPose(Rokid.UXR.Interaction.SkeletonIndexFlag.MIDDLE_FINGER_MCP, handType).position -
|
||||
GetSkeletonPose(Rokid.UXR.Interaction.SkeletonIndexFlag.WRIST, handType).position);
|
||||
return handForward;
|
||||
}
|
||||
|
||||
|
||||
#region 需要被重写的方法
|
||||
|
||||
/// <summary>
|
||||
/// 左手成功识别到手势不断执行操作
|
||||
/// </summary>
|
||||
/// <param name="gestureType">左手手势类型</param>
|
||||
/// <param name="handForward">左手掌心朝向</param>
|
||||
public abstract void GestureLeftSuccess(Rokid.UXR.Interaction.GestureType gestureType, Vector3 handForward);
|
||||
|
||||
/// <summary>
|
||||
/// 右手成功识别到手势不断执行操作
|
||||
/// </summary>
|
||||
/// <param name="gestureType">右手手势类型</param>
|
||||
/// <param name="handForward">右手掌心朝向</param>
|
||||
public abstract void GestureRightSuccess(Rokid.UXR.Interaction.GestureType gestureType, Vector3 handForward);
|
||||
|
||||
/// <summary>
|
||||
/// 左手未识别到手势执行操作
|
||||
/// </summary>
|
||||
public abstract void GestureLeftFail();
|
||||
|
||||
/// <summary>
|
||||
/// 右手未识别到手势执行操作
|
||||
/// </summary>
|
||||
public abstract void GestureRightFail();
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
126
Assets/07.RKTools/RunTime/GestureRecognition/GestureXrealBase.cs
Normal file
126
Assets/07.RKTools/RunTime/GestureRecognition/GestureXrealBase.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Stary.Evo.RKTools
|
||||
{
|
||||
#if Evo_Xreal
|
||||
public abstract class GestureXrealBase : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private UnityEngine.XR.Hands.Handedness m_Handedness;
|
||||
|
||||
private UnityEngine.XR.Hands.XRHandTrackingEvents handTrackingEvents = null;
|
||||
|
||||
[SerializeField] [Tooltip("The hand shape or pose that must be detected for the gesture to be performed.")]
|
||||
private ScriptableObject m_HandShapeOrPose;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip(
|
||||
"The minimum amount of time the hand must be held in the required shape and orientation for the gesture to be performed.")]
|
||||
float m_MinimumHoldTime = 0.2f;
|
||||
|
||||
[SerializeField] [Tooltip("The interval at which the gesture detection is performed.")]
|
||||
private float m_GestureDetectionInterval = 0.1f;
|
||||
|
||||
private float m_TimeOfLastConditionCheck;
|
||||
private UnityEngine.XR.Hands.Gestures.XRHandShape m_HandShape;
|
||||
private UnityEngine.XR.Hands.Gestures.XRHandPose m_HandPose;
|
||||
|
||||
private bool m_WasDetected; // 上一帧是否检测到手势
|
||||
private bool m_PerformedTriggered; // 手势执行事件是否已触发
|
||||
private float m_HoldStartTime; // 手势开始保持的时间
|
||||
|
||||
protected void OnEnable()
|
||||
{
|
||||
var trackingEvents = GameObject.FindObjectsOfType<UnityEngine.XR.Hands.XRHandTrackingEvents>();
|
||||
if (handTrackingEvents == null)
|
||||
{
|
||||
foreach (var track in trackingEvents)
|
||||
{
|
||||
if (track.handedness == m_Handedness)
|
||||
{
|
||||
handTrackingEvents = track;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handTrackingEvents.jointsUpdated.AddListener(OnJointsUpdated);
|
||||
m_HandShape = m_HandShapeOrPose as UnityEngine.XR.Hands.Gestures.XRHandShape;
|
||||
m_HandPose = m_HandShapeOrPose as UnityEngine.XR.Hands.Gestures.XRHandPose;
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
handTrackingEvents.jointsUpdated.RemoveListener(OnJointsUpdated);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 手部关节数据更新时的回调方法
|
||||
/// </summary>
|
||||
/// <param name="eventArgs">关节更新事件参数,包含手部关节数据</param>
|
||||
void OnJointsUpdated(UnityEngine.XR.Hands.XRHandJointsUpdatedEventArgs eventArgs)
|
||||
{
|
||||
// 检查是否在检测间隔内,避免过于频繁的检测
|
||||
if (!isActiveAndEnabled ||
|
||||
Time.timeSinceLevelLoad < m_TimeOfLastConditionCheck + m_GestureDetectionInterval)
|
||||
return;
|
||||
|
||||
// 检查手部是否被跟踪,以及是否满足形状或姿势条件
|
||||
var detected =
|
||||
handTrackingEvents.handIsTracked &&
|
||||
(m_HandShape != null && m_HandShape.CheckConditions(eventArgs) ||
|
||||
m_HandPose != null && m_HandPose.CheckConditions(eventArgs));
|
||||
|
||||
// 处理检测状态的变化
|
||||
if (!m_WasDetected && detected)
|
||||
{
|
||||
// 开始检测到手势,记录开始时间
|
||||
m_HoldStartTime = Time.timeSinceLevelLoad;
|
||||
}
|
||||
else if (m_WasDetected && !detected)
|
||||
{
|
||||
// 手势结束,重置触发状态并触发结束事件
|
||||
m_PerformedTriggered = false;
|
||||
GestureFail();
|
||||
// m_Background.color = m_BackgroundDefaultColor;
|
||||
}
|
||||
|
||||
// 更新检测状态
|
||||
m_WasDetected = detected;
|
||||
|
||||
// 检查是否满足保持时间要求
|
||||
if (!m_PerformedTriggered && detected)
|
||||
{
|
||||
var holdTimer = Time.timeSinceLevelLoad - m_HoldStartTime;
|
||||
if (holdTimer > m_MinimumHoldTime)
|
||||
{
|
||||
// 满足保持时间,触发手势执行事件
|
||||
GestureSuccess();
|
||||
m_PerformedTriggered = true;
|
||||
// m_Background.color = m_BackgroundHiglightColor;
|
||||
}
|
||||
}
|
||||
|
||||
// 更新上次检查时间
|
||||
m_TimeOfLastConditionCheck = Time.timeSinceLevelLoad;
|
||||
}
|
||||
|
||||
#region 需要被重写的方法
|
||||
|
||||
/// <summary>
|
||||
/// 左手成功识别到手势不断执行操作
|
||||
/// </summary>
|
||||
/// <param name="gestureType">左手手势类型</param>
|
||||
/// <param name="handForward">左手掌心朝向</param>
|
||||
public abstract void GestureSuccess();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 左手未识别到手势执行操作
|
||||
/// </summary>
|
||||
public abstract void GestureFail();
|
||||
|
||||
#endregion
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 962d6dd939fb40158b6e408420acdf6f
|
||||
timeCreated: 1774261529
|
||||
Reference in New Issue
Block a user