Sign in to follow this  
Sabonis

Creating a CS style camera

Recommended Posts

Hello, I'm just making a CS style camera for navigation through my 3D world (using openGL but that has little relevance here). My camera is a 'lookat' camera which holds an up vector, a center point and a look at point. I have the strafe done, but I am trying to implement the mouse look. Every time the mouse moves, I would like to rotate the camera with respect to how far it moved from the last position. My question: how can I find the current X Y and Z angles of the camera and then increment it with respect to the mouse movement? My current coord system is right handed with the Z vector being used as up. *One thing I have tried is this: create a transformation that rotates the camera to the original 0,0,0 degrees, perform the increment, then do the inverse transformation back. This did not seem to work Any Ideas?

Share this post


Link to post
Share on other sites
The way I handled this is by using a function to lock the mouse cursor to the center of the screen (Don't remember how off the top of my head, shouldn't be too hard), and every frame get how far it moved from the center, then update the angle of the camera based on that.

Share this post


Link to post
Share on other sites
bit like that?

It's usually very simple. You just have two angles, 'elevation', and 'rotation' I call them. Basically, polar coordinates. When the mouse moves, you increment the angles.

These angles give you the view direction Dir. Then the 'strafe' direction is the vector perpendicalar to the view direction, and the Vector(0, 1, 0). Then the camera up vector is the Strafe vector cross the view direction.


// camera 'Dir' vector.
// Dir = Vector(cos(rot)*cos(elev), sin(elev), sin(rot)*cos(elev));
Dir.x = cos(rotation) * cos(elevation);
Dir.y = sin(elevation);
Dir.z = sin(rotation) * cos(elevation);

// Camera 'strafe' vector.
// Strafe = Vector(0, 1, 0) x Dir.
// -> Normalised, it gives Strafe = Vector(-sin(rot), 0, cos(rot));
Strafe.x = -sin(rotation);
Strafe.y = 0.0f;
Strafe.z = cos(rotation);

// camera 'Up' vector.
// No need to normalise afterwards (both vectors are guaranteed to be at 90 degrees and of length = 1).
Up = Dir.CrossProduct(Strafe);

// camera 'target' vector.
// target = pos + dir * some_distance (doesn't really matter what distance).
Target = Position + Dir * 100.0f




The rotation angle is wrapped in the range [-180, 180] degrees. In this example, the elevation angle does not have to clamped. There is no singularity when you are looking straight up, but it's recommended to clamp the elevation angle in the range [-90, 90] degrees.

Share this post


Link to post
Share on other sites
BTW, the mouse movement is returned by the DirectX inputs (in DirectInput.h/cpp). It's a 'relative motion' device. DirectX doesn not tell you the position of the mouse, rather, the speed of movement of the mouse, in pixels. You work out the position yourself. In your case, you don't even need to do that, you just take the mouse speed directly from DirectX.

Not sure what the Windows message WM_MOUSEMOVE does, but I think it's pretty much the same.

EDIT : Actually no. It's returning the position of the cursor, which is basically useless.

Share this post


Link to post
Share on other sites
I use wm_mousemove, and grab the position of the cursor, store it, then re-center the cursor. If you re-center the cursor after each check, you have the cursor position is equal to the delta since the last check.

Share this post


Link to post
Share on other sites
Quote:
Original post by SimmerD
I use wm_mousemove, and grab the position of the cursor, store it, then re-center the cursor. If you re-center the cursor after each check, you have the cursor position is equal to the delta since the last check.


I can go one better. I use raw input, which gives you the relative mouse motion, along with this to restrict the cursor to lie in a 1x1 box in the center of the screen. Probably marginally faster.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this