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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
|
#pragma once
#include "math/vecmat.h"
#include "model/model.h"
class ik_constraint;
struct ik_node{
const bsp_info* submodel;
const ik_constraint* constraint;
vec3d calculatedPos = ZERO_VECTOR;
vec3d lastPos = ZERO_VECTOR;
matrix calculatedRot = IDENTITY_MATRIX;
float distance = 0.0f;
ik_node(const bsp_info* _submodel, const ik_constraint* _constraint) : submodel(_submodel), constraint(_constraint) { }
void calculateGlobalRotation(const ik_node& child);
};
class ik_solver {
protected:
std::vector<ik_node> m_nodes;
public:
template <typename... Args>
void addNode(Args&&... args) {
m_nodes.emplace_back(std::forward<Args>(args)...);
}
virtual void solve(const vec3d& targetPos, const matrix* targetOrient = nullptr) = 0;
//Allow const-iterating over created nodes
inline decltype(m_nodes)::const_iterator begin() const { return m_nodes.cbegin(); }
inline decltype(m_nodes)::const_iterator end() const { return m_nodes.cend(); }
virtual ~ik_solver() = default;
};
class ik_solver_fabrik : public ik_solver {
unsigned int m_maxIterations;
float m_targetDistance;
float m_minProgress;
public:
ik_solver_fabrik(unsigned int maxIterations = 15, float targetDistance = 0.01f, float minProgress = 0.05f);
void solve(const vec3d& targetPos, const matrix* targetOrient = nullptr) override;
};
class ik_constraint{
public:
/*
* Return true if the local rotation was modified by the constraint
* */
virtual bool constrain(matrix& /*localRot*/, bool /*backwardsPass*/ = false) const {
return false;
};
virtual ~ik_constraint() = default;
};
class ik_constraint_hinge : public ik_constraint{
vec3d axis;
public:
ik_constraint_hinge(const vec3d& _axis);
bool constrain(matrix& localRot, bool backwardsPass) const override;
};
class ik_constraint_window : public ik_constraint{
angles absLimit;
public:
ik_constraint_window(const angles& _absLimit);
bool constrain(matrix& localRot, bool backwardsPass) const override;
};
|