Getting a "forward" vector from "right", and "up" vectors.

This is a discussion on Getting a "forward" vector from "right", and "up" vectors. within the Game Programming forums, part of the General Programming Boards category; Relatively simple question, that I can't seem to find the answer to on google. Given the right and up vector ...

  1. #1
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,070

    Getting a "forward" vector from "right", and "up" vectors.

    Relatively simple question, that I can't seem to find the answer to on google.

    Given the right and up vector of a camera, how would I obtain a vector that points forward relative to those vectors?

    Thanks.
    Memorial University of Newfoundland
    Computer Science

    Mac and OpenGL evangelist.

  2. #2
    Registered User
    Join Date
    Aug 2003
    Posts
    1,203
    Im gonna guess this is 3D right? Shouldnt it be only to take the crossproduct of the 2 vectors? Say you have this vector for up:
    [0, 1, 0]
    and this for right:
    [1, 0, 0]

    Then the crossproduct will be:
    cross(up, right) = [0, 0, -1]
    and
    cross(right, up) = [0, 0, 1]

    Alhtough i must say it was a long time since i did vector-stuff but this doesnt seem to be too far off.
    STL Util a small headers-only library with various utility functions. Mainly for fun but feedback is welcome.

  3. #3
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    I'm not quite sure what you mean, either. Are you looking for a simple vector addition?
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  4. #4
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,070
    Sorry. Should've included some more description of what i'm trying to do.

    I'm working on object moving with the mouse (still). I calculate a "right" vector as the cross of the view vector and the up vector.

    Doing this:
    Code:
    Vec3 moveVec = Vec3((newX*procEngine->lgcModule->procCam->vRight.x)*2, -newY*2, (newX*procEngine->lgcModule->procCam->vRight.z)*2);
    Produces accurate results, where newX and newY are the mouse coordinates in 3D space (found with gluUnProject).

    The problem is, if I want to move the object in and out of the screen, I need a vector that always points forward, like my right vector always points right based on the current orientation.

    I tried:
    Code:
    Vec3 moveVec = Vec3((newX*procEngine->lgcModule->procCam->vRight.x)*2, 0.0f, (newY*forward.z)*2);
    where forward = Cross(right, up), like you said, but it's not working properly. At this point I can't tell if its the forward vector calculation that's the problem, or if it's the way i'm using it above.
    Memorial University of Newfoundland
    Computer Science

    Mac and OpenGL evangelist.

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    So you have two vectors (a vectical and a horizontal) and you're trying to create a perpendicular vector (depth)?
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  6. #6
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,070
    mm, yeah, basically.
    Memorial University of Newfoundland
    Computer Science

    Mac and OpenGL evangelist.

  7. #7
    Registered User
    Join Date
    Aug 2003
    Posts
    1,203
    Are you using opengl for this?? And in what way doesnt it work??

    Because if you are shouldnt you use cross(up, right) since the z-axis is negative as it moves into the screen??
    Last edited by Shakti; 09-27-2006 at 12:36 PM.
    STL Util a small headers-only library with various utility functions. Mainly for fun but feedback is welcome.

  8. #8
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    What are the dimensions of the Z-vector (the depth, "forward" vector)? Like, do you take its velocity from the X-vector or the Y-vector? (Are we clear on what a vector is here? I'm assuming it's a velocity, a direction and a speed.)
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  9. #9
    Registered User
    Join Date
    Aug 2003
    Posts
    1,203
    My guess is that he wants a z-vector in order to build up a coordinate system for 3D, and to be able to translate objects along that vector.
    STL Util a small headers-only library with various utility functions. Mainly for fun but feedback is welcome.

  10. #10
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,070
    Yep, using OpenGL.

    If the camera is looking straight down the world Z-axis, I can move the object along that axis fine. However, if I rotate the camera to look down the positive X, I can't move the object along that axis by moving the mouse up and down, even though the forward vector should be pointing in that direction (down the X).

    This same concept does work when trying to move objects on the X and Y, not X and Z with this method:
    Code:
    Vec3 moveVec = Vec3((newX*procEngine->lgcModule->procCam->vRight.x)*2, -newY*2, (newX*procEngine->lgcModule->procCam->vRight.z)*2);
    Sorry if it's still unclear or confusing. I'm having a little trouble trying to explain it.

    EDIT:
    Quote Originally Posted by shakti
    My guess is that he wants a z-vector in order to build up a coordinate system for 3D, and to be able to translate objects along that vector.
    Never saw that post. Yeah, that's basic idea here.
    Last edited by psychopath; 09-27-2006 at 12:43 PM.
    Memorial University of Newfoundland
    Computer Science

    Mac and OpenGL evangelist.

  11. #11
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,596
    Code:
    void CCamera::GetViewMatrix(D3DXMATRIX *outMatrix)
    {
      D3DXVec3Normalize(&Look,&Look);
      
      D3DXVec3Cross(&Up,&Look,&Right);
      D3DXVec3Normalize(&Right,&Right);
    
      D3DXVec3Cross(&Right,&Up,&Look);
      D3DXVec3Normalize(&Look,&Look);
    
      float x=-D3DXVec3Dot(&Right,&Pos);
      float y=-D3DXVec3Dot(&Up,&Pos);
      float z=-D3DXVec3Dot(&Look,&Pos);
    
      (*outMatrix)(0,0)=Right.x;
      (*outMatrix)(0,1)=Up.x;
      (*outMatrix)(0,2)=Look.x;
      (*outMatrix)(0,3)=0.0f;
    
      (*outMatrix)(1,0)=Right.y;
      (*outMatrix)(1,1)=Up.y;
      (*outMatrix)(1,2)=Look.y;
      (*outMatrix)(1,3)=0.0f;
    
      (*outMatrix)(2,0)=Right.z;
      (*outMatrix)(2,1)=Up.z;
      (*outMatrix)(2,2)=Look.z;
      (*outMatrix)(2,3)=0.0f;
    
      (*outMatrix)(3,0)=x;
      (*outMatrix)(3,1)=y;
      (*outMatrix)(3,2)=z;
      (*outMatrix)(3,3)=1.0f;
    }
    Again for DX matrices so yours will be a bit diff.
    The idea is to take the basis vectors x,y and z and compute a camera transform matrix.
    The base vectors are:

    Right 1.0f,0.0f,0.0f
    Up 0.0f,1.0f,0.0f
    Look 0.0f,0.0f,1.0f

    The resulting matrix becomes your new view matrix for the entire scene. Now doing rotations and such is a simple matter of doing axis angle rotations about the axis you need.

    I'm attaching my camera class. Most of this info comes from the books I've read on 3D and I've simply revised the class code a bit. Notice that now you could have a collection of cameras, stick a camera in each object or simply change the params of the camera to match an object and you have a very flexible camera system.

    This code uses Euler angles but because of the axis angle rotation you don't get gimble lock. Problem is, though, it is very hard to linear interpolate from one axis-angle orientation to another. For that you need quaternion rotation.
    Last edited by VirtualAce; 03-12-2011 at 10:42 AM.

  12. #12
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,070
    Thanks for the replies everyone, I got it working. It occured to me that I could just make two translation calls for each vector (right and forward), rather than trying to do it in one call.

    Here's the code, for anyone interested. It checks to see if the left mouse button is down, and if so, cycles through all the objects, checking to see if they've been selected. Each selected object is then translated on the axis/axii (offtopic: what's the plural of "axis"?), specified by axisMode;

    WARNING: code may contain traces of C++/CLI.
    Code:
    if(movingObject){
    	for(int i=0; i<procEngine->physModule->numObjects; i++){
    		if(procEngine->physModule->objects[i]->bSelected){
    			static double newX, newY, newZ;
    			Gl::glGetDoublev(Gl::GL_MODELVIEW_MATRIX, modelView = gcnew array<double>(16));
    			Gl::glGetDoublev(Gl::GL_PROJECTION_MATRIX, projection = gcnew array<double>(16));
    			Gl::glGetIntegerv(Gl::GL_VIEWPORT, viewport = gcnew array<int>(4));
    							Glu::gluUnProject(::Cursor::Position.X, ::Cursor::Position.Y, 0.0, modelView, projection, viewport, newX, newY, newZ);
    
    			Vec3 forward;
    			forward.Cross(procEngine->lgcModule->procCam->vRight, procEngine->lgcModule->procCam->vUp);
    			forward.Negate();
    			forward = forward.Normalize();
    							
    			if(axisMode == 0){
    				procEngine->physModule->objects[i]->Translate(procEngine->lgcModule->procCam->vRight*(newX*2));
    				procEngine->physModule->objects[i]->Translate(forward*(newY*2));
    			}
    			if(axisMode == 1){
    				procEngine->physModule->objects[i]->Translate(procEngine->lgcModule->procCam->vRight*(newX*2));
    				procEngine->physModule->objects[i]->Translate(Vec3(0.0f, 1.0f, 0.0f)*(-newY*2));
    			}
    			if(axisMode == 2){
    				procEngine->physModule->objects[i]->Translate(procEngine->lgcModule->procCam->vRight*(newX*2));
    			}
    			if(axisMode == 3){
    				procEngine->physModule->objects[i]->Translate(Vec3(0.0f, 1.0f, 0.0f)*(-newY*2));
    			}
    			if(axisMode == 4){
    				procEngine->physModule->objects[i]->Translate(forward*(newY*2));
    			}
    		}
    	}
    }
    Thanks again!
    Memorial University of Newfoundland
    Computer Science

    Mac and OpenGL evangelist.

Popular pages Recent additions subscribe to a feed

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21