// --------------------------------------------------------------------------------------------------------------------
//
// Copyright (c) VRMADA, All rights reserved.
//
// --------------------------------------------------------------------------------------------------------------------
using System;
using UnityEngine;
namespace UltimateXR.Animation.IK
{
///
/// Defines a link -bone- in an IK chain solved using CCD.
///
///
[Serializable]
public class UxrCcdLink
{
#region Inspector Properties/Serialized Fields
// Setup in the editor
[SerializeField] private Transform _bone;
[SerializeField] private float _weight;
[SerializeField] private UxrCcdConstraintType _constraint;
[SerializeField] private Vector3 _rotationAxis1;
[SerializeField] private Vector3 _rotationAxis2;
[SerializeField] private bool _axis1HasLimits;
[SerializeField] private float _axis1AngleMin;
[SerializeField] private float _axis1AngleMax;
[SerializeField] private bool _axis2HasLimits;
[SerializeField] private float _axis2AngleMin;
[SerializeField] private float _axis2AngleMax;
[SerializeField] private bool _alignToGoal;
#endregion
#region Public Types & Data
///
/// Gets the link transform.
///
public Transform Bone => _bone;
///
/// Gets the link constraint type.
///
public UxrCcdConstraintType Constraint => _constraint;
///
/// Gets the first rotation axis.
///
public Vector3 RotationAxis1 => _rotationAxis1;
///
/// Gets the second rotation axis when there are two constraints.
///
public Vector3 RotationAxis2 => _rotationAxis2;
///
/// Gets whether the first axis has rotational limits.
///
public bool Axis1HasLimits => _axis1HasLimits;
///
/// Gets the lower angle limits of the first axis.
///
public float Axis1AngleMin => _axis1AngleMin;
///
/// Gets the higher angle limits of the first axis.
///
public float Axis1AngleMax => _axis1AngleMax;
///
/// Gets whether the second axis has rotational limits when there are two constraints.
///
public bool Axis2HasLimits => _axis2HasLimits;
///
/// Gets the lower angle limits of the second axis when there are two constraints.
///
public float Axis2AngleMin => _axis2AngleMin;
///
/// Gets the higher angle limits of the second axis when there are two constraints.
///
public float Axis2AngleMax => _axis2AngleMax;
///
/// Gets whether the effector should not only try to position itself on the goal but also use the same orientation.
///
public bool AlignToGoal => _alignToGoal;
///
/// The weight among all the CCD links in the chain.
///
public float Weight
{
get => _weight;
set => _weight = value;
}
///
/// Gets whether the data has been initialized.
///
public bool Initialized { get; internal set; }
///
/// Gets the local rotation at the beginning.
///
public Quaternion InitialLocalRotation { get; internal set; }
///
/// Gets a reference perpendicular to axis1 that is considered as the reference of having 0 degrees around axis1.
///
public Vector3 LocalSpaceAxis1ZeroAngleVector { get; internal set; }
///
/// Gets a reference perpendicular to axis2 that is considered as the reference of having 0 degrees around axis2.
///
public Vector3 LocalSpaceAxis2ZeroAngleVector { get; internal set; }
///
/// Gets the length of the link.
///
public float LinkLength { get; internal set; }
///
/// Gets in local space of the parent object.
///
public Vector3 ParentSpaceAxis1 { get; internal set; }
///
/// Gets in local space of the parent object.
///
public Vector3 ParentSpaceAxis2 { get; internal set; }
///
/// Gets in local space of the parent object.
///
public Vector3 ParentSpaceAxis1ZeroAngleVector { get; internal set; }
///
/// Gets in local space of the parent object.
///
public Vector3 ParentSpaceAxis2ZeroAngleVector { get; internal set; }
///
/// Gets the transformation matrix that gets from world-space to local space in the parent transform.
///
public Matrix4x4 MtxToLocalParent { get; internal set; }
///
/// Gets rotation degrees around .
///
public float Angle1 { get; internal set; }
///
/// Gets rotation degrees around .
///
public float Angle2 { get; internal set; }
#endregion
#region Constructors & Finalizer
///
/// Default constructor.
///
public UxrCcdLink()
{
_weight = 1.0f;
_constraint = UxrCcdConstraintType.SingleAxis;
_rotationAxis1 = Vector3.right;
_rotationAxis2 = Vector3.up;
_axis1HasLimits = true;
_axis1AngleMin = -45.0f;
_axis1AngleMax = 45.0f;
_axis2HasLimits = false;
_axis2AngleMin = -45.0f;
_axis2AngleMax = 45.0f;
}
#endregion
}
}