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; } }