**NEWS:** This project is now hosted on

**GitHub**
https://github.com/Microsoft/DirectXTK. This site is being maintained for now, but please move to using GitHub

https://github.com/Microsoft/DirectXTK/wiki/Basic-game-math particularly as the CodePlex copy of the tutorials are a little dated.

This lesson will cover the basics of 3D transformations for graphics.

# Positioning the camera

We've already used a simple camera setup in the

3D shapes lesson.

In the Game class we added variables for the projection matrix and the view matrix:

DirectX::SimpleMath::Matrix m_view;
DirectX::SimpleMath::Matrix m_proj;

In the

**CreateResources** method, we used the backbuffer size to create a simple perspective view:

m_view = Matrix::CreateLookAt(Vector3(2.f, 2.f, 2.f), Vector3::Zero, Vector3::UnitY);
m_proj = Matrix::CreatePerspectiveFieldOfView(XM_PI / 4.f,
float(backBufferWidth) / float(backBufferHeight), 0.1f, 10.f);

The

**m_proj** matrix is created as a perspective camera using an

*field-of-view* of PI/4 radians (which is 45 degrees), the

*aspect ratio* of the backbuffer, the

*near-plane* distance of 0.1 and a

*far-plane* distance of 10.

The

**m_view** matrix Is created as a view looking from the position (2,2,2) looking at the position (0,0,0) with an

*up* vector of (0,1,0).

These two matrices handle transforming objects positioned in

*world* coordinates and transforming them to

*view* coordinates and then to

*screen* coordinates.

# Positioning an object

The

3D shapes lesson also provides an example of positioning an object.

In the Game class we added a variable for the world matrix for our 3D shape:

DirectX::SimpleMath::Matrix m_world;

We initially set it to the

*identity* in

**CreateDevice**:

m_world = Matrix::Identity

Then in

**Update** we set the matrix to a rotation about the Z-axis based on time:

float time = float(timer.GetTotalSeconds());
m_world = Matrix::CreateRotationZ(cosf(time) * 2.f);

Then later in the lesson we made it into a rotation about the Y-axes based on time:

float time = float(timer.GetTotalSeconds());
m_world = Matrix::CreateRotationY(time);

The

**m_world** matrix transforms the object's

*local* (also known as

*model*) coordinates into

*world* coordinates.

# Composing transformations

The power of affine transformation is that you can compose them by multiplying them together. In our

3D shapes lesson, we can modify the

**Update**: to get more interesting motion for the planet earth.

For example if you modified

**Update** as follows

float time = float(timer.GetTotalSeconds());
Vector3 pos = Vector3::Lerp(Vector3::Zero, Vector3::One, cos(time));
m_world = Matrix::CreateRotationY(time) * Matrix::CreateTranslation(pos);

Build and run to see the earth spinning and moving away and towards the camera.

If you flipped the order of the matrix multiply, you'll get much different results:

float time = float(timer.GetTotalSeconds());
Vector3 pos = Vector3::Lerp(Vector3::Zero, Vector3::One, cos(time));
m_world = Matrix::CreateTranslation( pos ) * Matrix::CreateRotationY( time);

Build and run to see the planet earth moving in a more complex pattern.

# Transforming a point

For performance, the majority of the 3D transformations we use in rendering at computed on the GPU using

*vertex shaders* based on the matrices we provide for world, view, and projection. There are times, however, when we want to compute a transformation on the CPU (such as doing collision detection or visibility culling). To transform a point using our variables
above we should first concatenate our matrices into a single matrix that combines the transformations.

Matrix matrix = m_world * m_view * m_proj;
Vector3 point; // Our input from somewhere
Vector3 newPoint = Vector3::Transform( point, matrix );

*Note: In our example we are only transforming a single point which means we are doing 3 matrix multiplies and 1 vector-matrix multiply. For a single point it might have been better to do 3 vector-matrix multiplies, but for most usage cases we are likely
to transform more than just a single point. Ideally we'd use the array version of
***Transform** to transform many points at once.
# Moving the camera

We can animate the camera's position as well as the object's. In the

3D shapes lesson, we will change

**Update** as follows:

float time = float(timer.GetTotalSeconds());
m_world = Matrix::CreateRotationY(time);
Vector3 cameraPos = Vector3::Lerp(Vector3(2.f, 2.f, 2.f),
Vector3(2.f, 0.f, 2.f), cos(time));
m_view = Matrix::CreateLookAt(cameraPos, Vector3::Zero, Vector3::UnitY);
m_effect->SetView(m_view);

Build and run to see the camera moving up and down while still looking at the planet earth as the center of focus.

**Next lesson:**
Collision detection
# Further reading

DirectX Tool Kit docs

SimpleMath
http://en.wikipedia.org/wiki/Radian
http://en.wikipedia.org/wiki/Graphical_projection