# 3D rotation problem, help please!

Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last
• 03-08-2009
GOBLIN-85
Hi all,

I'm writing a 3D space game. I have Vector3 to represent the position, velocity and angular velocity, and a Quaternion to represent the orientation of the spaceship.

Now I want to rotate the ship when I press the directional button, say turn it left when press left arrow key and turn it up when press the up arrow key. I have Vector3 to represent the force, torque etc.

I also have a method named addForceAtPoint(Vector3 force, Vector3 position) so that I can add a force at particular point, say add it on the right wing to turn it left. The position can be converted to the global coordinate no problem, but it's the force that bothers me. Say I call this:
Code:

```//add a force on the z direction(initially the ship is moving in the positive z direction) // at the point (30,0,0) - a point that is relative to the body, not in the global // coordinate, it will be converted in the body of the method. addForceAtPoint(Vector3(0,0,50), Vector3(30,0,0));```
Now I can use the same point over and over again because it can be converted to the global coordinate every time, but I can't do the same to the force as it can't always be in the z direction. The force should always be in the direction of the spaceship. That's what I don't know how to do.

If any of you kind souls ever encountered this problem or have experience on 3D rotation problem, I will much appreciate it if you can share a solution.

Many thanks!
• 03-08-2009
tabstop
If the force will always be in the direction of the spaceship, use spaceship.velocity (I'm assuming that's what you mean by "in the direction of the spaceship") and be done with it.
• 03-08-2009
MK27
It looks like you want to do this from scratch (ie, without using openGL or DirectX or something) because (at least in openGL) this need not be this complex because you can use a matrix stack (I believe they are there in DirectX too).

You could implement one yourself, the idea is fairly simple: You have a matrix representing the current orientation and location (a 4x4 matrix) of the ship, and one representing the next change to take place -- but this one is not relative to the ship's position, it's relative to the origin, ie, as if the ship were dead center, with no rotation. So the transformation matrix is simple, because this is no change:
Code:

``` --- orientation ------  x-axis  y-axis  z-axis    pos   1        0        0        0      x    0        1        0        0      y   0        0        1        0      z   0        0        0        1      need 4th row for multiplication (will always be 0,0,0,1)```
Multiplying another 4x4 matrix by this will leave it exactly the same (ie, no matter where the ship is and how it is oriented). Which means if you (for example) change row one column 4, the product of the multiplication will have a different x-axis position. To rotate something relative to itself, multiply it's current state by a matrix tweaked w/r/t eg. the z value of the x-axis AND the x value of the z-axis (turn left or right).

That's a bit of a headache, which is why most people would use an API like openGL or DirectX, which includes simple functions like "yRotate(degrees)" that do the matrix math for you.

In any case, then you can keep the "z force" as a simple constant because you would apply it by multiplying by a matrix with a positive value in row 3 column 4.

However, I thought you could do all that with quaterions anyway?
• 03-08-2009
GOBLIN-85
Thank you both for the advice. I've decided to just use Quaternion to rotate the ship, i.e. when a key pressed, just rotate the ship by certain amount without adding force.

However it is still a problem to me, as the quaternion of the ship is easy to get, how do I get the new quaternion that will be used to rotate the ship? Could you give me an example please?

Thanks.
• 03-08-2009
tabstop
Quote:

Originally Posted by GOBLIN-85
Thank you both for the advice. I've decided to just use Quaternion to rotate the ship, i.e. when a key pressed, just rotate the ship by certain amount without adding force.

However it is still a problem to me, as the quaternion of the ship is easy to get, how do I get the new quaternion that will be used to rotate the ship? Could you give me an example please?

Thanks.

Quaternions have the axis and a rotation angle, so presumably if you know how much you want to rotate by, then you're done.

Note that rotations (whether by quaternions or any other method) are not absolute; if you've done a rotation, then further rotations will be done with respect to the new axes, not some theoretical "absolute x-y-z".
• 03-08-2009
MK27
tabstop, I think the OP wants to know what the new axis will be.
• 03-08-2009
GOBLIN-85
Thanks tabstop, would you let me know if this works:

Code:

```//for example, i want to rotate the ship to the left Quaternion temp = Quaternion(pi/12, 0, 1, 0); player->orientation *= temp; player->orientation.normalise();```
And after the rotation, how do I use the information stored in the quaternion to display the object on screen. I'm using openGL. Obviously glRotated is used, but I'm not sure what are the parameters to pass to it.
• 03-08-2009
tabstop
Quote:

Originally Posted by GOBLIN-85
Thanks tabstop, would you let me know if this works:

Code:

```//for example, i want to rotate the ship to the left Quaternion temp = Quaternion(pi/12, 0, 1, 0); player->orientation *= temp; player->orientation.normalise();```
And after the rotation, how do I use the information stored in the quaternion to display the object on screen. I'm using openGL. Obviously glRotated is used, but I'm not sure what are the parameters to pass to it.

So type "man glRotate", or, if you're not on a *nix system, do the equivalent web search. You'll see:
Quote:

void glRotated( GLdouble angle,
GLdouble x,
GLdouble y,
GLdouble z )
and I'll bet you can guess what goes where.
• 03-08-2009
MK27
Quote:

Originally Posted by GOBLIN-85
openGL

I've been fooling around with openGL for a little while and let me guess: this spaceship you are talking about is supposed to be "first person perspective", right? Like, it's not an object we see zooming around and rotating in the view right? You want to be in the ship, looking out of it?

That is why you want to use quaternions, right? Because if the answer to all these questions is not yes, I would sooner chew my own hands off than go about rotation and transformation than the way you are doing it.
• 03-08-2009
GOBLIN-85
Well...the spaceship I'm talking about is 3rd person perspective, while the camera follows the ship. I.e. when the ship turns, the camera turns as well, it's kinda like the control of WOW. Sorry I haven't made that clear earlier.

I'm still new to those stuff, so If you think I'm on the wrong track, would you kindly let me know and possibly show me a way please?

By the way, I still don't know if the code I wrote in post #7 would work, so if you guys don't mind, can you tell me if it is correct?

Many thanks guys.
• 03-08-2009
MK27
Quote:

Originally Posted by GOBLIN-85
Well...the spaceship I'm talking about is 3rd person perspective, while the camera follows the ship. I.e.

WELL! That is pretty fancy then isn't it.

Quote:

I'm still new to those stuff, so If you think I'm on the wrong track, would you kindly let me know and possibly show me a way please?
I'm new too. I decided to avoid "quarternions" for now. Since I am kind of board with what I am supposed to be doing, maybe I will take a little time to see if what I am thinking of is possible -- just using the matrix stack and the rotate/transform functions. I will admit thus far I've been working on simpler tasks than the 3rd person perspective flying ship.
• 03-08-2009
tabstop
Quote:

Originally Posted by GOBLIN-85
Well...the spaceship I'm talking about is 3rd person perspective, while the camera follows the ship. I.e. when the ship turns, the camera turns as well, it's kinda like the control of WOW. Sorry I haven't made that clear earlier.

I'm still new to those stuff, so If you think I'm on the wrong track, would you kindly let me know and possibly show me a way please?

By the way, I still don't know if the code I wrote in post #7 would work, so if you guys don't mind, can you tell me if it is correct?

Many thanks guys.

Well, assuming somebody at some point has written a class called Quaternion, that has a *= operator and a normalise function that do what they say on the tin.
• 03-08-2009
GOBLIN-85
Thank you both again for helping me.

What I meant by what type of parameters to pass to glRotated is that I know the function looks like glRotate(angle, x, y, z), what I meant to ask is that how do I get the information of 'angle', 'x', 'y' and 'z' out of the orientation quaternion?

Is it as simple as accessing its four elements in order? i.e. orientation.w, orentation.x etc.
• 03-08-2009
tabstop
Quote:

Originally Posted by GOBLIN-85
Thank you both again for helping me.

What I meant by what type of parameters to pass to glRotated is that I know the function looks like glRotate(angle, x, y, z), what I meant to ask is that how do I get the information of 'angle', 'x', 'y' and 'z' out of the orientation quaternion?

Is it as simple as accessing its four elements in order? i.e. orientation.w, orentation.x etc.

Well ... yes. A quaternion is an angle and an axis, while glRotate expects an angle and an axis.
• 03-08-2009
MK27
I just think you should have done some more thinking about glPushMatrix(), glPopMatrix(), and glGetFloatv() -- which with the last one you can extract the current values of the matrix -- before some hoodwinking hooligan got you onto this 19th century math voyage. Which I'm sure it is interesting, but I will not be riding in your spaceship even if you let me (no offense).
Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last