mirror of
https://github.com/sampletext32/ParkanPlayground.git
synced 2026-08-15 15:07:48 +04:00
94 lines
3.1 KiB
C#
94 lines
3.1 KiB
C#
using System.Numerics;
|
|
using ImGuiNET;
|
|
|
|
namespace NResUI.Rendering.Viewport;
|
|
|
|
public sealed class ViewportInputController
|
|
{
|
|
private const float MouseRotationSpeed = 0.25f;
|
|
private const float MouseZoomSpeed = 0.35f;
|
|
|
|
private bool _isRotatingViewport;
|
|
private bool _isPanningViewport;
|
|
|
|
public void Handle(
|
|
ViewportRenderer renderer,
|
|
ViewportScene scene,
|
|
ViewportCamera camera,
|
|
bool viewportHovered,
|
|
bool viewportFocused,
|
|
Vector2 imageMin,
|
|
Vector2 imageSize)
|
|
{
|
|
var io = ImGui.GetIO();
|
|
|
|
var wantsPanWithMiddle = io.KeyAlt && ImGui.IsMouseClicked(ImGuiMouseButton.Middle);
|
|
var wantsPanWithRight = ImGui.IsMouseClicked(ImGuiMouseButton.Right);
|
|
|
|
if (viewportHovered && wantsPanWithMiddle)
|
|
_isPanningViewport = true;
|
|
else if (viewportHovered && ImGui.IsMouseClicked(ImGuiMouseButton.Middle))
|
|
_isRotatingViewport = true;
|
|
|
|
if (viewportHovered && wantsPanWithRight)
|
|
_isPanningViewport = true;
|
|
|
|
if (!ImGui.IsMouseDown(ImGuiMouseButton.Middle))
|
|
_isRotatingViewport = false;
|
|
|
|
if (!ImGui.IsMouseDown(ImGuiMouseButton.Right) && !(io.KeyAlt && ImGui.IsMouseDown(ImGuiMouseButton.Middle)))
|
|
_isPanningViewport = false;
|
|
|
|
if (_isRotatingViewport)
|
|
{
|
|
camera.YawDegrees += -io.MouseDelta.X * MouseRotationSpeed;
|
|
camera.PitchDegrees += io.MouseDelta.Y * MouseRotationSpeed;
|
|
camera.PitchDegrees = Math.Clamp(camera.PitchDegrees, -89.0f, 89.0f);
|
|
}
|
|
|
|
if (_isPanningViewport)
|
|
camera.Pan(io.MouseDelta, imageSize);
|
|
|
|
if (viewportHovered && Math.Abs(io.MouseWheel) > float.Epsilon)
|
|
{
|
|
camera.Distance -= io.MouseWheel * MouseZoomSpeed * MathF.Max(1.0f, camera.Distance * 0.15f);
|
|
camera.Distance = Math.Clamp(camera.Distance, 0.25f, 400.0f);
|
|
}
|
|
|
|
if (viewportHovered && ImGui.IsMouseClicked(ImGuiMouseButton.Left))
|
|
{
|
|
var mouse = ImGui.GetMousePos();
|
|
var localMouse = mouse - imageMin;
|
|
|
|
scene.SelectedPieceId = renderer.PickPiece(
|
|
Math.Max(1, (int)imageSize.X),
|
|
Math.Max(1, (int)imageSize.Y),
|
|
scene,
|
|
camera,
|
|
localMouse);
|
|
}
|
|
|
|
if (viewportFocused || viewportHovered)
|
|
HandleKeyboardShortcuts(scene, camera);
|
|
}
|
|
|
|
private static void HandleKeyboardShortcuts(ViewportScene scene, ViewportCamera camera)
|
|
{
|
|
if (ImGui.IsKeyPressed(ImGuiKey.F))
|
|
{
|
|
if (scene.TryGetSelectedPieceWorldBounds(out var selectedBounds))
|
|
camera.FrameBounds(selectedBounds.Min, selectedBounds.Max);
|
|
else if (scene.TryGetSceneWorldBounds(out var sceneBounds))
|
|
camera.FrameBounds(sceneBounds.Min, sceneBounds.Max);
|
|
}
|
|
|
|
if (ImGui.IsKeyPressed(ImGuiKey.Home))
|
|
{
|
|
if (scene.TryGetSceneWorldBounds(out var sceneBounds))
|
|
camera.FrameBounds(sceneBounds.Min, sceneBounds.Max);
|
|
else
|
|
camera.Reset();
|
|
}
|
|
}
|
|
}
|