VR4RoboticArm2/VR4RoboticArm/Library/PackageCache/com.meta.xr.sdk.interaction/Runtime/Scripts/Grab/ControllerPinchInjector.cs
IonutMocanu d7aba243a2 Main
2025-09-08 11:04:02 +03:00

181 lines
6.2 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 Oculus.Interaction.Input;
using UnityEngine;
namespace Oculus.Interaction.GrabAPI
{
/// <summary>
/// Use this component with a HandGrabAPI so it uses the Controller
/// trigger (index finger) and grip (middle finger) to drive the FingerAPIs.
/// </summary>
public class ControllerPinchInjector : MonoBehaviour
{
[SerializeField]
private HandGrabAPI _handGrabAPI;
[SerializeField, Interface(typeof(IController))]
private UnityEngine.Object _controller;
private IController Controller { get; set; }
protected bool _started;
protected virtual void Awake()
{
Controller = _controller as IController;
}
protected virtual void Start()
{
this.BeginStart(ref _started);
this.AssertField(_handGrabAPI, nameof(_handGrabAPI));
this.AssertField(Controller, nameof(Controller));
_handGrabAPI.InjectOptionalFingerPinchAPI(new ControllerPinchAPI(Controller));
_handGrabAPI.InjectOptionalFingerGrabAPI(new ControllerPinchAPI(Controller));
this.EndStart(ref _started);
}
#region Inject
public void InjectAll(HandGrabAPI handGrabAPI, IController controller)
{
InjectHandGrabAPI(handGrabAPI);
InjectController(controller);
}
public void InjectHandGrabAPI(HandGrabAPI handGrabAPI)
{
_handGrabAPI = handGrabAPI;
}
public void InjectController(IController controller)
{
_controller = controller as UnityEngine.Object;
Controller = controller;
}
#endregion
private class ControllerPinchAPI : IFingerAPI
{
private IController _controller;
private float _triggerStrength = 0f;
private float _gripStrength = 0f;
private bool _triggerDown = false;
private bool _gripDown = false;
private bool _prevTriggerDown;
private bool _prevGripDown;
private Pose _indexPinchPose = Pose.identity;
private Pose _middlePinchPose = Pose.identity;
private Pose _pinchPose = Pose.identity;
public ControllerPinchAPI(IController controller)
{
_controller = controller;
}
public float GetFingerGrabScore(HandFinger finger)
{
switch (finger)
{
case HandFinger.Thumb: return _triggerStrength;
case HandFinger.Index: return _triggerStrength;
case HandFinger.Middle:
case HandFinger.Ring:
case HandFinger.Pinky: return _gripStrength;
default: return 0f;
}
}
public bool GetFingerIsGrabbing(HandFinger finger)
{
switch (finger)
{
case HandFinger.Thumb: return _triggerDown;
case HandFinger.Index: return _triggerDown;
case HandFinger.Middle:
case HandFinger.Ring:
case HandFinger.Pinky: return _gripDown;
default: return false;
}
}
public bool GetFingerIsGrabbingChanged(HandFinger finger, bool targetPinchState)
{
switch (finger)
{
case HandFinger.Thumb:
return (_triggerDown == targetPinchState
&& _triggerDown != _prevTriggerDown)
|| (_gripDown == targetPinchState
&& _gripDown != _prevGripDown);
case HandFinger.Index:
return _triggerDown == targetPinchState
&& _triggerDown != _prevTriggerDown;
case HandFinger.Middle:
case HandFinger.Ring:
case HandFinger.Pinky:
return _gripDown == targetPinchState
&& _gripDown != _prevGripDown;
default: return false;
}
}
public Vector3 GetWristOffsetLocal()
{
return _pinchPose.position;
}
public void Update(IHand hand)
{
ControllerInput input = _controller.ControllerInput;
_prevGripDown = _gripDown;
_prevTriggerDown = _triggerDown;
_triggerStrength = input.Trigger;
_triggerDown = input.TriggerButton;
_gripStrength = input.Grip;
_gripDown = input.GripButton;
hand.GetJointPoseFromWrist(HandJointId.HandIndexTip, out _indexPinchPose);
hand.GetJointPoseFromWrist(HandJointId.HandMiddleTip, out _middlePinchPose);
hand.GetJointPoseFromWrist(HandJointId.HandThumbTip, out Pose thumbPose);
PoseUtils.Lerp(ref _indexPinchPose, thumbPose, 0.5f);
PoseUtils.Lerp(ref _middlePinchPose, thumbPose, 0.5f);
float combinedStrength = _triggerStrength + _gripStrength;
float t = combinedStrength > 0f ? _gripStrength / combinedStrength : 0.5f;
PoseUtils.Lerp(_indexPinchPose, _middlePinchPose, t, ref _pinchPose);
}
}
}
}