#pragma once #include "Core/IEditorContext.h" #include "IViewportHostService.h" #include "SceneViewportEditorModes.h" #include "SceneViewportHudOverlay.h" #include "SceneViewportInteractionResolver.h" #include "SceneViewportTransformGizmoCoordinator.h" namespace XCEngine { namespace Editor { struct SceneViewportToolState { bool usingViewMoveTool = false; bool usingTransformTool = false; bool showingMoveGizmo = false; bool showingRotateGizmo = false; bool showingScaleGizmo = false; bool useCenterPivot = false; bool localSpace = false; SceneViewportTransformGizmoFrameOptions gizmoFrameOptions = {}; }; inline SceneViewportToolState BuildSceneViewportToolState( SceneViewportToolMode toolMode, SceneViewportPivotMode pivotMode, SceneViewportTransformSpaceMode transformSpaceMode) { SceneViewportToolState state = {}; state.usingViewMoveTool = toolMode == SceneViewportToolMode::ViewMove; state.usingTransformTool = toolMode == SceneViewportToolMode::Transform; state.showingMoveGizmo = toolMode == SceneViewportToolMode::Move || state.usingTransformTool; state.showingRotateGizmo = toolMode == SceneViewportToolMode::Rotate || state.usingTransformTool; state.showingScaleGizmo = toolMode == SceneViewportToolMode::Scale || state.usingTransformTool; state.useCenterPivot = pivotMode == SceneViewportPivotMode::Center; state.localSpace = transformSpaceMode == SceneViewportTransformSpaceMode::Local; state.gizmoFrameOptions = BuildSceneViewportTransformGizmoFrameOptions( state.useCenterPivot, state.localSpace, state.usingTransformTool, state.showingMoveGizmo, state.showingRotateGizmo, state.showingScaleGizmo); return state; } struct SceneViewportFrameGeometry { Math::Vector2 viewportSize = Math::Vector2::Zero(); Math::Vector2 localMousePosition = Math::Vector2::Zero(); }; inline SceneViewportFrameGeometry BuildSceneViewportFrameGeometry( const ImVec2& viewportSize, const ImVec2& viewportMin, const ImVec2& absoluteMousePosition) { SceneViewportFrameGeometry geometry = {}; geometry.viewportSize = Math::Vector2(viewportSize.x, viewportSize.y); geometry.localMousePosition = Math::Vector2( absoluteMousePosition.x - viewportMin.x, absoluteMousePosition.y - viewportMin.y); return geometry; } struct SceneViewportInteractionFrameState { bool hasInteractiveViewport = false; SceneViewportOverlayData overlay = {}; SceneViewportTransformGizmoFrameUpdate gizmoFrameUpdate = {}; SceneViewportTransformGizmoFrameState gizmoFrameState = {}; const SceneViewportOverlayFrameData* overlayFrameData = nullptr; SceneViewportActiveGizmoKind activeGizmoKind = SceneViewportActiveGizmoKind::None; bool gizmoActive = false; SceneViewportHudOverlayData hudOverlay = {}; }; inline SceneViewportInteractionFrameState BuildSceneViewportInteractionFrameState( IEditorContext& context, IViewportHostService& viewportHostService, bool hasInteractiveViewport, const SceneViewportFrameGeometry& geometry, const SceneViewportTransformGizmoFrameOptions& gizmoFrameOptions, SceneViewportMoveGizmo& moveGizmo, SceneViewportRotateGizmo& rotateGizmo, SceneViewportScaleGizmo& scaleGizmo, const SceneViewportOverlayFrameData& emptyOverlayFrameData) { SceneViewportInteractionFrameState state = {}; state.hasInteractiveViewport = hasInteractiveViewport; state.overlayFrameData = &emptyOverlayFrameData; if (!hasInteractiveViewport) { CancelSceneViewportTransformGizmoFrame(context, moveGizmo, rotateGizmo, scaleGizmo); state.hudOverlay = BuildSceneViewportHudOverlayData(state.overlay); return state; } state.overlay = viewportHostService.GetSceneViewOverlayData(); state.gizmoFrameUpdate = RefreshAndSubmitSceneViewportTransformGizmoFrame( viewportHostService, BuildSceneViewportTransformGizmoRefreshRequest( context, state.overlay, geometry.viewportSize, geometry.localMousePosition, gizmoFrameOptions), moveGizmo, rotateGizmo, scaleGizmo); state.gizmoFrameState = state.gizmoFrameUpdate.frameState; state.overlayFrameData = &viewportHostService.GetSceneViewEditorOverlayFrameData(context); state.activeGizmoKind = state.gizmoFrameUpdate.overlaySubmission.activeGizmoKind; state.gizmoActive = state.gizmoFrameUpdate.overlaySubmission.GizmoActive(); state.hudOverlay = BuildSceneViewportHudOverlayData(state.overlay); return state; } inline SceneViewportInteractionResolveRequest BuildSceneViewportInteractionResolveRequest( const SceneViewportInteractionFrameState& frameState, const SceneViewportFrameGeometry& geometry, const ImVec2& viewportMin, const ImVec2& viewportMax, const ImVec2& absoluteMousePosition) { SceneViewportInteractionResolveRequest request = {}; request.overlayFrameData = frameState.overlayFrameData; request.viewportSize = geometry.viewportSize; request.localMousePosition = geometry.localMousePosition; request.hudOverlay = &frameState.hudOverlay; request.viewportMin = viewportMin; request.viewportMax = viewportMax; request.absoluteMousePosition = absoluteMousePosition; return request; } } // namespace Editor } // namespace XCEngine