using System; using GlitchyEngine.Math; namespace GlitchyEngine.Renderer { /** * If FarPlane is float.PositiveInfinity the projection matrix will be an infinite projection (that means no far plane) */ public class PerspectiveCamera : OldCamera { public enum ProjectionType { /** * The projection has a near and a far plane. The near plane has a depth of 0, the far plane a depth of 1. */ Limited, /** * The projection has a near and a far plane. The near plane has a depth of 1, the far plane a depth of 0. */ LimitedReversed, /** * The projection only has a near. The near plane has a depth of 0; infinite distance has a value of 1. */ Infinite, /** * The projection only has a near. The near plane has a depth of 1; infinite distance has a value of 0. */ InfiniteReversed } protected ProjectionType _projectionType; protected float _fovY; protected float _aspect; /** * Gets or Sets the projection type. */ public ProjectionType ProjectionType { get => _projectionType; set { if(_projectionType == value) return; _projectionType = value; _projectionOutdated = true; } } public float FovY { get => _fovY; set { if(_fovY == value) return; _fovY = value; _projectionOutdated = true; } } public float AspectRatio { get => _aspect; set { if(_aspect == value) return; _aspect = value; _projectionOutdated = true; } } protected override void UpdateProjection() { Debug.Profiler.ProfileFunction!(); if(_projectionType == .Limited || _projectionType == .LimitedReversed) Log.EngineLogger.AssertDebug(_nearPlane < _farPlane, "The near plane must be smaller than the far plane."); switch(_projectionType) { case .Limited: _projection = Matrix.PerspectiveProjection(_fovY, _aspect, _nearPlane, _farPlane); case .LimitedReversed: _projection = Matrix.ReversedPerspectiveProjection(_fovY, _aspect, _nearPlane, _farPlane); case .Infinite: _projection = Matrix.InfinitePerspectiveProjection(_fovY, _aspect, _nearPlane); case .InfiniteReversed: _projection = Matrix.ReversedInfinitePerspectiveProjection(_fovY, _aspect, _nearPlane); default: Log.EngineLogger.AssertDebug(false, "Unknown projection type."); } } protected override void UpdateTransform() { Debug.Profiler.ProfileFunction!(); _transform = Matrix.Translation(_position) * Matrix.RotationZ(_rotation.Z) * Matrix.RotationY(_rotation.Y) * Matrix.RotationX(_rotation.X); _view = _transform.Invert(); } } }