Formalize staged scene viewport gizmo frame API

This commit is contained in:
2026-04-04 01:09:02 +08:00
parent 64a2efe993
commit d207043f8f
5 changed files with 486 additions and 44 deletions

View File

@@ -5,6 +5,96 @@
namespace XCEngine {
namespace Editor {
SceneViewportTransformGizmoFrameOptions BuildSceneViewportTransformGizmoFrameOptions(
bool useCenterPivot,
bool localSpace,
bool usingTransformTool,
bool showingMoveGizmo,
bool showingRotateGizmo,
bool showingScaleGizmo) {
SceneViewportTransformGizmoFrameOptions options = {};
options.useCenterPivot = useCenterPivot;
options.localSpace = localSpace;
options.usingTransformTool = usingTransformTool;
options.showingMoveGizmo = showingMoveGizmo;
options.showingRotateGizmo = showingRotateGizmo;
options.showingScaleGizmo = showingScaleGizmo;
return options;
}
SceneViewportTransformGizmoRefreshRequest BuildSceneViewportTransformGizmoRefreshRequest(
IEditorContext& context,
const SceneViewportOverlayData& overlay,
const Math::Vector2& viewportSize,
const Math::Vector2& mousePosition,
const SceneViewportTransformGizmoFrameOptions& options) {
SceneViewportTransformGizmoRefreshRequest request = {};
request.context = &context;
request.overlay = overlay;
request.viewportSize = viewportSize;
request.mousePosition = mousePosition;
request.options = options;
return request;
}
void CancelSceneViewportTransformGizmoFrame(
IEditorContext& context,
SceneViewportMoveGizmo& moveGizmo,
SceneViewportRotateGizmo& rotateGizmo,
SceneViewportScaleGizmo& scaleGizmo) {
CancelSceneViewportTransformGizmoDrags(context, moveGizmo, rotateGizmo, scaleGizmo);
}
SceneViewportTransformGizmoFrameUpdate RefreshSceneViewportTransformGizmoFrame(
const SceneViewportTransformGizmoRefreshRequest& request,
SceneViewportMoveGizmo& moveGizmo,
SceneViewportRotateGizmo& rotateGizmo,
SceneViewportScaleGizmo& scaleGizmo) {
SceneViewportTransformGizmoFrameUpdate update = {};
if (!request.IsValid()) {
return update;
}
update.frameState = RefreshSceneViewportTransformGizmos(
*request.context,
request.overlay,
request.viewportSize,
request.mousePosition,
request.options.useCenterPivot,
request.options.localSpace,
request.options.usingTransformTool,
request.options.showingMoveGizmo,
moveGizmo,
request.options.showingRotateGizmo,
rotateGizmo,
request.options.showingScaleGizmo,
scaleGizmo);
update.overlaySubmission = BuildSceneViewportTransformGizmoOverlaySubmission(
update.frameState,
request.options.showingMoveGizmo,
moveGizmo,
request.options.showingRotateGizmo,
rotateGizmo,
request.options.showingScaleGizmo,
scaleGizmo);
return update;
}
SceneViewportTransformGizmoFrameUpdate RefreshAndSubmitSceneViewportTransformGizmoFrame(
IViewportHostService& viewportHostService,
const SceneViewportTransformGizmoRefreshRequest& request,
SceneViewportMoveGizmo& moveGizmo,
SceneViewportRotateGizmo& rotateGizmo,
SceneViewportScaleGizmo& scaleGizmo) {
SceneViewportTransformGizmoFrameUpdate update = RefreshSceneViewportTransformGizmoFrame(
request,
moveGizmo,
rotateGizmo,
scaleGizmo);
SubmitSceneViewportTransformGizmoOverlaySubmission(viewportHostService, update.overlaySubmission);
return update;
}
SceneViewportTransformGizmoOverlaySubmission BuildSceneViewportTransformGizmoOverlaySubmission(
const SceneViewportTransformGizmoFrameState& frameState,
bool showingMoveGizmo,

View File

@@ -1,7 +1,9 @@
#pragma once
#include "Core/IEditorContext.h"
#include "SceneViewportInteractionActions.h"
#include "SceneViewportOverlayHandleBuilder.h"
#include "SceneViewportTransformGizmoFrameBuilder.h"
#include <cstdint>
@@ -10,6 +12,27 @@ namespace Editor {
class IUndoManager;
struct SceneViewportTransformGizmoFrameOptions {
bool useCenterPivot = false;
bool localSpace = false;
bool usingTransformTool = false;
bool showingMoveGizmo = false;
bool showingRotateGizmo = false;
bool showingScaleGizmo = false;
};
struct SceneViewportTransformGizmoRefreshRequest {
IEditorContext* context = nullptr;
SceneViewportOverlayData overlay = {};
Math::Vector2 viewportSize = Math::Vector2::Zero();
Math::Vector2 mousePosition = Math::Vector2::Zero();
SceneViewportTransformGizmoFrameOptions options = {};
bool IsValid() const {
return context != nullptr;
}
};
struct SceneViewportTransformGizmoOverlaySubmission {
SceneViewportTransformGizmoOverlayState overlayState = {};
SceneViewportActiveGizmoKind activeGizmoKind = SceneViewportActiveGizmoKind::None;
@@ -36,6 +59,45 @@ struct SceneViewportTransformGizmoLifecycleCommand {
}
};
struct SceneViewportTransformGizmoFrameUpdate {
SceneViewportTransformGizmoFrameState frameState = {};
SceneViewportTransformGizmoOverlaySubmission overlaySubmission = {};
};
SceneViewportTransformGizmoFrameOptions BuildSceneViewportTransformGizmoFrameOptions(
bool useCenterPivot,
bool localSpace,
bool usingTransformTool,
bool showingMoveGizmo,
bool showingRotateGizmo,
bool showingScaleGizmo);
SceneViewportTransformGizmoRefreshRequest BuildSceneViewportTransformGizmoRefreshRequest(
IEditorContext& context,
const SceneViewportOverlayData& overlay,
const Math::Vector2& viewportSize,
const Math::Vector2& mousePosition,
const SceneViewportTransformGizmoFrameOptions& options);
void CancelSceneViewportTransformGizmoFrame(
IEditorContext& context,
SceneViewportMoveGizmo& moveGizmo,
SceneViewportRotateGizmo& rotateGizmo,
SceneViewportScaleGizmo& scaleGizmo);
SceneViewportTransformGizmoFrameUpdate RefreshSceneViewportTransformGizmoFrame(
const SceneViewportTransformGizmoRefreshRequest& request,
SceneViewportMoveGizmo& moveGizmo,
SceneViewportRotateGizmo& rotateGizmo,
SceneViewportScaleGizmo& scaleGizmo);
SceneViewportTransformGizmoFrameUpdate RefreshAndSubmitSceneViewportTransformGizmoFrame(
IViewportHostService& viewportHostService,
const SceneViewportTransformGizmoRefreshRequest& request,
SceneViewportMoveGizmo& moveGizmo,
SceneViewportRotateGizmo& rotateGizmo,
SceneViewportScaleGizmo& scaleGizmo);
SceneViewportTransformGizmoOverlaySubmission BuildSceneViewportTransformGizmoOverlaySubmission(
const SceneViewportTransformGizmoFrameState& frameState,
bool showingMoveGizmo,

View File

@@ -9,7 +9,6 @@
#include "Viewport/SceneViewportInteractionResolver.h"
#include "Viewport/SceneViewportMath.h"
#include "Viewport/SceneViewportTransformGizmoCoordinator.h"
#include "Viewport/SceneViewportTransformGizmoFrameBuilder.h"
#include "ViewportPanelContent.h"
#include "Platform/Win32Utf8.h"
#include "UI/UI.h"
@@ -339,46 +338,49 @@ void SceneViewPanel::Render() {
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 = {};
SceneViewportOverlayFrameData emptySceneOverlayFrameData = {};
if (hasInteractiveViewport) {
overlay = viewportHostService->GetSceneViewOverlayData();
gizmoFrameState = RefreshSceneViewportTransformGizmos(
*m_context,
overlay,
viewportSize,
localMousePosition,
useCenterPivot,
localSpace,
usingTransformTool,
showingMoveGizmo,
interactionGizmoFrame = RefreshAndSubmitSceneViewportTransformGizmoFrame(
*viewportHostService,
BuildSceneViewportTransformGizmoRefreshRequest(
*m_context,
overlay,
viewportSize,
localMousePosition,
gizmoFrameOptions),
m_moveGizmo,
showingRotateGizmo,
m_rotateGizmo,
showingScaleGizmo,
m_scaleGizmo);
gizmoFrameState = interactionGizmoFrame.frameState;
} else {
CancelSceneViewportTransformGizmoDrags(*m_context, m_moveGizmo, m_rotateGizmo, m_scaleGizmo);
CancelSceneViewportTransformGizmoFrame(
*m_context,
m_moveGizmo,
m_rotateGizmo,
m_scaleGizmo);
}
const SceneViewportTransformGizmoOverlaySubmission interactionGizmoSubmission =
hasInteractiveViewport
? BuildSceneViewportTransformGizmoOverlaySubmission(
gizmoFrameState,
showingMoveGizmo,
m_moveGizmo,
showingRotateGizmo,
m_rotateGizmo,
showingScaleGizmo,
m_scaleGizmo)
? interactionGizmoFrame.overlaySubmission
: SceneViewportTransformGizmoOverlaySubmission{};
SubmitSceneViewportTransformGizmoOverlaySubmission(*viewportHostService, interactionGizmoSubmission);
const SceneViewportOverlayFrameData& interactionOverlayFrameData =
hasInteractiveViewport
? viewportHostService->GetSceneViewEditorOverlayFrameData(*m_context)
@@ -559,32 +561,17 @@ void SceneViewPanel::Render() {
if (content.hasViewportArea && content.frame.hasTexture) {
overlay = viewportHostService->GetSceneViewOverlayData();
const SceneViewportTransformGizmoFrameState drawGizmoFrameState =
RefreshSceneViewportTransformGizmos(
RefreshAndSubmitSceneViewportTransformGizmoFrame(
*viewportHostService,
BuildSceneViewportTransformGizmoRefreshRequest(
*m_context,
overlay,
viewportSize,
localMousePosition,
useCenterPivot,
localSpace,
usingTransformTool,
showingMoveGizmo,
m_moveGizmo,
showingRotateGizmo,
m_rotateGizmo,
showingScaleGizmo,
m_scaleGizmo);
SubmitSceneViewportTransformGizmoOverlaySubmission(
*viewportHostService,
BuildSceneViewportTransformGizmoOverlaySubmission(
drawGizmoFrameState,
showingMoveGizmo,
m_moveGizmo,
showingRotateGizmo,
m_rotateGizmo,
showingScaleGizmo,
m_scaleGizmo));
gizmoFrameOptions),
m_moveGizmo,
m_rotateGizmo,
m_scaleGizmo);
DrawSceneViewportHudOverlay(
ImGui::GetWindowDrawList(),