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.

Printable View

- 09-27-2006psychopathGetting 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. - 09-27-2006Shakti
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. - 09-27-2006dwks
I'm not quite sure what you mean, either. Are you looking for a simple vector addition?

- 09-27-2006psychopath
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);`

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);`

- 09-27-2006dwks
So you have two vectors (a vectical and a horizontal) and you're trying to create a perpendicular vector (depth)?

- 09-27-2006psychopath
mm, yeah, basically.

- 09-27-2006Shakti
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?? - 09-27-2006dwks
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.)

- 09-27-2006Shakti
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.

- 09-27-2006psychopath
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);`

EDIT:

Quote:

Originally Posted by**shakti**

- 09-27-2006VirtualAceCode:
`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;

}

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. - 09-27-2006psychopath
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));

}

}

}

}