|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/ikengine.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/ikjacobian.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
enum Method { JACOB_TRANS,
|
|
Toshihiro Shimizu |
890ddd |
PURE_PSEUDO,
|
|
Toshihiro Shimizu |
890ddd |
DLS,
|
|
Toshihiro Shimizu |
890ddd |
SDLS,
|
|
Toshihiro Shimizu |
890ddd |
COMPARE };
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
IKEngine::IKEngine()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int IKEngine::addJoint(const TPointD &pos, int indexParent)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// TODO: evitare che si formino segmenti nulli
|
|
Toshihiro Shimizu |
890ddd |
//assert(m_joints.empty() || norm2(pos-m_joints.back())>0.000001);
|
|
Toshihiro Shimizu |
890ddd |
//assert(m_nodes[indexParent]);
|
|
Toshihiro Shimizu |
890ddd |
assert(m_skeleton.getNode(indexParent));
|
|
Toshihiro Shimizu |
890ddd |
m_skeleton.addNode(new IKNode());
|
|
Toshihiro Shimizu |
890ddd |
int index = m_skeleton.getNodeCount() - 1;
|
|
Toshihiro Shimizu |
890ddd |
m_skeleton.setNode(index, pos, IKNode::JOINT);
|
|
Toshihiro Shimizu |
890ddd |
m_skeleton.setParent(index, indexParent);
|
|
Toshihiro Shimizu |
890ddd |
return index;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//la root deve coincidere con un punto bloccato!
|
|
Toshihiro Shimizu |
890ddd |
void IKEngine::setRoot(const TPointD &pos)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_skeleton.addNode(new IKNode());
|
|
Toshihiro Shimizu |
890ddd |
m_skeleton.setNode(0, pos, IKNode::JOINT);
|
|
Toshihiro Shimizu |
890ddd |
//m_skeleton.setParent(0,0);
|
|
Toshihiro Shimizu |
890ddd |
m_skeleton.setRoot(0);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void IKEngine::lock(int index)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(index > -1 && index < m_skeleton.getNodeCount());
|
|
Toshihiro Shimizu |
890ddd |
m_skeleton.setPurpose(index, IKNode::EFFECTOR);
|
|
Toshihiro Shimizu |
890ddd |
IKNode *n = m_skeleton.getNode(index);
|
|
Toshihiro Shimizu |
890ddd |
TPointD pos = n->getPos();
|
|
Toshihiro Shimizu |
890ddd |
target.push_back(pos);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
void IKEngine::unlock(int index)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(index > -1 && index < m_skeleton.getNodeCount());
|
|
Toshihiro Shimizu |
890ddd |
m_skeleton.setPurpose(index, IKNode::JOINT);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool IKEngine::isLocked(int index)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(index > -1 && index < m_skeleton.getNodeCount());
|
|
Toshihiro Shimizu |
890ddd |
return m_skeleton.getNode(index)->IsEffector();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double IKEngine::getJointAngle(int index)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(index > -1 && index < m_skeleton.getNodeCount());
|
|
Toshihiro Shimizu |
890ddd |
TPointD pos = m_skeleton.getNode(index)->getPos();
|
|
Toshihiro Shimizu |
890ddd |
TPointD u(1, 0);
|
|
Toshihiro Shimizu |
890ddd |
if (index != 0) {
|
|
Toshihiro Shimizu |
890ddd |
int parent = getJointParent(index);
|
|
Toshihiro Shimizu |
890ddd |
TPointD prevPos = m_skeleton.getNode(parent)->getPos();
|
|
Toshihiro Shimizu |
890ddd |
u = normalize(pos - prevPos);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
TPointD v(-u.y, u.x);
|
|
Toshihiro Shimizu |
890ddd |
TPointD nextPos = m_skeleton.getNode(index + 1)->getPos();
|
|
Toshihiro Shimizu |
890ddd |
TPointD d = nextPos - pos;
|
|
Toshihiro Shimizu |
890ddd |
double theta = atan2(d * v, d * u);
|
|
Toshihiro Shimizu |
890ddd |
return theta;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void IKEngine::drag(TPointD &pos)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//assert(index>-1 && index
|
|
Toshihiro Shimizu |
890ddd |
// se lo scheletro รจ vuoto non succede nulla
|
|
Toshihiro Shimizu |
890ddd |
if (m_skeleton.getNodeCount() == 0)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// afferro l'ultimo punto della catena
|
|
Toshihiro Shimizu |
890ddd |
int indexDrag = m_skeleton.getNodeCount() - 1;
|
|
Toshihiro Shimizu |
890ddd |
if (m_skeleton.getNode(indexDrag)->getParent()->IsEffector())
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
m_skeleton.setPurpose(indexDrag, IKNode::EFFECTOR);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//assegno un indice alla sequenza dei giunti (nodi -end effectors)
|
|
Toshihiro Shimizu |
890ddd |
setSequenceJoints();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
target.push_back(pos);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Jacobian jacobian(&m_skeleton, target);
|
|
Toshihiro Shimizu |
890ddd |
target.pop_back();
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 0; i < 250; i++)
|
|
Toshihiro Shimizu |
890ddd |
doUpdateStep(jacobian);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void IKEngine::doUpdateStep(Jacobian &jacobian)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
jacobian.computeJacobian(); // calcolo Jacobiano e il vettore deltaS
|
|
Toshihiro Shimizu |
890ddd |
int WhichMethod = DLS;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool clampingDetected = true;
|
|
Toshihiro Shimizu |
890ddd |
while (clampingDetected) {
|
|
Toshihiro Shimizu |
890ddd |
// Calcolo i cambiamenti dell'angolo
|
|
Toshihiro Shimizu |
890ddd |
switch (WhichMethod) {
|
|
Toshihiro Shimizu |
890ddd |
case JACOB_TRANS:
|
|
Toshihiro Shimizu |
890ddd |
jacobian.CalcDeltaThetasTranspose(); // Jacobian transpose method
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case DLS:
|
|
Toshihiro Shimizu |
890ddd |
jacobian.CalcDeltaThetasDLS(); // Damped least squares method
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case PURE_PSEUDO:
|
|
Toshihiro Shimizu |
890ddd |
jacobian.CalcDeltaThetasPseudoinverse(); // Pure pseudoinverse method
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case SDLS:
|
|
Toshihiro Shimizu |
890ddd |
jacobian.CalcDeltaThetasSDLS(); // Selectively damped least squares method
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
default:
|
|
Toshihiro Shimizu |
890ddd |
jacobian.ZeroDeltaThetas();
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
jacobian.UpdateThetas(); // Aggiorno i valori di theta
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
clampingDetected = jacobian.checkJointsLimit();
|
|
Toshihiro Shimizu |
890ddd |
//jacobian.UpdatedSClampValue();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Assegno gli indici nella sequenza dei giunti
|
|
Toshihiro Shimizu |
890ddd |
void IKEngine::setSequenceJoints()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int indexJoint = 0;
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 0; i < (int)m_skeleton.getNodeCount(); i++) {
|
|
Toshihiro Shimizu |
890ddd |
IKNode *n = m_skeleton.getNode(i);
|
|
Toshihiro Shimizu |
890ddd |
IKNode::Purpose purpose = n->getPurpose();
|
|
Toshihiro Shimizu |
890ddd |
if (purpose != IKNode::EFFECTOR) {
|
|
Toshihiro Shimizu |
890ddd |
n->setSeqNumJoint(indexJoint);
|
|
Toshihiro Shimizu |
890ddd |
indexJoint++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|