214 lines
9.6 KiB
C++
214 lines
9.6 KiB
C++
#include "Actions/ActionRouting.h"
|
|
#include "Core/IEditorContext.h"
|
|
#include "Core/ISceneManager.h"
|
|
#include "Core/ISelectionManager.h"
|
|
#include "SceneViewPanel.h"
|
|
#include "Viewport/SceneViewportChrome.h"
|
|
#include "Viewport/SceneViewportEditorOverlayData.h"
|
|
#include "Viewport/SceneViewportInteractionFrame.h"
|
|
#include "Viewport/SceneViewportInteractionActions.h"
|
|
#include "Viewport/SceneViewportInteractionResolver.h"
|
|
#include "Viewport/SceneViewportMath.h"
|
|
#include "Viewport/SceneViewportNavigation.h"
|
|
#include "Viewport/SceneViewportTransformGizmoCoordinator.h"
|
|
#include "ViewportPanelContent.h"
|
|
|
|
#include <imgui.h>
|
|
|
|
namespace XCEngine {
|
|
namespace Editor {
|
|
|
|
SceneViewPanel::SceneViewPanel() : Panel("Scene") {}
|
|
|
|
void SceneViewPanel::Render() {
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
|
UI::PanelWindowScope panel(m_name.c_str());
|
|
ImGui::PopStyleVar();
|
|
if (!panel.IsOpen()) {
|
|
return;
|
|
}
|
|
|
|
RenderSceneViewportTopBar(m_pivotMode, m_transformSpaceMode);
|
|
const ViewportPanelContentResult content = RenderViewportPanelContent(*m_context, EditorViewportKind::Scene);
|
|
if (IViewportHostService* viewportHostService = m_context->GetViewportHostService()) {
|
|
const ImGuiIO& io = ImGui::GetIO();
|
|
const bool hasInteractiveViewport = content.hasViewportArea && content.frame.hasTexture;
|
|
const SceneViewportToolOverlayResult toolOverlay = RenderSceneViewportToolOverlay(content, m_toolMode);
|
|
const bool viewportContentHovered = content.hovered && !toolOverlay.hovered;
|
|
|
|
SceneViewportToolShortcutRequest toolShortcutRequest = {};
|
|
toolShortcutRequest.wantTextInput = io.WantTextInput;
|
|
toolShortcutRequest.lookDragging = m_navigationState.lookDragging;
|
|
toolShortcutRequest.panDragging = m_navigationState.panDragging;
|
|
toolShortcutRequest.pressedViewMove = ImGui::IsKeyPressed(ImGuiKey_Q, false);
|
|
toolShortcutRequest.pressedMove = ImGui::IsKeyPressed(ImGuiKey_W, false);
|
|
toolShortcutRequest.pressedRotate = ImGui::IsKeyPressed(ImGuiKey_E, false);
|
|
toolShortcutRequest.pressedScale = ImGui::IsKeyPressed(ImGuiKey_R, false);
|
|
const SceneViewportToolShortcutAction toolShortcutAction =
|
|
BuildSceneViewportToolShortcutAction(toolShortcutRequest);
|
|
const SceneViewportToolCommand toolCommand =
|
|
BuildSceneViewportToolCommand(toolOverlay, toolShortcutAction);
|
|
ExecuteSceneViewportToolCommand(
|
|
toolCommand,
|
|
m_context->GetUndoManager(),
|
|
m_moveGizmo,
|
|
m_rotateGizmo,
|
|
m_scaleGizmo,
|
|
m_toolMode);
|
|
|
|
const SceneViewportToolState toolState = BuildSceneViewportToolState(
|
|
m_toolMode,
|
|
m_pivotMode,
|
|
m_transformSpaceMode);
|
|
const SceneViewportFrameGeometry frameGeometry = BuildSceneViewportFrameGeometry(
|
|
content.availableSize,
|
|
content.itemMin,
|
|
io.MousePos);
|
|
SceneViewportOverlayFrameData emptySceneOverlayFrameData = {};
|
|
const SceneViewportInteractionFrameState interactionFrameState =
|
|
BuildSceneViewportInteractionFrameState(
|
|
*m_context,
|
|
*viewportHostService,
|
|
hasInteractiveViewport,
|
|
frameGeometry,
|
|
toolState.gizmoFrameOptions,
|
|
m_moveGizmo,
|
|
m_rotateGizmo,
|
|
m_scaleGizmo,
|
|
emptySceneOverlayFrameData);
|
|
SceneViewportInteractionResult hoveredInteraction = {};
|
|
const bool canResolveViewportInteraction = CanResolveSceneViewportInteraction(
|
|
hasInteractiveViewport,
|
|
viewportContentHovered,
|
|
toolState.usingViewMoveTool,
|
|
m_navigationState,
|
|
interactionFrameState.gizmoActive);
|
|
if (canResolveViewportInteraction) {
|
|
hoveredInteraction = ResolveSceneViewportInteraction(
|
|
BuildSceneViewportInteractionResolveRequest(
|
|
interactionFrameState,
|
|
frameGeometry,
|
|
content.itemMin,
|
|
content.itemMax,
|
|
io.MousePos));
|
|
}
|
|
|
|
ApplySceneViewportHoveredHandleState(
|
|
BuildSceneViewportHoveredHandleState(hoveredInteraction),
|
|
interactionFrameState.gizmoActive,
|
|
toolState.showingMoveGizmo,
|
|
m_moveGizmo,
|
|
toolState.showingRotateGizmo,
|
|
m_rotateGizmo,
|
|
toolState.showingScaleGizmo,
|
|
m_scaleGizmo);
|
|
|
|
const SceneViewportInteractionActions interactionActions =
|
|
BuildSceneViewportInteractionActions(
|
|
hoveredInteraction,
|
|
hasInteractiveViewport,
|
|
content.clickedLeft,
|
|
canResolveViewportInteraction);
|
|
SceneViewportNavigationRequest navigationRequest = {};
|
|
navigationRequest.state = m_navigationState;
|
|
navigationRequest.hasInteractiveViewport = hasInteractiveViewport;
|
|
navigationRequest.viewportHovered = viewportContentHovered;
|
|
navigationRequest.usingViewMoveTool = toolState.usingViewMoveTool;
|
|
navigationRequest.gizmoActive = interactionFrameState.gizmoActive;
|
|
navigationRequest.clickedLeft = content.clickedLeft;
|
|
navigationRequest.clickedRight = content.clickedRight;
|
|
navigationRequest.clickedMiddle = content.clickedMiddle;
|
|
navigationRequest.leftMouseDown = ImGui::IsMouseDown(ImGuiMouseButton_Left);
|
|
navigationRequest.rightMouseDown = ImGui::IsMouseDown(ImGuiMouseButton_Right);
|
|
navigationRequest.middleMouseDown = ImGui::IsMouseDown(ImGuiMouseButton_Middle);
|
|
const SceneViewportNavigationUpdate navigationUpdate =
|
|
UpdateSceneViewportNavigationState(navigationRequest);
|
|
m_navigationState = navigationUpdate.state;
|
|
|
|
if (ShouldFocusSceneViewportAfterInteraction(
|
|
toolCommand.HasAction(),
|
|
interactionActions,
|
|
navigationUpdate)) {
|
|
ImGui::SetWindowFocus();
|
|
}
|
|
|
|
ExecuteSceneViewportTransformGizmoLifecycleCommand(
|
|
BuildBeginSceneViewportTransformGizmoLifecycleCommand(interactionActions),
|
|
m_context->GetUndoManager(),
|
|
interactionFrameState.gizmoFrameState,
|
|
m_moveGizmo,
|
|
m_rotateGizmo,
|
|
m_scaleGizmo);
|
|
|
|
DispatchSceneViewportInteractionActions(
|
|
interactionActions,
|
|
*m_context,
|
|
*viewportHostService,
|
|
::XCEngine::UI::UISize(content.availableSize.x, content.availableSize.y),
|
|
frameGeometry.localMousePosition);
|
|
|
|
ExecuteSceneViewportTransformGizmoLifecycleCommand(
|
|
BuildFrameSceneViewportTransformGizmoLifecycleCommand(
|
|
interactionFrameState.activeGizmoKind,
|
|
ImGui::IsMouseDown(ImGuiMouseButton_Left)),
|
|
m_context->GetUndoManager(),
|
|
interactionFrameState.gizmoFrameState,
|
|
m_moveGizmo,
|
|
m_rotateGizmo,
|
|
m_scaleGizmo);
|
|
|
|
const SceneViewportCaptureFlags captureFlags = BuildSceneViewportCaptureFlags(
|
|
SceneViewportCaptureRequest{
|
|
m_navigationState,
|
|
m_moveGizmo.IsActive(),
|
|
m_rotateGizmo.IsActive(),
|
|
m_scaleGizmo.IsActive()});
|
|
if (captureFlags.captureMouse) {
|
|
ImGui::SetNextFrameWantCaptureMouse(true);
|
|
}
|
|
if (captureFlags.captureKeyboard) {
|
|
ImGui::SetNextFrameWantCaptureKeyboard(true);
|
|
}
|
|
|
|
SceneViewportInputBuildRequest inputRequest = {};
|
|
inputRequest.state = m_navigationState;
|
|
inputRequest.viewportSize = ::XCEngine::UI::UISize(content.availableSize.x, content.availableSize.y);
|
|
inputRequest.mouseDelta = ::XCEngine::UI::UIPoint(io.MouseDelta.x, io.MouseDelta.y);
|
|
inputRequest.mouseWheel = io.MouseWheel;
|
|
inputRequest.deltaTime = io.DeltaTime;
|
|
inputRequest.viewportHovered = viewportContentHovered;
|
|
inputRequest.viewportFocused = content.focused;
|
|
inputRequest.wantTextInput = io.WantTextInput;
|
|
inputRequest.fastMove = io.KeyShift;
|
|
inputRequest.focusSelectionKeyPressed = ImGui::IsKeyPressed(ImGuiKey_F, false);
|
|
inputRequest.moveForwardKeyDown = ImGui::IsKeyDown(ImGuiKey_W);
|
|
inputRequest.moveBackwardKeyDown = ImGui::IsKeyDown(ImGuiKey_S);
|
|
inputRequest.moveRightKeyDown = ImGui::IsKeyDown(ImGuiKey_D);
|
|
inputRequest.moveLeftKeyDown = ImGui::IsKeyDown(ImGuiKey_A);
|
|
inputRequest.moveUpKeyDown = ImGui::IsKeyDown(ImGuiKey_E);
|
|
inputRequest.moveDownKeyDown = ImGui::IsKeyDown(ImGuiKey_Q);
|
|
const SceneViewportInput input = BuildSceneViewportInput(inputRequest);
|
|
|
|
viewportHostService->UpdateSceneViewInput(*m_context, input);
|
|
|
|
SceneViewportPresentationRequest presentationRequest = {};
|
|
presentationRequest.context = m_context;
|
|
presentationRequest.viewportHostService = viewportHostService;
|
|
presentationRequest.hasInteractiveViewport = hasInteractiveViewport;
|
|
presentationRequest.geometry = frameGeometry;
|
|
presentationRequest.gizmoFrameOptions = toolState.gizmoFrameOptions;
|
|
presentationRequest.moveGizmo = &m_moveGizmo;
|
|
presentationRequest.rotateGizmo = &m_rotateGizmo;
|
|
presentationRequest.scaleGizmo = &m_scaleGizmo;
|
|
presentationRequest.drawList = ImGui::GetWindowDrawList();
|
|
presentationRequest.viewportMin = content.itemMin;
|
|
presentationRequest.viewportMax = content.itemMax;
|
|
RefreshAndDrawSceneViewportPresentation(presentationRequest);
|
|
}
|
|
|
|
Actions::ObserveInactiveActionRoute(*m_context);
|
|
}
|
|
|
|
}
|
|
}
|