Direction of Flight Transformation
Hi,
I have the following problem using OpenGL (but this is a more general problem): I have a 3d-modell-object, which has an absolute position and a vector containing the direction the modell should face (Direction of Flight - DOF). I tried to programm the transformation-matrix for the rotation by myself.. Here the code I have written:
//Ry = DOF/|DOF|
vertX Ry;
Ry.x = m_Normal.x/m_NormalLength;
Ry.y = m_Normal.y/m_NormalLength;
Ry.z = m_Normal.z/m_NormalLength;
//Rz = YxDOF/|YxDOF| (Y = (0,1,0))
vertX YxNormal;
YxNormal.x = m_Normal.z; //a2b3 - a3b2
YxNormal.y = 0.0f; //a3b1 - a1b3
YxNormal.z = -m_Normal.x; //a1b2 - a2b1
double YxNormalLength = sqrt((YxNormal.x*YxNormal.x)+(YxNormal.y*YxNormal.y)+(YxNormal.z*YxNormal.z));
vertX Rz;
if (!YxNormalLength == 0)
{
Rz.x = YxNormal.x/YxNormalLength;
Rz.y = YxNormal.y/YxNormalLength;
Rz.z = YxNormal.z/YxNormalLength;
}
else
{
std::cout << "ERROR: DIVISION BY ZERO - portal.cpp";
}
//Rx = |Rz x Ry|
vertX RzxRy;
RzxRy.x = ((Ry.y*Rz.z) - (Ry.z*Rz.y)); //a2b3 - a3b2
RzxRy.y = ((Ry.z*Rz.x) - (Ry.x*Rz.z)); //a3b1 - a1b3
RzxRy.z= ((Ry.x*Rz.y) - (Ry.y*Rz.x)); //a1b2 - a2b1
//There may be no need for this..?:
double RzxRyLength = sqrt((RzxRy.x*RzxRy.x)+(RzxRy.y*RzxRy.y)+(RzxRy.z*RzxRy.z));
vertX Rx;
if (!RzxRyLength == 0)
{
Rx.x = RzxRy.x/RzxRyLength;
Rx.y = RzxRy.y/RzxRyLength;
Rx.z = RzxRy.z/RzxRyLength;
}
else
{
std::cout << "ERROR: DIVISION BY ZERO - portal.cpp";
}
//fill m_RotationMatrix
m_fRotationMatrix[0] = Rx.x;
m_fRotationMatrix[1] = Ry.x;
m_fRotationMatrix[2] = Rz.x;
m_fRotationMatrix[3] = 0;
m_fRotationMatrix[4] = Rx.y;
m_fRotationMatrix[5] = Ry.y;
m_fRotationMatrix[6] = Rz.y;
m_fRotationMatrix[7] = 0;
m_fRotationMatrix[8] = Rx.z;
m_fRotationMatrix[9] = Ry.z;
m_fRotationMatrix[10] = Rz.z;
m_fRotationMatrix[11] = 0;
m_fRotationMatrix[12] = 0;
m_fRotationMatrix[13] = 0;
m_fRotationMatrix[14] = 0;
m_fRotationMatrix[15] = 1;
Later in the rendering-routine I multiply this m_fRotationMatrix with glMultMatrix() to the MODELVIEWMATRIX:
glPushMatrix();
//Rotate Object to "look" into the DOF = m_Normal
glMultMatrixf(m_fRotationMatrix);
//Translate it to the right position
glTranslatef(m_Position.x, m_Position.y, m_Position.z);
...
This code works - but just in two directions, the result is the same for using (1,0,0) or (0,0,1) as DOF.. I rewrote that code several times, but the result is always the same, it just doesn't work properly.
Can someone help me?
Quote:Original post by Fallsilent
m_fRotationMatrix[12] = 0;
m_fRotationMatrix[13] = 0;
m_fRotationMatrix[14] = 0;
m_fRotationMatrix[15] = 1;
Later in the rendering-routine I multiply this m_fRotationMatrix with glMultMatrix() to the MODELVIEWMATRIX:
glPushMatrix();
//Rotate Object to "look" into the DOF = m_Normal
glMultMatrixf(m_fRotationMatrix);
//Translate it to the right position
glTranslatef(m_Position.x, m_Position.y, m_Position.z);
Are you trying to place your model in the world or the camera at your model? If you're trying to place your model in the world I think you need to reverse the order of transformations, translate then rotate.
I see you're using a 4x4 matrix which can store a translation. The translation part is stored in elements 12, 13 and 14 so you could say:
m_fRotationMatrix[12] = m_Position.x;
m_fRotationMatrix[13] = m_Position.y;
m_fRotationMatrix[14] = m_Position.z;
glPushMatrix();
//apply model's transformation
glMultMatrixf(m_fRotationMatrix);
If you want to move the camera to your model you need to multiply by the inverse of the transformation matrix.
Sorry, I didn't get a chance to go over the code to create the rotation matrix.
Is there any reason you're doing all of your vector operations (e.g. normalization, dot and cross products etc.) manually and inline? This is highly error-prone (not to mention tedious). It would be better to move all of these operations to dedicated functions.
Also, although this:
Also, although this:
if (!YxNormalLength == 0) {...}
May work in most cases, it's not very robust, as division by numbers with very small magnitude can cause overflow errors or precision loss. It would be better to test against a threshold or epsilon here.
rasher: It is in the world.. Thanks for the advice, you're right - the order is important, but I only tried it on Position 0,0,0 so this has not influenced my results and the problem is still there :(
jyk: You're right too - that code was a kind of quick-and-dirty test, because I wasn't sure, if the idea was right at all. I think it is - so I will write a better version of this, but I am going to find the mistake first.. Otherwise it wouldn't make sense to write it ;)
And by the way: I tried it with values like 0.9, 0.1, 0.1 or something, so a division by zero or something alike is no problem..
jyk: You're right too - that code was a kind of quick-and-dirty test, because I wasn't sure, if the idea was right at all. I think it is - so I will write a better version of this, but I am going to find the mistake first.. Otherwise it wouldn't make sense to write it ;)
And by the way: I tried it with values like 0.9, 0.1, 0.1 or something, so a division by zero or something alike is no problem..
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement