I need to modify the above matrix so that it projects outward instead of inward…but how??? I’ve been playing with this thing for two days now. It’s a simple as swapping 1000 with z in the old formula. It should be just as simple with the matrix but I can’t seem to pull it off .
[This message has been edited by WhatEver (edited 01-24-2003).]
You can’t do this with the projection matrix. Sorry.
In homogenous coordinates, a vertex position is (x/w, y/w, z/w). The projection matrix sets it so that this calculates (x/z, y/z, depth). You can divide over a linear combination of your vertex x/y/z/w, but you cannot multiply.
You could probably do it with a vertex program or by using software to preprocess your vertices.
Ok, that’s alright. Is there any way to take the near, far and fov parameters and create a deviser for the old formula? Right now this formula works for only 800x600 with a 60 degree fovy:
x=-x*(z/518.4810127f);
y=-y*(z/518.4810127f);
I need to derive 518.4810127 mathamaticly from the same info you give glFrustum. I got that number from deviding my far plane 2048 by 3.95. I found 3.95 by deviding 2048 by an approximation I found by trial and error.
I think the only way I’m going to pull this off is by raycasting. I wanted a faster way, but I think that I’ll just rotate the point instead of scale it. That should work. I’ll try it later.
I believe you can do this with the depth test set to greater. You just need to add an extra transform onto the projection matrix.
Basically you push the regular projection on, then you push on a matrix that mirrors eye space such that the near and far clip planes flip. It would work like this:
Ok, I’m officially going crazy. Every theory I have, and every sample source I use, I can’t get to work.
I MUST figure this out for my terrain editor. I don’t want to restrict picing in ortho mode. Every 3D editor I know of has perspective picking, but I can’t find any resources that explain it well. I’ve even looked through my old game programming books yet I can still not figure it out because OpenGL uses a Projection matrix not that old formula like in my first post.
Here’s was a briliant theory that didn’t work. The idea was to multiply a -zdepth of the ray with the projection matrix. This would create a point behind the view point which would be scaled out instead of in…BUT, it didn’t work! Bah!
Here’s my code:
S3Dvoid s3d_camera::ScreenToWorld(S3Dfloat xin, S3Dfloat yin, S3Dfloat zin, S3Dfloat* xout, S3Dfloat* yout, S3Dfloat* zout)
{
S3Dmat16f Projection;
S3Dint ViewPort[4];
S3Dvec3f Pos;
S3Dfloat Temp;
//get the viewport dimentions
glGetIntegerv(GL_VIEWPORT, ViewPort);
//get the projection matrix
glGetFloatv(GL_PROJECTION_MATRIX, Projection);
//4rth emement must be 1.0f for correct matrix multiplication
Pos[3]=1.0f;
//flip y
yin=ViewPort[3]-yin;
//orientate point relative to the center of the viewport
xin=xin-(ViewPort[2]*0.5f);
yin=yin-(ViewPort[3]*0.5f);
//assign x, y and z to vector
s3dVecSet3f(Pos, xin, yin, zin);
//scale x and y position out the further away the vertex is from the screen
//this method only works at 800x600 and a 60 degree fov
//Pos[0]=-Pos[0]*Pos[2]/518.4810127f;//60 degrees
//Pos[1]=-Pos[1]*Pos[2]/518.4810127f;
//we don't want to change the z value, just the x and y value so store the
//original z value in a temp float
Temp=Pos[2];
//place point behind viewer so it scale outward instead of inward
Pos[2]=-Pos[2];
//project, aka scale x and y.
s3dMatMultiply4x16f(Pos, Projection);
//restore z value
Pos[2]=Temp;
//move the Pos into world space
s3dMatMultiply4x16f(Pos, CameraMatrix);
*xout=Pos[0];
*yout=Pos[1];
*zout=Pos[2];
}
I can’t get it to work when the z doesn’t eqaul 0. It seems like it’s only good for projecting a point on the viewing plane and nowhere else. Am I wrong?
I made a demo that uses gluUnProject for casting rays. I call gluUnproject twice; once with the z depth returned by glReadPixels and again with a z depth of zero. This creates the two points in space that I need to make a ray for ray collision detection and point selection.
I haven’t started on the terrain part yet, so for now I used the spitfire to test the ray casting. All you have to do is point the mouse anywhere on the spitfire and it will draw the normal of the bounding collision areas.