diff --git a/editor/src/Viewport/IViewportHostService.h b/editor/src/Viewport/IViewportHostService.h index 2b884a44..4b4e19ba 100644 --- a/editor/src/Viewport/IViewportHostService.h +++ b/editor/src/Viewport/IViewportHostService.h @@ -16,7 +16,7 @@ namespace Editor { class IEditorContext; struct SceneViewportOverlayFrameData; -struct SceneViewportTransformGizmoHandleBuildInputs; +struct SceneViewportTransformGizmoOverlayState; enum class EditorViewportKind { Scene, @@ -86,13 +86,8 @@ public: virtual void AlignSceneViewToOrientationAxis(SceneViewportOrientationAxis axis) = 0; virtual SceneViewportOverlayData GetSceneViewOverlayData() const = 0; virtual const SceneViewportOverlayFrameData& GetSceneViewEditorOverlayFrameData(IEditorContext& context) = 0; - virtual const SceneViewportOverlayFrameData& GetSceneViewInteractionOverlayFrameData( - IEditorContext& context, - const SceneViewportOverlayData& overlay, - const SceneViewportTransformGizmoHandleBuildInputs& inputs) = 0; - virtual void SetSceneViewTransientTransformGizmoOverlayData( - const SceneViewportOverlayData& overlay, - const SceneViewportTransformGizmoHandleBuildInputs& inputs) = 0; + virtual void SetSceneViewTransformGizmoOverlayState( + const SceneViewportTransformGizmoOverlayState& state) = 0; virtual void RenderRequestedViewports( IEditorContext& context, const Rendering::RenderContext& renderContext) = 0; diff --git a/editor/src/Viewport/SceneViewportOverlayBuilder.cpp b/editor/src/Viewport/SceneViewportOverlayBuilder.cpp index d16adc95..82dc61ab 100644 --- a/editor/src/Viewport/SceneViewportOverlayBuilder.cpp +++ b/editor/src/Viewport/SceneViewportOverlayBuilder.cpp @@ -24,7 +24,8 @@ SceneViewportOverlayFrameData SceneViewportOverlayBuilder::Build( const SceneViewportOverlayData& overlay, uint32_t viewportWidth, uint32_t viewportHeight, - const std::vector& selectedObjectIds) const { + const std::vector& selectedObjectIds, + const SceneViewportTransformGizmoOverlayState* transformGizmoOverlayState) const { SceneViewportOverlayFrameData frameData = {}; frameData.overlay = overlay; if (!overlay.valid || viewportWidth == 0u || viewportHeight == 0u) { @@ -42,7 +43,8 @@ SceneViewportOverlayFrameData SceneViewportOverlayBuilder::Build( &overlay, viewportWidth, viewportHeight, - &selectedObjectIds + &selectedObjectIds, + transformGizmoOverlayState }; m_providerRegistry.AppendOverlay(buildContext, frameData); return frameData; diff --git a/editor/src/Viewport/SceneViewportOverlayBuilder.h b/editor/src/Viewport/SceneViewportOverlayBuilder.h index 05173a5e..370c431b 100644 --- a/editor/src/Viewport/SceneViewportOverlayBuilder.h +++ b/editor/src/Viewport/SceneViewportOverlayBuilder.h @@ -21,7 +21,8 @@ public: const SceneViewportOverlayData& overlay, uint32_t viewportWidth, uint32_t viewportHeight, - const std::vector& selectedObjectIds) const; + const std::vector& selectedObjectIds, + const SceneViewportTransformGizmoOverlayState* transformGizmoOverlayState = nullptr) const; const SceneViewportOverlayProviderRegistry& GetProviderRegistry() const { return m_providerRegistry; diff --git a/editor/src/Viewport/SceneViewportOverlayHandleBuilder.h b/editor/src/Viewport/SceneViewportOverlayHandleBuilder.h index 80e24a8f..8662d8a9 100644 --- a/editor/src/Viewport/SceneViewportOverlayHandleBuilder.h +++ b/editor/src/Viewport/SceneViewportOverlayHandleBuilder.h @@ -20,6 +20,24 @@ struct SceneViewportTransformGizmoHandleBuildInputs { uint64_t scaleEntityId = 0; }; +struct SceneViewportTransformGizmoOverlayState { + bool hasMoveGizmo = false; + SceneViewportMoveGizmoDrawData moveGizmo = {}; + uint64_t moveEntityId = 0; + bool hasRotateGizmo = false; + SceneViewportRotateGizmoDrawData rotateGizmo = {}; + uint64_t rotateEntityId = 0; + bool hasScaleGizmo = false; + SceneViewportScaleGizmoDrawData scaleGizmo = {}; + uint64_t scaleEntityId = 0; + + bool HasAnyVisibleGizmo() const { + return (hasMoveGizmo && moveGizmo.visible) || + (hasRotateGizmo && rotateGizmo.visible) || + (hasScaleGizmo && scaleGizmo.visible); + } +}; + inline SceneViewportTransformGizmoHandleBuildInputs BuildSceneViewportTransformGizmoHandleBuildInputs( bool showingMoveGizmo, const SceneViewportMoveGizmo& moveGizmo, @@ -47,6 +65,47 @@ inline SceneViewportTransformGizmoHandleBuildInputs BuildSceneViewportTransformG return inputs; } +inline SceneViewportTransformGizmoOverlayState BuildSceneViewportTransformGizmoOverlayState( + const SceneViewportTransformGizmoHandleBuildInputs& inputs) { + SceneViewportTransformGizmoOverlayState state = {}; + if (inputs.moveGizmo != nullptr) { + state.hasMoveGizmo = true; + state.moveGizmo = *inputs.moveGizmo; + state.moveEntityId = inputs.moveEntityId; + } + if (inputs.rotateGizmo != nullptr) { + state.hasRotateGizmo = true; + state.rotateGizmo = *inputs.rotateGizmo; + state.rotateEntityId = inputs.rotateEntityId; + } + if (inputs.scaleGizmo != nullptr) { + state.hasScaleGizmo = true; + state.scaleGizmo = *inputs.scaleGizmo; + state.scaleEntityId = inputs.scaleEntityId; + } + + return state; +} + +inline SceneViewportTransformGizmoHandleBuildInputs BuildSceneViewportTransformGizmoHandleBuildInputs( + const SceneViewportTransformGizmoOverlayState& state) { + SceneViewportTransformGizmoHandleBuildInputs inputs = {}; + if (state.hasMoveGizmo) { + inputs.moveGizmo = &state.moveGizmo; + inputs.moveEntityId = state.moveEntityId; + } + if (state.hasRotateGizmo) { + inputs.rotateGizmo = &state.rotateGizmo; + inputs.rotateEntityId = state.rotateEntityId; + } + if (state.hasScaleGizmo) { + inputs.scaleGizmo = &state.scaleGizmo; + inputs.scaleEntityId = state.scaleEntityId; + } + + return inputs; +} + namespace Detail { inline constexpr int kSceneViewportHandlePrioritySceneIcon = 100; diff --git a/editor/src/Viewport/SceneViewportOverlayProviders.cpp b/editor/src/Viewport/SceneViewportOverlayProviders.cpp index 8ef7e2c1..cc677102 100644 --- a/editor/src/Viewport/SceneViewportOverlayProviders.cpp +++ b/editor/src/Viewport/SceneViewportOverlayProviders.cpp @@ -450,6 +450,28 @@ public: } }; +class SceneViewportTransformGizmoOverlayProvider final : public ISceneViewportOverlayProvider { +public: + const char* GetName() const override { + return "SceneViewportTransformGizmoOverlayProvider"; + } + + void AppendOverlay( + const SceneViewportOverlayBuildContext& context, + SceneViewportOverlayFrameData& frameData) const override { + if (!context.IsValid() || + context.transformGizmoOverlayState == nullptr || + !context.transformGizmoOverlayState->HasAnyVisibleGizmo()) { + return; + } + + const SceneViewportTransformGizmoHandleBuildInputs inputs = + BuildSceneViewportTransformGizmoHandleBuildInputs(*context.transformGizmoOverlayState); + AppendTransformGizmoScreenTriangles(frameData, inputs); + AppendTransformGizmoHandleRecords(frameData, inputs); + } +}; + } // namespace void SceneViewportOverlayProviderRegistry::AddProvider( @@ -491,10 +513,15 @@ std::unique_ptr CreateSceneViewportLightOverlayPr return std::make_unique(); } +std::unique_ptr CreateSceneViewportTransformGizmoOverlayProvider() { + return std::make_unique(); +} + SceneViewportOverlayProviderRegistry BuildDefaultSceneViewportOverlayProviderRegistry() { SceneViewportOverlayProviderRegistry registry; registry.AddProvider(CreateSceneViewportCameraOverlayProvider()); registry.AddProvider(CreateSceneViewportLightOverlayProvider()); + registry.AddProvider(CreateSceneViewportTransformGizmoOverlayProvider()); return registry; } diff --git a/editor/src/Viewport/SceneViewportOverlayProviders.h b/editor/src/Viewport/SceneViewportOverlayProviders.h index 5bb4c174..52ad0bbb 100644 --- a/editor/src/Viewport/SceneViewportOverlayProviders.h +++ b/editor/src/Viewport/SceneViewportOverlayProviders.h @@ -23,6 +23,7 @@ struct SceneViewportOverlayBuildContext { uint32_t viewportWidth = 0u; uint32_t viewportHeight = 0u; const std::vector* selectedObjectIds = nullptr; + const SceneViewportTransformGizmoOverlayState* transformGizmoOverlayState = nullptr; bool IsValid() const { return editorContext != nullptr && @@ -60,6 +61,7 @@ private: std::unique_ptr CreateSceneViewportCameraOverlayProvider(); std::unique_ptr CreateSceneViewportLightOverlayProvider(); +std::unique_ptr CreateSceneViewportTransformGizmoOverlayProvider(); SceneViewportOverlayProviderRegistry BuildDefaultSceneViewportOverlayProviderRegistry(); } // namespace Editor diff --git a/editor/src/Viewport/SceneViewportRenderPlan.h b/editor/src/Viewport/SceneViewportRenderPlan.h index f1b84c5f..5d17b46a 100644 --- a/editor/src/Viewport/SceneViewportRenderPlan.h +++ b/editor/src/Viewport/SceneViewportRenderPlan.h @@ -51,7 +51,6 @@ inline SceneViewportRenderPlanBuildResult BuildSceneViewportRenderPlan( const SceneViewportOverlayData& overlay, const std::vector& selectedObjectIds, const SceneViewportOverlayFrameData& editorOverlayFrameData, - const SceneViewportOverlayFrameData& transientOverlayFrameData, const SceneViewportGridPassFactory& gridPassFactory, const SceneViewportSelectionOutlinePassFactory& selectionOutlinePassFactory, const SceneViewportOverlayPassFactory& overlayPassFactory, @@ -85,11 +84,9 @@ inline SceneViewportRenderPlanBuildResult BuildSceneViewportRenderPlan( } } - SceneViewportOverlayFrameData renderOverlayFrameData = editorOverlayFrameData; - AppendSceneViewportOverlayFrameData(renderOverlayFrameData, transientOverlayFrameData); - if (renderOverlayFrameData.HasOverlayPrimitives() && + if (editorOverlayFrameData.HasOverlayPrimitives() && overlayPassFactory != nullptr) { - std::unique_ptr overlayPass = overlayPassFactory(renderOverlayFrameData); + std::unique_ptr overlayPass = overlayPassFactory(editorOverlayFrameData); if (overlayPass != nullptr) { result.plan.overlayPasses.AddPass(std::move(overlayPass)); } diff --git a/editor/src/Viewport/ViewportHostService.h b/editor/src/Viewport/ViewportHostService.h index 28df3fbd..ade72c59 100644 --- a/editor/src/Viewport/ViewportHostService.h +++ b/editor/src/Viewport/ViewportHostService.h @@ -213,6 +213,8 @@ public: m_sceneViewportEditorOverlayRenderer.Shutdown(); m_sceneViewCamera = {}; ResetSceneViewEditorOverlayFrameData(); + m_sceneViewTransformGizmoOverlayState = {}; + m_sceneViewTransformGizmoOverlayDirty = false; m_sceneViewLastRenderContext = {}; m_device = nullptr; m_backend = nullptr; @@ -225,8 +227,8 @@ public: entry.requestedWidth = 0; entry.requestedHeight = 0; } - m_sceneViewTransientTransformGizmoOverlay = {}; - m_sceneViewTransientTransformGizmoInputs = {}; + m_sceneViewTransformGizmoOverlayState = {}; + m_sceneViewTransformGizmoOverlayDirty = true; } EditorViewportFrame RequestViewport(EditorViewportKind kind, const ImVec2& requestedSize) override { @@ -360,23 +362,10 @@ public: return m_sceneViewEditorOverlayFrameData; } - const SceneViewportOverlayFrameData& GetSceneViewInteractionOverlayFrameData( - IEditorContext& context, - const SceneViewportOverlayData& overlay, - const SceneViewportTransformGizmoHandleBuildInputs& inputs) override { - EnsureSceneViewEditorOverlayFrameData(context); - m_sceneViewInteractionOverlayFrameData = m_sceneViewEditorOverlayFrameData; - AppendSceneViewportOverlayFrameData( - m_sceneViewInteractionOverlayFrameData, - BuildSceneViewportTransformGizmoOverlayFrameData(overlay, inputs)); - return m_sceneViewInteractionOverlayFrameData; - } - - void SetSceneViewTransientTransformGizmoOverlayData( - const SceneViewportOverlayData& overlay, - const SceneViewportTransformGizmoHandleBuildInputs& inputs) override { - m_sceneViewTransientTransformGizmoOverlay = overlay; - m_sceneViewTransientTransformGizmoInputs = inputs; + void SetSceneViewTransformGizmoOverlayState( + const SceneViewportTransformGizmoOverlayState& state) override { + m_sceneViewTransformGizmoOverlayState = state; + m_sceneViewTransformGizmoOverlayDirty = true; } void RenderRequestedViewports( @@ -533,7 +522,6 @@ private: void ResetSceneViewEditorOverlayFrameData() { m_sceneViewEditorOverlayFrameData = {}; - m_sceneViewInteractionOverlayFrameData = {}; m_sceneViewEditorOverlayScene = nullptr; m_sceneViewEditorOverlaySelectedObjectIds.clear(); m_sceneViewEditorOverlayViewportWidth = 0u; @@ -557,7 +545,8 @@ private: uint32_t viewportHeight, const std::vector& selectedObjectIds, uint64_t contentSignature) const { - return !m_sceneViewEditorOverlayCached || + return m_sceneViewTransformGizmoOverlayDirty || + !m_sceneViewEditorOverlayCached || m_sceneViewEditorOverlayScene != scene || m_sceneViewEditorOverlayViewportWidth != viewportWidth || m_sceneViewEditorOverlayViewportHeight != viewportHeight || @@ -600,7 +589,8 @@ private: overlay, viewportWidth, viewportHeight, - selectedObjectIds); + selectedObjectIds, + &m_sceneViewTransformGizmoOverlayState); } m_sceneViewEditorOverlayScene = scene; @@ -609,6 +599,7 @@ private: m_sceneViewEditorOverlayViewportHeight = viewportHeight; m_sceneViewEditorOverlayContentSignature = contentSignature; m_sceneViewEditorOverlayCached = true; + m_sceneViewTransformGizmoOverlayDirty = false; } void ApplyViewportRenderFailure( @@ -653,7 +644,6 @@ private: outState.overlay, selectedObjectIds, editorOverlayFrameData, - BuildSceneViewTransientTransformGizmoOverlayFrameData(), [this](const Rendering::Passes::InfiniteGridPassData& data) { return CreateSceneViewportGridPass( m_sceneViewportGridRenderer, @@ -864,12 +854,6 @@ private: }); } - SceneViewportOverlayFrameData BuildSceneViewTransientTransformGizmoOverlayFrameData() const { - return BuildSceneViewportTransformGizmoOverlayFrameData( - m_sceneViewTransientTransformGizmoOverlay, - m_sceneViewTransientTransformGizmoInputs); - } - UI::ImGuiBackendBridge* m_backend = nullptr; RHI::RHIDevice* m_device = nullptr; std::unique_ptr m_sceneRenderer; @@ -878,15 +862,14 @@ private: std::array m_entries = {}; SceneViewCameraState m_sceneViewCamera; SceneViewportOverlayFrameData m_sceneViewEditorOverlayFrameData = {}; - SceneViewportOverlayFrameData m_sceneViewInteractionOverlayFrameData = {}; - SceneViewportOverlayData m_sceneViewTransientTransformGizmoOverlay = {}; - SceneViewportTransformGizmoHandleBuildInputs m_sceneViewTransientTransformGizmoInputs = {}; + SceneViewportTransformGizmoOverlayState m_sceneViewTransformGizmoOverlayState = {}; const Components::Scene* m_sceneViewEditorOverlayScene = nullptr; std::vector m_sceneViewEditorOverlaySelectedObjectIds = {}; uint32_t m_sceneViewEditorOverlayViewportWidth = 0u; uint32_t m_sceneViewEditorOverlayViewportHeight = 0u; uint64_t m_sceneViewEditorOverlayContentSignature = 0u; bool m_sceneViewEditorOverlayCached = false; + bool m_sceneViewTransformGizmoOverlayDirty = false; SceneViewportGridPassRenderer m_sceneViewportGridRenderer; SceneViewportSelectionOutlinePassRenderer m_sceneViewportSelectionOutlineRenderer; SceneViewportEditorOverlayPassRenderer m_sceneViewportEditorOverlayRenderer; diff --git a/editor/src/panels/SceneViewPanel.cpp b/editor/src/panels/SceneViewPanel.cpp index 5de56cd8..93596481 100644 --- a/editor/src/panels/SceneViewPanel.cpp +++ b/editor/src/panels/SceneViewPanel.cpp @@ -14,13 +14,9 @@ #include "Platform/Win32Utf8.h" #include "UI/UI.h" -#include - #include #include -#include -#include #include #include @@ -388,15 +384,6 @@ SceneViewportToolOverlayResult RenderSceneViewportToolOverlay( return result; } -void LogSceneViewNavigation(Debug::Logger& logger, const char* format, ...) { - char buffer[512] = {}; - va_list args; - va_start(args, format); - std::vsnprintf(buffer, sizeof(buffer), format, args); - va_end(args); - logger.Info(Debug::LogCategory::General, buffer); -} - bool ShouldBeginSceneViewportNavigationDrag( bool hasInteractiveViewport, bool hovered, @@ -428,7 +415,6 @@ void SceneViewPanel::Render() { const ViewportPanelContentResult content = RenderViewportPanelContent(*m_context, EditorViewportKind::Scene); if (IViewportHostService* viewportHostService = m_context->GetViewportHostService()) { const ImGuiIO& io = ImGui::GetIO(); - auto& logger = Debug::Logger::Get(); const bool hasInteractiveViewport = content.hasViewportArea && content.frame.hasTexture; const SceneViewportToolOverlayResult toolOverlay = RenderSceneViewportToolOverlay(content, m_toolMode); const bool viewportContentHovered = content.hovered && !toolOverlay.hovered; @@ -536,12 +522,12 @@ void SceneViewPanel::Render() { m_scaleGizmo, gizmoFrameState.scaleContext) : SceneViewportTransformGizmoHandleBuildInputs{}; + const SceneViewportTransformGizmoOverlayState interactionGizmoOverlayState = + BuildSceneViewportTransformGizmoOverlayState(interactionGizmoInputs); + viewportHostService->SetSceneViewTransformGizmoOverlayState(interactionGizmoOverlayState); const SceneViewportOverlayFrameData& interactionOverlayFrameData = hasInteractiveViewport - ? viewportHostService->GetSceneViewInteractionOverlayFrameData( - *m_context, - overlay, - interactionGizmoInputs) + ? viewportHostService->GetSceneViewEditorOverlayFrameData(*m_context) : emptySceneOverlayFrameData; const SceneViewportOverlayHandleHitResult overlayHandleHit = hasInteractiveViewport @@ -664,25 +650,6 @@ void SceneViewPanel::Render() { ImGuiMouseButton_Middle); const bool beginPanDrag = beginLeftPanDrag || beginMiddlePanDrag; - if (ImGui::IsMouseClicked(ImGuiMouseButton_Right) || ImGui::IsMouseClicked(ImGuiMouseButton_Middle)) { - LogSceneViewNavigation( - logger, - "SceneView nav click hovered=%d focused=%d hasViewport=%d clickedR=%d clickedM=%d downR=%d downM=%d " - "look=%d pan=%d gizmoActive=%d ioDelta=(%.2f, %.2f)", - content.hovered ? 1 : 0, - content.focused ? 1 : 0, - hasInteractiveViewport ? 1 : 0, - ImGui::IsMouseClicked(ImGuiMouseButton_Right) ? 1 : 0, - ImGui::IsMouseClicked(ImGuiMouseButton_Middle) ? 1 : 0, - ImGui::IsMouseDown(ImGuiMouseButton_Right) ? 1 : 0, - ImGui::IsMouseDown(ImGuiMouseButton_Middle) ? 1 : 0, - m_lookDragging ? 1 : 0, - m_panDragging ? 1 : 0, - gizmoActive ? 1 : 0, - io.MouseDelta.x, - io.MouseDelta.y); - } - if (toolOverlay.clicked || beginTransformGizmo || orientationGizmoClick || sceneIconClick || selectClick || beginLookDrag || beginPanDrag) { ImGui::SetWindowFocus(); @@ -741,14 +708,6 @@ void SceneViewPanel::Render() { m_panDragging = false; m_loggedLookDelta = false; m_loggedPanDelta = false; - LogSceneViewNavigation( - logger, - "SceneView begin look drag hovered=%d focused=%d downR=%d downM=%d gizmoActive=%d", - content.hovered ? 1 : 0, - content.focused ? 1 : 0, - ImGui::IsMouseDown(ImGuiMouseButton_Right) ? 1 : 0, - ImGui::IsMouseDown(ImGuiMouseButton_Middle) ? 1 : 0, - gizmoActive ? 1 : 0); } if (beginPanDrag) { m_panDragging = true; @@ -756,25 +715,13 @@ void SceneViewPanel::Render() { m_panDragButton = beginLeftPanDrag ? ImGuiMouseButton_Left : ImGuiMouseButton_Middle; m_loggedPanDelta = false; m_loggedLookDelta = false; - LogSceneViewNavigation( - logger, - "SceneView begin pan drag hovered=%d focused=%d button=%d downR=%d downM=%d downL=%d gizmoActive=%d", - content.hovered ? 1 : 0, - content.focused ? 1 : 0, - m_panDragButton, - ImGui::IsMouseDown(ImGuiMouseButton_Right) ? 1 : 0, - ImGui::IsMouseDown(ImGuiMouseButton_Middle) ? 1 : 0, - ImGui::IsMouseDown(ImGuiMouseButton_Left) ? 1 : 0, - gizmoActive ? 1 : 0); } if (m_lookDragging && !ImGui::IsMouseDown(ImGuiMouseButton_Right)) { - LogSceneViewNavigation(logger, "SceneView end look drag"); m_lookDragging = false; m_loggedLookDelta = false; } if (m_panDragging && !ImGui::IsMouseDown(m_panDragButton)) { - LogSceneViewNavigation(logger, "SceneView end pan drag"); m_panDragging = false; m_panDragButton = ImGuiMouseButton_Middle; m_loggedPanDelta = false; @@ -819,13 +766,6 @@ void SceneViewPanel::Render() { input.mouseDelta = io.MouseDelta; if (!m_loggedLookDelta && (input.mouseDelta.x != 0.0f || input.mouseDelta.y != 0.0f)) { - LogSceneViewNavigation( - logger, - "SceneView look delta=(%.2f, %.2f) hovered=%d downR=%d", - input.mouseDelta.x, - input.mouseDelta.y, - content.hovered ? 1 : 0, - ImGui::IsMouseDown(ImGuiMouseButton_Right) ? 1 : 0); m_loggedLookDelta = true; } } @@ -834,13 +774,6 @@ void SceneViewPanel::Render() { input.mouseDelta = io.MouseDelta; if (!m_loggedPanDelta && (input.mouseDelta.x != 0.0f || input.mouseDelta.y != 0.0f)) { - LogSceneViewNavigation( - logger, - "SceneView pan delta=(%.2f, %.2f) hovered=%d downM=%d", - input.mouseDelta.x, - input.mouseDelta.y, - content.hovered ? 1 : 0, - ImGui::IsMouseDown(ImGuiMouseButton_Middle) ? 1 : 0); m_loggedPanDelta = true; } } @@ -866,18 +799,18 @@ void SceneViewPanel::Render() { showingScaleGizmo, m_scaleGizmo); - viewportHostService->SetSceneViewTransientTransformGizmoOverlayData( - overlay, - BuildSceneViewportTransformGizmoHandleBuildInputs( - showingMoveGizmo, - m_moveGizmo, - drawGizmoFrameState.moveContext, - showingRotateGizmo, - m_rotateGizmo, - drawGizmoFrameState.rotateContext, - showingScaleGizmo, - m_scaleGizmo, - drawGizmoFrameState.scaleContext)); + viewportHostService->SetSceneViewTransformGizmoOverlayState( + BuildSceneViewportTransformGizmoOverlayState( + BuildSceneViewportTransformGizmoHandleBuildInputs( + showingMoveGizmo, + m_moveGizmo, + drawGizmoFrameState.moveContext, + showingRotateGizmo, + m_rotateGizmo, + drawGizmoFrameState.rotateContext, + showingScaleGizmo, + m_scaleGizmo, + drawGizmoFrameState.scaleContext))); DrawSceneViewportOverlay( ImGui::GetWindowDrawList(), diff --git a/tests/editor/test_scene_viewport_overlay_providers.cpp b/tests/editor/test_scene_viewport_overlay_providers.cpp index f9aa0b6b..da0009ed 100644 --- a/tests/editor/test_scene_viewport_overlay_providers.cpp +++ b/tests/editor/test_scene_viewport_overlay_providers.cpp @@ -2,6 +2,7 @@ #include "Core/EditorContext.h" #include "Viewport/SceneViewportOverlayBuilder.h" +#include "Viewport/SceneViewportOverlayHandleBuilder.h" #include "Viewport/SceneViewportOverlayProviders.h" #include @@ -62,17 +63,35 @@ SceneViewportOverlayBuildContext CreateBuildContext( const SceneViewportOverlayData& overlay, const std::vector& selectedObjectIds, uint32_t viewportWidth = 1280u, - uint32_t viewportHeight = 720u) { + uint32_t viewportHeight = 720u, + const SceneViewportTransformGizmoOverlayState* transformGizmoOverlayState = nullptr) { return { &context, context.GetSceneManager().GetScene(), &overlay, viewportWidth, viewportHeight, - &selectedObjectIds + &selectedObjectIds, + transformGizmoOverlayState }; } +SceneViewportTransformGizmoOverlayState CreateMoveGizmoOverlayState(uint64_t entityId = 99u) { + SceneViewportTransformGizmoOverlayState state = {}; + state.hasMoveGizmo = true; + state.moveEntityId = entityId; + state.moveGizmo.visible = true; + + SceneViewportMoveGizmoHandleDrawData& handle = state.moveGizmo.handles[0]; + handle.axis = SceneViewportGizmoAxis::X; + handle.start = Math::Vector2(24.0f, 48.0f); + handle.end = Math::Vector2(104.0f, 48.0f); + handle.color = Math::Color(0.91f, 0.09f, 0.05f, 1.0f); + handle.visible = true; + + return state; +} + bool ContainsSpriteKind( const SceneViewportOverlayFrameData& frameData, SceneViewportOverlaySpriteTextureKind textureKind) { @@ -173,6 +192,32 @@ TEST(SceneViewportOverlayProviderRegistryTest, LightProviderBuildsSceneIconAndSe EXPECT_GT(frameData.worldLines.size(), 0u); } +TEST(SceneViewportOverlayProviderRegistryTest, TransformGizmoProviderBuildsOverlayFromFormalState) { + EditorContext context; + context.GetSceneManager().NewScene("Transform Gizmo Overlay Provider"); + + const SceneViewportOverlayData overlay = CreateValidOverlay(); + const std::vector selectedObjectIds = {}; + const SceneViewportTransformGizmoOverlayState gizmoState = CreateMoveGizmoOverlayState(73u); + const SceneViewportOverlayBuildContext buildContext = + CreateBuildContext(context, overlay, selectedObjectIds, 1280u, 720u, &gizmoState); + + auto provider = CreateSceneViewportTransformGizmoOverlayProvider(); + ASSERT_NE(provider, nullptr); + + SceneViewportOverlayFrameData frameData = {}; + frameData.overlay = overlay; + provider->AppendOverlay(buildContext, frameData); + + ASSERT_EQ(frameData.handleRecords.size(), 1u); + EXPECT_EQ(frameData.handleRecords[0].kind, SceneViewportOverlayHandleKind::MoveAxis); + EXPECT_EQ(frameData.handleRecords[0].handleId, static_cast(SceneViewportGizmoAxis::X)); + EXPECT_EQ(frameData.handleRecords[0].entityId, 73u); + EXPECT_GT(frameData.screenTriangles.size(), 0u); + EXPECT_TRUE(frameData.worldLines.empty()); + EXPECT_TRUE(frameData.worldSprites.empty()); +} + TEST( SceneViewportOverlayProviderRegistryTest, OverlayBuilderUsesDefaultRegistryToAggregateCameraAndLightProviders) { @@ -206,5 +251,25 @@ TEST( EXPECT_GT(frameData.worldLines.size(), 12u); } +TEST( + SceneViewportOverlayProviderRegistryTest, + OverlayBuilderAppendsFormalTransformGizmoProviderOutput) { + EditorContext context; + context.GetSceneManager().NewScene("Overlay Builder Transform Gizmo"); + + const SceneViewportOverlayData overlay = CreateValidOverlay(); + const std::vector selectedObjectIds = {}; + const SceneViewportTransformGizmoOverlayState gizmoState = CreateMoveGizmoOverlayState(91u); + + SceneViewportOverlayBuilder builder; + const SceneViewportOverlayFrameData frameData = + builder.Build(context, overlay, 1280u, 720u, selectedObjectIds, &gizmoState); + + EXPECT_TRUE(frameData.overlay.valid); + ASSERT_EQ(frameData.handleRecords.size(), 1u); + EXPECT_EQ(frameData.handleRecords[0].entityId, 91u); + EXPECT_GT(frameData.screenTriangles.size(), 0u); +} + } // namespace } // namespace XCEngine::Editor diff --git a/tests/editor/test_viewport_render_flow_utils.cpp b/tests/editor/test_viewport_render_flow_utils.cpp index 84b36ecc..f868ca36 100644 --- a/tests/editor/test_viewport_render_flow_utils.cpp +++ b/tests/editor/test_viewport_render_flow_utils.cpp @@ -255,11 +255,6 @@ TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportRenderPlanCollectsPostSceneA overlay, XCEngine::Math::Vector3::Zero(), XCEngine::Math::Vector3::Right()); - const SceneViewportOverlayFrameData transientOverlayFrameData = - CreateOverlayFrameDataWithLine( - overlay, - XCEngine::Math::Vector3::Zero(), - XCEngine::Math::Vector3::Up()); size_t factoryCallCount = 0u; size_t combinedWorldLineCount = 0u; @@ -270,7 +265,6 @@ TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportRenderPlanCollectsPostSceneA overlay, { 7u, 11u }, editorOverlayFrameData, - transientOverlayFrameData, [&gridPassFactoryCallCount](const XCEngine::Rendering::Passes::InfiniteGridPassData& data) { ++gridPassFactoryCallCount; EXPECT_TRUE(data.valid); @@ -298,7 +292,7 @@ TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportRenderPlanCollectsPostSceneA EXPECT_EQ(factoryCallCount, 1u); EXPECT_EQ(gridPassFactoryCallCount, 1u); EXPECT_EQ(selectionOutlinePassFactoryCallCount, 1u); - EXPECT_EQ(combinedWorldLineCount, 2u); + EXPECT_EQ(combinedWorldLineCount, 1u); EXPECT_EQ(result.warningStatusText, nullptr); } @@ -310,7 +304,6 @@ TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportRenderPlanWarnsWhenSelection overlay, { 42u }, {}, - {}, [](const XCEngine::Rendering::Passes::InfiniteGridPassData&) { return std::make_unique(); },