Formalize scene viewport interaction frame helpers

This commit is contained in:
2026-04-04 01:42:35 +08:00
parent a920ca7a6a
commit e636abb76d
5 changed files with 531 additions and 79 deletions

View File

@@ -5,6 +5,7 @@
#include "SceneViewPanel.h"
#include "Viewport/SceneViewportEditorOverlayData.h"
#include "Viewport/SceneViewportHudOverlay.h"
#include "Viewport/SceneViewportInteractionFrame.h"
#include "Viewport/SceneViewportInteractionActions.h"
#include "Viewport/SceneViewportInteractionResolver.h"
#include "Viewport/SceneViewportMath.h"
@@ -292,91 +293,51 @@ void SceneViewPanel::Render() {
m_toolMode = toolShortcutAction.targetTool;
}
const bool usingViewMoveTool = m_toolMode == SceneViewportToolMode::ViewMove;
const bool usingTransformTool = m_toolMode == SceneViewportToolMode::Transform;
const bool showingMoveGizmo = m_toolMode == SceneViewportToolMode::Move || usingTransformTool;
const bool showingRotateGizmo = m_toolMode == SceneViewportToolMode::Rotate || usingTransformTool;
const bool showingScaleGizmo = m_toolMode == SceneViewportToolMode::Scale || usingTransformTool;
const bool useCenterPivot = m_pivotMode == SceneViewportPivotMode::Center;
const bool localSpace = m_transformSpaceMode == SceneViewportTransformSpaceMode::Local;
const SceneViewportTransformGizmoFrameOptions gizmoFrameOptions =
BuildSceneViewportTransformGizmoFrameOptions(
useCenterPivot,
localSpace,
usingTransformTool,
showingMoveGizmo,
showingRotateGizmo,
showingScaleGizmo);
const Math::Vector2 viewportSize(content.availableSize.x, content.availableSize.y);
const Math::Vector2 localMousePosition(
io.MousePos.x - content.itemMin.x,
io.MousePos.y - content.itemMin.y);
SceneViewportOverlayData overlay = {};
SceneViewportTransformGizmoFrameUpdate interactionGizmoFrame = {};
SceneViewportTransformGizmoFrameState gizmoFrameState = {};
const SceneViewportToolState toolState = BuildSceneViewportToolState(
m_toolMode,
m_pivotMode,
m_transformSpaceMode);
const SceneViewportFrameGeometry frameGeometry = BuildSceneViewportFrameGeometry(
content.availableSize,
content.itemMin,
io.MousePos);
SceneViewportOverlayFrameData emptySceneOverlayFrameData = {};
if (hasInteractiveViewport) {
overlay = viewportHostService->GetSceneViewOverlayData();
interactionGizmoFrame = RefreshAndSubmitSceneViewportTransformGizmoFrame(
*viewportHostService,
BuildSceneViewportTransformGizmoRefreshRequest(
*m_context,
overlay,
viewportSize,
localMousePosition,
gizmoFrameOptions),
m_moveGizmo,
m_rotateGizmo,
m_scaleGizmo);
gizmoFrameState = interactionGizmoFrame.frameState;
} else {
CancelSceneViewportTransformGizmoFrame(
const SceneViewportInteractionFrameState interactionFrameState =
BuildSceneViewportInteractionFrameState(
*m_context,
*viewportHostService,
hasInteractiveViewport,
frameGeometry,
toolState.gizmoFrameOptions,
m_moveGizmo,
m_rotateGizmo,
m_scaleGizmo);
}
const SceneViewportTransformGizmoOverlaySubmission interactionGizmoSubmission =
hasInteractiveViewport
? interactionGizmoFrame.overlaySubmission
: SceneViewportTransformGizmoOverlaySubmission{};
const SceneViewportOverlayFrameData& interactionOverlayFrameData =
hasInteractiveViewport
? viewportHostService->GetSceneViewEditorOverlayFrameData(*m_context)
: emptySceneOverlayFrameData;
const SceneViewportActiveGizmoKind activeGizmoKind = interactionGizmoSubmission.activeGizmoKind;
const bool gizmoActive = interactionGizmoSubmission.GizmoActive();
const SceneViewportHudOverlayData interactionHudOverlay =
BuildSceneViewportHudOverlayData(overlay);
m_scaleGizmo,
emptySceneOverlayFrameData);
SceneViewportInteractionResult hoveredInteraction = {};
const bool canResolveViewportInteraction = CanResolveSceneViewportInteraction(
hasInteractiveViewport,
viewportContentHovered,
usingViewMoveTool,
toolState.usingViewMoveTool,
m_navigationState,
gizmoActive);
interactionFrameState.gizmoActive);
if (canResolveViewportInteraction) {
SceneViewportInteractionResolveRequest interactionRequest = {};
interactionRequest.overlayFrameData = &interactionOverlayFrameData;
interactionRequest.viewportSize = viewportSize;
interactionRequest.localMousePosition = localMousePosition;
interactionRequest.hudOverlay = &interactionHudOverlay;
interactionRequest.viewportMin = content.itemMin;
interactionRequest.viewportMax = content.itemMax;
interactionRequest.absoluteMousePosition = io.MousePos;
hoveredInteraction = ResolveSceneViewportInteraction(interactionRequest);
hoveredInteraction = ResolveSceneViewportInteraction(
BuildSceneViewportInteractionResolveRequest(
interactionFrameState,
frameGeometry,
content.itemMin,
content.itemMax,
io.MousePos));
}
ApplySceneViewportHoveredHandleState(
BuildSceneViewportHoveredHandleState(hoveredInteraction),
gizmoActive,
showingMoveGizmo,
interactionFrameState.gizmoActive,
toolState.showingMoveGizmo,
m_moveGizmo,
showingRotateGizmo,
toolState.showingRotateGizmo,
m_rotateGizmo,
showingScaleGizmo,
toolState.showingScaleGizmo,
m_scaleGizmo);
const SceneViewportInteractionActions interactionActions =
@@ -389,8 +350,8 @@ void SceneViewPanel::Render() {
navigationRequest.state = m_navigationState;
navigationRequest.hasInteractiveViewport = hasInteractiveViewport;
navigationRequest.viewportHovered = viewportContentHovered;
navigationRequest.usingViewMoveTool = usingViewMoveTool;
navigationRequest.gizmoActive = gizmoActive;
navigationRequest.usingViewMoveTool = toolState.usingViewMoveTool;
navigationRequest.gizmoActive = interactionFrameState.gizmoActive;
navigationRequest.clickedLeft = content.clickedLeft;
navigationRequest.clickedRight = content.clickedRight;
navigationRequest.clickedMiddle = content.clickedMiddle;
@@ -409,7 +370,7 @@ void SceneViewPanel::Render() {
ExecuteSceneViewportTransformGizmoLifecycleCommand(
BuildBeginSceneViewportTransformGizmoLifecycleCommand(interactionActions),
m_context->GetUndoManager(),
gizmoFrameState,
interactionFrameState.gizmoFrameState,
m_moveGizmo,
m_rotateGizmo,
m_scaleGizmo);
@@ -419,14 +380,14 @@ void SceneViewPanel::Render() {
*m_context,
*viewportHostService,
content.availableSize,
localMousePosition);
frameGeometry.localMousePosition);
ExecuteSceneViewportTransformGizmoLifecycleCommand(
BuildFrameSceneViewportTransformGizmoLifecycleCommand(
activeGizmoKind,
interactionFrameState.activeGizmoKind,
ImGui::IsMouseDown(ImGuiMouseButton_Left)),
m_context->GetUndoManager(),
gizmoFrameState,
interactionFrameState.gizmoFrameState,
m_moveGizmo,
m_rotateGizmo,
m_scaleGizmo);
@@ -466,15 +427,15 @@ void SceneViewPanel::Render() {
viewportHostService->UpdateSceneViewInput(*m_context, input);
if (content.hasViewportArea && content.frame.hasTexture) {
overlay = viewportHostService->GetSceneViewOverlayData();
const SceneViewportOverlayData overlay = viewportHostService->GetSceneViewOverlayData();
RefreshAndSubmitSceneViewportTransformGizmoFrame(
*viewportHostService,
BuildSceneViewportTransformGizmoRefreshRequest(
*m_context,
overlay,
viewportSize,
localMousePosition,
gizmoFrameOptions),
frameGeometry.viewportSize,
frameGeometry.localMousePosition,
toolState.gizmoFrameOptions),
m_moveGizmo,
m_rotateGizmo,
m_scaleGizmo);