Skip to content

fix: capture cursor during viewport camera drags (#8)#236

Open
SeanRamey wants to merge 1 commit into
HailToDodongo:mainfrom
SeanRamey:fix/viewport-cursor-capture
Open

fix: capture cursor during viewport camera drags (#8)#236
SeanRamey wants to merge 1 commit into
HailToDodongo:mainfrom
SeanRamey:fix/viewport-cursor-capture

Conversation

@SeanRamey

Copy link
Copy Markdown

Summary

Fixes #8.

The three viewport camera-drag controls (right-click free look, middle-click pan, and alt + left-click orbit)
all drove the camera by raw cursor motion.

There were at least two consequences:

  1. Once the cursor hit a screen edge, the camera stopped, requiring a mouse release then starting the rotation again.
  2. Releasing the button outside the editor viewport window could land the click on another button, gizmo, input box, or application.

This PR captures the cursor for the duration of any of the three camera drags, so motion is unbounded and the release always lands inside the editor.

How it works

The new cameraDragActive flag viewport3D.h:33, plus the press position cursorLockPos viewport3D.h:37, drives a small set of changes in viewport3D.cpp:

On press (Alt+LMB / MMB / RMB while in editor viewport) viewport3D.cpp:650-657:

  • record cursorLockPos set to ImGui::GetMousePos()
  • drain SDL's accumulated relative mouse motion SDL_GetRelativeMouseState(nullptr, nullptr)
  • set cameraDragActive = true

Each frame while captured viewport3D.cpp:475-488:

  • Get the mouse movement delta from SDL_GetRelativeMouseState, which reports raw user motion since the last call. This delta is added to mousePos, so the existing dragDelta = mousePos - mousePosStart is unchanged.
  • Lock ImGui's cursor at the press position via io.WantSetMousePos = true; io.MousePos = cursorLockPos. ImGui's handles warping the OS cursor back each frame, so other widgets never see the cursor move and don't register false hover.
  • Hide the cursor for all three modes (previously only RMB hid it) viewport3D.cpp:568.

On release viewport3D.cpp:733:

  • clear cameraDragActive. Cursor is at the press point because we kept warping it there.

Pin the cursor to the press position via io.WantSetMousePos while a
camera drag is active, and source motion from SDL_GetRelativeMouseState
so deltas keep growing past screen edges. Hide the cursor for all
three modes (previously only RMB hid it).
@HailToDodongo

Copy link
Copy Markdown
Owner

This change introduce a lot of stuttering when holding right to move the camera.
Seems to be that the delta position is not as smooth as the version before

@SeanRamey

Copy link
Copy Markdown
Author

This change introduce a lot of stuttering when holding right to move the camera. Seems to be that the delta position is not as smooth as the version before

So, I thought I was going crazy because I thought it was stuttering or slower FPS in my changes, but when I really tried to compare, I couldn't actually tell if it was or not. It's like my eyes would sometimes unconsciously notice it. But, I'm not really finding anything that I change makes a difference. I'll still work some more on this to see if I can't make it better, but I'll have to do it later because I've got a lot of other responsibilities to take care of. Maybe I'll submit some changes sometime later this week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Right mouse button hold to move camera in viewport doesn't capture mouse cursor

2 participants