Formalize scene viewport navigation input helpers
This commit is contained in:
27
editor/src/Viewport/SceneViewportEditorModes.h
Normal file
27
editor/src/Viewport/SceneViewportEditorModes.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Editor {
|
||||
|
||||
enum class SceneViewportToolMode : uint8_t {
|
||||
ViewMove = 0,
|
||||
Move,
|
||||
Rotate,
|
||||
Scale,
|
||||
Transform
|
||||
};
|
||||
|
||||
enum class SceneViewportPivotMode : uint8_t {
|
||||
Pivot = 0,
|
||||
Center
|
||||
};
|
||||
|
||||
enum class SceneViewportTransformSpaceMode : uint8_t {
|
||||
Global = 0,
|
||||
Local
|
||||
};
|
||||
|
||||
} // namespace Editor
|
||||
} // namespace XCEngine
|
||||
279
editor/src/Viewport/SceneViewportNavigation.h
Normal file
279
editor/src/Viewport/SceneViewportNavigation.h
Normal file
@@ -0,0 +1,279 @@
|
||||
#pragma once
|
||||
|
||||
#include "IViewportHostService.h"
|
||||
#include "SceneViewportEditorModes.h"
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Editor {
|
||||
|
||||
struct SceneViewportToolShortcutRequest {
|
||||
bool wantTextInput = false;
|
||||
bool lookDragging = false;
|
||||
bool panDragging = false;
|
||||
bool pressedViewMove = false;
|
||||
bool pressedMove = false;
|
||||
bool pressedRotate = false;
|
||||
bool pressedScale = false;
|
||||
};
|
||||
|
||||
struct SceneViewportToolShortcutAction {
|
||||
SceneViewportToolMode targetTool = SceneViewportToolMode::Move;
|
||||
bool triggered = false;
|
||||
bool cancelMoveGizmo = false;
|
||||
bool cancelRotateGizmo = false;
|
||||
bool cancelScaleGizmo = false;
|
||||
|
||||
bool HasAction() const {
|
||||
return triggered;
|
||||
}
|
||||
};
|
||||
|
||||
inline bool CanUseSceneViewportToolShortcut(const SceneViewportToolShortcutRequest& request) {
|
||||
return !request.wantTextInput && !request.lookDragging && !request.panDragging;
|
||||
}
|
||||
|
||||
inline SceneViewportToolShortcutAction BuildSceneViewportToolShortcutAction(
|
||||
const SceneViewportToolShortcutRequest& request) {
|
||||
SceneViewportToolShortcutAction action = {};
|
||||
if (!CanUseSceneViewportToolShortcut(request)) {
|
||||
return action;
|
||||
}
|
||||
|
||||
if (request.pressedViewMove) {
|
||||
action.targetTool = SceneViewportToolMode::ViewMove;
|
||||
action.triggered = true;
|
||||
action.cancelMoveGizmo = true;
|
||||
action.cancelRotateGizmo = true;
|
||||
action.cancelScaleGizmo = true;
|
||||
} else if (request.pressedMove) {
|
||||
action.targetTool = SceneViewportToolMode::Move;
|
||||
action.triggered = true;
|
||||
action.cancelRotateGizmo = true;
|
||||
action.cancelScaleGizmo = true;
|
||||
} else if (request.pressedRotate) {
|
||||
action.targetTool = SceneViewportToolMode::Rotate;
|
||||
action.triggered = true;
|
||||
action.cancelMoveGizmo = true;
|
||||
action.cancelScaleGizmo = true;
|
||||
} else if (request.pressedScale) {
|
||||
action.targetTool = SceneViewportToolMode::Scale;
|
||||
action.triggered = true;
|
||||
action.cancelMoveGizmo = true;
|
||||
action.cancelRotateGizmo = true;
|
||||
}
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
struct SceneViewportNavigationState {
|
||||
bool lookDragging = false;
|
||||
bool panDragging = false;
|
||||
int panDragButton = ImGuiMouseButton_Middle;
|
||||
};
|
||||
|
||||
struct SceneViewportNavigationRequest {
|
||||
SceneViewportNavigationState state = {};
|
||||
bool hasInteractiveViewport = false;
|
||||
bool viewportHovered = false;
|
||||
bool usingViewMoveTool = false;
|
||||
bool gizmoActive = false;
|
||||
bool clickedLeft = false;
|
||||
bool clickedRight = false;
|
||||
bool clickedMiddle = false;
|
||||
bool leftMouseDown = false;
|
||||
bool rightMouseDown = false;
|
||||
bool middleMouseDown = false;
|
||||
};
|
||||
|
||||
struct SceneViewportNavigationUpdate {
|
||||
SceneViewportNavigationState state = {};
|
||||
bool beginLookDrag = false;
|
||||
bool beginPanDrag = false;
|
||||
bool beginLeftPanDrag = false;
|
||||
bool beginMiddlePanDrag = false;
|
||||
};
|
||||
|
||||
inline bool ShouldBeginSceneViewportNavigationDrag(
|
||||
bool hasInteractiveViewport,
|
||||
bool hovered,
|
||||
bool activeDrag,
|
||||
bool otherDrag,
|
||||
bool gizmoActive,
|
||||
bool clicked) {
|
||||
return hasInteractiveViewport && hovered && !activeDrag && !otherDrag && !gizmoActive && clicked;
|
||||
}
|
||||
|
||||
inline bool IsSceneViewportPanDragButtonDown(
|
||||
const SceneViewportNavigationRequest& request,
|
||||
int button) {
|
||||
switch (button) {
|
||||
case ImGuiMouseButton_Left:
|
||||
return request.leftMouseDown;
|
||||
case ImGuiMouseButton_Right:
|
||||
return request.rightMouseDown;
|
||||
case ImGuiMouseButton_Middle:
|
||||
default:
|
||||
return request.middleMouseDown;
|
||||
}
|
||||
}
|
||||
|
||||
inline SceneViewportNavigationUpdate UpdateSceneViewportNavigationState(
|
||||
const SceneViewportNavigationRequest& request) {
|
||||
SceneViewportNavigationUpdate update = {};
|
||||
update.state = request.state;
|
||||
update.beginLeftPanDrag = request.usingViewMoveTool
|
||||
? ShouldBeginSceneViewportNavigationDrag(
|
||||
request.hasInteractiveViewport,
|
||||
request.viewportHovered,
|
||||
request.state.panDragging,
|
||||
request.state.lookDragging,
|
||||
request.gizmoActive,
|
||||
request.clickedLeft)
|
||||
: false;
|
||||
update.beginLookDrag = ShouldBeginSceneViewportNavigationDrag(
|
||||
request.hasInteractiveViewport,
|
||||
request.viewportHovered,
|
||||
request.state.lookDragging,
|
||||
request.state.panDragging,
|
||||
request.gizmoActive,
|
||||
request.clickedRight);
|
||||
update.beginMiddlePanDrag = ShouldBeginSceneViewportNavigationDrag(
|
||||
request.hasInteractiveViewport,
|
||||
request.viewportHovered,
|
||||
request.state.panDragging,
|
||||
request.state.lookDragging,
|
||||
request.gizmoActive,
|
||||
request.clickedMiddle);
|
||||
update.beginPanDrag = update.beginLeftPanDrag || update.beginMiddlePanDrag;
|
||||
|
||||
if (update.beginLookDrag) {
|
||||
update.state.lookDragging = true;
|
||||
update.state.panDragging = false;
|
||||
}
|
||||
if (update.beginPanDrag) {
|
||||
update.state.panDragging = true;
|
||||
update.state.lookDragging = false;
|
||||
update.state.panDragButton = update.beginLeftPanDrag
|
||||
? ImGuiMouseButton_Left
|
||||
: ImGuiMouseButton_Middle;
|
||||
}
|
||||
|
||||
if (update.state.lookDragging && !request.rightMouseDown) {
|
||||
update.state.lookDragging = false;
|
||||
}
|
||||
if (update.state.panDragging &&
|
||||
!IsSceneViewportPanDragButtonDown(request, update.state.panDragButton)) {
|
||||
update.state.panDragging = false;
|
||||
update.state.panDragButton = ImGuiMouseButton_Middle;
|
||||
}
|
||||
|
||||
return update;
|
||||
}
|
||||
|
||||
struct SceneViewportCaptureRequest {
|
||||
SceneViewportNavigationState state = {};
|
||||
bool moveGizmoActive = false;
|
||||
bool rotateGizmoActive = false;
|
||||
bool scaleGizmoActive = false;
|
||||
};
|
||||
|
||||
struct SceneViewportCaptureFlags {
|
||||
bool captureMouse = false;
|
||||
bool captureKeyboard = false;
|
||||
};
|
||||
|
||||
inline SceneViewportCaptureFlags BuildSceneViewportCaptureFlags(
|
||||
const SceneViewportCaptureRequest& request) {
|
||||
SceneViewportCaptureFlags flags = {};
|
||||
flags.captureMouse =
|
||||
request.state.lookDragging ||
|
||||
request.state.panDragging ||
|
||||
request.moveGizmoActive ||
|
||||
request.rotateGizmoActive ||
|
||||
request.scaleGizmoActive;
|
||||
flags.captureKeyboard = request.state.lookDragging;
|
||||
return flags;
|
||||
}
|
||||
|
||||
inline bool CanResolveSceneViewportInteraction(
|
||||
bool hasInteractiveViewport,
|
||||
bool viewportHovered,
|
||||
bool usingViewMoveTool,
|
||||
const SceneViewportNavigationState& navigationState,
|
||||
bool gizmoActive) {
|
||||
return hasInteractiveViewport &&
|
||||
viewportHovered &&
|
||||
!usingViewMoveTool &&
|
||||
!navigationState.lookDragging &&
|
||||
!navigationState.panDragging &&
|
||||
!gizmoActive;
|
||||
}
|
||||
|
||||
struct SceneViewportInputBuildRequest {
|
||||
SceneViewportNavigationState state = {};
|
||||
ImVec2 viewportSize = ImVec2(0.0f, 0.0f);
|
||||
ImVec2 mouseDelta = ImVec2(0.0f, 0.0f);
|
||||
float mouseWheel = 0.0f;
|
||||
float deltaTime = 0.0f;
|
||||
bool viewportHovered = false;
|
||||
bool viewportFocused = false;
|
||||
bool wantTextInput = false;
|
||||
bool fastMove = false;
|
||||
bool focusSelectionKeyPressed = false;
|
||||
bool moveForwardKeyDown = false;
|
||||
bool moveBackwardKeyDown = false;
|
||||
bool moveRightKeyDown = false;
|
||||
bool moveLeftKeyDown = false;
|
||||
bool moveUpKeyDown = false;
|
||||
bool moveDownKeyDown = false;
|
||||
};
|
||||
|
||||
inline SceneViewportInput BuildSceneViewportInput(const SceneViewportInputBuildRequest& request) {
|
||||
SceneViewportInput input = {};
|
||||
input.viewportSize = request.viewportSize;
|
||||
input.deltaTime = request.deltaTime;
|
||||
input.hovered = request.viewportHovered;
|
||||
input.focused =
|
||||
request.viewportFocused ||
|
||||
request.state.lookDragging ||
|
||||
request.state.panDragging;
|
||||
input.mouseWheel =
|
||||
(request.viewportHovered && !request.state.lookDragging)
|
||||
? request.mouseWheel
|
||||
: 0.0f;
|
||||
input.flySpeedDelta =
|
||||
(request.viewportHovered && request.state.lookDragging)
|
||||
? request.mouseWheel
|
||||
: 0.0f;
|
||||
input.looking = request.state.lookDragging;
|
||||
input.orbiting = false;
|
||||
input.panning = request.state.panDragging;
|
||||
input.fastMove = request.fastMove;
|
||||
input.focusSelectionRequested =
|
||||
input.focused &&
|
||||
!request.wantTextInput &&
|
||||
request.focusSelectionKeyPressed;
|
||||
|
||||
if (request.state.lookDragging && !request.wantTextInput) {
|
||||
input.moveForward =
|
||||
(request.moveForwardKeyDown ? 1.0f : 0.0f) -
|
||||
(request.moveBackwardKeyDown ? 1.0f : 0.0f);
|
||||
input.moveRight =
|
||||
(request.moveRightKeyDown ? 1.0f : 0.0f) -
|
||||
(request.moveLeftKeyDown ? 1.0f : 0.0f);
|
||||
input.moveUp =
|
||||
(request.moveUpKeyDown ? 1.0f : 0.0f) -
|
||||
(request.moveDownKeyDown ? 1.0f : 0.0f);
|
||||
}
|
||||
|
||||
if (request.state.lookDragging || request.state.panDragging) {
|
||||
input.mouseDelta = request.mouseDelta;
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
} // namespace Editor
|
||||
} // namespace XCEngine
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "Viewport/SceneViewportInteractionActions.h"
|
||||
#include "Viewport/SceneViewportInteractionResolver.h"
|
||||
#include "Viewport/SceneViewportMath.h"
|
||||
#include "Viewport/SceneViewportNavigation.h"
|
||||
#include "Viewport/SceneViewportTransformGizmoCoordinator.h"
|
||||
#include "ViewportPanelContent.h"
|
||||
#include "Platform/Win32Utf8.h"
|
||||
@@ -243,21 +244,6 @@ SceneViewportToolOverlayResult RenderSceneViewportToolOverlay(
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ShouldBeginSceneViewportNavigationDrag(
|
||||
bool hasInteractiveViewport,
|
||||
bool hovered,
|
||||
bool activeDrag,
|
||||
bool otherDrag,
|
||||
bool gizmoActive,
|
||||
ImGuiMouseButton button) {
|
||||
return hasInteractiveViewport &&
|
||||
hovered &&
|
||||
!activeDrag &&
|
||||
!otherDrag &&
|
||||
!gizmoActive &&
|
||||
ImGui::IsMouseClicked(button);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
SceneViewPanel::SceneViewPanel() : Panel("Scene") {}
|
||||
@@ -279,56 +265,31 @@ void SceneViewPanel::Render() {
|
||||
const bool viewportContentHovered = content.hovered && !toolOverlay.hovered;
|
||||
|
||||
if (toolOverlay.clicked) {
|
||||
if (m_moveGizmo.IsActive()) {
|
||||
m_moveGizmo.CancelDrag(&m_context->GetUndoManager());
|
||||
}
|
||||
if (m_rotateGizmo.IsActive()) {
|
||||
m_rotateGizmo.CancelDrag(&m_context->GetUndoManager());
|
||||
}
|
||||
if (m_scaleGizmo.IsActive()) {
|
||||
m_scaleGizmo.CancelDrag(&m_context->GetUndoManager());
|
||||
}
|
||||
CancelSceneViewportTransformGizmoFrame(*m_context, m_moveGizmo, m_rotateGizmo, m_scaleGizmo);
|
||||
m_toolMode = toolOverlay.clickedTool;
|
||||
}
|
||||
|
||||
const bool allowToolShortcut = !io.WantTextInput && !m_lookDragging && !m_panDragging;
|
||||
if (allowToolShortcut) {
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_Q, false)) {
|
||||
if (m_moveGizmo.IsActive()) {
|
||||
m_moveGizmo.CancelDrag(&m_context->GetUndoManager());
|
||||
}
|
||||
if (m_rotateGizmo.IsActive()) {
|
||||
m_rotateGizmo.CancelDrag(&m_context->GetUndoManager());
|
||||
}
|
||||
if (m_scaleGizmo.IsActive()) {
|
||||
m_scaleGizmo.CancelDrag(&m_context->GetUndoManager());
|
||||
}
|
||||
m_toolMode = SceneViewportToolMode::ViewMove;
|
||||
} else if (ImGui::IsKeyPressed(ImGuiKey_W, false)) {
|
||||
if (m_rotateGizmo.IsActive()) {
|
||||
m_rotateGizmo.CancelDrag(&m_context->GetUndoManager());
|
||||
}
|
||||
if (m_scaleGizmo.IsActive()) {
|
||||
m_scaleGizmo.CancelDrag(&m_context->GetUndoManager());
|
||||
}
|
||||
m_toolMode = SceneViewportToolMode::Move;
|
||||
} else if (ImGui::IsKeyPressed(ImGuiKey_E, false)) {
|
||||
if (m_moveGizmo.IsActive()) {
|
||||
m_moveGizmo.CancelDrag(&m_context->GetUndoManager());
|
||||
}
|
||||
if (m_scaleGizmo.IsActive()) {
|
||||
m_scaleGizmo.CancelDrag(&m_context->GetUndoManager());
|
||||
}
|
||||
m_toolMode = SceneViewportToolMode::Rotate;
|
||||
} else if (ImGui::IsKeyPressed(ImGuiKey_R, false)) {
|
||||
if (m_moveGizmo.IsActive()) {
|
||||
m_moveGizmo.CancelDrag(&m_context->GetUndoManager());
|
||||
}
|
||||
if (m_rotateGizmo.IsActive()) {
|
||||
m_rotateGizmo.CancelDrag(&m_context->GetUndoManager());
|
||||
}
|
||||
m_toolMode = SceneViewportToolMode::Scale;
|
||||
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);
|
||||
if (toolShortcutAction.HasAction()) {
|
||||
if (toolShortcutAction.cancelMoveGizmo && m_moveGizmo.IsActive()) {
|
||||
m_moveGizmo.CancelDrag(&m_context->GetUndoManager());
|
||||
}
|
||||
if (toolShortcutAction.cancelRotateGizmo && m_rotateGizmo.IsActive()) {
|
||||
m_rotateGizmo.CancelDrag(&m_context->GetUndoManager());
|
||||
}
|
||||
if (toolShortcutAction.cancelScaleGizmo && m_scaleGizmo.IsActive()) {
|
||||
m_scaleGizmo.CancelDrag(&m_context->GetUndoManager());
|
||||
}
|
||||
m_toolMode = toolShortcutAction.targetTool;
|
||||
}
|
||||
|
||||
const bool usingViewMoveTool = m_toolMode == SceneViewportToolMode::ViewMove;
|
||||
@@ -390,14 +351,12 @@ void SceneViewPanel::Render() {
|
||||
const SceneViewportHudOverlayData interactionHudOverlay =
|
||||
BuildSceneViewportHudOverlayData(overlay);
|
||||
SceneViewportInteractionResult hoveredInteraction = {};
|
||||
const bool canResolveViewportInteraction =
|
||||
hasInteractiveViewport &&
|
||||
viewportContentHovered &&
|
||||
!usingViewMoveTool &&
|
||||
!m_lookDragging &&
|
||||
!m_panDragging &&
|
||||
!toolOverlay.hovered &&
|
||||
!gizmoActive;
|
||||
const bool canResolveViewportInteraction = CanResolveSceneViewportInteraction(
|
||||
hasInteractiveViewport,
|
||||
viewportContentHovered,
|
||||
usingViewMoveTool,
|
||||
m_navigationState,
|
||||
gizmoActive);
|
||||
if (canResolveViewportInteraction) {
|
||||
SceneViewportInteractionResolveRequest interactionRequest = {};
|
||||
interactionRequest.overlayFrameData = &interactionOverlayFrameData;
|
||||
@@ -426,33 +385,24 @@ void SceneViewPanel::Render() {
|
||||
hasInteractiveViewport,
|
||||
content.clickedLeft,
|
||||
canResolveViewportInteraction);
|
||||
const bool beginLeftPanDrag = usingViewMoveTool
|
||||
? ShouldBeginSceneViewportNavigationDrag(
|
||||
hasInteractiveViewport,
|
||||
viewportContentHovered,
|
||||
m_panDragging,
|
||||
m_lookDragging,
|
||||
gizmoActive,
|
||||
ImGuiMouseButton_Left)
|
||||
: false;
|
||||
const bool beginLookDrag = ShouldBeginSceneViewportNavigationDrag(
|
||||
hasInteractiveViewport,
|
||||
viewportContentHovered,
|
||||
m_lookDragging,
|
||||
m_panDragging,
|
||||
gizmoActive,
|
||||
ImGuiMouseButton_Right);
|
||||
const bool beginMiddlePanDrag = ShouldBeginSceneViewportNavigationDrag(
|
||||
hasInteractiveViewport,
|
||||
viewportContentHovered,
|
||||
m_panDragging,
|
||||
m_lookDragging,
|
||||
gizmoActive,
|
||||
ImGuiMouseButton_Middle);
|
||||
const bool beginPanDrag = beginLeftPanDrag || beginMiddlePanDrag;
|
||||
SceneViewportNavigationRequest navigationRequest = {};
|
||||
navigationRequest.state = m_navigationState;
|
||||
navigationRequest.hasInteractiveViewport = hasInteractiveViewport;
|
||||
navigationRequest.viewportHovered = viewportContentHovered;
|
||||
navigationRequest.usingViewMoveTool = usingViewMoveTool;
|
||||
navigationRequest.gizmoActive = 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 (toolOverlay.clicked || interactionActions.HasClickAction() || beginLookDrag ||
|
||||
beginPanDrag) {
|
||||
if (toolOverlay.clicked || interactionActions.HasClickAction() || navigationUpdate.beginLookDrag ||
|
||||
navigationUpdate.beginPanDrag) {
|
||||
ImGui::SetWindowFocus();
|
||||
}
|
||||
|
||||
@@ -481,81 +431,37 @@ void SceneViewPanel::Render() {
|
||||
m_rotateGizmo,
|
||||
m_scaleGizmo);
|
||||
|
||||
if (beginLookDrag) {
|
||||
m_lookDragging = true;
|
||||
m_panDragging = false;
|
||||
m_loggedLookDelta = false;
|
||||
m_loggedPanDelta = false;
|
||||
}
|
||||
if (beginPanDrag) {
|
||||
m_panDragging = true;
|
||||
m_lookDragging = false;
|
||||
m_panDragButton = beginLeftPanDrag ? ImGuiMouseButton_Left : ImGuiMouseButton_Middle;
|
||||
m_loggedPanDelta = false;
|
||||
m_loggedLookDelta = false;
|
||||
}
|
||||
|
||||
if (m_lookDragging && !ImGui::IsMouseDown(ImGuiMouseButton_Right)) {
|
||||
m_lookDragging = false;
|
||||
m_loggedLookDelta = false;
|
||||
}
|
||||
if (m_panDragging && !ImGui::IsMouseDown(m_panDragButton)) {
|
||||
m_panDragging = false;
|
||||
m_panDragButton = ImGuiMouseButton_Middle;
|
||||
m_loggedPanDelta = false;
|
||||
}
|
||||
|
||||
if (m_lookDragging || m_panDragging || m_moveGizmo.IsActive() || m_rotateGizmo.IsActive() ||
|
||||
m_scaleGizmo.IsActive()) {
|
||||
const SceneViewportCaptureFlags captureFlags = BuildSceneViewportCaptureFlags(
|
||||
SceneViewportCaptureRequest{
|
||||
m_navigationState,
|
||||
m_moveGizmo.IsActive(),
|
||||
m_rotateGizmo.IsActive(),
|
||||
m_scaleGizmo.IsActive()});
|
||||
if (captureFlags.captureMouse) {
|
||||
ImGui::SetNextFrameWantCaptureMouse(true);
|
||||
}
|
||||
if (m_lookDragging) {
|
||||
if (captureFlags.captureKeyboard) {
|
||||
ImGui::SetNextFrameWantCaptureKeyboard(true);
|
||||
}
|
||||
|
||||
SceneViewportInput input = {};
|
||||
input.viewportSize = content.availableSize;
|
||||
input.deltaTime = io.DeltaTime;
|
||||
input.hovered = viewportContentHovered;
|
||||
input.focused = content.focused || m_lookDragging || m_panDragging;
|
||||
input.mouseWheel = (viewportContentHovered && !m_lookDragging) ? io.MouseWheel : 0.0f;
|
||||
input.flySpeedDelta = (viewportContentHovered && m_lookDragging) ? io.MouseWheel : 0.0f;
|
||||
input.looking = m_lookDragging;
|
||||
input.orbiting = false;
|
||||
input.panning = m_panDragging;
|
||||
input.fastMove = io.KeyShift;
|
||||
input.focusSelectionRequested =
|
||||
input.focused && !io.WantTextInput && ImGui::IsKeyPressed(ImGuiKey_F, false);
|
||||
|
||||
if (m_lookDragging && !io.WantTextInput) {
|
||||
input.moveForward =
|
||||
(ImGui::IsKeyDown(ImGuiKey_W) ? 1.0f : 0.0f) -
|
||||
(ImGui::IsKeyDown(ImGuiKey_S) ? 1.0f : 0.0f);
|
||||
input.moveRight =
|
||||
(ImGui::IsKeyDown(ImGuiKey_D) ? 1.0f : 0.0f) -
|
||||
(ImGui::IsKeyDown(ImGuiKey_A) ? 1.0f : 0.0f);
|
||||
input.moveUp =
|
||||
(ImGui::IsKeyDown(ImGuiKey_E) ? 1.0f : 0.0f) -
|
||||
(ImGui::IsKeyDown(ImGuiKey_Q) ? 1.0f : 0.0f);
|
||||
}
|
||||
|
||||
if (m_lookDragging || m_panDragging) {
|
||||
if (m_lookDragging) {
|
||||
input.mouseDelta = io.MouseDelta;
|
||||
if (!m_loggedLookDelta &&
|
||||
(input.mouseDelta.x != 0.0f || input.mouseDelta.y != 0.0f)) {
|
||||
m_loggedLookDelta = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_panDragging) {
|
||||
input.mouseDelta = io.MouseDelta;
|
||||
if (!m_loggedPanDelta &&
|
||||
(input.mouseDelta.x != 0.0f || input.mouseDelta.y != 0.0f)) {
|
||||
m_loggedPanDelta = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
SceneViewportInputBuildRequest inputRequest = {};
|
||||
inputRequest.state = m_navigationState;
|
||||
inputRequest.viewportSize = content.availableSize;
|
||||
inputRequest.mouseDelta = io.MouseDelta;
|
||||
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);
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "Panel.h"
|
||||
#include "Viewport/SceneViewportEditorModes.h"
|
||||
#include "Viewport/SceneViewportMoveGizmo.h"
|
||||
#include "Viewport/SceneViewportNavigation.h"
|
||||
#include "Viewport/SceneViewportRotateGizmo.h"
|
||||
#include "Viewport/SceneViewportScaleGizmo.h"
|
||||
|
||||
@@ -10,24 +12,6 @@
|
||||
namespace XCEngine {
|
||||
namespace Editor {
|
||||
|
||||
enum class SceneViewportToolMode : uint8_t {
|
||||
ViewMove = 0,
|
||||
Move,
|
||||
Rotate,
|
||||
Scale,
|
||||
Transform
|
||||
};
|
||||
|
||||
enum class SceneViewportPivotMode : uint8_t {
|
||||
Pivot = 0,
|
||||
Center
|
||||
};
|
||||
|
||||
enum class SceneViewportTransformSpaceMode : uint8_t {
|
||||
Global = 0,
|
||||
Local
|
||||
};
|
||||
|
||||
class SceneViewPanel : public Panel {
|
||||
public:
|
||||
SceneViewPanel();
|
||||
@@ -37,11 +21,7 @@ private:
|
||||
SceneViewportToolMode m_toolMode = SceneViewportToolMode::Move;
|
||||
SceneViewportPivotMode m_pivotMode = SceneViewportPivotMode::Pivot;
|
||||
SceneViewportTransformSpaceMode m_transformSpaceMode = SceneViewportTransformSpaceMode::Global;
|
||||
bool m_lookDragging = false;
|
||||
bool m_panDragging = false;
|
||||
int m_panDragButton = ImGuiMouseButton_Middle;
|
||||
bool m_loggedLookDelta = false;
|
||||
bool m_loggedPanDelta = false;
|
||||
SceneViewportNavigationState m_navigationState = {};
|
||||
SceneViewportMoveGizmo m_moveGizmo;
|
||||
SceneViewportRotateGizmo m_rotateGizmo;
|
||||
SceneViewportScaleGizmo m_scaleGizmo;
|
||||
|
||||
Reference in New Issue
Block a user