creating a flexible camera class l.
Skip this Video
Download Presentation
Creating a Flexible Camera Class

Loading in 2 Seconds...

play fullscreen
1 / 39

Creating a Flexible Camera Class - PowerPoint PPT Presentation

  • Uploaded on

Creating a Flexible Camera Class. Bryan Duggan. Refresher on Vectors. u.v = (u x v x + u y v y + u z v z ) p = u x v = (u y v z - u z v y , u z v x - u x v z, u x v y - u y v x ). Identity Matrix. Identity Matrix.

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
Download Presentation

PowerPoint Slideshow about 'Creating a Flexible Camera Class' - pia

Download Now An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
refresher on vectors
Refresher on Vectors
  • u.v = (ux vx + uy vy + uz vz)
  • p = u x v = (uy vz - uz vy, uz vx - ux vz, ux vy - uy vx)
identity matrix
Identity Matrix
  • Identity Matrix
  • The identity matrix has the property that if A is a square matrix, then
local space
Local Space
  • The co-ordinate system we define the objects triangle list
  • Build all models around their own co-ordinates
  • Construct models without regard to position and orientation
world space
World Space
  • World Transform brings
    • Objects into the world
    • Sets up the relationship between objects in the scene
    • Translations rotations and scaling
    • May be a different transform for each object in the scene
    • Use:
      • IDirect3DDevice::SetTransform(D3DTS_WORLD, &matrix);
view space
View Space
  • View Space transform:
    • Translates the camera to the origin, looking down the positive Z-Axis
  • We don’t need to calculate it!! DirectX has an API to do this:
    • D3DXMatrixLookAtLH(


, D3DXVECTOR3 * eye

, D3DXVECTOR3 * at

, D3DXVECTOR3 * up)

  • Up is usually (0,1,0)
  • Use:
      • IDirect3DDevice::SetTransform(D3DTS_VIEW, &matrix);
backface culling
Backface culling
  • All polygons have 2 sides. A front (visible) side
  • And a back (invisible) side
  • DirectX can cull the backfaces to reduce processing
  • Triangles with vertices specified in a clockwise winding order are considered front facing
  • Use: _

device->SetRenderState(D3DRS_CULLMODE, value)

Where value is:

    • D3DCULL_CW
  • Transforming a 3D Scene to a 2D one
  • Uses perspective projection
  • Far away objects are smaller
  • Defines our frustum
the projection matrix
The projection matrix
  • Is complex to derive, but directX has an API to do it:




D3DX_PI * 0.5f, // 90 - degree

(float)_width / (float)_height,



_device->SetTransform(D3DTS_PROJECTION, &proj);

the viewport transform
The Viewport transform
  • We can optionally transform to a viewport in the display window:

typedef struct _D3DVIEWPORT9 




DWORD Width;

DWORD Height;

float MinZ;

float MaxZ;


We set the viewport using:


fps camera
FPS Camera
  • In an FPS, the camera may need to:
    • walk forwards and backwards (W, S keys)
    • strafe left and right (A, D keys)
    • fly/jump (space key?)
    • Look around (the mouse)
      • Pitch (look up and down)
      • Yaw (Look left and right)
      • Roll (tilt left and right)
a static camera can be programmed by
A static camera can be programmed by…

// Position and aim the camera.

D3DXVECTOR3 position(-50.0f, 5.0f, -50.0f);

D3DXVECTOR3 target(0.0f, 5.0f, 0.0f);

D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);


D3DXMatrixLookAtLH(&V, &position, &target, &up);

device->SetTransform(D3DTS_VIEW, &V);

this is ok for
This is ok for
  • A fixed camera position, but not very flexible when we want to have a moving camera as most games
so lets create our own
So lets create our own!
  • To model a camera we require 4 vectors:
    • _position
    • _look
    • _right
    • _up

Must always be

mutually orthogonal

(perpendicular) to each other





  • To walk:
    • Position changes in units of the look vector
    • Making sure we don’t change the Y value!! (A person can look at the ground, but we don’t want to go in that direction)
  • To strafe:
    • Position changes in units of the right vector
  • To jump:
    • Position changes in the y direction
  • To look around:
    • On the X-Axis, we rotate around the y-axis (Yaw)
      • Rotate _right and _look
    • Up and down, we rotate on the _right vector (pitch)
      • Rotate _up and _look

void MoveableEntity::walk(float units)



newPos = _pos + D3DXVECTOR3(_look.x, 0.0f, _look.z) * units;

BoundableEntity * boundableEntity = _world->collidesWith(&newPos);

if ((!_collisionDetection) || (boundableEntity == NULL) || (boundableEntity == this))


_moved = true;

_pos = newPos;




void MoveableEntity::strafe(float units)



newPos = _pos + D3DXVECTOR3(_right.x, 0.0f, _right.z) * units;

BoundableEntity * boundableEntity = _world->collidesWith(&newPos);

if ( (!_collisionDetection) || (boundableEntity == NULL) || (boundableEntity == this))


_moved = true;

_pos = newPos;




void MoveableEntity::yaw(float angle)



D3DXMatrixRotationY(&T, angle);

// rotate _right and _look around _up or y-axis

D3DXVec3TransformCoord(&_right,&_right, &T);

D3DXVec3TransformCoord(&_look,&_look, &T);

_moved = true;



void MoveableEntity::pitch(float angle)



D3DXMatrixRotationAxis(&T, &_right, angle);

// rotate _up and _look around _right vector

D3DXVec3TransformCoord(&_up,&_up, &T);

D3DXVec3TransformCoord(&_look,&_look, &T);

_moved = true;


view matrix
View Matrix
  • At some point, we need to make a view transform matrix
  • The view transform does 3 things:
    • Makes the camera 0, 0, 0. Everything in the world needs to be translated by the same amount
    • Makes the camera looks down the positive Z axis
so we need to
So we need to…
  • Translate
    • Translate the camera to the origin (and everything else by the same amount)
  • Rotate
    • Align the right vector with the x-axis (and everything else by the same amount)
    • Align the up vector with the y-axis (and everything else by the same amount)
    • Align the look vector with the z-axis (and everything else by the same amount)
  • Our new view matrix combines those operations (multiplies the 4 matrices to generate a combined transformation)
calculate the translation bit
Calculate the translation bit
  • To translate by -px, -py, -pz, we multiply by:
calculate the rotation matrix
Calculate the rotation matrix

Rotate the right vector so that it aligns with the x-axis

Rotate the up vector so that it aligns with the y-axis

Rotate the look vector so that it aligns with the z-axis

solve for the matrix a
Solve for the matrix A
  • Since A is the same in all 3 transformations, we can write them together:
solve for matrix a
Solve for Matrix A
  • A is the inverse of B because:
    • BA = BB-1 = I
  • You get the inverse of a matrix by switching the rows and columns:
in code
In code:

// Build the view matrix:

float x = -D3DXVec3Dot(&_right, &_pos);

float y = -D3DXVec3Dot(&_up, &_pos);

float z = -D3DXVec3Dot(&_look, &_pos);

(_viewMatrix)(0,0) = _right.x; (_viewMatrix)(0, 1) = _up.x; (_viewMatrix)(0, 2) = _look.x; (_viewMatrix)(0, 3) = 0.0f;

(_viewMatrix)(1,0) = _right.y; (_viewMatrix)(1, 1) = _up.y; (_viewMatrix)(1, 2) = _look.y; (_viewMatrix)(1, 3) = 0.0f;

(_viewMatrix)(2,0) = _right.z; (_viewMatrix)(2, 1) = _up.z; (_viewMatrix)(2, 2) = _look.z; (_viewMatrix)(2, 3) = 0.0f;

(_viewMatrix)(3,0) = x; (_viewMatrix)(3, 1) = y; (_viewMatrix)(3, 2) = z; (_viewMatrix)(3, 3) = 1.0f;

mouse look
Mouse look
  • The aim
    • When the player moves the mouse left and right, we yaw
    • When the player moves the mouse up and down, we pitch
    • By how much is determined by the delta between the last mouse position and the current mouse position
mouse look algorithm
Mouse look algorithm



If (event == MOUSE_MOVEMENT)


midX = width / 2

midY = height / 2

deltaX = currentX – midX

deltaY = currentY – midY

yaw(deltaY * modifier_heuristic)

roll(deltaX * modifier_heuristic)

set_cursor(midX, midY)



to trap mouse events
To trap mouse events
  • Windows calls the WinProc (the handler we registered to receive notifications of events
  • The framework calls:
    • handleEvent(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  • When a mouse movement has occurred, we receive WM_MOUSEMOVE as the msg parameter
firstly some win32 api code to turn off the mouse
Firstly some Win32 API code to turn off the mouse


// Turn off window cursor



return TRUE; // prevent Windows from setting cursor to window class cursor


now to capture the mouse
Now to capture the mouse:


midX = _width / 2;

midY = _height / 2;



xPos = p.x;

yPos = p.y;

if ((xPos == midX) && (yPos == midY))




deltaX = xPos - midX;

deltaY = yPos - midY;

_camera->yaw(((float)deltaX) / 100.0f);

_camera->pitch(((float)deltaY) / 100.0f);

SetCursorPos(midX, midY);


rts camera
RTS Camera
  • Camera position is over the world
  • Enable the mouse cursor
  • When the cursor moves to the extremes of the window:
  • Pan left & right
    • Move the position in units of the right vector
    • Without affecting the Y
  • Forward & backwards
    • Move the position in units of the look vector
    • Without affecting the Y
extra operations
Extra operations
  • Zoom in and out by using the scroll wheel?
  • Free Rotate by holding down the ALT key?
some important win32 calls
Some important Win32 Calls!
  • _device->ShowCursor(TRUE);
    • Turns on the cursor
  • GetWindowRect
    • To get the window size
  • ClipCursor
    • To keep the cursor within certain screen coordinates
  • GET_X_LPARAM(lParam);
  • GET_Y_LPARAM(lParam);
    • To get the X and Y of the cursor
  • If we enable the mouse, we need to know when the user clicks something, what it is
  • We need to translate from a screen position (x, y) to an (x, y, z) in our world