Fix mouse resetting issues after ending relative mode
This commit is contained in:
@@ -10,6 +10,12 @@
|
|||||||
#include "Engine/Input/Mouse.h"
|
#include "Engine/Input/Mouse.h"
|
||||||
#include "Engine/Input/Keyboard.h"
|
#include "Engine/Input/Keyboard.h"
|
||||||
#include "Engine/Input/Gamepad.h"
|
#include "Engine/Input/Gamepad.h"
|
||||||
|
#include "Engine/Engine/Engine.h"
|
||||||
|
#include "Engine/Engine/Screen.h"
|
||||||
|
#if USE_EDITOR
|
||||||
|
#include "Editor/Editor.h"
|
||||||
|
#include "Editor/Managed/ManagedEditor.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <SDL3/SDL_events.h>
|
#include <SDL3/SDL_events.h>
|
||||||
|
|
||||||
@@ -351,7 +357,9 @@ public:
|
|||||||
class SDLMouse : public Mouse
|
class SDLMouse : public Mouse
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Float2 oldPosition;
|
Float2 oldPosition = Float2::Zero;
|
||||||
|
Window* relativeModeWindow = nullptr;
|
||||||
|
const SDL_Rect* oldScreenRect = nullptr;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -369,14 +377,24 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Float2 GetOldMousePosition() const
|
Float2 GetOldMousePosition() const
|
||||||
{
|
{
|
||||||
return oldPosition;
|
ASSERT(relativeModeWindow != nullptr);
|
||||||
|
return relativeModeWindow->ClientToScreen(oldPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
// [Mouse]
|
// [Mouse]
|
||||||
void SetMousePosition(const Float2& newPosition) final override
|
void SetMousePosition(const Float2& screenPosition) final override
|
||||||
{
|
{
|
||||||
SDL_WarpMouseGlobal(newPosition.X, newPosition.Y);
|
#if USE_EDITOR
|
||||||
OnMouseMoved(newPosition);
|
auto window = Editor::Managed->GetGameWindow();
|
||||||
|
if (window == nullptr)
|
||||||
|
window = Engine::MainWindow;
|
||||||
|
#else
|
||||||
|
auto window = Engine::MainWindow;
|
||||||
|
#endif
|
||||||
|
Float2 position = window->ScreenToClient(screenPosition);
|
||||||
|
SDL_WarpMouseInWindow(static_cast<SDLWindow*>(window)->_window, position.X, position.Y);
|
||||||
|
|
||||||
|
OnMouseMoved(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetRelativeMode(bool relativeMode, Window* window) final override
|
void SetRelativeMode(bool relativeMode, Window* window) final override
|
||||||
@@ -384,19 +402,29 @@ public:
|
|||||||
if (relativeMode == _relativeMode)
|
if (relativeMode == _relativeMode)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto sdlWindow = static_cast<SDLWindow*>(window)->GetSDLWindow();
|
auto windowHandle = static_cast<SDLWindow*>(window)->_window;
|
||||||
if (relativeMode)
|
if (relativeMode)
|
||||||
|
{
|
||||||
|
oldScreenRect = SDL_GetWindowMouseRect(windowHandle);
|
||||||
|
relativeModeWindow = window;
|
||||||
SDL_GetMouseState(&oldPosition.X, &oldPosition.Y);
|
SDL_GetMouseState(&oldPosition.X, &oldPosition.Y);
|
||||||
|
if (!SDL_CursorVisible())
|
||||||
|
{
|
||||||
|
// Trap the cursor in current location
|
||||||
|
SDL_Rect clipRect = { (int)oldPosition.X, (int)oldPosition.Y, 1, 1 };
|
||||||
|
SDL_SetWindowMouseRect(windowHandle, &clipRect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SDL_SetWindowMouseRect(windowHandle, oldScreenRect);
|
||||||
|
oldScreenRect = nullptr;
|
||||||
|
relativeModeWindow = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
Mouse::SetRelativeMode(relativeMode, window);
|
Mouse::SetRelativeMode(relativeMode, window);
|
||||||
if (!SDL_SetWindowRelativeMouseMode(sdlWindow, relativeMode))
|
if (!SDL_SetWindowRelativeMouseMode(windowHandle, relativeMode))
|
||||||
LOG(Error, "Failed to set mouse relative mode: {0}", String(SDL_GetError()));
|
LOG(Error, "Failed to set mouse relative mode: {0}", String(SDL_GetError()));
|
||||||
|
|
||||||
if (!relativeMode)
|
|
||||||
{
|
|
||||||
SDL_WarpMouseInWindow(sdlWindow, oldPosition.X, oldPosition.Y);
|
|
||||||
OnMouseMoved(oldPosition);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ bool SDLPlatform::Init()
|
|||||||
|
|
||||||
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_WARP_MOTION, "0");
|
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_WARP_MOTION, "0");
|
||||||
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE, "1"); // Needed for tracking mode
|
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE, "1"); // Needed for tracking mode
|
||||||
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_CENTER, "1"); // Is this needed?
|
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_CENTER, "0"); //
|
||||||
|
|
||||||
//SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1"); // Disables raw mouse input
|
//SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1"); // Disables raw mouse input
|
||||||
SDL_SetHint(SDL_HINT_WINDOWS_RAW_KEYBOARD, "1");
|
SDL_SetHint(SDL_HINT_WINDOWS_RAW_KEYBOARD, "1");
|
||||||
|
|||||||
Reference in New Issue
Block a user