Move third party assets to ThirdParty folder

This commit is contained in:
2024-08-08 11:26:28 +02:00
parent 386f303057
commit bd91af6f98
10340 changed files with 100 additions and 175 deletions

View File

@@ -0,0 +1,28 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrBlendPoseType.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace UltimateXR.Manipulation.HandPoses
{
/// <summary>
/// Enumerates the different poses in a blend pose.
/// </summary>
public enum UxrBlendPoseType
{
/// <summary>
/// Not a blend pose.
/// </summary>
None,
/// <summary>
/// Pose with the open hand.
/// </summary>
OpenGrip,
/// <summary>
/// Pose with the closed hand.
/// </summary>
ClosedGrip
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a7be4a9e3a7f4cdbadc26754550fd0ff
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,167 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrFingerDescriptor.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Avatar.Rig;
using UltimateXR.Core.Math;
using UnityEditor;
using UnityEngine;
namespace UltimateXR.Manipulation.HandPoses
{
/// <summary>
/// Stores base-independent node orientations for a finger.
/// </summary>
[Serializable]
public struct UxrFingerDescriptor
{
#region Inspector Properties/Serialized Fields
[SerializeField] private bool _hasMetacarpalInfo;
[SerializeField] private UxrFingerNodeDescriptor _metacarpal;
[SerializeField] private UxrFingerNodeDescriptor _proximal;
[SerializeField] private UxrFingerNodeDescriptor _proximalNoMetacarpal;
[SerializeField] private UxrFingerNodeDescriptor _intermediate;
[SerializeField] private UxrFingerNodeDescriptor _distal;
#endregion
#region Public Types & Data
/// <summary>
/// Gets whether metacarpal bone information is present. Metacarpal information is optional.
/// </summary>
public bool HasMetacarpalInfo => _hasMetacarpalInfo;
/// <summary>
/// Gets the metacarpal bone transform information.
/// </summary>
public UxrFingerNodeDescriptor Metacarpal => _metacarpal;
/// <summary>
/// Gets the proximal bone transform information.
/// </summary>
public UxrFingerNodeDescriptor Proximal => _proximal;
/// <summary>
/// Gets the proximal bone transform information with respect to the wrist even if there is metacarpal information. It
/// is used in case a pose including metacarpal information wants to be mapped to a hand that has no metacarpal bones.
/// </summary>
public UxrFingerNodeDescriptor ProximalNoMetacarpal => _proximalNoMetacarpal;
/// <summary>
/// Gets the intermediate bone transform information.
/// </summary>
public UxrFingerNodeDescriptor Intermediate => _intermediate;
/// <summary>
/// Gets the distal bone transform information.
/// </summary>
public UxrFingerNodeDescriptor Distal => _distal;
#endregion
#region Public Methods
/// <summary>
/// Computes well-known axes systems for all finger bones, to handle transforms independently of the coordinate system
/// being used by a hand rig.
/// </summary>
/// <param name="wrist">Wrist transform</param>
/// <param name="finger">Finger rig information</param>
/// <param name="handLocalAxes">Well-known axes system for the hand</param>
/// <param name="fingerLocalAxes">Well-known axes system for the finger elements</param>
/// <param name="computeRelativeMatrixOnly">Whether to compute only the relative transform to the hand</param>
public void Compute(Transform wrist, UxrAvatarFinger finger, UxrUniversalLocalAxes handLocalAxes, UxrUniversalLocalAxes fingerLocalAxes, bool computeRelativeMatrixOnly)
{
if (finger.Metacarpal)
{
_hasMetacarpalInfo = true;
_metacarpal.Compute(wrist, wrist, finger.Metacarpal, handLocalAxes, fingerLocalAxes, computeRelativeMatrixOnly);
_proximal.Compute(wrist, finger.Metacarpal, finger.Proximal, fingerLocalAxes, fingerLocalAxes, computeRelativeMatrixOnly);
_proximalNoMetacarpal.Compute(wrist, wrist, finger.Proximal, handLocalAxes, fingerLocalAxes, computeRelativeMatrixOnly);
}
else
{
_hasMetacarpalInfo = false;
_proximal.Compute(wrist, wrist, finger.Proximal, handLocalAxes, fingerLocalAxes, computeRelativeMatrixOnly);
_proximalNoMetacarpal.Compute(wrist, wrist, finger.Proximal, handLocalAxes, fingerLocalAxes, computeRelativeMatrixOnly);
}
_intermediate.Compute(wrist, finger.Proximal, finger.Intermediate, fingerLocalAxes, fingerLocalAxes, computeRelativeMatrixOnly);
_distal.Compute(wrist, finger.Intermediate, finger.Distal, fingerLocalAxes, fingerLocalAxes, computeRelativeMatrixOnly);
}
/// <summary>
/// Mirrors the bone information, so that it can be used for the opposite hand.
/// </summary>
public void Mirror()
{
if (_hasMetacarpalInfo)
{
_metacarpal.Mirror();
}
_proximal.Mirror();
_proximalNoMetacarpal.Mirror();
_intermediate.Mirror();
_distal.Mirror();
}
/// <summary>
/// Interpolates the data towards another descriptor.
/// </summary>
/// <param name="to">Descriptor to interpolate the data to</param>
/// <param name="t">Interpolation factor [0.0, 1.0]</param>
public void InterpolateTo(UxrFingerDescriptor to, float t)
{
if (_hasMetacarpalInfo)
{
_metacarpal.InterpolateTo(to._metacarpal, t);
}
_proximal.InterpolateTo(to._proximal, t);
_proximalNoMetacarpal.InterpolateTo(to._proximalNoMetacarpal, t);
_intermediate.InterpolateTo(to._intermediate, t);
_distal.InterpolateTo(to._distal, t);
}
#if UNITY_EDITOR
/// <summary>
/// Outputs transform information to the editor window.
/// </summary>
/// <param name="prefix">String to prefix the information with</param>
public void DrawEditorDebugLabels(string prefix)
{
EditorGUILayout.LabelField(prefix + _proximal.Right);
EditorGUILayout.LabelField(prefix + _proximal.Up);
EditorGUILayout.LabelField(prefix + _proximal.Forward);
}
#endif
/// <summary>
/// Compares the transform information with another finger.
/// </summary>
/// <param name="other">Finger information to compare it to</param>
/// <returns>Whether both fingers describe the same transform information</returns>
public bool Equals(UxrFingerDescriptor other)
{
if (_hasMetacarpalInfo != other._hasMetacarpalInfo)
{
return false;
}
if (_hasMetacarpalInfo)
{
return _metacarpal.Equals(other._metacarpal) && _proximal.Equals(other._proximal) && _intermediate.Equals(other._intermediate) && _distal.Equals(other._distal);
}
return _proximal.Equals(other._proximal) && _intermediate.Equals(other._intermediate) && _distal.Equals(other._distal);
}
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 25fe587ebcf04b76afc04cfd1a84d413
timeCreated: 1643749392

View File

@@ -0,0 +1,229 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrFingerNodeDescriptor.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Core.Math;
using UnityEngine;
namespace UltimateXR.Manipulation.HandPoses
{
/// <summary>
/// Stores a bone's right, up and forward vectors in local coordinates of its parent. Right, up and forward
/// vectors will always point to this directions independently of how the transforms have been set up in
/// order to guarantee poses can be reused by other hands that use a different coordinate system.
/// </summary>
[Serializable]
public struct UxrFingerNodeDescriptor
{
#region Inspector Properties/Serialized Fields
[SerializeField] private Matrix4x4 _transformRelativeToHand;
[SerializeField] private Vector3 _right;
[SerializeField] private Vector3 _up;
[SerializeField] private Vector3 _forward;
#endregion
#region Public Types & Data
/// <summary>
/// Gets the original relative transform to the hand bone. We use it mainly to compute
/// <see cref="UxrGrabbableObject" /> preview meshes more conveniently.
/// </summary>
public Matrix4x4 TransformRelativeToHand => _transformRelativeToHand;
/// <summary>
/// Gets the universal right vector. The vector that points in our well-known right direction, in the coordinate system
/// of the finger.
/// </summary>
public Vector3 Right => _right;
/// <summary>
/// Gets the universal up vector. The vector that points in our well-known up direction, in the coordinate system of
/// the finger.
/// </summary>
public Vector3 Up => _up;
/// <summary>
/// Gets the universal forward vector. The vector that points in our well-known forward direction, in the coordinate
/// system of the finger.
/// </summary>
public Vector3 Forward => _forward;
#endregion
#region Constructors & Finalizer
/// <summary>
/// Creates a well-known axes system for a node, to handle transforms independently of the coordinate system being used
/// by a hand rig.
/// </summary>
/// <param name="hand">Hand node</param>
/// <param name="parent">Parent node</param>
/// <param name="node">Current node being created</param>
/// <param name="parentLocalAxes">
/// In local coordinates, which parent axes point to the well-known right, up and forward directions
/// </param>
/// <param name="nodeLocalAxes">
/// In local coordinates, which node axes point to the well-known right, up and forward directions
/// </param>
public UxrFingerNodeDescriptor(Transform hand, Transform parent, Transform node, UxrUniversalLocalAxes parentLocalAxes, UxrUniversalLocalAxes nodeLocalAxes)
{
_right = Vector3.right;
_up = Vector3.up;
_forward = Vector3.forward;
_transformRelativeToHand = Matrix4x4.identity;
if (hand == null || parent == null || node != null)
{
return;
}
Compute(hand, parent, node, parentLocalAxes, nodeLocalAxes, false);
}
#endregion
#region Public Methods
/// <summary>
/// Creates a well-known axes system for a node, to handle transforms independently of the coordinate system being used
/// by a hand rig.
/// </summary>
/// <param name="hand">Hand node</param>
/// <param name="parent">Parent node</param>
/// <param name="node">Current node being created</param>
/// <param name="parentLocalAxes">
/// In local coordinates, which parent axes point to the well-known right, up and forward
/// directions
/// </param>
/// <param name="nodeLocalAxes">
/// In local coordinates, which node axes point to the well-known right, up and forward
/// directions
/// </param>
/// <param name="computeRelativeMatrixOnly">Whether to compute only the <see cref="TransformRelativeToHand" /> value</param>
public void Compute(Transform hand, Transform parent, Transform node, UxrUniversalLocalAxes parentLocalAxes, UxrUniversalLocalAxes nodeLocalAxes, bool computeRelativeMatrixOnly)
{
_transformRelativeToHand = hand.worldToLocalMatrix * node.localToWorldMatrix;
if (!computeRelativeMatrixOnly)
{
Matrix4x4 matrixParent = new Matrix4x4();
matrixParent.SetColumn(0, parent.TransformVector(parentLocalAxes.LocalRight));
matrixParent.SetColumn(1, parent.TransformVector(parentLocalAxes.LocalUp));
matrixParent.SetColumn(2, parent.TransformVector(parentLocalAxes.LocalForward));
matrixParent.SetColumn(3, new Vector4(parent.position.x, parent.position.y, parent.position.z, 1));
_right = matrixParent.inverse.MultiplyVector(node.TransformVector(nodeLocalAxes.LocalRight));
_up = matrixParent.inverse.MultiplyVector(node.TransformVector(nodeLocalAxes.LocalUp));
_forward = matrixParent.inverse.MultiplyVector(node.TransformVector(nodeLocalAxes.LocalForward));
}
}
/// <summary>
/// Mirrors the descriptor. Useful to switch between left and right hand data.
/// </summary>
public void Mirror()
{
// We do not need to mirror position and rotation because we don't use them for mirroring
_right.x = -_right.x;
_right = -_right;
_up.x = -_up.x;
_forward.x = -_forward.x;
}
/// <summary>
/// Interpolates the axes data towards another descriptor.
/// </summary>
/// <param name="to">Descriptor to interpolate the data to</param>
/// <param name="t">Interpolation factor [0.0, 1.0]</param>
public void InterpolateTo(UxrFingerNodeDescriptor to, float t)
{
Quaternion quatSlerp = Quaternion.Slerp(Quaternion.LookRotation(_forward, _up), Quaternion.LookRotation(to._forward, to._up), t);
_right = quatSlerp * Vector3.right;
_up = quatSlerp * Vector3.up;
_forward = quatSlerp * Vector3.forward;
// For performance reasons, _transformRelativeToHand isn't interpolated because it is only used for grab preview poses. Interpolation is used for runtime pose blending.
// If at any point it becomes necessary, uncomment the line below:
// _transformRelativeToHand = Matrix4x4Ext.Interpolate(_transformRelativeToHand, to._transformRelativeToHand, t);
}
/// <summary>
/// Checks if the content of two FingerNodeDescriptors is equal (they describe the same axes).
/// </summary>
/// <param name="other">UxrFingerNodeDescriptor to compare it to</param>
/// <returns>Boolean telling if the two FingerNodeDescriptors describe the same axes</returns>
public bool Equals(UxrFingerNodeDescriptor other)
{
float epsilon = 0.00001f;
for (int i = 0; i < 4; ++i)
{
for (int j = 0; j < 4; ++j)
{
if (Mathf.Abs(_transformRelativeToHand[i, j] - other._transformRelativeToHand[i, j]) > epsilon)
{
return false;
}
}
}
bool equal = _right == other._right && _up == other._up && _forward == other._forward;
/*
double inequalityThreshold = 9.99999943962493E-11;
if (Right != other.Right)
{
double inequalityValue = GetInequalityValue(Right, other.Right);
double inequalityMargin = inequalityValue - inequalityThreshold;
double inequalityFactor = inequalityValue / inequalityThreshold;
Debug.Log($"right != other.right Inequality value = {inequalityValue}, margin = {inequalityMargin}, factor {inequalityFactor}");
}
if (Up != other.Up)
{
double inequalityValue = GetInequalityValue(Up, other.Up);
double inequalityMargin = inequalityValue - inequalityThreshold;
double inequalityFactor = inequalityValue / inequalityThreshold;
Debug.Log($"up != other.up Inequality value = {inequalityValue}, margin = {inequalityMargin}, factor {inequalityFactor}");
}
if (Forward != other.Forward)
{
double inequalityValue = GetInequalityValue(Forward, other.Forward);
double inequalityMargin = inequalityValue - inequalityThreshold;
double inequalityFactor = inequalityValue / inequalityThreshold;
Debug.Log($"forward != other.forward Inequality value = {inequalityValue}, margin = {inequalityMargin}, factor {inequalityFactor}");
}*/
return equal;
}
#endregion
#region Private Methods
/// <summary>
/// Gets an inequality value that measures how different two vectors are. It is used to provide a way to compare
/// vectors considering floating point errors.
/// </summary>
/// <param name="lhs">Vector A</param>
/// <param name="rhs">Vector B</param>
/// <returns>Inequality value</returns>
private double GetInequalityValue(Vector3 lhs, Vector3 rhs)
{
float num1 = lhs.x - rhs.x;
float num2 = lhs.y - rhs.y;
float num3 = lhs.z - rhs.z;
return num1 * (double)num1 + num2 * (double)num2 + num3 * (double)num3;
}
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8f9dc40c111844888f796a51ac2e7e82
timeCreated: 1643749470

View File

@@ -0,0 +1,234 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrHandDescriptor.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Avatar;
using UltimateXR.Avatar.Rig;
using UltimateXR.Core;
using UltimateXR.Core.Math;
using UnityEngine;
namespace UltimateXR.Manipulation.HandPoses
{
/// <summary>
/// Stores base-independent node orientations for all fingers of a hand.
/// </summary>
[Serializable]
public class UxrHandDescriptor
{
#region Inspector Properties/Serialized Fields
[SerializeField] private UxrFingerDescriptor _index;
[SerializeField] private UxrFingerDescriptor _middle;
[SerializeField] private UxrFingerDescriptor _ring;
[SerializeField] private UxrFingerDescriptor _little;
[SerializeField] private UxrFingerDescriptor _thumb;
#endregion
#region Public Types & Data
/// <summary>
/// Gets the index finger information.
/// </summary>
public UxrFingerDescriptor Index => _index;
/// <summary>
/// Gets the middle finger information.
/// </summary>
public UxrFingerDescriptor Middle => _middle;
/// <summary>
/// Gets the ring finger information.
/// </summary>
public UxrFingerDescriptor Ring => _ring;
/// <summary>
/// Gets the little finger information.
/// </summary>
public UxrFingerDescriptor Little => _little;
/// <summary>
/// Gets the thumb finger information.
/// </summary>
public UxrFingerDescriptor Thumb => _thumb;
#endregion
#region Constructors & Finalizer
/// <summary>
/// Default constructor.
/// </summary>
public UxrHandDescriptor()
{
_index = new UxrFingerDescriptor();
_middle = new UxrFingerDescriptor();
_ring = new UxrFingerDescriptor();
_little = new UxrFingerDescriptor();
_thumb = new UxrFingerDescriptor();
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="avatar">Avatar whose hand to compute the descriptor for</param>
/// <param name="handSide">Which hand to process</param>
public UxrHandDescriptor(UxrAvatar avatar, UxrHandSide handSide)
{
_index = new UxrFingerDescriptor();
_middle = new UxrFingerDescriptor();
_ring = new UxrFingerDescriptor();
_little = new UxrFingerDescriptor();
_thumb = new UxrFingerDescriptor();
Compute(avatar, handSide);
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="arm">Arm whose hand to compute the descriptor for</param>
/// <param name="handLocalAxes">Hand axes system</param>
/// <param name="fingerLocalAxes">Finger axes system</param>
public UxrHandDescriptor(UxrAvatarArm arm, UxrUniversalLocalAxes handLocalAxes, UxrUniversalLocalAxes fingerLocalAxes)
{
_index = new UxrFingerDescriptor();
_middle = new UxrFingerDescriptor();
_ring = new UxrFingerDescriptor();
_little = new UxrFingerDescriptor();
_thumb = new UxrFingerDescriptor();
Compute(arm, handLocalAxes, fingerLocalAxes);
}
#endregion
#region Public Methods
/// <summary>
/// Gets the given finger.
/// </summary>
/// <param name="fingerType">Which finger to get</param>
/// <returns>Finger information</returns>
public UxrFingerDescriptor GetFinger(UxrFingerType fingerType)
{
switch (fingerType)
{
case UxrFingerType.Thumb: return Thumb;
case UxrFingerType.Index: return Index;
case UxrFingerType.Middle: return Middle;
case UxrFingerType.Ring: return Ring;
case UxrFingerType.Little: return Little;
default: throw new ArgumentOutOfRangeException(nameof(fingerType), fingerType, null);
}
}
/// <summary>
/// Computes the hand data.
/// </summary>
/// <param name="avatar">Avatar to compute the hand data of</param>
/// <param name="handSide">Which hand to compute the hand data of</param>
/// <param name="computeRelativeMatrixOnly">Whether to compute the relative transform to the hand only</param>
public void Compute(UxrAvatar avatar, UxrHandSide handSide, bool computeRelativeMatrixOnly = false)
{
Compute(handSide == UxrHandSide.Left ? avatar.AvatarRig.LeftArm : avatar.AvatarRig.RightArm, avatar.AvatarRigInfo.GetArmInfo(handSide).HandUniversalLocalAxes, avatar.AvatarRigInfo.GetArmInfo(handSide).FingerUniversalLocalAxes, computeRelativeMatrixOnly);
}
/// <summary>
/// Computes the hand data.
/// </summary>
/// <param name="arm">Arm where the hand is</param>
/// <param name="handLocalAxes">Hand axes system</param>
/// <param name="fingerLocalAxes">Finger axes system</param>
/// <param name="computeRelativeMatrixOnly">Whether to compute the relative transform to the hand only</param>
public void Compute(UxrAvatarArm arm, UxrUniversalLocalAxes handLocalAxes, UxrUniversalLocalAxes fingerLocalAxes, bool computeRelativeMatrixOnly = false)
{
_index.Compute(arm.Hand.Wrist, arm.Hand.Index, handLocalAxes, fingerLocalAxes, computeRelativeMatrixOnly);
_middle.Compute(arm.Hand.Wrist, arm.Hand.Middle, handLocalAxes, fingerLocalAxes, computeRelativeMatrixOnly);
_ring.Compute(arm.Hand.Wrist, arm.Hand.Ring, handLocalAxes, fingerLocalAxes, computeRelativeMatrixOnly);
_little.Compute(arm.Hand.Wrist, arm.Hand.Little, handLocalAxes, fingerLocalAxes, computeRelativeMatrixOnly);
_thumb.Compute(arm.Hand.Wrist, arm.Hand.Thumb, handLocalAxes, fingerLocalAxes, computeRelativeMatrixOnly);
}
/// <summary>
/// Copies the data from another descriptor.
/// </summary>
/// <param name="src">Source data</param>
public void CopyFrom(UxrHandDescriptor src)
{
_index = src._index;
_middle = src._middle;
_ring = src._ring;
_little = src._little;
_thumb = src._thumb;
}
/// <summary>
/// Interpolates the data towards another descriptor.
/// </summary>
/// <param name="to">Descriptor to interpolate the data to</param>
/// <param name="t">Interpolation factor [0.0, 1.0]</param>
public void InterpolateTo(UxrHandDescriptor to, float t)
{
_index.InterpolateTo(to._index, t);
_middle.InterpolateTo(to._middle, t);
_ring.InterpolateTo(to._ring, t);
_little.InterpolateTo(to._little, t);
_thumb.InterpolateTo(to._thumb, t);
}
#if UNITY_EDITOR
/// <summary>
/// Outputs transform data in the editor window.
/// </summary>
public void DrawEditorDebugLabels()
{
_index.DrawEditorDebugLabels("index: ");
_middle.DrawEditorDebugLabels("middle: ");
_ring.DrawEditorDebugLabels("ring: ");
_little.DrawEditorDebugLabels("little: ");
_thumb.DrawEditorDebugLabels("thumb: ");
}
#endif
/// <summary>
/// Returns a hand descriptor with mirrored transforms, so that the data can be used for the opposite hand.
/// </summary>
/// <returns>Mirrored hand descriptor</returns>
public UxrHandDescriptor Mirrored()
{
UxrHandDescriptor mirroredHandDescriptor = new UxrHandDescriptor();
mirroredHandDescriptor.CopyFrom(this);
mirroredHandDescriptor._index.Mirror();
mirroredHandDescriptor._middle.Mirror();
mirroredHandDescriptor._ring.Mirror();
mirroredHandDescriptor._little.Mirror();
mirroredHandDescriptor._thumb.Mirror();
return mirroredHandDescriptor;
}
/// <summary>
/// Checks whether a hand descriptor contains the same transform data.
/// </summary>
/// <param name="other">Hand descriptor to compare it to</param>
/// <returns>Whether the hand descriptor contains the same transform data</returns>
public bool Equals(UxrHandDescriptor other)
{
if (other != null)
{
return _index.Equals(other._index) && _middle.Equals(other._middle) && _ring.Equals(other._ring) && _little.Equals(other._little) && _thumb.Equals(other._thumb);
}
return false;
}
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a99921d3e6b94b62bb8cd0b7a227be0a
timeCreated: 1643749379

View File

@@ -0,0 +1,183 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrHandPoseAsset.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
using System;
using UltimateXR.Core;
using UnityEngine;
namespace UltimateXR.Manipulation.HandPoses
{
/// <summary>
/// ScriptableObject that stores custom hand poses. Data is stored in a well-known axes system so that poses can be
/// exchanged between different avatars.
/// </summary>
[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
/// <summary>
/// Current data version.
/// </summary>
public const int CurrentVersion = 1;
/// <summary>
/// Gets the version the pose was stored in.
/// </summary>
public int Version
{
get => _handPoseAssetVersion;
set => _handPoseAssetVersion = value;
}
/// <summary>
/// Gets the pose type.
/// </summary>
public UxrHandPoseType PoseType
{
get => _poseType;
set => _poseType = value;
}
/// <summary>
/// Gets the left fixed pose hand descriptor.
/// </summary>
public UxrHandDescriptor HandDescriptorLeft
{
get => _handDescriptorLeft;
set => _handDescriptorLeft = value;
}
/// <summary>
/// Gets the right fixed pose hand descriptor.
/// </summary>
public UxrHandDescriptor HandDescriptorRight
{
get => _handDescriptorRight;
set => _handDescriptorRight = value;
}
/// <summary>
/// Gets the left blend pose hand descriptor for the open state.
/// </summary>
public UxrHandDescriptor HandDescriptorOpenLeft
{
get => _handDescriptorOpenLeft;
set => _handDescriptorOpenLeft = value;
}
/// <summary>
/// Gets the right blend pose hand descriptor for the open state.
/// </summary>
public UxrHandDescriptor HandDescriptorOpenRight
{
get => _handDescriptorOpenRight;
set => _handDescriptorOpenRight = value;
}
/// <summary>
/// Gets the left blend pose hand descriptor for the closed state.
/// </summary>
public UxrHandDescriptor HandDescriptorClosedLeft
{
get => _handDescriptorClosedLeft;
set => _handDescriptorClosedLeft = value;
}
/// <summary>
/// Gets the right blend pose hand descriptor for the closed state.
/// </summary>
public UxrHandDescriptor HandDescriptorClosedRight
{
get => _handDescriptorClosedRight;
set => _handDescriptorClosedRight = value;
}
#endregion
#region Public Methods
/// <summary>
/// Gets the hand descriptor for the given hand, based on the <see cref="PoseType" />.
/// </summary>
/// <param name="handSide">Hand to get the descriptor for</param>
/// <param name="blendPoseType">
/// If <see cref="PoseType" /> is <see cref="UxrHandPoseType.Blend" />, whether to get the open or
/// closed pose descriptor.
/// </param>
/// <returns>Hand descriptor</returns>
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
};
}
/// <summary>
/// Gets the hand descriptor for the given hand, based on an external <see cref="UxrHandPoseType" /> parameter.
/// </summary>
/// <param name="handSide">Hand to get the descriptor for</param>
/// <param name="poseType">The pose type to get the descriptor for</param>
/// <param name="blendPoseType">
/// If <see cref="PoseType" /> is <see cref="UxrHandPoseType.Blend" />, whether to get the open or
/// closed pose descriptor.
/// </param>
/// <returns>Hand descriptor</returns>
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
/// <summary>
/// Outputs transform debug data to the editor window.
/// </summary>
/// <param name="handSide">Hand to output the data for</param>
/// <param name="blendPoseType">The blend pose type or <see cref="UxrBlendPoseType.None" /> if it is a fixed pose</param>
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
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: a3e4dbcd197921446835b52ba65d418e
timeCreated: 1543332642
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,29 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UxrHandPoseType.cs" company="VRMADA">
// Copyright (c) VRMADA, All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace UltimateXR.Manipulation.HandPoses
{
/// <summary>
/// Enumerates the different pose types.
/// </summary>
public enum UxrHandPoseType
{
/// <summary>
/// Not initialized.
/// </summary>
None,
/// <summary>
/// Fixed pose (pose with a single state).
/// </summary>
Fixed,
/// <summary>
/// Blend pose. A blend pose has two states, open and closed, and allows to blend between them. In the grabbing system
/// it allows using a single blend grab pose for multiple objects with different sizes.
/// </summary>
Blend
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1657dc842d6e4de4a6c3182e6f4efa04
timeCreated: 1643744329