// --------------------------------------------------------------------------------------------------------------------
//
// Copyright (c) VRMADA, All rights reserved.
//
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Core;
using UnityEngine;
namespace UltimateXR.Manipulation.HandPoses
{
///
/// ScriptableObject that stores custom hand poses. Data is stored in a well-known axes system so that poses can be
/// exchanged between different avatars.
///
[Serializable]
public class UxrHandPoseAsset : ScriptableObject
{
#region Inspector Properties/Serialized Fields
[SerializeField] private int _handPoseAssetVersion;
[SerializeField] private UxrHandPoseType _poseType;
[SerializeField] private UxrHandDescriptor _handDescriptorLeft;
[SerializeField] private UxrHandDescriptor _handDescriptorRight;
[SerializeField] private UxrHandDescriptor _handDescriptorOpenLeft;
[SerializeField] private UxrHandDescriptor _handDescriptorOpenRight;
[SerializeField] private UxrHandDescriptor _handDescriptorClosedLeft;
[SerializeField] private UxrHandDescriptor _handDescriptorClosedRight;
#endregion
#region Public Types & Data
///
/// Current data version.
///
public const int CurrentVersion = 1;
///
/// Gets the version the pose was stored in.
///
public int Version
{
get => _handPoseAssetVersion;
set => _handPoseAssetVersion = value;
}
///
/// Gets the pose type.
///
public UxrHandPoseType PoseType
{
get => _poseType;
set => _poseType = value;
}
///
/// Gets the left fixed pose hand descriptor.
///
public UxrHandDescriptor HandDescriptorLeft
{
get => _handDescriptorLeft;
set => _handDescriptorLeft = value;
}
///
/// Gets the right fixed pose hand descriptor.
///
public UxrHandDescriptor HandDescriptorRight
{
get => _handDescriptorRight;
set => _handDescriptorRight = value;
}
///
/// Gets the left blend pose hand descriptor for the open state.
///
public UxrHandDescriptor HandDescriptorOpenLeft
{
get => _handDescriptorOpenLeft;
set => _handDescriptorOpenLeft = value;
}
///
/// Gets the right blend pose hand descriptor for the open state.
///
public UxrHandDescriptor HandDescriptorOpenRight
{
get => _handDescriptorOpenRight;
set => _handDescriptorOpenRight = value;
}
///
/// Gets the left blend pose hand descriptor for the closed state.
///
public UxrHandDescriptor HandDescriptorClosedLeft
{
get => _handDescriptorClosedLeft;
set => _handDescriptorClosedLeft = value;
}
///
/// Gets the right blend pose hand descriptor for the closed state.
///
public UxrHandDescriptor HandDescriptorClosedRight
{
get => _handDescriptorClosedRight;
set => _handDescriptorClosedRight = value;
}
#endregion
#region Public Methods
///
/// Gets the hand descriptor for the given hand, based on the .
///
/// Hand to get the descriptor for
///
/// If is , whether to get the open or
/// closed pose descriptor.
///
/// Hand descriptor
public UxrHandDescriptor GetHandDescriptor(UxrHandSide handSide, UxrBlendPoseType blendPoseType = UxrBlendPoseType.None)
{
return PoseType switch
{
UxrHandPoseType.Fixed => handSide == UxrHandSide.Left ? _handDescriptorLeft : _handDescriptorRight,
UxrHandPoseType.Blend when blendPoseType == UxrBlendPoseType.OpenGrip => handSide == UxrHandSide.Left ? _handDescriptorOpenLeft : _handDescriptorOpenRight,
UxrHandPoseType.Blend when blendPoseType == UxrBlendPoseType.ClosedGrip => handSide == UxrHandSide.Left ? _handDescriptorClosedLeft : _handDescriptorClosedRight,
_ => null
};
}
///
/// Gets the hand descriptor for the given hand, based on an external parameter.
///
/// Hand to get the descriptor for
/// The pose type to get the descriptor for
///
/// If is , whether to get the open or
/// closed pose descriptor.
///
/// Hand descriptor
public UxrHandDescriptor GetHandDescriptor(UxrHandSide handSide, UxrHandPoseType poseType, UxrBlendPoseType blendPoseType = UxrBlendPoseType.None)
{
return poseType switch
{
UxrHandPoseType.Fixed => handSide == UxrHandSide.Left ? _handDescriptorLeft : _handDescriptorRight,
UxrHandPoseType.Blend when blendPoseType == UxrBlendPoseType.OpenGrip => handSide == UxrHandSide.Left ? _handDescriptorOpenLeft : _handDescriptorOpenRight,
UxrHandPoseType.Blend when blendPoseType == UxrBlendPoseType.ClosedGrip => handSide == UxrHandSide.Left ? _handDescriptorClosedLeft : _handDescriptorClosedRight,
_ => null
};
}
#if UNITY_EDITOR
///
/// Outputs transform debug data to the editor window.
///
/// Hand to output the data for
/// The blend pose type or if it is a fixed pose
public void DrawEditorDebugLabels(UxrHandSide handSide, UxrBlendPoseType blendPoseType = UxrBlendPoseType.None)
{
UxrHandDescriptor handDescriptor = handSide == UxrHandSide.Left ? HandDescriptorLeft : HandDescriptorRight;
if (blendPoseType == UxrBlendPoseType.OpenGrip)
{
handDescriptor = handSide == UxrHandSide.Left ? HandDescriptorOpenLeft : HandDescriptorOpenRight;
}
else if (blendPoseType == UxrBlendPoseType.ClosedGrip)
{
handDescriptor = handSide == UxrHandSide.Left ? HandDescriptorClosedLeft : HandDescriptorClosedRight;
}
handDescriptor?.DrawEditorDebugLabels();
}
#endif
#endregion
}
}