Direction Vector in FPS style games

Started by
18 comments, last by Hydrael 18 years, 1 month ago
Hello everyone, I have a little problem regarding proper direction vector calculation in a first person view game. Given is the following: In my project I implemented a quaternion camera class. For testing purposes I didn't add any axis restrictions, meaning it was a "freeflight" camera. Now, that I added collision detection I wanted the camera to "stick to the ground" and act like a normal FPS camera. But now I have following problem: The more "I don't look straight ahead", the slower I walk (when looking 90 degrees up or down, I won't move at all anymore). This is because, when i.e. looking all the way up, my direction vector will be (0.0,0.0,1.0) with the gravity vector being (0.0,0.0,-1.0). I guess I will somehow have to distribute the z vector to the x and y vectors dependant on camera pitch and heading. The problem is, I don't know how to do that :( Can anyone help? Since I don't know, if this is a plain mathematical or application specific problem, please let me know if you need any sourcecode. Thanks a lot in advance Chris
Advertisement
Normalize the (x,y,0) vector, this yields a horizontal direction vector. Of course, if x=y=0, you're not looking in any direction, so you don't move (for this reason, in many games you can't look straight up).
Quote:Original post by ToohrVyk
Normalize the (x,y,0) vector, this yields a horizontal direction vector. Of course, if x=y=0, you're not looking in any direction, so you don't move (for this reason, in many games you can't look straight up).
I don't think this is quite how things work in most FPS's. Typically in an FPS, the speed of forward and backward motion is constant, and the direction is associated with which way you are facing; whether you're looking up or down has no effect.

@The OP: For FPS movement and viewing, you need to calculate and store your direction movement vectors differently than you do your view movement vectors. I can explain in more detail if needed, but here's a quick summary:

1. The forward view vector depends on yaw and pitch and can be calculated using a spherical coordinate conversion
2. The forward movement vector depends on yaw only and is calculated as usual using sin() and cos()
3. The side movement and view vectors are the same and are perpendicular to the forward movement vector in the ground plane
4. The view up vector is the cross product of the view forward and side vectors
5. The movement up vector (e.g. for jumping or spectator mode) is the world up vector

IMO quaternions aren't the best tool for this sort of motion; I would recommend an Euler angle pair (yaw and pitch) instead. Again, I can provide more details or some working code samples if you need.
Quote:Original post by ToohrVyk
Normalize the (x,y,0) vector, this yields a horizontal direction vector. Of course, if x=y=0, you're not looking in any direction, so you don't move


Ah, thanks a lot, I should have thought of that ;)

Quote:Original post by ToohrVyk(for this reason, in many games you can't look straight up).


I didn't take notice to that. In my project, I cap the pitch at -90.0 and 90.0 degrees. Do you think I should reduce it to something like -89.0 and 89.0?

Quote:Original post by jyk
@The OP: For FPS movement and viewing, you need to calculate and store your direction movement vectors differently than you do your view movement vectors. I can explain in more detail if needed, but here's a quick summary:

1. The forward view vector depends on yaw and pitch and can be calculated using a spherical coordinate conversion
2. The forward movement vector depends on yaw only and is calculated as usual using sin() and cos()
3. The side movement and view vectors are the same and are perpendicular to the forward movement vector in the ground plane
4. The view up vector is the cross product of the view forward and side vectors
5. The movement up vector (e.g. for jumping or spectator mode) is the world up vector


Ah, allright - that makes sense. I guess I can figure that out myself - thanks! ;)

Quote:Original post by jyk
IMO quaternions aren't the best tool for this sort of motion; I would recommend an Euler angle pair (yaw and pitch) instead. Again, I can provide more details or some working code samples if you need.


Regarding this, I would be glad, if you could provide some code for an Euler angle pair camera.
I'm using Quaternions, because after following some camera tutorials, that implementation (from NeHe) was the first, that didn't suffer from gimbal lock.

I'd gladly use something else than Quaternions though, because I
a) don't understand, and really just "use" them
and they
b) caused other problems in my project (different values being inverted - took me a while to figure that out in some recursive functions)

Thanks a lot

Regards
Chris
Quote:Original post by jyk
Quote:Original post by ToohrVyk
Normalize the (x,y,0) vector, this yields a horizontal direction vector. Of course, if x=y=0, you're not looking in any direction, so you don't move (for this reason, in many games you can't look straight up).
I don't think this is quite how things work in most FPS's. Typically in an FPS, the speed of forward and backward motion is constant, and the direction is associated with which way you are facing; whether you're looking up or down has no effect.


In Half-Life, looking straight up would prevent you from moving, and I suspect that it was the case for Quake and Quake II as well. Half-Life angles were capped at -89 and 89. Setting the cap to something greater than 89 (for instance, 180) would allow you to bend around and look back, seeing the world upside down. IIRC, under that case, pressing forward would make you move in the direction you were looking, which means backwards.
Quote:Original post by Hydrael
I didn't take notice to that. In my project, I cap the pitch at -90.0 and 90.0 degrees. Do you think I should reduce it to something like -89.0 and 89.0?
Nope, +/-90 degrees is fine.
Quote:Regarding this, I would be glad, if you could provide some code for an Euler angle pair camera.
I'm using Quaternions, because after following some camera tutorials, that implementation (from NeHe) was the first, that didn't suffer from gimbal lock.
Gimbal lock isn't an issue with FPS motion, so it's not really relevant here. If at some point though you want to do full 6DOF motion (e.g. a spaceship in 3d), Euler angles will no longer be the best choice.

I'll post some example code in a bit.
Quote:Original post by ToohrVyk
In Half-Life, looking straight up would prevent you from moving, and I suspect that it was the case for Quake and Quake II as well.
I don't have Half Life installed at the moment, but try firing up the Quake game of your choice, then look straight up or down and press the forward or backward key. You should find that your pitch has no effect on your forward motion.

Or are we talking about different things?
Quote:Original post by jyk
Gimbal lock isn't an issue with FPS motion, so it's not really relevant here.


Hmm...in my first implementation of a camera class I was simply using gluLookAt. The problem here was, that I also couldn't look all the way up/down. At about 80 degrees, the camera wouldn't pitch any farther without changing the up vector - isn't that, what gimbal lock is?

Quote:Original post by Hydrael
Hmm...in my first implementation of a camera class I was simply using gluLookAt. The problem here was, that I also couldn't look all the way up/down. At about 80 degrees, the camera wouldn't pitch any farther without changing the up vector - isn't that, what gimbal lock is?
Nope, that's just a limitation of how gluLookAt() computes the view matrix, and is one of the reasons not to use it for a general camera.

ToohrVyk, I just checked Q1, Q2 and Q3, and in none of them is forward motion affected (noticably) by your pitch. Also, I think Q3 clamps to +/-90 rather than +/-89. I do in my engine also and it doesn't cause any problems. We might be talking about different things, though.

This topic is closed to new replies.

Advertisement