Heroes_of_Hiis/Assets/Oculus/Interaction/Runtime/Scripts/PoseDetection/ShapeRecognizerActiveState.cs

147 lines
4.9 KiB
C#
Raw Normal View History

2022-03-07 15:52:41 +00:00
/************************************************************************************
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
Your use of this SDK or tool is subject to the Oculus SDK License Agreement, available at
https://developer.oculus.com/licenses/oculussdk/
Unless required by applicable law or agreed to in writing, the Utilities 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;
using UnityEngine.Assertions;
using UnityEngine.Serialization;
namespace Oculus.Interaction.PoseDetection
{
public class ShapeRecognizerActiveState : MonoBehaviour, IActiveState
{
[SerializeField, Interface(typeof(IHand))]
private MonoBehaviour _hand;
public IHand Hand { get; private set; }
[SerializeField]
private ShapeRecognizer[] _shapes;
public IReadOnlyList<ShapeRecognizer> Shapes => _shapes;
private IFingerFeatureStateProvider FingerFeatureStateProvider { get; set; }
public Handedness Handedness => Hand.Handedness;
struct FingerFeatureStateUsage
{
public HandFinger handFinger;
public ShapeRecognizer.FingerFeatureConfig config;
}
private List<FingerFeatureStateUsage> _allFingerStates = new List<FingerFeatureStateUsage>();
protected virtual void Awake()
{
Hand = _hand as IHand;
}
protected virtual void Start()
{
Assert.IsNotNull(Hand);
Assert.IsNotNull(_shapes);
for (var index = 0; index < _shapes.Length; index++)
{
var sr = _shapes[index];
if (sr == null)
{
Assert.IsNotNull(sr, "_shapes[" + index + "] != null");
}
}
bool foundAspect = Hand.GetHandAspect(out IFingerFeatureStateProvider state);
Assert.IsTrue(foundAspect);
FingerFeatureStateProvider = state;
_allFingerStates = FlattenUsedFeatures();
// Warm up the proactive evaluation
InitStateProvider();
}
private void InitStateProvider()
{
foreach (FingerFeatureStateUsage state in _allFingerStates)
{
FingerFeatureStateProvider.GetCurrentState(state.handFinger, state.config.Feature, out _);
}
}
private List<FingerFeatureStateUsage> FlattenUsedFeatures()
{
var fingerFeatureStateUsages = new List<FingerFeatureStateUsage>();
foreach (var sr in _shapes)
{
int configCount = 0;
for (var fingerIdx = 0; fingerIdx < Constants.NUM_FINGERS; ++fingerIdx)
{
var handFinger = (HandFinger)fingerIdx;
foreach (var config in sr.GetFingerFeatureConfigs(handFinger))
{
++configCount;
fingerFeatureStateUsages.Add(new FingerFeatureStateUsage()
{
handFinger = handFinger, config = config
});
}
}
// If this assertion is hit, open the ScriptableObject in the Unity Inspector
// and ensure that it has at least one valid condition.
Assert.IsTrue(configCount > 0, $"Shape {sr.ShapeName} has no valid conditions.");
}
return fingerFeatureStateUsages;
}
public bool Active
{
get
{
if (!isActiveAndEnabled || _allFingerStates.Count == 0)
{
return false;
}
foreach (FingerFeatureStateUsage stateUsage in _allFingerStates)
{
if (!FingerFeatureStateProvider.IsStateActive(stateUsage.handFinger,
stateUsage.config.Feature, stateUsage.config.Mode, stateUsage.config.State))
{
return false;
}
}
return true;
}
}
#region Inject
public void InjectAllShapeRecognizerActiveState(IHand hand, ShapeRecognizer[] shapes)
{
InjectHand(hand);
InjectShapes(shapes);
}
public void InjectHand(IHand hand)
{
_hand = hand as MonoBehaviour;
Hand = hand;
}
public void InjectShapes(ShapeRecognizer[] shapes)
{
_shapes = shapes;
}
#endregion
}
}