[Closed] Match object to vector
Hi guys,
i have a biped in 3ds max and i am currently trying to make its thigh point in the direction of an arbitrary vector. I am aware of the fact, that a vector can’t define a concrete orientation, because it can still rotate around its own axis. But for the moment i would like to ignore that and just make the thigh point in the same direction as the vector.
Basically i was trying to do it like this:
I made a second vector which defines the current direction of the thigh by getting the positions of the thigh and the knee and computing a directional vector from it. So I have two vectors: The first points to the direction i want the thigh to point at, and the second is the direction the thigh is currently pointing at.
I can now easily compute the angle between those vectors, and a normal which is orthogonal to both vectors. Now i thought all i had to do is rotate the thigh about the normal with the angle, by using a quaterion. But somehow it doesn’t work. The Thigh is rotating, but it is pointing to any position that looks just random to me
I got to say, that i am programming with the SDK. But i am pretty desperate and ANY help is arpreciated
Here is my code:
INode* pNodeBipA = pthis->ip->GetINodeByName("Bip001 L Thigh");
INode* pNodeBipB = pthis->ip->GetINodeByName("Bip001 L Calf");
Point3 bipA = pthis->getPosition(pNodeBipA);
Point3 bipB = pthis->getPosition(pNodeBipB);
Point3 bipCurrent = bipB-bipA;
//arbitrary target vector
Point3 target;
target.x = 1;
target.y = 1;
target.z = -1;
bipCurrent = bipCurrent.FNormalize();
//Get the normal by computing the cross product
Point3 normal = bipCurrent^target;
normal = normal.FNormalize;
//the angle is the acos of the dot product of both vectors
//no need to divide by the length of the vectors, because they are normalized
double angle = acos(bipCurrent.x*target.x + bipCurrent.y*target.y + bipCurrent.z*target.z);
Quat qRotation;
qRotation.w = cos(angle/2);
qRotation.x = normal.x * sin(angle/2);
qRotation.y = normal.y * sin(angle/2);
qRotation.z = normal.z * sin(angle/2);
qRot.Normalize();
Matrix3 tmWorld = pNodeBipA->GetNodeTM(0);
Matrix3 tmParent = pNodeBipA->GetParentTM(0);
Matrix3 tmLocal = tmWorld * Inverse(tmParent);
pNodeBipA->Rotate(0, tmWorld, qRot);
ip->RedrawViews(0, REDRAW_BEGIN, NULL);
All you need is to create Matrix3 from the TARGET vector, NORMAL vector and the CROSS product of them, after that, put this Matrix to object’s transform. That’s all.
Matrix3 *TM = new Matrix3 (NORMAL, (TARGET^NORMAL) , TARGET);
TM->Translate( pNodeBipA ->getNodeTm(0).GetTrans() );
pNodeBipA -> setNodeTM(0,TM);