|
@@ -87,6 +87,7 @@ UIElement* TouchState::GetTouchedElement()
|
|
|
* - The OS mouse cursor position can't be set.
|
|
* - The OS mouse cursor position can't be set.
|
|
|
* - The mouse can be trapped within play area via 'PointerLock API', which requires a request and interaction between the user and browser.
|
|
* - The mouse can be trapped within play area via 'PointerLock API', which requires a request and interaction between the user and browser.
|
|
|
* - To request mouse lock, call SetMouseMode(MM_RELATIVE). The E_MOUSEMODECHANGED event will be sent if/when the user confirms the request.
|
|
* - To request mouse lock, call SetMouseMode(MM_RELATIVE). The E_MOUSEMODECHANGED event will be sent if/when the user confirms the request.
|
|
|
|
|
+ * NOTE: The request must be initiated by the user (eg: on mouse button down/up, key down/up).
|
|
|
* - The user can press 'escape' key and browser will force user out of pointer lock. Urho will send the E_MOUSEMODECHANGED event.
|
|
* - The user can press 'escape' key and browser will force user out of pointer lock. Urho will send the E_MOUSEMODECHANGED event.
|
|
|
* - SetMouseMode(MM_ABSOLUTE) will leave pointer lock.
|
|
* - SetMouseMode(MM_ABSOLUTE) will leave pointer lock.
|
|
|
* - MM_WRAP is unsupported.
|
|
* - MM_WRAP is unsupported.
|
|
@@ -110,10 +111,15 @@ public:
|
|
|
/// Send request to user to gain pointer lock.
|
|
/// Send request to user to gain pointer lock.
|
|
|
void RequestPointerLock();
|
|
void RequestPointerLock();
|
|
|
void ExitPointerLock();
|
|
void ExitPointerLock();
|
|
|
|
|
+
|
|
|
|
|
+private:
|
|
|
|
|
+ /// Instance of Input subsystem that constructed this instance.
|
|
|
|
|
+ Input* inputInst_;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
EmscriptenInput::EmscriptenInput(Input* inputInst)
|
|
EmscriptenInput::EmscriptenInput(Input* inputInst)
|
|
|
{
|
|
{
|
|
|
|
|
+ inputInst_ = inputInst;
|
|
|
emscripten_set_pointerlockchange_callback(NULL, (void*)inputInst, false, EmscriptenInput::PointerLockCallback);
|
|
emscripten_set_pointerlockchange_callback(NULL, (void*)inputInst, false, EmscriptenInput::PointerLockCallback);
|
|
|
|
|
|
|
|
// Handle focus changes:
|
|
// Handle focus changes:
|
|
@@ -128,6 +134,7 @@ void EmscriptenInput::RequestPointerLock()
|
|
|
|
|
|
|
|
void EmscriptenInput::ExitPointerLock()
|
|
void EmscriptenInput::ExitPointerLock()
|
|
|
{
|
|
{
|
|
|
|
|
+ inputInst_->emscriptenExitingPointerLock_ = true;
|
|
|
emscripten_exit_pointerlock();
|
|
emscripten_exit_pointerlock();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -137,13 +144,12 @@ EM_BOOL EmscriptenInput::PointerLockCallback(int eventType, const EmscriptenPoin
|
|
|
if (keyEvent->isActive > 0)
|
|
if (keyEvent->isActive > 0)
|
|
|
{
|
|
{
|
|
|
// Pointer Lock is now active
|
|
// Pointer Lock is now active
|
|
|
- inputInst->SetMouseVisibleEmscripten(false);
|
|
|
|
|
|
|
+ inputInst->emscriptenEnteredPointerLock_ = true;
|
|
|
inputInst->SetMouseModeEmscripten(MM_RELATIVE);
|
|
inputInst->SetMouseModeEmscripten(MM_RELATIVE);
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
// Pointer Lock is now inactive
|
|
// Pointer Lock is now inactive
|
|
|
- inputInst->SetMouseVisibleEmscripten(true);
|
|
|
|
|
inputInst->SetMouseModeEmscripten(MM_ABSOLUTE);
|
|
inputInst->SetMouseModeEmscripten(MM_ABSOLUTE);
|
|
|
}
|
|
}
|
|
|
return 1;
|
|
return 1;
|
|
@@ -200,6 +206,10 @@ Input::Input(Context* context) :
|
|
|
lastMouseVisible_(false),
|
|
lastMouseVisible_(false),
|
|
|
mouseGrabbed_(false),
|
|
mouseGrabbed_(false),
|
|
|
mouseMode_(MM_ABSOLUTE),
|
|
mouseMode_(MM_ABSOLUTE),
|
|
|
|
|
+#ifdef EMSCRIPTEN
|
|
|
|
|
+ emscriptenExitingPointerLock_(false),
|
|
|
|
|
+ emscriptenEnteredPointerLock_(false),
|
|
|
|
|
+#endif
|
|
|
lastVisibleMousePosition_(MOUSE_POSITION_OFFSCREEN),
|
|
lastVisibleMousePosition_(MOUSE_POSITION_OFFSCREEN),
|
|
|
touchEmulation_(false),
|
|
touchEmulation_(false),
|
|
|
inputFocus_(false),
|
|
inputFocus_(false),
|
|
@@ -325,6 +335,16 @@ void Input::Update()
|
|
|
#else
|
|
#else
|
|
|
if (!window)
|
|
if (!window)
|
|
|
return;
|
|
return;
|
|
|
|
|
+
|
|
|
|
|
+ if (emscriptenExitingPointerLock_)
|
|
|
|
|
+ {
|
|
|
|
|
+ // Suppress mouse jump when exiting Pointer Lock
|
|
|
|
|
+ IntVector2 mousePosition = GetMousePosition();
|
|
|
|
|
+ mouseMove_ = IntVector2::ZERO;
|
|
|
|
|
+ lastMousePosition_ = lastVisibleMousePosition_;
|
|
|
|
|
+ emscriptenExitingPointerLock_ = false;
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
// Check for relative mode mouse move
|
|
// Check for relative mode mouse move
|
|
@@ -485,6 +505,15 @@ void Input::SetMouseVisibleEmscripten(bool enable)
|
|
|
void Input::SetMouseModeEmscripten(MouseMode mode)
|
|
void Input::SetMouseModeEmscripten(MouseMode mode)
|
|
|
{
|
|
{
|
|
|
mouseMode_ = mode;
|
|
mouseMode_ = mode;
|
|
|
|
|
+
|
|
|
|
|
+ if (mode == MM_RELATIVE)
|
|
|
|
|
+ {
|
|
|
|
|
+ SetMouseVisibleEmscripten(false);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ ResetMouseVisible();
|
|
|
|
|
+ }
|
|
|
suppressNextMouseMove_ = true;
|
|
suppressNextMouseMove_ = true;
|
|
|
|
|
|
|
|
VariantMap& eventData = GetEventDataMap();
|
|
VariantMap& eventData = GetEventDataMap();
|
|
@@ -509,10 +538,10 @@ void Input::SetMouseMode(MouseMode mode)
|
|
|
// Handle changing away from previous mode
|
|
// Handle changing away from previous mode
|
|
|
if (previousMode == MM_RELATIVE)
|
|
if (previousMode == MM_RELATIVE)
|
|
|
{
|
|
{
|
|
|
|
|
+ #ifndef EMSCRIPTEN
|
|
|
/// \todo Use SDL_SetRelativeMouseMode() for MM_RELATIVE mode
|
|
/// \todo Use SDL_SetRelativeMouseMode() for MM_RELATIVE mode
|
|
|
ResetMouseVisible();
|
|
ResetMouseVisible();
|
|
|
-
|
|
|
|
|
- #ifdef EMSCRIPTEN
|
|
|
|
|
|
|
+ #else
|
|
|
emscriptenInput_->ExitPointerLock();
|
|
emscriptenInput_->ExitPointerLock();
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
@@ -1332,6 +1361,18 @@ void Input::SetMouseButton(int button, bool newState)
|
|
|
}
|
|
}
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
|
|
+#ifdef EMSCRIPTEN
|
|
|
|
|
+ if (emscriptenEnteredPointerLock_)
|
|
|
|
|
+ {
|
|
|
|
|
+ // Suppress mouse jump on initial Pointer Lock
|
|
|
|
|
+ IntVector2 mousePosition = GetMousePosition();
|
|
|
|
|
+ lastMousePosition_ = mousePosition;
|
|
|
|
|
+ mouseMove_ = IntVector2::ZERO;
|
|
|
|
|
+ suppressNextMouseMove_ = true;
|
|
|
|
|
+ emscriptenEnteredPointerLock_ = false;
|
|
|
|
|
+ }
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
// If we do not have focus yet, do not react to the mouse button down
|
|
// If we do not have focus yet, do not react to the mouse button down
|
|
|
if (!graphics_->GetExternalWindow() && newState && !inputFocus_)
|
|
if (!graphics_->GetExternalWindow() && newState && !inputFocus_)
|
|
|
return;
|
|
return;
|