Jump to content
  • Advertisement
Sign in to follow this  
Fallsilent

OpenGL Direction of Flight Transformation

This topic is 3494 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Share this post


Link to post
Share on other sites
Advertisement
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.

Share this post


Link to post
Share on other sites
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:
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.

Share this post


Link to post
Share on other sites
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..

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!