diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index cb057923..124ca878 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -77,8 +77,6 @@ add_executable(${PROJECT_NAME} WIN32 src/Viewport/SceneViewportMoveGizmo.cpp src/Viewport/SceneViewportRotateGizmo.cpp src/Viewport/SceneViewportScaleGizmo.cpp - src/Viewport/SceneViewportGrid.cpp - src/Viewport/SceneViewportInfiniteGridPass.cpp src/Viewport/SceneViewportOrientationGizmo.cpp src/Viewport/SceneViewportOverlayRenderer.cpp src/panels/GameViewPanel.cpp diff --git a/editor/src/Viewport/SceneViewportGrid.cpp b/editor/src/Viewport/SceneViewportGrid.cpp deleted file mode 100644 index 0934f0d1..00000000 --- a/editor/src/Viewport/SceneViewportGrid.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "SceneViewportGrid.h" - -#include -#include - -namespace XCEngine { -namespace Editor { - -namespace { - -constexpr float kCameraHeightScaleFactor = 0.50f; -constexpr float kTransitionStart = 0.65f; -constexpr float kTransitionEnd = 0.95f; -constexpr float kMinimumVerticalViewComponent = 0.15f; - -float SnapGridSpacing(float targetSpacing) { - const float clampedTarget = (std::max)(targetSpacing, 0.02f); - const float exponent = std::floor(std::log10(clampedTarget)); - return std::pow(10.0f, exponent); -} - -float ComputeTransitionBlend(float targetSpacing, float baseScale) { - const float normalizedSpacing = (std::max)(targetSpacing / (std::max)(baseScale, 1e-4f), 1.0f); - const float transitionPosition = std::log10(normalizedSpacing); - const float t = - (transitionPosition - kTransitionStart) / - (kTransitionEnd - kTransitionStart); - const float saturated = (std::clamp)(t, 0.0f, 1.0f); - return saturated * saturated * (3.0f - 2.0f * saturated); -} - -float ComputeViewDistanceToGridPlane(const SceneViewportOverlayData& overlay) { - const float cameraHeight = std::abs(overlay.cameraPosition.y); - const Math::Vector3 forward = overlay.cameraForward.Normalized(); - - const bool lookingTowardGrid = - (overlay.cameraPosition.y >= 0.0f && forward.y < 0.0f) || - (overlay.cameraPosition.y < 0.0f && forward.y > 0.0f); - if (!lookingTowardGrid) { - return cameraHeight; - } - - const float verticalViewComponent = (std::max)(std::abs(forward.y), kMinimumVerticalViewComponent); - return cameraHeight / verticalViewComponent; -} - -} // namespace - -SceneGridParameters BuildSceneGridParameters(const SceneViewportOverlayData& overlay) { - SceneGridParameters parameters = {}; - if (!overlay.valid) { - return parameters; - } - - const float cameraHeight = std::abs(overlay.cameraPosition.y); - const float viewDistance = ComputeViewDistanceToGridPlane(overlay); - // Keep grid density stable while orbiting/looking around. Rotation should - // only affect how much of the infinite grid is visible, not its base LOD. - const float targetSpacing = (std::max)(cameraHeight * kCameraHeightScaleFactor, 0.1f); - - parameters.valid = true; - parameters.baseScale = SnapGridSpacing(targetSpacing); - parameters.transitionBlend = ComputeTransitionBlend(targetSpacing, parameters.baseScale); - parameters.fadeDistance = (std::max)( - parameters.baseScale * 320.0f, - viewDistance * 80.0f); - return parameters; -} - -} // namespace Editor -} // namespace XCEngine diff --git a/editor/src/Viewport/SceneViewportGrid.h b/editor/src/Viewport/SceneViewportGrid.h deleted file mode 100644 index 3e831800..00000000 --- a/editor/src/Viewport/SceneViewportGrid.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "IViewportHostService.h" - -namespace XCEngine { -namespace Editor { - -struct SceneGridParameters { - bool valid = false; - float baseScale = 1.0f; - float transitionBlend = 0.0f; - float fadeDistance = 500.0f; -}; - -SceneGridParameters BuildSceneGridParameters(const SceneViewportOverlayData& overlay); - -} // namespace Editor -} // namespace XCEngine diff --git a/editor/src/Viewport/SceneViewportInfiniteGridPass.h b/editor/src/Viewport/SceneViewportInfiniteGridPass.h deleted file mode 100644 index a9c0eadf..00000000 --- a/editor/src/Viewport/SceneViewportInfiniteGridPass.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include "IViewportHostService.h" - -#include -#include -#include -#include -#include -#include -#include - -namespace XCEngine { -namespace Editor { - -class SceneViewportInfiniteGridPass { -public: - ~SceneViewportInfiniteGridPass() = default; - - void Shutdown(); - - bool Render( - const Rendering::RenderContext& renderContext, - const Rendering::RenderSurface& surface, - const SceneViewportOverlayData& overlay); - -private: - bool EnsureInitialized(const Rendering::RenderContext& renderContext); - bool CreateResources(const Rendering::RenderContext& renderContext); - void DestroyResources(); - -private: - RHI::RHIDevice* m_device = nullptr; - RHI::RHIType m_backendType = RHI::RHIType::D3D12; - RHI::RHIPipelineLayout* m_pipelineLayout = nullptr; - RHI::RHIPipelineState* m_pipelineState = nullptr; - RHI::RHIDescriptorPool* m_constantPool = nullptr; - RHI::RHIDescriptorSet* m_constantSet = nullptr; -}; - -} // namespace Editor -} // namespace XCEngine diff --git a/editor/src/Viewport/ViewportHostService.h b/editor/src/Viewport/ViewportHostService.h index a3f69e9b..c0336095 100644 --- a/editor/src/Viewport/ViewportHostService.h +++ b/editor/src/Viewport/ViewportHostService.h @@ -6,7 +6,6 @@ #include "IViewportHostService.h" #include "SceneViewportPicker.h" #include "SceneViewportCameraController.h" -#include "SceneViewportInfiniteGridPass.h" #include "SceneViewportPostPassPlan.h" #include "UI/ImGuiBackendBridge.h" @@ -18,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -86,6 +86,21 @@ inline uint32_t ClampViewportPixelCoordinate(float value, uint32_t extent) { return static_cast(std::floor(clamped)); } +Rendering::Passes::InfiniteGridPassData BuildInfiniteGridPassData( + const SceneViewportOverlayData& overlay) { + Rendering::Passes::InfiniteGridPassData data = {}; + data.valid = overlay.valid; + data.cameraPosition = overlay.cameraPosition; + data.cameraForward = overlay.cameraForward; + data.cameraRight = overlay.cameraRight; + data.cameraUp = overlay.cameraUp; + data.verticalFovDegrees = overlay.verticalFovDegrees; + data.nearClipPlane = overlay.nearClipPlane; + data.farClipPlane = overlay.farClipPlane; + data.orbitDistance = overlay.orbitDistance; + return data; +} + Math::Vector3 GetSceneViewportOrientationAxisVector(SceneViewportOrientationAxis axis) { switch (axis) { case SceneViewportOrientationAxis::PositiveX: @@ -595,7 +610,7 @@ private: const bool rendered = m_sceneGridPass.Render( context.renderContext, context.surface, - overlay); + BuildInfiniteGridPassData(overlay)); if (!rendered) { SetViewportStatusIfEmpty(entry.statusText, "Scene grid pass failed"); } @@ -1005,7 +1020,7 @@ private: Rendering::RenderContext m_sceneViewLastRenderContext = {}; std::array m_entries = {}; SceneViewCameraState m_sceneViewCamera; - SceneViewportInfiniteGridPass m_sceneGridPass; + Rendering::Passes::BuiltinInfiniteGridPass m_sceneGridPass; Rendering::Passes::BuiltinObjectIdOutlinePass m_sceneSelectionOutlinePass; }; diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 94b601ac..6fd5c541 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -345,10 +345,12 @@ add_library(XCEngine STATIC ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/ObjectIdPass.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/SceneRenderer.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinObjectIdPass.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinInfiniteGridPass.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinObjectIdOutlinePass.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/CameraRenderer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Passes/BuiltinObjectIdPass.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Passes/BuiltinInfiniteGridPass.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Passes/BuiltinObjectIdOutlinePass.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/RenderSurface.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/RenderSceneExtractor.cpp diff --git a/engine/include/XCEngine/Rendering/Passes/BuiltinInfiniteGridPass.h b/engine/include/XCEngine/Rendering/Passes/BuiltinInfiniteGridPass.h new file mode 100644 index 00000000..eca7b57f --- /dev/null +++ b/engine/include/XCEngine/Rendering/Passes/BuiltinInfiniteGridPass.h @@ -0,0 +1,64 @@ +#pragma once + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace XCEngine { +namespace Rendering { +namespace Passes { + +struct InfiniteGridPassData { + bool valid = false; + Math::Vector3 cameraPosition = Math::Vector3::Zero(); + Math::Vector3 cameraForward = Math::Vector3::Forward(); + Math::Vector3 cameraRight = Math::Vector3::Right(); + Math::Vector3 cameraUp = Math::Vector3::Up(); + float verticalFovDegrees = 60.0f; + float nearClipPlane = 0.03f; + float farClipPlane = 2000.0f; + float orbitDistance = 6.0f; +}; + +struct InfiniteGridParameters { + bool valid = false; + float baseScale = 1.0f; + float transitionBlend = 0.0f; + float fadeDistance = 500.0f; +}; + +InfiniteGridParameters BuildInfiniteGridParameters(const InfiniteGridPassData& data); + +class BuiltinInfiniteGridPass { +public: + ~BuiltinInfiniteGridPass() = default; + + void Shutdown(); + + bool Render( + const RenderContext& renderContext, + const RenderSurface& surface, + const InfiniteGridPassData& data); + +private: + bool EnsureInitialized(const RenderContext& renderContext); + bool CreateResources(const RenderContext& renderContext); + void DestroyResources(); + + RHI::RHIDevice* m_device = nullptr; + RHI::RHIType m_backendType = RHI::RHIType::D3D12; + RHI::RHIPipelineLayout* m_pipelineLayout = nullptr; + RHI::RHIPipelineState* m_pipelineState = nullptr; + RHI::RHIDescriptorPool* m_constantPool = nullptr; + RHI::RHIDescriptorSet* m_constantSet = nullptr; +}; + +} // namespace Passes +} // namespace Rendering +} // namespace XCEngine diff --git a/editor/src/Viewport/SceneViewportInfiniteGridPass.cpp b/engine/src/Rendering/Passes/BuiltinInfiniteGridPass.cpp similarity index 71% rename from editor/src/Viewport/SceneViewportInfiniteGridPass.cpp rename to engine/src/Rendering/Passes/BuiltinInfiniteGridPass.cpp index 7be47232..7f5f3f46 100644 --- a/editor/src/Viewport/SceneViewportInfiniteGridPass.cpp +++ b/engine/src/Rendering/Passes/BuiltinInfiniteGridPass.cpp @@ -1,20 +1,26 @@ -#include "SceneViewportInfiniteGridPass.h" - -#include "SceneViewportGrid.h" -#include "SceneViewportMath.h" +#include "Rendering/Passes/BuiltinInfiniteGridPass.h" +#include #include #include #include +#include +#include #include namespace XCEngine { -namespace Editor { +namespace Rendering { +namespace Passes { namespace { -const char kInfiniteGridHlsl[] = R"( +constexpr float kCameraHeightScaleFactor = 0.50f; +constexpr float kTransitionStart = 0.65f; +constexpr float kTransitionEnd = 0.95f; +constexpr float kMinimumVerticalViewComponent = 0.15f; + +const char kBuiltinInfiniteGridHlsl[] = R"( cbuffer GridConstants : register(b0) { float4x4 gViewProjectionMatrix; float4 gCameraPositionAndScale; @@ -170,17 +176,104 @@ struct GridConstants { Math::Vector4 gridTransition = Math::Vector4::Zero(); }; +float SnapGridSpacing(float targetSpacing) { + const float clampedTarget = (std::max)(targetSpacing, 0.02f); + const float exponent = std::floor(std::log10(clampedTarget)); + return std::pow(10.0f, exponent); +} + +float ComputeTransitionBlend(float targetSpacing, float baseScale) { + const float normalizedSpacing = (std::max)(targetSpacing / (std::max)(baseScale, 1e-4f), 1.0f); + const float transitionPosition = std::log10(normalizedSpacing); + const float t = + (transitionPosition - kTransitionStart) / + (kTransitionEnd - kTransitionStart); + const float saturated = (std::clamp)(t, 0.0f, 1.0f); + return saturated * saturated * (3.0f - 2.0f * saturated); +} + +float ComputeViewDistanceToGridPlane(const InfiniteGridPassData& data) { + const float cameraHeight = std::abs(data.cameraPosition.y); + const Math::Vector3 forward = data.cameraForward.Normalized(); + + const bool lookingTowardGrid = + (data.cameraPosition.y >= 0.0f && forward.y < 0.0f) || + (data.cameraPosition.y < 0.0f && forward.y > 0.0f); + if (!lookingTowardGrid) { + return cameraHeight; + } + + const float verticalViewComponent = (std::max)(std::abs(forward.y), kMinimumVerticalViewComponent); + return cameraHeight / verticalViewComponent; +} + +Math::Matrix4x4 BuildInfiniteGridViewMatrix(const InfiniteGridPassData& data) { + const Math::Vector3 right = data.cameraRight.Normalized(); + const Math::Vector3 up = data.cameraUp.Normalized(); + const Math::Vector3 forward = data.cameraForward.Normalized(); + + Math::Matrix4x4 view = Math::Matrix4x4::Identity(); + view.m[0][0] = right.x; + view.m[0][1] = right.y; + view.m[0][2] = right.z; + view.m[0][3] = -Math::Vector3::Dot(right, data.cameraPosition); + + view.m[1][0] = up.x; + view.m[1][1] = up.y; + view.m[1][2] = up.z; + view.m[1][3] = -Math::Vector3::Dot(up, data.cameraPosition); + + view.m[2][0] = forward.x; + view.m[2][1] = forward.y; + view.m[2][2] = forward.z; + view.m[2][3] = -Math::Vector3::Dot(forward, data.cameraPosition); + return view; +} + +Math::Matrix4x4 BuildInfiniteGridProjectionMatrix( + const InfiniteGridPassData& data, + float viewportWidth, + float viewportHeight) { + const float aspect = viewportHeight > 0.0f + ? viewportWidth / viewportHeight + : 1.0f; + return Math::Matrix4x4::Perspective( + data.verticalFovDegrees * Math::DEG_TO_RAD, + aspect, + data.nearClipPlane, + data.farClipPlane); +} + } // namespace -void SceneViewportInfiniteGridPass::Shutdown() { +InfiniteGridParameters BuildInfiniteGridParameters(const InfiniteGridPassData& data) { + InfiniteGridParameters parameters = {}; + if (!data.valid) { + return parameters; + } + + const float cameraHeight = std::abs(data.cameraPosition.y); + const float viewDistance = ComputeViewDistanceToGridPlane(data); + const float targetSpacing = (std::max)(cameraHeight * kCameraHeightScaleFactor, 0.1f); + + parameters.valid = true; + parameters.baseScale = SnapGridSpacing(targetSpacing); + parameters.transitionBlend = ComputeTransitionBlend(targetSpacing, parameters.baseScale); + parameters.fadeDistance = (std::max)( + parameters.baseScale * 320.0f, + viewDistance * 80.0f); + return parameters; +} + +void BuiltinInfiniteGridPass::Shutdown() { DestroyResources(); } -bool SceneViewportInfiniteGridPass::Render( - const Rendering::RenderContext& renderContext, - const Rendering::RenderSurface& surface, - const SceneViewportOverlayData& overlay) { - if (!overlay.valid || !renderContext.IsValid() || renderContext.backendType != RHI::RHIType::D3D12) { +bool BuiltinInfiniteGridPass::Render( + const RenderContext& renderContext, + const RenderSurface& surface, + const InfiniteGridPassData& data) { + if (!data.valid || !renderContext.IsValid() || renderContext.backendType != RHI::RHIType::D3D12) { return false; } @@ -193,17 +286,17 @@ bool SceneViewportInfiniteGridPass::Render( return false; } - const SceneGridParameters parameters = BuildSceneGridParameters(overlay); + const InfiniteGridParameters parameters = BuildInfiniteGridParameters(data); if (!parameters.valid) { return false; } const Math::Matrix4x4 viewProjection = - BuildSceneViewportProjectionMatrix( - overlay, + BuildInfiniteGridProjectionMatrix( + data, static_cast(surface.GetWidth()), static_cast(surface.GetHeight())) * - BuildSceneViewportViewMatrix(overlay); + BuildInfiniteGridViewMatrix(data); const float aspect = surface.GetHeight() > 0 ? static_cast(surface.GetWidth()) / static_cast(surface.GetHeight()) @@ -211,17 +304,17 @@ bool SceneViewportInfiniteGridPass::Render( GridConstants constants = {}; constants.viewProjection = viewProjection.Transpose(); - constants.cameraPositionAndScale = Math::Vector4(overlay.cameraPosition, parameters.baseScale); - constants.cameraRightAndFade = Math::Vector4(overlay.cameraRight, parameters.fadeDistance); + constants.cameraPositionAndScale = Math::Vector4(data.cameraPosition, parameters.baseScale); + constants.cameraRightAndFade = Math::Vector4(data.cameraRight, parameters.fadeDistance); constants.cameraUpAndTanHalfFov = Math::Vector4( - overlay.cameraUp, - std::tan(overlay.verticalFovDegrees * Math::DEG_TO_RAD * 0.5f)); - constants.cameraForwardAndAspect = Math::Vector4(overlay.cameraForward, aspect); + data.cameraUp, + std::tan(data.verticalFovDegrees * Math::DEG_TO_RAD * 0.5f)); + constants.cameraForwardAndAspect = Math::Vector4(data.cameraForward, aspect); constants.viewportNearFar = Math::Vector4( static_cast(surface.GetWidth()), static_cast(surface.GetHeight()), - overlay.nearClipPlane, - overlay.farClipPlane); + data.nearClipPlane, + data.farClipPlane); constants.gridTransition = Math::Vector4(parameters.transitionBlend, 0.0f, 0.0f, 0.0f); m_constantSet->WriteConstant(0, &constants, sizeof(constants)); @@ -256,7 +349,7 @@ bool SceneViewportInfiniteGridPass::Render( return true; } -bool SceneViewportInfiniteGridPass::EnsureInitialized(const Rendering::RenderContext& renderContext) { +bool BuiltinInfiniteGridPass::EnsureInitialized(const RenderContext& renderContext) { if (m_pipelineState != nullptr && m_pipelineLayout != nullptr && m_constantPool != nullptr && @@ -270,7 +363,7 @@ bool SceneViewportInfiniteGridPass::EnsureInitialized(const Rendering::RenderCon return CreateResources(renderContext); } -bool SceneViewportInfiniteGridPass::CreateResources(const Rendering::RenderContext& renderContext) { +bool BuiltinInfiniteGridPass::CreateResources(const RenderContext& renderContext) { if (!renderContext.IsValid() || renderContext.backendType != RHI::RHIType::D3D12) { return false; } @@ -339,15 +432,15 @@ bool SceneViewportInfiniteGridPass::CreateResources(const Rendering::RenderConte pipelineDesc.depthStencilState.depthFunc = static_cast(RHI::ComparisonFunc::LessEqual); pipelineDesc.vertexShader.source.assign( - kInfiniteGridHlsl, - kInfiniteGridHlsl + std::strlen(kInfiniteGridHlsl)); + kBuiltinInfiniteGridHlsl, + kBuiltinInfiniteGridHlsl + std::strlen(kBuiltinInfiniteGridHlsl)); pipelineDesc.vertexShader.sourceLanguage = RHI::ShaderLanguage::HLSL; pipelineDesc.vertexShader.entryPoint = L"MainVS"; pipelineDesc.vertexShader.profile = L"vs_5_0"; pipelineDesc.fragmentShader.source.assign( - kInfiniteGridHlsl, - kInfiniteGridHlsl + std::strlen(kInfiniteGridHlsl)); + kBuiltinInfiniteGridHlsl, + kBuiltinInfiniteGridHlsl + std::strlen(kBuiltinInfiniteGridHlsl)); pipelineDesc.fragmentShader.sourceLanguage = RHI::ShaderLanguage::HLSL; pipelineDesc.fragmentShader.entryPoint = L"MainPS"; pipelineDesc.fragmentShader.profile = L"ps_5_0"; @@ -361,7 +454,7 @@ bool SceneViewportInfiniteGridPass::CreateResources(const Rendering::RenderConte return true; } -void SceneViewportInfiniteGridPass::DestroyResources() { +void BuiltinInfiniteGridPass::DestroyResources() { if (m_pipelineState != nullptr) { m_pipelineState->Shutdown(); delete m_pipelineState; @@ -390,5 +483,6 @@ void SceneViewportInfiniteGridPass::DestroyResources() { m_backendType = RHI::RHIType::D3D12; } -} // namespace Editor +} // namespace Passes +} // namespace Rendering } // namespace XCEngine diff --git a/tests/editor/CMakeLists.txt b/tests/editor/CMakeLists.txt index 69d570b5..b63470f8 100644 --- a/tests/editor/CMakeLists.txt +++ b/tests/editor/CMakeLists.txt @@ -19,7 +19,6 @@ set(EDITOR_TEST_SOURCES ${CMAKE_SOURCE_DIR}/editor/src/Viewport/SceneViewportMoveGizmo.cpp ${CMAKE_SOURCE_DIR}/editor/src/Viewport/SceneViewportRotateGizmo.cpp ${CMAKE_SOURCE_DIR}/editor/src/Viewport/SceneViewportScaleGizmo.cpp - ${CMAKE_SOURCE_DIR}/editor/src/Viewport/SceneViewportGrid.cpp ) add_executable(editor_tests ${EDITOR_TEST_SOURCES}) diff --git a/tests/editor/test_scene_viewport_overlay_renderer.cpp b/tests/editor/test_scene_viewport_overlay_renderer.cpp index 232be44b..6ed1c0d5 100644 --- a/tests/editor/test_scene_viewport_overlay_renderer.cpp +++ b/tests/editor/test_scene_viewport_overlay_renderer.cpp @@ -1,11 +1,11 @@ #include #include "Viewport/SceneViewportCameraController.h" -#include "Viewport/SceneViewportGrid.h" #include "Viewport/SceneViewportMath.h" #include #include +#include #include namespace { @@ -47,25 +47,40 @@ bool IsPowerOfTenSpacing(float value) { } // namespace -using XCEngine::Editor::BuildSceneGridParameters; +XCEngine::Rendering::Passes::InfiniteGridPassData ToInfiniteGridPassData( + const XCEngine::Editor::SceneViewportOverlayData& overlay) { + XCEngine::Rendering::Passes::InfiniteGridPassData data = {}; + data.valid = overlay.valid; + data.cameraPosition = overlay.cameraPosition; + data.cameraForward = overlay.cameraForward; + data.cameraRight = overlay.cameraRight; + data.cameraUp = overlay.cameraUp; + data.verticalFovDegrees = overlay.verticalFovDegrees; + data.nearClipPlane = overlay.nearClipPlane; + data.farClipPlane = overlay.farClipPlane; + data.orbitDistance = overlay.orbitDistance; + return data; +} + using XCEngine::Editor::BuildSceneViewportAxisDragPlaneNormal; using XCEngine::Editor::SceneViewportCameraController; using XCEngine::Editor::BuildSceneViewportProjectionMatrix; using XCEngine::Editor::BuildSceneViewportViewMatrix; using XCEngine::Editor::ProjectSceneViewportWorldPoint; -using XCEngine::Editor::SceneGridParameters; using XCEngine::Editor::SceneViewportOverlayData; using XCEngine::Components::GameObject; using XCEngine::Math::Vector3; using XCEngine::Math::Vector4; +using XCEngine::Rendering::Passes::BuildInfiniteGridParameters; +using XCEngine::Rendering::Passes::InfiniteGridParameters; -TEST(SceneViewportOverlayRenderer_Test, BuildSceneGridParametersUsesPowerOfTenSpacingSeries) { +TEST(SceneViewportOverlayRenderer_Test, BuildInfiniteGridParametersUsesPowerOfTenSpacingSeries) { SceneViewportOverlayData overlay = {}; overlay.valid = true; overlay.cameraPosition = Vector3(0.0f, 6.0f, -6.0f); overlay.cameraForward = Vector3(0.0f, -0.5f, 0.8660254f); - const SceneGridParameters parameters = BuildSceneGridParameters(overlay); + const InfiniteGridParameters parameters = BuildInfiniteGridParameters(ToInfiniteGridPassData(overlay)); EXPECT_TRUE(parameters.valid); EXPECT_TRUE(IsPowerOfTenSpacing(parameters.baseScale)); @@ -74,7 +89,7 @@ TEST(SceneViewportOverlayRenderer_Test, BuildSceneGridParametersUsesPowerOfTenSp EXPECT_GT(parameters.fadeDistance, parameters.baseScale); } -TEST(SceneViewportOverlayRenderer_Test, BuildSceneGridParametersIsStableAcrossHorizontalCameraMovement) { +TEST(SceneViewportOverlayRenderer_Test, BuildInfiniteGridParametersIsStableAcrossHorizontalCameraMovement) { SceneViewportOverlayData left = {}; left.valid = true; left.cameraPosition = Vector3(-120.0f, 12.0f, 40.0f); @@ -83,8 +98,8 @@ TEST(SceneViewportOverlayRenderer_Test, BuildSceneGridParametersIsStableAcrossHo SceneViewportOverlayData right = left; right.cameraPosition = Vector3(380.0f, 12.0f, -260.0f); - const SceneGridParameters leftParameters = BuildSceneGridParameters(left); - const SceneGridParameters rightParameters = BuildSceneGridParameters(right); + const InfiniteGridParameters leftParameters = BuildInfiniteGridParameters(ToInfiniteGridPassData(left)); + const InfiniteGridParameters rightParameters = BuildInfiniteGridParameters(ToInfiniteGridPassData(right)); EXPECT_TRUE(leftParameters.valid); EXPECT_TRUE(rightParameters.valid); @@ -93,7 +108,7 @@ TEST(SceneViewportOverlayRenderer_Test, BuildSceneGridParametersIsStableAcrossHo EXPECT_FLOAT_EQ(leftParameters.fadeDistance, rightParameters.fadeDistance); } -TEST(SceneViewportOverlayRenderer_Test, BuildSceneGridParametersExpandsScaleAsCameraHeightGrows) { +TEST(SceneViewportOverlayRenderer_Test, BuildInfiniteGridParametersExpandsScaleAsCameraHeightGrows) { SceneViewportOverlayData nearOverlay = {}; nearOverlay.valid = true; nearOverlay.cameraPosition = Vector3(0.0f, 3.0f, -4.0f); @@ -102,8 +117,8 @@ TEST(SceneViewportOverlayRenderer_Test, BuildSceneGridParametersExpandsScaleAsCa SceneViewportOverlayData farOverlay = nearOverlay; farOverlay.cameraPosition = Vector3(0.0f, 120.0f, -150.0f); - const SceneGridParameters nearParameters = BuildSceneGridParameters(nearOverlay); - const SceneGridParameters farParameters = BuildSceneGridParameters(farOverlay); + const InfiniteGridParameters nearParameters = BuildInfiniteGridParameters(ToInfiniteGridPassData(nearOverlay)); + const InfiniteGridParameters farParameters = BuildInfiniteGridParameters(ToInfiniteGridPassData(farOverlay)); EXPECT_TRUE(nearParameters.valid); EXPECT_TRUE(farParameters.valid); @@ -111,20 +126,20 @@ TEST(SceneViewportOverlayRenderer_Test, BuildSceneGridParametersExpandsScaleAsCa EXPECT_GE(farParameters.fadeDistance, nearParameters.fadeDistance); } -TEST(SceneViewportOverlayRenderer_Test, BuildSceneGridParametersPromotesMajorLinesByDecimalGrouping) { +TEST(SceneViewportOverlayRenderer_Test, BuildInfiniteGridParametersPromotesMajorLinesByDecimalGrouping) { SceneViewportOverlayData overlay = {}; overlay.valid = true; overlay.cameraPosition = Vector3(0.0f, 14.0f, -18.0f); overlay.cameraForward = Vector3(0.0f, -0.5f, 0.8660254f); - const SceneGridParameters parameters = BuildSceneGridParameters(overlay); + const InfiniteGridParameters parameters = BuildInfiniteGridParameters(ToInfiniteGridPassData(overlay)); EXPECT_TRUE(parameters.valid); EXPECT_TRUE(IsPowerOfTenSpacing(parameters.baseScale)); EXPECT_TRUE(IsPowerOfTenSpacing(parameters.baseScale * 10.0f)); } -TEST(SceneViewportOverlayRenderer_Test, BuildSceneGridParametersFadesTowardNextScaleBeforeThreshold) { +TEST(SceneViewportOverlayRenderer_Test, BuildInfiniteGridParametersFadesTowardNextScaleBeforeThreshold) { SceneViewportOverlayData earlyOverlay = {}; earlyOverlay.valid = true; earlyOverlay.cameraPosition = Vector3(0.0f, 4.0f, -6.0f); @@ -132,8 +147,8 @@ TEST(SceneViewportOverlayRenderer_Test, BuildSceneGridParametersFadesTowardNextS SceneViewportOverlayData lateOverlay = earlyOverlay; lateOverlay.cameraPosition = Vector3(0.0f, 18.0f, -6.0f); - const SceneGridParameters earlyParameters = BuildSceneGridParameters(earlyOverlay); - const SceneGridParameters lateParameters = BuildSceneGridParameters(lateOverlay); + const InfiniteGridParameters earlyParameters = BuildInfiniteGridParameters(ToInfiniteGridPassData(earlyOverlay)); + const InfiniteGridParameters lateParameters = BuildInfiniteGridParameters(ToInfiniteGridPassData(lateOverlay)); EXPECT_FLOAT_EQ(earlyParameters.baseScale, 1.0f); EXPECT_FLOAT_EQ(lateParameters.baseScale, 1.0f); @@ -141,7 +156,7 @@ TEST(SceneViewportOverlayRenderer_Test, BuildSceneGridParametersFadesTowardNextS EXPECT_GT(lateParameters.transitionBlend, 0.90f); } -TEST(SceneViewportOverlayRenderer_Test, BuildSceneGridParametersSwitchesScaleAtHalfThePreviousDistanceThreshold) { +TEST(SceneViewportOverlayRenderer_Test, BuildInfiniteGridParametersSwitchesScaleAtHalfThePreviousDistanceThreshold) { SceneViewportOverlayData nearOverlay = {}; nearOverlay.valid = true; nearOverlay.cameraPosition = Vector3(0.0f, 19.9f, -6.0f); @@ -149,8 +164,8 @@ TEST(SceneViewportOverlayRenderer_Test, BuildSceneGridParametersSwitchesScaleAtH SceneViewportOverlayData farOverlay = nearOverlay; farOverlay.cameraPosition = Vector3(0.0f, 20.0f, -6.0f); - const SceneGridParameters nearParameters = BuildSceneGridParameters(nearOverlay); - const SceneGridParameters farParameters = BuildSceneGridParameters(farOverlay); + const InfiniteGridParameters nearParameters = BuildInfiniteGridParameters(ToInfiniteGridPassData(nearOverlay)); + const InfiniteGridParameters farParameters = BuildInfiniteGridParameters(ToInfiniteGridPassData(farOverlay)); EXPECT_FLOAT_EQ(nearParameters.baseScale, 1.0f); EXPECT_FLOAT_EQ(farParameters.baseScale, 10.0f); @@ -158,7 +173,7 @@ TEST(SceneViewportOverlayRenderer_Test, BuildSceneGridParametersSwitchesScaleAtH EXPECT_LT(farParameters.transitionBlend, 0.05f); } -TEST(SceneViewportOverlayRenderer_Test, BuildSceneGridParametersIgnoresStaleOrbitDistanceForSameView) { +TEST(SceneViewportOverlayRenderer_Test, BuildInfiniteGridParametersIgnoresStaleOrbitDistanceForSameView) { SceneViewportOverlayData nearOrbit = {}; nearOrbit.valid = true; nearOrbit.cameraPosition = Vector3(0.0f, 12.0f, -24.0f); @@ -168,8 +183,8 @@ TEST(SceneViewportOverlayRenderer_Test, BuildSceneGridParametersIgnoresStaleOrbi SceneViewportOverlayData farOrbit = nearOrbit; farOrbit.orbitDistance = 200.0f; - const SceneGridParameters nearOrbitParameters = BuildSceneGridParameters(nearOrbit); - const SceneGridParameters farOrbitParameters = BuildSceneGridParameters(farOrbit); + const InfiniteGridParameters nearOrbitParameters = BuildInfiniteGridParameters(ToInfiniteGridPassData(nearOrbit)); + const InfiniteGridParameters farOrbitParameters = BuildInfiniteGridParameters(ToInfiniteGridPassData(farOrbit)); EXPECT_TRUE(nearOrbitParameters.valid); EXPECT_TRUE(farOrbitParameters.valid);