projecting a vertex into camera space

Now tjis may sound like a real newbie question (mainly cause it is one )but I’m kinda confused cause I it diesn’t seem to work although it should.So I need to project a vertex from object space into camera space.Assuming I have the 4x4 camera matrix this should be real easy.Just multiply the vector by the matrix right?That’s what I’m doing but I was wondering if I’m doing it the wrong way.If the camera matrix is stored in column-major format(the one opengl uses) what would the multiplication look like?So assuming I have the following:

  1. the camera matrix(col. major):
    |c0 c4 c8 c12|
    |c1 c5 c9 c13|
    |c2 c6 c10 c14|
    |c3 c7 c11 c15|
  2. the vector
    |v0|
    |v1|
    |v2|
    |v3|
    what would the resulting vector be?Something like:
    |c0v0+c4v1+c8v2c12v3|
    |c1
    v0+c5v1+c9v2c13v3|
    |c2v0+c6v1+c10v2c14v3|
    |c3
    v0+c7v1+c11v2c15v3|

Again,I’m sorry to pollute the advanced forum with such a simple question but I was recently convinved I was doing matrix to martix multiplication the right way until some source from the ogl FAQ proved I wasn’t

I’m assuming you know how to multiply matrices.

Are you trying to impliment orthographic projection or one with a perspective?

For just the orthographic projection you only need to multiply your vertices by the camera matrix. If you want a persepective, you’ll need to multiply by the camera and the projection matrix.

I hope that made sence. If you were to use OpenGLs matrices you would need to multiply by the Modelview matrix and the Projection matrix for a perspective transformation. For orthographic you only need to multiply by the Modelview matrix.

From my experimentation I’ve noticed that I can take a Column Major matrix and multiply it with my Row Major matrix multiplier and it works just fine. Visa versa works too. Isn’t OpenGL Column Major? My routines are Row Major and I took my Row Major matrix and used glMultiply and it did exactly what a Column Major matrix created by glRotatef would do.

I know what you may be doing wrong. I’m not sure on the order of mutiplication though.

Are you setting your fourth element to 1.0? If you don’t, you won’t get the correct results.

By 4th element,do you mean v3?I do set vr to 1.0.And I do know how matrix to vector multiplication works as well but I don’t know for sure how to do it when the matrix is in col.-major format.

ok you multiply your vector with this order: (vector * modelview =) new vector * procetion= what you have done, right ?!?, ok now you have to perform the most important part for frustum etc. : divide now this vector by w, so you get:
vector.x= x/w;
vector.y= y/w;
vector.z= z/w;
vector.w= 1;// w/w;

thats all, now you have the view in a box around the center with size of 2, one in every direction ( p(-1,-1,-1) to p(1,1,1) should be a diagonal), check by yourself where front,up, etc is:

[This message has been edited by T2k (edited 05-13-2001).]

T2k:
I don’t wan to get the normalised device coords. of the vertex just, the camera space coords. without projection,so what I’m doing should be right,right?

Right.
Alexei.

the trick is, opengl does use the matrices different, means you cant do it like this:

v.x = p.x * m[0] + p.y * m[1] + p.z * m[2] + p.w * m[3];
etc, you have to use the transposed… means swapping at the diagonal…

v.x = p.x * m[0] + p.y * m[4] + p.z * m[8] + p.w * m[12];
v.y = p.x * m[1] + p.y * m[5] + p.z * m[9] + p.w * m[13];
v.z = p.x * m[2] + p.y * m[6] + p.z * m[10] + p.w * m[14];
v.w = p.x * m[3] + p.y * m[7] + p.z * m[11] + p.w * m[15];

like that… with m as
float m[ 16 ];
glGetFloatv( GL_MODELVIEW_MATRIX, m );

works nice here…

Dave:
Thanx for posting but that’s what I’m doing(ain’t it?) and it doesn’t seem to work very well.But then again the problem might not be with the projection part of the calculation…

'ello.

don’t forget that you have to convert to/from homogeneous coordinates and then to/from device coordinates.

here’s a walk-throuugh"

  • get some three-dimensional cartesian point m=<x y z>
  • turn it into a homogenous column vector, . v <- <m 1>T (note 1)
  • project the point: v’=PMv (note 2)
  • turn v’ back into cartesian space. m’=cartesian(v’) (note 3)
  • map m’ to device coordinates. m’ <- device(m’) (note 4)

note 1: v becomes a column vector with 1 tacked onto the end. (c.f. t2k’s post). by T on the end of <> i mean take the transpose.

note 2: Projection * Modelview. You must multiply by your proejction even with ortographic projection. the reason being the ortho projection maps points into a square which we have to map to device coords

note 3: okay, you probably don’t need to do this at THIS point, but. eh. =) divide each element of v’ vy w’.w to turn the homogeneous coord into the cartesian coord.

note 4: the opengl projection matricies map points in the 3D space to points inside a +/- 1 square. so the trick is to turn the ‘unit’ square into device coordinates. ie. map -1…1 on the x-range to 0…639 (for args sake),a nd map -1…1 on the y-range to 0…479 (assuming a 640x480 res screen).

hoep this helps,
cheers,
John

Hi john,
thanks for the reply,but I only need to project the point into camera space(I think it’s called eye coordintes in ogl terms) w/o projection,so I just need to take the first three steps of your walkthrough and use only the modelview matrix instead of PM.That’s what I’m doing.

Hello,

ah, okies. its just that “projection”, by defn, means you’re losing a dimension. ie, 3D->2D is projection, but just multiplying by a 4x4 matrix is still 3D->3D, which is a transfrom.

just, you know, so you can make sense when ppl refer to projection.

(caveat: opengl doesn’t exactly “lose” the third dimension, because its needed for the z-buffer. but it IS finding the intersection of the vector through a 3D point and the optical centre with the near plane, which is projection)

cheers,
John