Camera and clipping planes?
NormalLeft = (cos(FovX/2), 0, sin(FovX/2));
NormalRight = (-cos(FovX/2), 0, sin(FovX/2));
NormalTop = (0, -cos(FovY/2), sin(FovY/2));
NormalBottom = (0, cos(FovY/2), sin(FovY/2));
If you use a righthanded coordinate system as OpenGL does, you need to negate the z coordinate of the normals.
Then transform each of the normals by the camera matrix that you already have, except that you should set the position to (0,0,0) so that they aren't translated.
TransformMatrix = [right.x right.y right.z 0][ up.x up.y up.z 0][front.x front.z front.z 0][ 0 0 0 1]
(For OpenGL you need to transpose this matrix)
TransformedNormalLeft = NormalLeft*TransformMatrix
Then finally you compute the last component of the clipplanes, d, with a dotproduct like this:
dLeft = -DotProduct(CameraPosition, TransformedNormalLeft);
The plane equation for the left plane would be
(tnl = TransformedNormalLeft)
x*tnl.x + y*tnl.y + z*tnl.z + dLeft = 0
(I think my calculations are correct, you of course need to verify them )
- WitchLord
(I fixed a small error: dLeft wasn't negated before)
Edited by - WitchLord on May 24, 2000 8:03:14 AM
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
P.S.: I think I also figured out the maths behind this: I’m transforming from viewspace into worldspace coordinates. To transform points I would need to multiply them with the inverse of the camera matrix.
But (as I read in the Open GL blue book) normals are transformed by the inverse transpose of the matrix that of the transformation that transforms points.
So the inverse of the inverse of the camera matrix gives me the original matrix. I only need to transpose it.
Thanks again
Pascalix
- WitchLord
Edited by - WitchLord on May 20, 2000 7:06:42 PM
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
quote:
md2ge wrote:
Hi Witchlord =)
Idea for tutorial, I've been trying to follow the code you posted as a reply, here's is the URL
http://www.gamedev.net/community/forums/topic.asp?topic_id=14022&forum_id=11&Topic_Title=Camera+and+clipping+planes%3F&forum_title=General+and+Game+Programming+Discussion&M=True&S=True
Altho I think I understand the basics of this I'm doing something wrong, I can't seem to arrive at any usefull values for plane equation, here's is what I've done in case you can spot something obvious, otherwise I'll just wait til tutorial =)
I'm only including the code for one of the planes (left plane), also in your post you didn't mention anything regarding aspect ratio, so we dont need it for any of this calculations?
Actually if you examine the code carefully you'll find two references to FOV one being FovX and the other being FovY. For a normal aspect ratio of 4:3 these aren't the same. (I don't have the energy to find paper and pen to actually compute the angles right now )
quote:
// Make a vector in worldspace
D3DXVECTOR3 w;
w.x = 0.0f;
w.y = 0.0f;
w.z = 1.0f;
D3DXMATRIX view;
app->d3d_device->GetTransform(D3DTRANSFORMSTATE_VIEW, D3DMATRIX *)view);
// Need to transpose? or Invert? or ?
D3DXMatrixTranspose(&view,&view);
view.m30=view.m31=view.m32=0.0f;
For a rotation matrix, the inversion and the transposing does the exact same thing. Since we don't have a pure rotation matrix we need to remove the translation part, either before transposing or after. If you inverted the matrix you don't need to bother removing translation part as it will be inverted along with the rest.
quote:
// Assuming an FOV of 90 I need the cos and sin of radian(45)?
D3DXVECTOR3 NormalLeft =( (float)cos(D3DXToRadian(45.0f)),0.0f, (float)sin(D3DXToRadian(45.0f)) );
Yes, when you compute the normal you should divide the angle by two. Imagine what would happen if you didn't divide the angle and you had FOV = 90.
quote:
D3DXVECTOR3 tnl; // transformed normal left
D3DXVec3TransformCoord(&tnl,&NormalLeft,&view);
// There are 3 versions of D3DXVec3Transfrom... I'm guessing this is the correct one.
It would probably be more accurate to use D3DXVec3TransformNormal() instead, since that is exactly what we are doing. However for the pure rotation matrix (that was computed above) these two would do the exact same thing.
quote:
D3DXVECTOR3 cam_pos;
// This function returns the camera position in worldspace
app->CamGetPosition(&cam_pos);
float dLeft = D3DXVec3Dot(&cam_pos,&tnl);
I made a small error here before, dLeft should be computed as:
float dLeft = -D3DXVec3Dot(&cam_pos,&tnl);
(I have fixed it in the above equation)
quote:
float pl = w.x*tnl.x + w.y*tnl.y + w.z*tnl.z + dLeft;
When w=0,0,0 then pl=dLeft
Neither of this 2 values seem to return any usefull information, so I'm either doing something wrong (which is very likely) or I don't know how to interpret this values.
Actually dLeft tells you at what distance the clip plane is from the world origo. And after inserting w in the plane equation p1 tells you at what distance from the plane the point is.
quote:
Thanks,
Rick
Your welcome
- WitchLord
Edited by - WitchLord on May 24, 2000 8:01:24 AM
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
Let''s say I set up the app with fov 90 and aspect 1.33, can I do this then?
fovx = toradian(45)*1.33
fovy = toradian(45)
and also for this line:
float dLeft = -D3DXVec3Dot(&cam_pos,&tnl);
for cam_pos, I can just use the 3 matrix values we zero out before (store them in cam_pos before I zero them out) right? or do I need to use a 0,0,0 value here?
And lastly, the normals are created in view space, then multiplied by the inverse of the vew matrix, so basically we putting them into world space (but without the translation part?), so when I plug in the xyz point to solve the plane equation this point needs to be in world space?
The frustrum is for some reason diffucult to me to understand, this is my current mental picture =)
It all starts with a pyramid where your eyes are, also referred to as the camera "position", in view space, this point is represented by the translation part of the view matrix, it then extends towards the screen passing thru the 4 corners all the way back to your back clipping plane. The bigger the fov is the closer the eye point gets to the screen and the wider the frustrum becomes, for an fov of 180 the eye would acctualy end up right ON the screen (???) but then this thing is no longer a pyramid more like a rectange (???)
Thanks,
Rick
quote: Original post by md2ge
Thanks, just comple more questions =)
Let''s say I set up the app with fov 90 and aspect 1.33, can I do this then?
fovx = toradian(45)*1.33
fovy = toradian(45)
if fovy is 90 degrees then fovx will be:
fovx = todegree(2*atan(1.33*tan(toradian(fovy/2))) = 106degr
quote:
and also for this line:
float dLeft = -D3DXVec3Dot(&cam_pos,&tnl);
for cam_pos, I can just use the 3 matrix values we zero out before (store them in cam_pos before I zero them out) right? or do I need to use a 0,0,0 value here?
The cam_pos that you send to the dotproduct must be the cameras position in world coordinates. It is not that easy to obtain the camera position from the view matrix, it can be done but it is better to store it in a variable.
quote:
And lastly, the normals are created in view space, then multiplied by the inverse of the vew matrix, so basically we putting them into world space (but without the translation part?), so when I plug in the xyz point to solve the plane equation this point needs to be in world space?
Yes the points that you check against the planes we have computed are in world coordinates.
quote:
The frustrum is for some reason diffucult to me to understand, this is my current mental picture =)
It all starts with a pyramid where your eyes are, also referred to as the camera "position", in view space, this point is represented by the translation part of the view matrix, it then extends towards the screen passing thru the 4 corners all the way back to your back clipping plane. The bigger the fov is the closer the eye point gets to the screen and the wider the frustrum becomes, for an fov of 180 the eye would acctualy end up right ON the screen (???) but then this thing is no longer a pyramid more like a rectange (???)
Correct
quote:
Thanks,
Rick
- WitchLord
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
float aspect = 1.33;
float fov = toradian(90);
setup_projection( blah blah fov, aspect, blah blah)
fovy = fov/2;
fovx = 2*atan(aspect*tan(fovy) )
then use fovy and fovx to calculate the normals, exept that I dont need to divide by 2 anymore, correct? =)
Thanks,
Rick
HalfFovY = FovY/2;
HalfFovX = todegree(atan(1.33*tan(toradian(HalfFovY)));
- WitchLord
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game