PDA

View Full Version : fps navigation



silicon_chipper
03-10-2007, 11:37 PM
Hi all, I have a question that may be somewhat involved, but figured I might just post it. I have somewhat of a game like a first person shooter in the works. I wrote a bsp tree tool for partitioning and it works fine. I can draw all the walls in my game and navigate through the level. I am using the timerfunc to update the position of the player and it was giving me very decent performance. So I came to the floors and ceilings and I found that I needed a tessellator. That was the end of my performance. So after a while I decided I had to use a display list for the ceilings and floors. Thus I had employ either glrotate/translate or glulookat to simulate navigation with static floors and ceilings. It is not going well. The player position is a point in the xz plane. I draw all the ceilings and floors for the whole level in a display list. They are rendered with respect to an initial position and view angle(the positive x-axis is 0 degrees while the positive z axis is 90 and so on). As the player moves I use the position and angle to govern the glulookat coords. Here is the code:

float ang;
point* pos = new point;
glPushMatrix();

//get the eye position for glulookat as the offset of the current position from the initial position
pos->xCoord=-(ipoint->xCoord-GlobalPosition->xCoord);
pos->yCoord=ipoint->yCoord-GlobalPosition->yCoord;

//set the ang of the player to the opposite of the current angle
//other wise turning left actually turns you right
//the angle is a float from 0 to 65536 where 65536 is 360
ang = -GlobalAngle;


if (ang < 0)
ang = ang + 65536;
else if(ang>65536)
ang = ang - 65536;
if (ang==65536)
ang=0;

//get line of sight
line* ln = gimmeeLine(pos,ang);

//get a point in the line of sight for glulookat
if(ang==0)
{
x=pos->xCoord+5;
y=ln->intercept;
}
else if(ang<16384)
{
x=pos->xCoord+5;
y=ln->slope*x + ln->intercept;
}
else if(ang==16384)
{
y = pos->yCoord +5;
x= ln->intercept;
}
else if(ang==32768)
{
x=pos->xCoord-5;
y=ln->intercept;
}
else if(ang>16384&amp;&amp;ang<49152)
{
x=pos->xCoord-5;
y=ln->slope*x + ln->intercept;
}
else if (ang==49152)
{
y = pos->yCoord-5;
x= ln->intercept;
}
else
{
x=pos->xCoord+5;
y=ln->slope*x + ln->intercept;
}
gluLookAt (pos->xCoord,0,pos->yCoord,x, 0,y, 0.0, 1.0, 0.0);

//draw the ceilings and floors
glCallList(tesser);
glPopMatrix();I can navigate through my whole level with one exception sometimes the floors kind of pull away from the walls a little. I don't know why, but would really really like to know why things don't align correctly. The floors only pull away a little but for a serious game it is completely unacceptable. I am sorry I know this is a vague problem.

silicon

thinks
03-12-2007, 12:41 PM
Could it have something to do with the fact that you are passing _huge_ values to gluLookAt()? The trigonometry that is calculated in this function is solved using Taylor expansions of the trigonometric functions, and I would guess that for large values numeric instability is an issue. I would have thought that you were planning on using unsigned shorts to look up precomputed values for trigonometric functions (a good idea by the way, if you have the time to spend implementing it...), otherwise I don't see the point of having the range [0, 65536]. If you are stroing it as floats you might as well use the range [0, 2*pi]. If you want to use lookup tables you will have to implement your own gluLookAt(). Implementations are available by googling "gluLookAt implementation" or something like that.

Aah, sorry, you are not actually passing the huge values to gluLookAt(). Anyway, the above still stands. But you are comparing floats using ==, which is never good.

I am not sure I totally understand your code, but what I do is use the x- and y-relative mouse coordinates from previous mouse input to determine two angles (look up spherical coordinates and the angles I am talking about will be obvious). I use these in spherical coordinates to determine the view vector. If I am moving on a plane I just project the view direction onto that plane and normalize it and I have the direction in which I am moving. Depending on how much linear algebra you can handle, this is a convenient way of doing it... ;)

Stuart McDonald
03-12-2007, 11:48 PM
I also don't fully understand your code. Why use 0 to 65536 float for an angle between 0 to 360?

But as thinks says you can't compare floats. Youu need to check if the two values are very close to each other e.g. something li1ke

#include <limits>
#include <cmath>

#define FLOATS_EQUAL(f1,f2) ( fabs(f2-f1) <= std::numeric_limits<float>::epsilon() * fabs(f1) )

Not that I advocate using macros for this :D

silicon_chipper
03-25-2007, 12:15 AM
Thanks a lot you guys I actually just reverted to rendering the ceilings and floors dynamically. It hurts performance because of the tessellation, but it is acceptable. Thanks for the replies I may be back.
silicon