feat: refine scene viewport gizmos and controls

This commit is contained in:
2026-03-31 21:26:40 +08:00
parent be15bc2fc4
commit 6d3a90ef74
16 changed files with 969 additions and 155 deletions

View File

@@ -3,6 +3,7 @@
#include "Core/ISceneManager.h"
#include "Core/ISelectionManager.h"
#include "SceneViewPanel.h"
#include "Viewport/SceneViewportOrientationGizmo.h"
#include "Viewport/SceneViewportOverlayRenderer.h"
#include "ViewportPanelContent.h"
#include "UI/UI.h"
@@ -75,24 +76,48 @@ void SceneViewPanel::Render() {
!m_lookDragging &&
!m_panDragging &&
m_moveGizmo.IsHoveringHandle();
const SceneViewportOrientationAxis orientationAxisHit =
hasInteractiveViewport &&
content.hovered &&
!m_lookDragging &&
!m_panDragging &&
!m_moveGizmo.IsHoveringHandle() &&
!m_moveGizmo.IsActive()
? HitTestSceneViewportOrientationGizmo(
overlay,
content.itemMin,
content.itemMax,
io.MousePos)
: SceneViewportOrientationAxis::None;
const bool orientationGizmoClick =
hasInteractiveViewport &&
content.hovered &&
ImGui::IsMouseClicked(ImGuiMouseButton_Left) &&
orientationAxisHit != SceneViewportOrientationAxis::None;
const bool selectClick =
hasInteractiveViewport &&
content.hovered &&
ImGui::IsMouseClicked(ImGuiMouseButton_Left) &&
!m_lookDragging &&
!m_panDragging &&
!orientationGizmoClick &&
!m_moveGizmo.IsHoveringHandle() &&
!m_moveGizmo.IsActive();
const bool beginLookDrag =
hasInteractiveViewport &&
content.hovered &&
!m_lookDragging &&
!m_moveGizmo.IsActive() &&
ImGui::IsMouseClicked(ImGuiMouseButton_Right);
const bool beginPanDrag =
hasInteractiveViewport &&
content.hovered &&
!m_panDragging &&
!m_moveGizmo.IsActive() &&
!m_lookDragging &&
ImGui::IsMouseClicked(ImGuiMouseButton_Middle);
if (beginMoveGizmo || selectClick || beginLookDrag || beginPanDrag) {
if (beginMoveGizmo || orientationGizmoClick || selectClick || beginLookDrag || beginPanDrag) {
ImGui::SetWindowFocus();
}
@@ -100,6 +125,13 @@ void SceneViewPanel::Render() {
m_moveGizmo.TryBeginDrag(moveGizmoContext, m_context->GetUndoManager());
}
if (orientationGizmoClick) {
viewportHostService->AlignSceneViewToOrientationAxis(orientationAxisHit);
overlay = viewportHostService->GetSceneViewOverlayData();
moveGizmoContext = BuildMoveGizmoContext(*m_context, overlay, content, io.MousePos);
m_moveGizmo.Update(moveGizmoContext);
}
if (selectClick) {
const ImVec2 localMousePosition(
io.MousePos.x - content.itemMin.x,
@@ -125,11 +157,15 @@ void SceneViewPanel::Render() {
if (beginLookDrag) {
m_lookDragging = true;
m_panDragging = false;
m_lastLookDragDelta = ImVec2(0.0f, 0.0f);
m_lastPanDragDelta = ImVec2(0.0f, 0.0f);
}
if (beginPanDrag) {
m_panDragging = true;
m_lookDragging = false;
m_lastPanDragDelta = ImVec2(0.0f, 0.0f);
m_lastLookDragDelta = ImVec2(0.0f, 0.0f);
}
if (m_lookDragging && !ImGui::IsMouseDown(ImGuiMouseButton_Right)) {