mirror of
https://github.com/xiaopeng12138/MaiDXR.git
synced 2024-12-19 04:15:53 +01:00
231 lines
6.5 KiB
C#
231 lines
6.5 KiB
C#
|
/*
|
||
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* Licensed under the Oculus SDK License Agreement (the "License");
|
||
|
* you may not use the Oculus SDK except in compliance with the License,
|
||
|
* which is provided at the time of installation or download, or which
|
||
|
* otherwise accompanies this software in either electronic or hard copy form.
|
||
|
*
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* https://developer.oculus.com/licenses/oculussdk/
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
|
||
|
using System.Collections;
|
||
|
using System.Collections.Generic;
|
||
|
using UnityEngine;
|
||
|
|
||
|
[DefaultExecutionOrder(-90)]
|
||
|
public class OVRHand : MonoBehaviour,
|
||
|
OVRSkeleton.IOVRSkeletonDataProvider,
|
||
|
OVRSkeletonRenderer.IOVRSkeletonRendererDataProvider,
|
||
|
OVRMesh.IOVRMeshDataProvider,
|
||
|
OVRMeshRenderer.IOVRMeshRendererDataProvider
|
||
|
{
|
||
|
public enum Hand
|
||
|
{
|
||
|
None = OVRPlugin.Hand.None,
|
||
|
HandLeft = OVRPlugin.Hand.HandLeft,
|
||
|
HandRight = OVRPlugin.Hand.HandRight,
|
||
|
}
|
||
|
|
||
|
public enum HandFinger
|
||
|
{
|
||
|
Thumb = OVRPlugin.HandFinger.Thumb,
|
||
|
Index = OVRPlugin.HandFinger.Index,
|
||
|
Middle = OVRPlugin.HandFinger.Middle,
|
||
|
Ring = OVRPlugin.HandFinger.Ring,
|
||
|
Pinky = OVRPlugin.HandFinger.Pinky,
|
||
|
Max = OVRPlugin.HandFinger.Max,
|
||
|
}
|
||
|
|
||
|
public enum TrackingConfidence
|
||
|
{
|
||
|
Low = OVRPlugin.TrackingConfidence.Low,
|
||
|
High = OVRPlugin.TrackingConfidence.High
|
||
|
}
|
||
|
|
||
|
[SerializeField]
|
||
|
private Hand HandType = Hand.None;
|
||
|
[SerializeField]
|
||
|
private Transform _pointerPoseRoot = null;
|
||
|
private GameObject _pointerPoseGO;
|
||
|
private OVRPlugin.HandState _handState = new OVRPlugin.HandState();
|
||
|
|
||
|
public bool IsDataValid { get; private set; }
|
||
|
public bool IsDataHighConfidence { get; private set; }
|
||
|
public bool IsTracked { get; private set; }
|
||
|
public bool IsSystemGestureInProgress { get; private set; }
|
||
|
public bool IsPointerPoseValid { get; private set; }
|
||
|
public Transform PointerPose { get; private set; }
|
||
|
public float HandScale { get; private set; }
|
||
|
public TrackingConfidence HandConfidence { get; private set; }
|
||
|
public bool IsDominantHand { get; private set; }
|
||
|
|
||
|
private void Awake()
|
||
|
{
|
||
|
_pointerPoseGO = new GameObject();
|
||
|
PointerPose = _pointerPoseGO.transform;
|
||
|
if (_pointerPoseRoot != null)
|
||
|
{
|
||
|
PointerPose.SetParent(_pointerPoseRoot, false);
|
||
|
}
|
||
|
|
||
|
GetHandState(OVRPlugin.Step.Render);
|
||
|
}
|
||
|
|
||
|
private void Update()
|
||
|
{
|
||
|
GetHandState(OVRPlugin.Step.Render);
|
||
|
}
|
||
|
|
||
|
private void FixedUpdate()
|
||
|
{
|
||
|
if (OVRPlugin.nativeXrApi != OVRPlugin.XrApi.OpenXR)
|
||
|
{
|
||
|
GetHandState(OVRPlugin.Step.Physics);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void GetHandState(OVRPlugin.Step step)
|
||
|
{
|
||
|
if (OVRPlugin.GetHandState(step, (OVRPlugin.Hand)HandType, ref _handState))
|
||
|
{
|
||
|
IsTracked = (_handState.Status & OVRPlugin.HandStatus.HandTracked) != 0;
|
||
|
IsSystemGestureInProgress = (_handState.Status & OVRPlugin.HandStatus.SystemGestureInProgress) != 0;
|
||
|
IsPointerPoseValid = (_handState.Status & OVRPlugin.HandStatus.InputStateValid) != 0;
|
||
|
IsDominantHand = (_handState.Status & OVRPlugin.HandStatus.DominantHand) != 0;
|
||
|
PointerPose.localPosition = _handState.PointerPose.Position.FromFlippedZVector3f();
|
||
|
PointerPose.localRotation = _handState.PointerPose.Orientation.FromFlippedZQuatf();
|
||
|
HandScale = _handState.HandScale;
|
||
|
HandConfidence = (TrackingConfidence)_handState.HandConfidence;
|
||
|
|
||
|
IsDataValid = true;
|
||
|
IsDataHighConfidence = IsTracked && HandConfidence == TrackingConfidence.High;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
IsTracked = false;
|
||
|
IsSystemGestureInProgress = false;
|
||
|
IsPointerPoseValid = false;
|
||
|
PointerPose.localPosition = Vector3.zero;
|
||
|
PointerPose.localRotation = Quaternion.identity;
|
||
|
HandScale = 1.0f;
|
||
|
HandConfidence = TrackingConfidence.Low;
|
||
|
|
||
|
IsDataValid = false;
|
||
|
IsDataHighConfidence = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public bool GetFingerIsPinching(HandFinger finger)
|
||
|
{
|
||
|
return IsDataValid && (((int)_handState.Pinches & (1 << (int)finger)) != 0);
|
||
|
}
|
||
|
|
||
|
public float GetFingerPinchStrength(HandFinger finger)
|
||
|
{
|
||
|
if (IsDataValid
|
||
|
&& _handState.PinchStrength != null
|
||
|
&& _handState.PinchStrength.Length == (int)OVRPlugin.HandFinger.Max)
|
||
|
{
|
||
|
return _handState.PinchStrength[(int)finger];
|
||
|
}
|
||
|
|
||
|
return 0.0f;
|
||
|
}
|
||
|
|
||
|
public TrackingConfidence GetFingerConfidence(HandFinger finger)
|
||
|
{
|
||
|
if (IsDataValid
|
||
|
&& _handState.FingerConfidences != null
|
||
|
&& _handState.FingerConfidences.Length == (int)OVRPlugin.HandFinger.Max)
|
||
|
{
|
||
|
return (TrackingConfidence)_handState.FingerConfidences[(int)finger];
|
||
|
}
|
||
|
|
||
|
return TrackingConfidence.Low;
|
||
|
}
|
||
|
|
||
|
OVRSkeleton.SkeletonType OVRSkeleton.IOVRSkeletonDataProvider.GetSkeletonType()
|
||
|
{
|
||
|
switch (HandType)
|
||
|
{
|
||
|
case Hand.HandLeft:
|
||
|
return OVRSkeleton.SkeletonType.HandLeft;
|
||
|
case Hand.HandRight:
|
||
|
return OVRSkeleton.SkeletonType.HandRight;
|
||
|
case Hand.None:
|
||
|
default:
|
||
|
return OVRSkeleton.SkeletonType.None;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
OVRSkeleton.SkeletonPoseData OVRSkeleton.IOVRSkeletonDataProvider.GetSkeletonPoseData()
|
||
|
{
|
||
|
var data = new OVRSkeleton.SkeletonPoseData();
|
||
|
|
||
|
data.IsDataValid = IsDataValid;
|
||
|
if (IsDataValid)
|
||
|
{
|
||
|
data.RootPose = _handState.RootPose;
|
||
|
data.RootScale = _handState.HandScale;
|
||
|
data.BoneRotations = _handState.BoneRotations;
|
||
|
data.IsDataHighConfidence = IsTracked && HandConfidence == TrackingConfidence.High;
|
||
|
}
|
||
|
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
OVRSkeletonRenderer.SkeletonRendererData OVRSkeletonRenderer.IOVRSkeletonRendererDataProvider.GetSkeletonRendererData()
|
||
|
{
|
||
|
var data = new OVRSkeletonRenderer.SkeletonRendererData();
|
||
|
|
||
|
data.IsDataValid = IsDataValid;
|
||
|
if (IsDataValid)
|
||
|
{
|
||
|
data.RootScale = _handState.HandScale;
|
||
|
data.IsDataHighConfidence = IsTracked && HandConfidence == TrackingConfidence.High;
|
||
|
data.ShouldUseSystemGestureMaterial = IsSystemGestureInProgress;
|
||
|
}
|
||
|
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
OVRMesh.MeshType OVRMesh.IOVRMeshDataProvider.GetMeshType()
|
||
|
{
|
||
|
switch (HandType)
|
||
|
{
|
||
|
case Hand.None:
|
||
|
return OVRMesh.MeshType.None;
|
||
|
case Hand.HandLeft:
|
||
|
return OVRMesh.MeshType.HandLeft;
|
||
|
case Hand.HandRight:
|
||
|
return OVRMesh.MeshType.HandRight;
|
||
|
default:
|
||
|
return OVRMesh.MeshType.None;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
OVRMeshRenderer.MeshRendererData OVRMeshRenderer.IOVRMeshRendererDataProvider.GetMeshRendererData()
|
||
|
{
|
||
|
var data = new OVRMeshRenderer.MeshRendererData();
|
||
|
|
||
|
data.IsDataValid = IsDataValid;
|
||
|
if (IsDataValid)
|
||
|
{
|
||
|
data.IsDataHighConfidence = IsTracked && HandConfidence == TrackingConfidence.High;
|
||
|
data.ShouldUseSystemGestureMaterial = IsSystemGestureInProgress;
|
||
|
}
|
||
|
|
||
|
return data;
|
||
|
}
|
||
|
}
|