I have question for you.
I'm trying to implement ik with CCD and I got in some type of problem or i found a bug in CCD ( probably not the last :) )
Here is my ccd algorithm:
bool CCD::Compute(Joint* base, Joint* end, Target target)
{
//TO DO
/*
add constraints
do something when the cross product is 0
this happens when the curVector and targetVector are colinears
*/
Vector3 rootPos, curEnd, targetVector, desiredEnd, curVector, crossResult, endPos = target.GetPosition();
double cosAngle,turnAngle;
Joint* link;
int tries;
// start at the last link in the chain
link = end->GetParent();
tries = 0;
do
{
rootPos = link->GetWorldPosition();
curEnd = end->GetWorldPosition();
desiredEnd = endPos;
double distance = Vector3::DistanceSqared(curEnd, desiredEnd);
// see if i'm already close enough
if (distance > 0.1)
{
// create the vector to the current effector pos
curVector = curEnd - rootPos;
// create the desired effector position vector
targetVector = endPos - rootPos;
// normalize the vectors (expensive, requires a sqrt)
curVector.Normalize();
targetVector.Normalize();
// the dot product gives me the cosine of the desired angle
cosAngle = curVector.DotProduct(targetVector);
// if the dot product returns 1.0, i don't need to rotate as it is 0 degrees
if (cosAngle < 1.0)
{
// use the cross product to check which way to rotate
crossResult = curVector.CrossProduct(targetVector);
crossResult.Normalize();
turnAngle = acos(cosAngle); // get the angle
Quaternion rotation = Quaternion::FromAngleAxis(turnAngle, crossResult);
rotation.Normalize();
link->Rotate(rotation);
link->Update();
}
if (link->GetParent() == NULL)
{
link = end->GetParent(); // start of the chain, restart
}
else
{
link = link->GetParent();
}
}
// quit if i am close enough or been running long enough
} while (++tries < maxTries &&
Vector3::DistanceSqared(curEnd, desiredEnd) > 0.1);
if (tries == maxTries)
{
return false;
}
return true;
}
Basically it's identical with the one from here:
http://www.darwin3d.com/gdm1998.htm
My problem is when curVector and targetVector become collinear
Then the crossproduct between them will be zero and you don't know the rotation axis.
Basically the quaternion will give a 0 degree rotation
This happens when the bones are in a configuration like this:
[n] being the joints
- being the links
x being the target
[1]----[2]----[3]--x-[4]----[5]
and the target is on the same line lets say between joint [3] an [4]
For now i did not impose any constraints on the joints , i just left them to move freely
I well man research thesis it says that the CCD method works well around singularities.
Well this is a singularity situation i apparently the algorithm does not work
or is my implementation which is not good.
Hope I'm wrong and I need to change something in the implementation.
Where is a picture with situation:
http://img530.imag...problemdq9.jpg
If someone has an idea about this :d











