Time for action – implementing a look-at point
- Add the following properties to the
Fields
region of theCamera
class:private Vector3 lookAt; private Vector3 baseCameraReference = new Vector3(0, 0, 1); private bool needViewResync = true;
- Add the following region and method to the
Camera
class:#region Helper Methods private void UpdateLookAt() { Matrix rotationMatrix = Matrix.CreateRotationY(rotation); Vector3 lookAtOffset = Vector3.Transform( baseCameraReference, rotationMatrix); lookAt = position + lookAtOffset; needViewResync = true; } #endregion
- Define the
MoveTo()
method that is called in the constructor. This method should be placed inside the Helper Methods region you just created:public void MoveTo(Vector3 position, float rotation) { this.position = position; this.rotation = rotation; UpdateLookAt(); }
- Add two new public properties to the
Properties
region of theCamera
class:public Vector3 Position { get { return position; } set { position = value; UpdateLookAt(); } } public float Rotation { get { return rotation; } set { rotation = value; UpdateLookAt(); } }
What just happened?
Just like the camera's position, the point we are going to look at is stored as a Vector3
. In order to build this point, we need a frame of reference, indicating the direction the camera would be pointing if it were not rotated at all. We define this direction in the baseCameraReference
field, specifying that the non-rotated camera will point along the Z axis (assuming that the camera was located at the origin point (0, 0, 0)).
The last field we added, needViewResync
, will be used to determine when we need to rebuild the next important matrix we will be discussing – the View
matrix. We will return to that topic in a moment.
In order to determine the point in 3D space that the camera will look towards (called the Look At point), we create a rotation
matrix around the Y axis (which points up from the X-Z plane) equal to the current value of the rotation field. We then transform the baseCameraReference
vector with this rotation
matrix, resulting in a Vector3
which points in the direction of the rotation relative to the world origin at (0, 0, 0) in 3D space.
We then build the lookAt
point field by adding this offset vector to the camera's current position, in effect relocating the lookAt
point from the origin to be relative to the camera position. Finally, we mark the needViewResync
flag as true.
The remaining code mentioned previously implements the MoveTo()
method, and exposes public properties for the Position
and Rotation
values. All three of these items simply set their related fields and call the UpdateLookAt()
method we just defined.