XNA 4 3D Game Development by Example:Beginner's Guide
上QQ阅读APP看书,第一时间看更新

Time for action – implementing a look-at point

  1. Add the following properties to the Fields region of the Camera class:
    private Vector3 lookAt;
    private Vector3 baseCameraReference = new Vector3(0, 0, 1);
    private bool needViewResync = true;
  2. 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
  3. 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();
    }
  4. Add two new public properties to the Properties region of the Camera 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.

What just happened?

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.