Add scene viewport move gizmo workflow
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "Actions/ActionRouting.h"
|
||||
#include "Core/IEditorContext.h"
|
||||
#include "Core/ISceneManager.h"
|
||||
#include "Core/ISelectionManager.h"
|
||||
#include "SceneViewPanel.h"
|
||||
#include "Viewport/SceneViewportOverlayRenderer.h"
|
||||
@@ -11,10 +12,38 @@
|
||||
namespace XCEngine {
|
||||
namespace Editor {
|
||||
|
||||
namespace {
|
||||
|
||||
SceneViewportMoveGizmoContext BuildMoveGizmoContext(
|
||||
IEditorContext& context,
|
||||
const SceneViewportOverlayData& overlay,
|
||||
const ViewportPanelContentResult& content,
|
||||
const ImVec2& mousePosition) {
|
||||
SceneViewportMoveGizmoContext gizmoContext = {};
|
||||
gizmoContext.overlay = overlay;
|
||||
gizmoContext.viewportSize = Math::Vector2(content.availableSize.x, content.availableSize.y);
|
||||
gizmoContext.mousePosition = Math::Vector2(
|
||||
mousePosition.x - content.itemMin.x,
|
||||
mousePosition.y - content.itemMin.y);
|
||||
|
||||
if (context.GetSelectionManager().GetSelectionCount() == 1) {
|
||||
const uint64_t selectedEntity = context.GetSelectionManager().GetSelectedEntity();
|
||||
if (selectedEntity != 0) {
|
||||
gizmoContext.selectedObject = context.GetSceneManager().GetEntity(selectedEntity);
|
||||
}
|
||||
}
|
||||
|
||||
return gizmoContext;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -22,21 +51,55 @@ void SceneViewPanel::Render() {
|
||||
const ViewportPanelContentResult content = RenderViewportPanelContent(*m_context, EditorViewportKind::Scene);
|
||||
if (IViewportHostService* viewportHostService = m_context->GetViewportHostService()) {
|
||||
const ImGuiIO& io = ImGui::GetIO();
|
||||
const bool selectClick =
|
||||
const bool hasInteractiveViewport = content.hasViewportArea && content.frame.hasTexture;
|
||||
SceneViewportOverlayData overlay = {};
|
||||
SceneViewportMoveGizmoContext moveGizmoContext = {};
|
||||
|
||||
if (hasInteractiveViewport) {
|
||||
overlay = viewportHostService->GetSceneViewOverlayData();
|
||||
moveGizmoContext = BuildMoveGizmoContext(*m_context, overlay, content, io.MousePos);
|
||||
if (m_moveGizmo.IsActive() &&
|
||||
(moveGizmoContext.selectedObject == nullptr ||
|
||||
m_context->GetSelectionManager().GetSelectedEntity() != m_moveGizmo.GetActiveEntityId())) {
|
||||
m_moveGizmo.CancelDrag(&m_context->GetUndoManager());
|
||||
}
|
||||
m_moveGizmo.Update(moveGizmoContext);
|
||||
} else if (m_moveGizmo.IsActive()) {
|
||||
m_moveGizmo.CancelDrag(&m_context->GetUndoManager());
|
||||
}
|
||||
|
||||
const bool beginMoveGizmo =
|
||||
hasInteractiveViewport &&
|
||||
content.hovered &&
|
||||
content.frame.hasTexture &&
|
||||
ImGui::IsMouseClicked(ImGuiMouseButton_Left) &&
|
||||
!m_lookDragging &&
|
||||
!m_panDragging;
|
||||
!m_panDragging &&
|
||||
m_moveGizmo.IsHoveringHandle();
|
||||
const bool selectClick =
|
||||
hasInteractiveViewport &&
|
||||
content.hovered &&
|
||||
ImGui::IsMouseClicked(ImGuiMouseButton_Left) &&
|
||||
!m_lookDragging &&
|
||||
!m_panDragging &&
|
||||
!m_moveGizmo.IsHoveringHandle() &&
|
||||
!m_moveGizmo.IsActive();
|
||||
const bool beginLookDrag =
|
||||
content.hovered && ImGui::IsMouseClicked(ImGuiMouseButton_Right);
|
||||
content.hovered &&
|
||||
!m_moveGizmo.IsActive() &&
|
||||
ImGui::IsMouseClicked(ImGuiMouseButton_Right);
|
||||
const bool beginPanDrag =
|
||||
content.hovered && ImGui::IsMouseClicked(ImGuiMouseButton_Middle);
|
||||
content.hovered &&
|
||||
!m_moveGizmo.IsActive() &&
|
||||
ImGui::IsMouseClicked(ImGuiMouseButton_Middle);
|
||||
|
||||
if (selectClick || beginLookDrag || beginPanDrag) {
|
||||
if (beginMoveGizmo || selectClick || beginLookDrag || beginPanDrag) {
|
||||
ImGui::SetWindowFocus();
|
||||
}
|
||||
|
||||
if (beginMoveGizmo) {
|
||||
m_moveGizmo.TryBeginDrag(moveGizmoContext, m_context->GetUndoManager());
|
||||
}
|
||||
|
||||
if (selectClick) {
|
||||
const ImVec2 localMousePosition(
|
||||
io.MousePos.x - content.itemMin.x,
|
||||
@@ -52,6 +115,14 @@ void SceneViewPanel::Render() {
|
||||
}
|
||||
}
|
||||
|
||||
if (m_moveGizmo.IsActive()) {
|
||||
if (ImGui::IsMouseDown(ImGuiMouseButton_Left)) {
|
||||
m_moveGizmo.UpdateDrag(moveGizmoContext);
|
||||
} else {
|
||||
m_moveGizmo.EndDrag(m_context->GetUndoManager());
|
||||
}
|
||||
}
|
||||
|
||||
if (beginLookDrag) {
|
||||
m_lookDragging = true;
|
||||
m_lastLookDragDelta = ImVec2(0.0f, 0.0f);
|
||||
@@ -70,7 +141,7 @@ void SceneViewPanel::Render() {
|
||||
m_lastPanDragDelta = ImVec2(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
if (m_lookDragging || m_panDragging) {
|
||||
if (m_lookDragging || m_panDragging || m_moveGizmo.IsActive()) {
|
||||
ImGui::SetNextFrameWantCaptureMouse(true);
|
||||
}
|
||||
if (m_lookDragging) {
|
||||
@@ -126,13 +197,16 @@ void SceneViewPanel::Render() {
|
||||
viewportHostService->UpdateSceneViewInput(*m_context, input);
|
||||
|
||||
if (content.hasViewportArea && content.frame.hasTexture) {
|
||||
const SceneViewportOverlayData overlay = viewportHostService->GetSceneViewOverlayData();
|
||||
overlay = viewportHostService->GetSceneViewOverlayData();
|
||||
moveGizmoContext = BuildMoveGizmoContext(*m_context, overlay, content, io.MousePos);
|
||||
m_moveGizmo.Update(moveGizmoContext);
|
||||
DrawSceneViewportOverlay(
|
||||
ImGui::GetWindowDrawList(),
|
||||
overlay,
|
||||
content.itemMin,
|
||||
content.itemMax,
|
||||
content.availableSize);
|
||||
content.availableSize,
|
||||
&m_moveGizmo.GetDrawData());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user