/*
* 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 System.Collections.Generic;
using UnityEngine;
namespace Oculus.Interaction
{
///
/// Exposes a hand tracking confidence value for an interactor. An
/// can be associated with a with this component, this confidence
/// status can be fetched using an as a key.
///
public class HandTrackingConfidenceProvider : MonoBehaviour
{
[SerializeField, Interface(typeof(IInteractor))]
private UnityEngine.Object _interactor;
private IInteractor Interactor;
[SerializeField, Interface(typeof(IHand))]
private UnityEngine.Object _hand;
private IHand Hand { get; set; }
private static Dictionary _interactorTrackingConfidence;
protected bool _started;
#region Editor Callbacks
protected virtual void Reset()
{
_interactor = this.GetComponent() as UnityEngine.Object;
_hand = this.GetComponent() as UnityEngine.Object;
}
#endregion
protected virtual void Awake()
{
if (_interactorTrackingConfidence == null)
{
_interactorTrackingConfidence = new Dictionary();
}
Interactor = _interactor as IInteractor;
Hand = _hand as IHand;
}
protected virtual void Start()
{
this.BeginStart(ref _started);
this.AssertField(Interactor, nameof(_interactor));
this.AssertField(Hand, nameof(_hand));
this.EndStart(ref _started);
}
protected virtual void OnEnable()
{
if (_started)
{
int key = Interactor.Identifier;
if (_interactorTrackingConfidence != null && !_interactorTrackingConfidence.ContainsKey(key))
{
_interactorTrackingConfidence.Add(key, this);
}
else
{
Debug.LogError($"This interactor was already added to {nameof(HandTrackingConfidenceProvider)}. "
+ $"Ensure each interactor is paired just once");
}
}
}
protected virtual void OnDisable()
{
if (_started)
{
int key = Interactor.Identifier;
if (_interactorTrackingConfidence != null && _interactorTrackingConfidence.ContainsKey(key))
{
_interactorTrackingConfidence.Remove(Interactor.Identifier);
}
}
}
///
/// Retrieves the value for the
/// associated with the provided , if present.
///
/// The of the interactor.
/// True if the is tracked with high confidence.
/// True if the provided interactor is associated with an , and confidence
/// value can be retrieved.
public static bool TryGetTrackingConfidence(int key, out bool isTrackingHighConfidence)
{
if (_interactorTrackingConfidence != null && _interactorTrackingConfidence.ContainsKey(key))
{
isTrackingHighConfidence = _interactorTrackingConfidence[key].Hand.IsHighConfidence;
return true;
}
isTrackingHighConfidence = true;
return false;
}
#region Inject
///
/// Injects all required dependencies for a dynamically instantiated
/// .
/// This method exists to support Interaction SDK's dependency injection pattern and is not
/// needed for typical Unity Editor-based usage.
///
public void InjectAllHandTrackingConfidenceProvider(IInteractor interactor, IHand hand)
{
InjectInteractor(interactor);
InjectHand(hand);
}
///
/// Sets the underlying for a dynamically instantiated
/// .
/// This method exists to support Interaction SDK's dependency injection pattern and is not
/// needed for typical Unity Editor-based usage.
///
public void InjectInteractor(IInteractor interactor)
{
_interactor = interactor as UnityEngine.Object;
Interactor = interactor;
}
///
/// Sets the underlying for a dynamically instantiated
/// .
/// This method exists to support Interaction SDK's dependency injection pattern and is not
/// needed for typical Unity Editor-based usage.
///
public void InjectHand(IHand hand)
{
_hand = hand as UnityEngine.Object;
Hand = hand;
}
#endregion
}
}