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

1. ## 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. 2. 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. 3. I'm not quite sure what you mean, either. Are you looking for a simple vector addition? 4. 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. 5. So you have two vectors (a vectical and a horizontal) and you're trying to create a perpendicular vector (depth)? 6. mm, yeah, basically. 7. 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?? 8. 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.) 9. 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. 10. 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: 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. 11. 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. 12. 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! Popular pages Recent additions 