private void UpdateViewMatrix()
        {
            Vector3 lookAtTarget  = this.position + this.viewDirection;
            Matrix  newViewMatrix = Matrix.CreateLookAt(this.position, lookAtTarget, this.upDirection);

            this.viewMatrix  = newViewMatrix;
            this.dirtyFlags ^= CameraDirtyFlags.ViewMatrix;
            this.dirtyFlags |= CameraDirtyFlags.UpdateId;
        }
        /// <summary>
        /// Updates the projection matrix used by this camera.
        /// </summary>
        private void UpdateProjectionMatrix()
        {
            // Monogame expects the vertical FOV to be specified as half aperture angle in radians.
            float verticalFovMonogame = MathHelper.ToRadians(this.verticalFieldOfViewDegree / 2.0f);

            this.projectionMatrix = Matrix.CreatePerspectiveFieldOfView(verticalFovMonogame, this.aspectRatio, this.nearClippingPlaneDistance, this.farClippingPlaneDistance);
            this.dirtyFlags      ^= CameraDirtyFlags.ProjectionMatrix;
            this.dirtyFlags      |= CameraDirtyFlags.UpdateId;
        }
 /// <summary>
 /// Updates the view frustrum of this camera.
 /// </summary>
 private void UpdateViewFrustrum()
 {
     this.viewFrustrum = new BoundingFrustum(this.ViewMatrix * this.ProjectionMatrix);
     this.dirtyFlags  ^= CameraDirtyFlags.ViewFrustrum;
     this.dirtyFlags  |= CameraDirtyFlags.UpdateId;
 }
        /// <summary>
        /// Creates a new FreeCamera instance.
        /// </summary>
        /// <param name="position">The starting position of the camera in world space.</param>
        /// <param name="viewDirection">The initial viewing direction (not the target point!) of the camera in world space.</param>
        /// <param name="upDirection">The initial up direction of the camera.</param>
        /// <param name="verticalFieldOfView">The vertical field of view / the vertical aperture angle (https://en.wikipedia.org/wiki/Field_of_view_in_video_games) of the camera in degrees.</param>
        /// <param name="aspectRatio">The aspect ratio of the camera.</param>
        /// <param name="nearClippingPlaneDistance">The distance to the near clipping plane.</param>
        /// <param name="farClippingPlaneDistance">The distance to the far clipping plane.</param>
        internal FreeCamera(Vector3 position, Vector3 viewDirection, Vector3 upDirection, float verticalFieldOfView, float aspectRatio,
                            float nearClippingPlaneDistance, float farClippingPlaneDistance)
        {
            // Default values.
            this.rotation         = Quaternion.Identity;
            this.projectionMatrix = Matrix.Identity;
            this.viewMatrix       = Matrix.Identity;
            this.dirtyFlags       = CameraDirtyFlags.UpdateId | CameraDirtyFlags.ProjectionMatrix | CameraDirtyFlags.ViewMatrix | CameraDirtyFlags.ViewFrustrum;

            // Check and transfer values from call.
            if (aspectRatio < 0.0f)
            {
                throw new ArgumentOutOfRangeException(nameof(aspectRatio), "The aspect ration has to be greater than zero.");
            }
            else
            {
                this.aspectRatio = aspectRatio;
            }

            if (farClippingPlaneDistance <= 0.0f)
            {
                throw new ArgumentOutOfRangeException(nameof(farClippingPlaneDistance), "The far clipping plane has to have a disctance > 0.0 to the camera.");
            }
            else
            {
                this.farClippingPlaneDistance = farClippingPlaneDistance;
            }

            if (nearClippingPlaneDistance <= 0.0f)
            {
                throw new ArgumentOutOfRangeException(nameof(farClippingPlaneDistance), "The near clipping plane has to have a distance > 0.0 to the camera.");
            }
            else if (nearClippingPlaneDistance >= farClippingPlaneDistance)
            {
                throw new ArgumentException(nameof(nearClippingPlaneDistance) + " / " + nameof(farClippingPlaneDistance),
                                            "The far clipping plane has to be further away from the camera than the near clipping plane.");
            }
            else
            {
                this.nearClippingPlaneDistance = nearClippingPlaneDistance;
            }

            this.position = position;

            if (upDirection.Length() == 0.0f)
            {
                throw new ArgumentOutOfRangeException(nameof(upDirection), "The up Direction has to be a direction. A vector of length 0.0 does not have a direction.");
            }
            else
            {
                this.upDirection = Vector3.Normalize(upDirection);
            }

            if (verticalFieldOfView <= 0.0f)
            {
                throw new ArgumentOutOfRangeException(nameof(verticalFieldOfView), "The field of view has to be wider than 0.0°.");
            }
            else if (verticalFieldOfView > 360.0f)
            {
                throw new ArgumentOutOfRangeException(nameof(verticalFieldOfView), "The field of view may not be wider than 360°.");
            }
            else
            {
                this.verticalFieldOfViewDegree = verticalFieldOfView;
            }

            if (viewDirection.Length() == 0.0f)
            {
                throw new ArgumentOutOfRangeException(nameof(upDirection), "The upDirection has to be a direction. A vector of length 0.0 does not have a direction.");
            }
            else
            {
                this.viewDirection = viewDirection;
            }
        }