using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace TrueCraft.Client.Rendering { /// /// Represents a camera for use with rendering. /// public class Camera { // _Camera settings private float _aspectRatio; private float _fov, _nearZ, _farZ; // Position/rotation private TrueCraft.API.Vector3 _position; private float _pitch, _yaw; // Dependent variables private BoundingFrustum _frustum; private Matrix _view, _projection; private bool _isDirty; // Whether dependent variables need to be recalculated. /// /// Gets or sets the aspect ratio for this camera. /// public float AspectRatio { get { return _aspectRatio; } set { _aspectRatio = value; _isDirty = true; } } /// /// Gets or sets the field of view for this camera, in degrees. /// public float Fov { get { return _fov; } set { _fov = value; _isDirty = true; } } /// /// Gets or sets the near Z clipping plane for this camera. /// public float NearZ { get { return _nearZ; } set { _nearZ = value; _isDirty = true; } } /// /// Gets or sets the far Z clipping plane for this camera. /// public float FarZ { get { return _farZ; } set { _farZ = value; _isDirty = true; } } /// /// Gets or sets the position of this camera. /// public TrueCraft.API.Vector3 Position { get { return _position; } set { _position = value; _isDirty = true; } } /// /// Gets or sets the pitch for this camera, in degrees. /// public float Pitch { get { return _pitch; } set { _pitch = value; _isDirty = true; } } /// /// Gets or sets the yaw for this camera, in degrees. /// public float Yaw { get { return _yaw; } set { _yaw = value; _isDirty = true; } } /// /// Creates a new camera from the specified values. /// /// /// /// /// public Camera(float aspectRatio, float fov, float nearZ, float farZ) : this(aspectRatio, fov, nearZ, farZ, TrueCraft.API.Vector3.Zero, 0.0f, 0.0f) { } /// /// Creates a new camera from the specified values. /// /// /// /// /// /// /// /// public Camera(float aspectRatio, float fov, float nearZ, float farZ, TrueCraft.API.Vector3 position, float pitch, float yaw) { AspectRatio = aspectRatio; Fov = fov; NearZ = nearZ; FarZ = farZ; Position = position; Pitch = pitch; Yaw = yaw; _frustum = new BoundingFrustum(Matrix.Identity); _view = _projection = Matrix.Identity; _isDirty = true; } /// /// Applies this camera to the specified effect. /// /// The effect to apply this camera to. public void ApplyTo(IEffectMatrices effectMatrices) { if (_isDirty) Recalculate(); effectMatrices.View = _view; effectMatrices.Projection = _projection; } /// /// Returns the bounding frustum calculated for this camera. /// /// public BoundingFrustum Frustum { get { if (_isDirty) Recalculate(); return _frustum; } } /// /// Returns the view matrix calculated for this camera. /// /// public Matrix GetViewMatrix() { if (_isDirty) Recalculate(); return _view; } /// /// Gets the projection matrix calculated for this camera. /// /// public Matrix GetProjectionMatrix() { if (_isDirty) Recalculate(); return _projection; } /// /// Recalculates the dependent variables for this camera. /// private void Recalculate() { var origin = new Vector3( (float)this._position.X, (float)this._position.Y, (float)this._position.Z); var direction = Vector3.Transform(Vector3.UnitZ, Matrix.CreateRotationX(MathHelper.ToRadians(_pitch)) * Matrix.CreateRotationY(MathHelper.ToRadians(-(_yaw - 180) + 180))); _view = Matrix.CreateLookAt(origin, origin + direction, Vector3.Up); _projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(_fov), _aspectRatio, _nearZ, _farZ); _frustum.Matrix = _view * _projection; _isDirty = false; } } }