From 73a596cb2f06c41f2ea49b4ea3ea1abe0621c977 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 21 Aug 2024 21:54:22 +0200 Subject: [PATCH] Add `OrthographicSize` to Camera for fixed ortho projection size #1970 --- Source/Engine/Level/Actors/Camera.cpp | 25 ++++++++++++++++++++++--- Source/Engine/Level/Actors/Camera.h | 14 +++++++++++++- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/Source/Engine/Level/Actors/Camera.cpp b/Source/Engine/Level/Actors/Camera.cpp index 008f00520..a2822b09e 100644 --- a/Source/Engine/Level/Actors/Camera.cpp +++ b/Source/Engine/Level/Actors/Camera.cpp @@ -39,6 +39,7 @@ Camera::Camera(const SpawnParams& params) , _customAspectRatio(0.0f) , _near(10.0f) , _far(40000.0f) + , _orthoSize(0.0f) , _orthoScale(1.0f) { #if USE_EDITOR @@ -120,6 +121,21 @@ void Camera::SetFarPlane(float value) } } +float Camera::GetOrthographicSize() const +{ + return _orthoSize; +} + +void Camera::SetOrthographicSize(float value) +{ + value = Math::Clamp(value, 0.0f, 1000000.0f); + if (Math::NotNearEqual(_orthoSize, value)) + { + _orthoSize = value; + UpdateCache(); + } +} + float Camera::GetOrthographicScale() const { return _orthoScale; @@ -201,7 +217,9 @@ Ray Camera::ConvertMouseToRay(const Float2& mousePosition, const Viewport& viewp Float2 screenPosition(mousePosition.X / viewport.Width - 0.5f, -mousePosition.Y / viewport.Height + 0.5f); Quaternion orientation = GetOrientation(); Float3 direction = orientation * Float3::Forward; - Vector3 rayOrigin(screenPosition.X * viewport.Width * _orthoScale, screenPosition.Y * viewport.Height * _orthoScale, 0); + const float orthoSize = (_orthoSize > 0.0f ? _orthoSize : viewport.Height) * _orthoScale; + const float aspect = _customAspectRatio <= 0.0f ? viewport.GetAspectRatio() : _customAspectRatio; + Vector3 rayOrigin(screenPosition.X * orthoSize * aspect, screenPosition.Y * orthoSize, 0); rayOrigin = position + Vector3::Transform(rayOrigin, orientation); rayOrigin += direction * _near; return Ray(rayOrigin, direction); @@ -260,14 +278,15 @@ void Camera::GetMatrices(Matrix& view, Matrix& projection, const Viewport& viewp void Camera::GetMatrices(Matrix& view, Matrix& projection, const Viewport& viewport, const Vector3& origin) const { // Create projection matrix + const float aspect = _customAspectRatio <= 0.0f ? viewport.GetAspectRatio() : _customAspectRatio; if (_usePerspective) { - const float aspect = _customAspectRatio <= 0.0f ? viewport.GetAspectRatio() : _customAspectRatio; Matrix::PerspectiveFov(_fov * DegreesToRadians, aspect, _near, _far, projection); } else { - Matrix::Ortho(viewport.Width * _orthoScale, viewport.Height * _orthoScale, _near, _far, projection); + const float orthoSize = (_orthoSize > 0.0f ? _orthoSize : viewport.Height) * _orthoScale; + Matrix::Ortho(orthoSize * aspect, orthoSize, _near, _far, projection); } // Create view matrix diff --git a/Source/Engine/Level/Actors/Camera.h b/Source/Engine/Level/Actors/Camera.h index 190126e54..7da37c4b6 100644 --- a/Source/Engine/Level/Actors/Camera.h +++ b/Source/Engine/Level/Actors/Camera.h @@ -44,6 +44,7 @@ private: float _customAspectRatio; float _near; float _far; + float _orthoSize; float _orthoScale; #if USE_EDITOR @@ -88,7 +89,7 @@ public: /// /// Gets the custom aspect ratio. 0 if not use custom value. /// - API_PROPERTY(Attributes="EditorOrder(50), DefaultValue(0.0f), Limit(0, 10, 0.01f), EditorDisplay(\"Camera\"), VisibleIf(nameof(UsePerspective))") + API_PROPERTY(Attributes="EditorOrder(50), DefaultValue(0.0f), Limit(0, 10, 0.01f), EditorDisplay(\"Camera\")") float GetCustomAspectRatio() const; /// @@ -118,6 +119,17 @@ public: /// API_PROPERTY() void SetFarPlane(float value); + /// + /// Gets the orthographic projection view height (width is based on the aspect ratio). Use `0` for size to be based on the viewport size. + /// + API_PROPERTY(Attributes="EditorOrder(59), DefaultValue(0.0f), Limit(0.0f), EditorDisplay(\"Camera\"), VisibleIf(nameof(UsePerspective), true)") + float GetOrthographicSize() const; + + /// + /// Sets the orthographic projection view height (width is based on the aspect ratio). Use `0` for size to be based on the viewport size. + /// + API_PROPERTY() void SetOrthographicSize(float value); + /// /// Gets the orthographic projection scale. ///