// --------------------------------------------------------------------------------------------------------------------
//
// Copyright (c) VRMADA, All rights reserved.
//
// --------------------------------------------------------------------------------------------------------------------
using UltimateXR.Core;
using UltimateXR.Core.Math;
using UltimateXR.Extensions.Unity;
using UltimateXR.Extensions.Unity.Math;
using UnityEngine;
namespace UltimateXR.Animation.IK
{
///
/// IK solver that distributes a wrist torsion among different bones in a forearm in order to smooth it out.
///
public class UxrWristTorsionIKSolver : UxrIKSolver
{
#region Inspector Properties/Serialized Fields
[SerializeField] [Range(0.0f, 1.0f)] private float _amount = 1.0f;
#endregion
#region Public Types & Data
///
/// Gets or sets the amount of torsion to apply on this Transform from the source. 0 = no torsion, 1 = full torsion,
/// etc.
///
public float Amount
{
get => _amount;
set => _amount = value;
}
#endregion
#region Public Overrides UxrIKSolver
///
public override bool Initialized => _initialized;
#endregion
#region Unity
///
/// Initializes the component.
///
protected override void Awake()
{
base.Awake();
_handSide = transform.HasParent(Avatar.AvatarRig.LeftArm.UpperArm) ? UxrHandSide.Left : UxrHandSide.Right;
_startLocalRotation = transform.localRotation;
UxrUniversalLocalAxes handUniversalLocalAxes = Avatar.AvatarRigInfo.GetArmInfo(_handSide).HandUniversalLocalAxes;
_torsionLocalAxis = transform.InverseTransformDirection(handUniversalLocalAxes.WorldForward).GetClosestAxis();
_initialized = true;
}
#endregion
#region Protected Overrides UxrIKSolver
///
/// Solves the Inverse Kinematics.
///
protected override void InternalSolveIK()
{
float angle = Avatar.AvatarRigInfo.GetArmInfo(_handSide).WristTorsionInfo.WristTorsionAngle;
transform.localRotation = _startLocalRotation * Quaternion.AngleAxis(angle * Amount, _torsionLocalAxis);
}
#endregion
#region Private Types & Data
private bool _initialized;
private UxrHandSide _handSide;
private Quaternion _startLocalRotation;
private Vector3 _torsionLocalAxis;
#endregion
}
}