-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCCD.h
43 lines (35 loc) · 1.33 KB
/
CCD.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#pragma once
#include "IKSolver.h"
#include <numbers>
#include <cmath>
/// @brief Implementation of the Cyclic Coordinated Descend (CCD) algorithm for solving inverse kinematics
class CCD : public IKSolver
{
public:
/// @brief Trys to set the end effector of the skeleton to the desired target position by rotating the bones of the skeleton
virtual bool solve(Skeleton& skeleton, const Vector2& targetPos, int maxIterations, float epsilon) override
{
for (int i = 0; i < maxIterations; i++)
{
Bone* node = skeleton.pivotBone();
// Adjust rotation of each bone in the skeleton
while (node != nullptr)
{
Vector2 pivotPos = skeleton.pivotPosition();
Vector2 currrentBasePos = skeleton.boneBasePosition(node);
Vector2 basePivotVec = (pivotPos - currrentBasePos).normalize();
Vector2 baseTargetVec = (targetPos - currrentBasePos).normalize();
float dot = basePivotVec.dot(baseTargetVec);
float det = basePivotVec.cross(baseTargetVec);
float rotateAngle = atan2(det, dot);
node->angle = node->angle + rotateAngle;
node = node->parent;
}
// Return if pivot is near enought to the target -> success
if ((targetPos - skeleton.pivotPosition()).length() < epsilon)
return true;
}
// Algorithm finished by reaching max Iterations -> pivot is not near enough to the target
return false;
}
};