2026-04-04 00:21:25 +08:00
|
|
|
#include "SceneViewportInteractionActions.h"
|
|
|
|
|
|
|
|
|
|
#include "IViewportHostService.h"
|
|
|
|
|
|
|
|
|
|
namespace XCEngine {
|
|
|
|
|
namespace Editor {
|
|
|
|
|
|
|
|
|
|
SceneViewportActiveGizmoKind ToSceneViewportActiveGizmoKind(SceneViewportInteractionKind kind) {
|
|
|
|
|
switch (kind) {
|
|
|
|
|
case SceneViewportInteractionKind::MoveGizmo:
|
|
|
|
|
return SceneViewportActiveGizmoKind::Move;
|
|
|
|
|
case SceneViewportInteractionKind::RotateGizmo:
|
|
|
|
|
return SceneViewportActiveGizmoKind::Rotate;
|
|
|
|
|
case SceneViewportInteractionKind::ScaleGizmo:
|
|
|
|
|
return SceneViewportActiveGizmoKind::Scale;
|
|
|
|
|
case SceneViewportInteractionKind::OrientationGizmo:
|
|
|
|
|
case SceneViewportInteractionKind::SceneIcon:
|
|
|
|
|
case SceneViewportInteractionKind::None:
|
|
|
|
|
default:
|
|
|
|
|
return SceneViewportActiveGizmoKind::None;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SceneViewportHoveredHandleState BuildSceneViewportHoveredHandleState(
|
|
|
|
|
const SceneViewportInteractionResult& interaction) {
|
|
|
|
|
SceneViewportHoveredHandleState state = {};
|
|
|
|
|
state.hoveredGizmoKind = ToSceneViewportActiveGizmoKind(interaction.kind);
|
|
|
|
|
if (interaction.kind == SceneViewportInteractionKind::MoveGizmo) {
|
|
|
|
|
state.moveAxis = interaction.moveAxis;
|
|
|
|
|
state.movePlane = interaction.movePlane;
|
|
|
|
|
} else if (interaction.kind == SceneViewportInteractionKind::RotateGizmo) {
|
|
|
|
|
state.rotateAxis = interaction.rotateAxis;
|
|
|
|
|
} else if (interaction.kind == SceneViewportInteractionKind::ScaleGizmo) {
|
|
|
|
|
state.scaleHandle = interaction.scaleHandle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return state;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ApplySceneViewportHoveredHandleState(
|
|
|
|
|
const SceneViewportHoveredHandleState& hoveredHandleState,
|
|
|
|
|
bool gizmoActive,
|
|
|
|
|
bool showingMoveGizmo,
|
|
|
|
|
SceneViewportMoveGizmo& moveGizmo,
|
|
|
|
|
bool showingRotateGizmo,
|
|
|
|
|
SceneViewportRotateGizmo& rotateGizmo,
|
|
|
|
|
bool showingScaleGizmo,
|
|
|
|
|
SceneViewportScaleGizmo& scaleGizmo) {
|
|
|
|
|
if (gizmoActive) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (showingMoveGizmo) {
|
|
|
|
|
moveGizmo.SetHoveredHandle(hoveredHandleState.moveAxis, hoveredHandleState.movePlane);
|
|
|
|
|
}
|
|
|
|
|
if (showingRotateGizmo) {
|
|
|
|
|
rotateGizmo.SetHoveredHandle(hoveredHandleState.rotateAxis);
|
|
|
|
|
}
|
|
|
|
|
if (showingScaleGizmo) {
|
|
|
|
|
scaleGizmo.SetHoveredHandle(hoveredHandleState.scaleHandle);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SceneViewportInteractionActions BuildSceneViewportInteractionActions(
|
|
|
|
|
const SceneViewportInteractionResult& interaction,
|
|
|
|
|
bool hasInteractiveViewport,
|
|
|
|
|
bool clickedLeft,
|
|
|
|
|
bool canResolveViewportInteraction) {
|
|
|
|
|
SceneViewportInteractionActions actions = {};
|
|
|
|
|
actions.hoveredGizmoKind = ToSceneViewportActiveGizmoKind(interaction.kind);
|
|
|
|
|
actions.orientationAxis = interaction.kind == SceneViewportInteractionKind::OrientationGizmo
|
|
|
|
|
? interaction.orientationAxis
|
|
|
|
|
: SceneViewportOrientationAxis::None;
|
|
|
|
|
actions.sceneIconEntityId = interaction.kind == SceneViewportInteractionKind::SceneIcon
|
|
|
|
|
? interaction.entityId
|
|
|
|
|
: 0;
|
|
|
|
|
actions.beginTransformGizmo =
|
|
|
|
|
hasInteractiveViewport &&
|
|
|
|
|
clickedLeft &&
|
|
|
|
|
actions.hoveredGizmoKind != SceneViewportActiveGizmoKind::None;
|
|
|
|
|
actions.orientationGizmoClick =
|
|
|
|
|
hasInteractiveViewport &&
|
|
|
|
|
clickedLeft &&
|
|
|
|
|
actions.orientationAxis != SceneViewportOrientationAxis::None;
|
|
|
|
|
actions.sceneIconClick =
|
|
|
|
|
hasInteractiveViewport &&
|
|
|
|
|
clickedLeft &&
|
|
|
|
|
actions.sceneIconEntityId != 0;
|
|
|
|
|
actions.selectSceneClick =
|
|
|
|
|
hasInteractiveViewport &&
|
|
|
|
|
clickedLeft &&
|
|
|
|
|
canResolveViewportInteraction &&
|
|
|
|
|
!interaction.HasHit();
|
|
|
|
|
return actions;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DispatchSceneViewportInteractionActions(
|
|
|
|
|
const SceneViewportInteractionActions& actions,
|
|
|
|
|
IEditorContext& context,
|
|
|
|
|
IViewportHostService& viewportHostService,
|
2026-04-04 18:15:04 +08:00
|
|
|
const ::XCEngine::UI::UISize& viewportSize,
|
2026-04-04 00:21:25 +08:00
|
|
|
const Math::Vector2& localMousePosition) {
|
|
|
|
|
if (actions.orientationGizmoClick) {
|
|
|
|
|
viewportHostService.AlignSceneViewToOrientationAxis(actions.orientationAxis);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (actions.sceneIconClick) {
|
|
|
|
|
context.GetSelectionManager().SetSelectedEntity(actions.sceneIconEntityId);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!actions.selectSceneClick) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const uint64_t selectedEntity = viewportHostService.PickSceneViewEntity(
|
|
|
|
|
context,
|
|
|
|
|
viewportSize,
|
2026-04-04 18:15:04 +08:00
|
|
|
::XCEngine::UI::UIPoint(localMousePosition.x, localMousePosition.y));
|
2026-04-04 00:21:25 +08:00
|
|
|
if (selectedEntity != 0) {
|
|
|
|
|
context.GetSelectionManager().SetSelectedEntity(selectedEntity);
|
|
|
|
|
} else {
|
|
|
|
|
context.GetSelectionManager().ClearSelection();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace Editor
|
|
|
|
|
} // namespace XCEngine
|