Thread: 3D rotation problem, help please!

  1. #1
    Registered User
    Join Date
    Nov 2007
    Posts
    34

    3D rotation problem, help please!

    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!

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    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.

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    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?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #4
    Registered User
    Join Date
    Nov 2007
    Posts
    34
    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.

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by GOBLIN-85 View Post
    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".

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    tabstop, I think the OP wants to know what the new axis will be.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User
    Join Date
    Nov 2007
    Posts
    34
    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.

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by GOBLIN-85 View Post
    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:
    void glRotated( GLdouble angle,
    GLdouble x,
    GLdouble y,
    GLdouble z )
    and I'll bet you can guess what goes where.

  9. #9
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by GOBLIN-85 View Post
    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.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  10. #10
    Registered User
    Join Date
    Nov 2007
    Posts
    34
    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.

  11. #11
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by GOBLIN-85 View Post
    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.

    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.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by GOBLIN-85 View Post
    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.

  13. #13
    Registered User
    Join Date
    Nov 2007
    Posts
    34
    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.

  14. #14
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by GOBLIN-85 View Post
    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.

  15. #15
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    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).
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. camera rotation matrix
    By Vick jr in forum Game Programming
    Replies: 5
    Last Post: 05-26-2009, 08:16 AM
  2. Bin packing problem....
    By 81N4RY_DR460N in forum C++ Programming
    Replies: 0
    Last Post: 08-01-2005, 05:20 AM
  3. rotation in 3d
    By DavidP in forum Game Programming
    Replies: 3
    Last Post: 11-04-2003, 10:06 PM
  4. 3D SDK for C++ programmers
    By chand in forum Game Programming
    Replies: 2
    Last Post: 05-20-2003, 07:38 AM
  5. 3d engines
    By Unregistered in forum Game Programming
    Replies: 7
    Last Post: 12-17-2001, 11:19 AM