Notifications
Clear all

[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);
2 Replies

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);