#### Archived

This topic is now archived and is closed to further replies.

# First Person Camera Control Schemes

This topic is 5821 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I have a little 3D world I can render in DirectX. Now I want a first-person camera to move around it. I have searched quite a bit, but have only found a couple of very basic tutorials. What I need is a medium-level example: - Move with up/down keyboard buttons - Strafe with left/right keyboard buttons - Look left/right with mouse, camera moves along that direction when up/down keyboard buttons pressed - Perhaps some limited up/down looking via the mouse while moving - "Look around" mode where user is stopped and can look in any direction with the mouse The examples I''ve seen move the camera, but it certainly wouldn''t be anything I''d want to use in a game. I don''t think this is tremendously difficult, I just need a good tutorial or example to get me started.

##### Share on other sites
Just setup a projection and view matrix. Whats the problem with that? Then just change the variables in the view matrix.

##### Share on other sites
Well, my answer won't be useless (looks at hexalite ). What you need to know how to do is rotate a vector given the degrees of rotation. Then it's really simple.

Here is my code for an operator called rotated_by. I'll example how to use it afterwards. It uses D3DX functions, but you can use these with OpenGL (I do) as they are just math functions, not tied to the DirectX API.

      // The rotated_by operator is really operator::^. You can use any symbol// you want, if you're already using ^ for something else.#define rotated_by ^ #define PI_OVER_180 0.017453292519943295769236907684886 // The operator is a member function of the 'vector' class.vector vector :: operator rotated_by ( vector Rotation ){    static D3DXMATRIX   Matrix;    static D3DXVECTOR3  LookAt;    static vector       Return;     LookAt.x = X;    LookAt.y = Y;    LookAt.z = -Z;     D3DXMatrixRotationYawPitchRoll( &Matrix,                                    -float(PI_OVER_180) * (float)Rotation.Y,                                    -float(PI_OVER_180) * (float)Rotation.X,                                    -float(PI_OVER_180) * (float)Rotation.Z );    D3DXVec3TransformCoord( &LookAt, &LookAt, &Matrix );     Return.X = (Type)LookAt.x;    Return.Y = (Type)LookAt.y;    Return.Z = (Type)LookAt.z;     return Return;}

Now to move the camera forward you do this:

Camera.Position += vector(0,0,WALK_SPEED) rotated_by Camera.Rotation;

...where Camera.Rotation.X is pitch, .Y is yaw and .Z is roll. To strafe right, you'd do this:

Camera.Position += vector(STRAFE_SPEED,0,0) rotated_by Camera.Rotation;

And of course you'd make that -WALK_SPEED or -STRAFE_SPEED to move backwards or left.

Now this is the code to set up the view matrices, sans comments. Hopefully it's not hard to follow or use. It uses D3DX functions, but again, these are only math functions and they do work with OpenGL, since I use them with OpenGL.

  D3DXMATRIX  Pitch;D3DXMATRIX  Yaw;D3DXMATRIX  Roll;D3DXMATRIX  Rotation;D3DXVECTOR3 Eye;D3DXVECTOR3 LookAt; D3DXMatrixRotationX( &Pitch, (float)PI_OVER_180 * -ms_Camera.Pitch );D3DXMatrixRotationY( &Yaw, (float)PI_OVER_180 * -ms_Camera.Yaw );D3DXMatrixRotationZ( &Roll, (float)PI_OVER_180 * -ms_Camera.Roll ); D3DXMatrixMultiply( &Rotation, &Pitch, &Yaw );D3DXMatrixMultiply( &Rotation, &Rotation, &Roll ); LookAt = D3DXVECTOR3( 0, 0, -1 ); D3DXVec3TransformCoord( &LookAt, &LookAt, &Rotation ); LookAt.x += ms_Camera.X;LookAt.y += ms_Camera.Y;LookAt.z += ms_Camera.Z; if( ms_Camera.Follow ){    Eye = D3DXVECTOR3( 0, 0, 1 );    D3DXVec3TransformCoord( &Eye, &Eye, &Rotation );    Eye.x = (Eye.x * ms_Camera.Follow) + ms_Camera.X;    Eye.y = (Eye.y * ms_Camera.Follow) + ms_Camera.Y;    Eye.z = (Eye.z * ms_Camera.Follow) + ms_Camera.Z;}else{    Eye.x = ms_Camera.X;    Eye.y = ms_Camera.Y;    Eye.z = ms_Camera.Z;} ms_Camera.Eye = vector<float>( Eye.x, Eye.y, Eye.z );ms_Camera.LookAt = vector<float>( LookAt.x, LookAt.y, LookAt.z ); D3DXMatrixIdentity( &ms_Camera.World );D3DXMatrixPerspectiveFovRH( &ms_Camera.Project,                            ms_FOV * 0.5f,                            float(ms_Viewport.Width) / float(ms_Viewport.Height),                            ms_Near,                            ms_Far );D3DXMatrixLookAtRH( &ms_Camera.View,                    &Eye,                    &LookAt,                    &D3DXVECTOR3(0,1,0) );

~CGameProgrammer( );

EDIT: Oh yeah, I forgot to mention that my code for calculating the View matrix ignores roll. That last line "D3DXVECTOR3(0,1,0)" specifies the Up vector. Setting it at (0,1,0) ignores roll. Oh well. For most games, it is not needed.

[edited by - CGameProgrammer on December 1, 2002 9:40:25 PM]

##### Share on other sites
Thanks, CGP. That''s exactly the kind of stuff I was looking for.

Hex - take a lesson on giving helpful responses from CGP.

No, lol

##### Share on other sites
CGP - in your rotated_by code, you list

LookAt.x = X;
LookAt.y = Y;
LookAt.z = -Z;

Are X, Y and Z really rotation.X, .Y and .Z? Or, are they the previous camera location? Previous LookAt vector...?

##### Share on other sites
CGP - also, how is ms_camera.Follow used? What are its usual values? Where is it set?

##### Share on other sites
Good questions. When you say "A rotated_by B" that calls "A::rotated_by( B )". So X, Y, and Z are the values of the transformation vector that you are rotating. Z is negative just because I had to do that to make sure a positive Z moves forward, or something. I wrote this code a year ago.

"Follow" is the third-person camera distance. If it''s zero, you have a first-person camera. If it''s anything else, it''s the distance of the third-person camera behind the focus (the player).

~CGameProgrammer( );

##### Share on other sites
So: X, Y and Z are members of the vector class object, then? In your "A rotated_by B" example, they would be A.X, A.Y, and A.Z?

##### Share on other sites
Yes. A is the untransformed vector, B is the rotation vector, and A rotated_by B is the transformed vector.

~CGameProgrammer( );

1. 1
Rutin
32
2. 2
3. 3
4. 4
5. 5

• 13
• 9
• 9
• 9
• 14
• ### Forum Statistics

• Total Topics
633323
• Total Posts
3011361
• ### Who's Online (See full list)

There are no registered users currently online

×