// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Core/Math/Vector3.h"
#include "Engine/Core/Math/Quaternion.h"
#include "Engine/Core/Math/Transform.h"
///
/// The Inverse Kinematics (IK) utility library.
///
class FLAXENGINE_API InverseKinematics
{
public:
///
/// Rotates a node so it aims at a target. Solves the transformation (rotation) that needs to be applied to the node such that a provided forward vector (in node local space) aims at the target position (in skeleton model space).
///
/// The node transformation (in model space).
/// The target position to aim at (in model space).
/// The calculated output node correction (in model- space). It needs to be multiplied with node model space quaternion.
static void SolveAimIK(const Transform& node, const Vector3& target, Quaternion& outNodeCorrection);
///
/// Performs inverse kinematic on a three nodes chain (must be ancestors).
///
/// The start node transformation (in model space).
/// The middle node transformation (in model space).
/// The end node transformation (in model space).
/// The target position of the end node to reach (in model space).
/// The target position of the middle node to face into (in model space).
/// True if allow bones stretching, otherwise bone lengths will be preserved when trying to reach the target.
/// The maximum scale when stretching bones. Used only if allowStretching is true.
static void SolveTwoBoneIK(Transform& rootNode, Transform& jointNode, Transform& targetNode, const Vector3& target, const Vector3& jointTarget, bool allowStretching = false, float maxStretchScale = 1.5f);
};