diff --git a/interface/resources/controllers/keyboardMouse.json b/interface/resources/controllers/keyboardMouse.json index 11c80a4dd2..a91151f4e5 100644 --- a/interface/resources/controllers/keyboardMouse.json +++ b/interface/resources/controllers/keyboardMouse.json @@ -3,9 +3,9 @@ "channels": [ { "from": "Keyboard.A", "when": ["Keyboard.RightMouseButton", "!Keyboard.Control"], "to": "Actions.LATERAL_LEFT" }, { "from": "Keyboard.D", "when": ["Keyboard.RightMouseButton", "!Keyboard.Control"], "to": "Actions.LATERAL_RIGHT" }, - { "from": "Keyboard.E", "when": ["!Application.CameraSelfie", "!Keyboard.Control"], "to": "Actions.LATERAL_RIGHT" }, - { "from": "Keyboard.Q", "when": ["!Application.CameraSelfie", "!Keyboard.Control"], "to": "Actions.LATERAL_LEFT" }, + { "from": "Keyboard.Q", "when": ["!Application.CameraSelfie", "!Keyboard.Control", "!Application.CaptureMouse"], "to": "Actions.LATERAL_LEFT" }, { "from": "Keyboard.Q", "when": ["Application.CameraSelfie", "!Keyboard.Control"], "to": "Actions.LATERAL_RIGHT" }, + { "from": "Keyboard.E", "when": ["!Application.CameraSelfie", "!Keyboard.Control", "!Application.CaptureMouse"], "to": "Actions.LATERAL_RIGHT" }, { "from": "Keyboard.E", "when": ["Application.CameraSelfie", "!Keyboard.Control"], "to": "Actions.LATERAL_LEFT" }, { "from": "Keyboard.T", "when": "!Keyboard.Control", "to": "Actions.TogglePushToTalk" }, @@ -72,46 +72,20 @@ { "from": { "makeAxis" : [ ["Keyboard.Left"], ["Keyboard.Right"] - ] + ] }, - "when": ["Application.CameraFirstPerson", "!Keyboard.Shift"], + "when": ["!Application.CameraFSM", "!Application.CameraIndependent", "!Application.CameraEntity", "!Application.CaptureMouse", "!Keyboard.Shift"], "to": "Actions.Yaw" }, - { "from": { "makeAxis" : [ - ["Keyboard.Left"], - ["Keyboard.Right"] - ] - }, - "when": ["Application.CameraFirstPersonLookat", "!Keyboard.Shift"], - "to": "Actions.Yaw" + { "from": "Keyboard.Left", + "when": ["!Application.CameraFSM", "!Application.CameraIndependent", "!Application.CameraEntity", "Application.CaptureMouse", "!Keyboard.Shift"], + "to": "Actions.LATERAL_LEFT" }, - { "from": { "makeAxis" : [ - ["Keyboard.Left"], - ["Keyboard.Right"] - ] - }, - "when": ["Application.CameraThirdPerson", "!Keyboard.Shift"], - "to": "Actions.Yaw" - }, - - { "from": { "makeAxis" : [ - ["Keyboard.Left"], - ["Keyboard.Right"] - ] - }, - "when": ["Application.CameraLookAt", "!Keyboard.Shift"], - "to": "Actions.Yaw" - }, - - { "from": { "makeAxis" : [ - ["Keyboard.Left"], - ["Keyboard.Right"] - ] - }, - "when": ["Application.CameraSelfie", "!Keyboard.Shift"], - "to": "Actions.Yaw" + { "from": "Keyboard.Right", + "when": ["!Application.CameraFSM", "!Application.CameraIndependent", "!Application.CameraEntity", "Application.CaptureMouse", "!Keyboard.Shift"], + "to": "Actions.LATERAL_RIGHT" }, { "from": { "makeAxis" : [ @@ -119,53 +93,18 @@ ["Keyboard.D"] ] }, - "when": ["Application.CameraFirstPerson", "!Keyboard.Control"], + "when": ["!Application.CameraFSM", "!Application.CameraIndependent", "!Application.CameraEntity", "!Application.CaptureMouse", "!Keyboard.Control"], "to": "Actions.Yaw" }, - { "from": { "makeAxis" : [ - ["Keyboard.A"], - ["Keyboard.D"] - ] - }, - "when": ["Application.CameraFirstPersonLookat", "!Keyboard.Control"], - "to": "Actions.Yaw" + { "from": "Keyboard.A", + "when": ["!Application.CameraFSM", "!Application.CameraIndependent", "!Application.CameraEntity", "Application.CaptureMouse", "!Keyboard.Control"], + "to": "Actions.LATERAL_LEFT" }, - { "from": { "makeAxis" : [ - ["Keyboard.A"], - ["Keyboard.D"] - ] - }, - "when": ["Application.CameraThirdPerson", "!Keyboard.Control"], - "to": "Actions.Yaw" - }, - - { "from": { "makeAxis" : [ - ["Keyboard.A"], - ["Keyboard.D"] - ] - }, - "when": ["Application.CameraLookAt", "!Keyboard.Control"], - "to": "Actions.Yaw" - }, - - { "from": { "makeAxis" : [ - ["Keyboard.A"], - ["Keyboard.D"] - ] - }, - "when": ["Application.CameraSelfie", "!Keyboard.Control"], - "to": "Actions.Yaw" - }, - - { "from": { "makeAxis" : [ - ["Keyboard.TouchpadLeft"], - ["Keyboard.TouchpadRight"] - ] - }, - "when": "Application.CameraFirstPerson", - "to": "Actions.Yaw" + { "from": "Keyboard.D", + "when": ["!Application.CameraFSM", "!Application.CameraIndependent", "!Application.CameraEntity", "Application.CaptureMouse", "!Keyboard.Control"], + "to": "Actions.LATERAL_RIGHT" }, { "from": { "makeAxis" : [ @@ -173,39 +112,12 @@ ["Keyboard.TouchpadRight"] ] }, - "when": "Application.CameraFirstPersonLookat", - "to": "Actions.Yaw" - }, - - { "from": { "makeAxis" : [ - ["Keyboard.TouchpadLeft"], - ["Keyboard.TouchpadRight"] - ] - }, - "when": "Application.CameraThirdPerson", - "to": "Actions.Yaw" - }, - - { "from": { "makeAxis" : [ - ["Keyboard.TouchpadLeft"], - ["Keyboard.TouchpadRight"] - ] - }, - "when": "Application.CameraLookAt", - "to": "Actions.Yaw" - }, - - { "from": { "makeAxis" : [ - ["Keyboard.TouchpadLeft"], - ["Keyboard.TouchpadRight"] - ] - }, - "when": "Application.CameraSelfie", + "when": ["!Application.CameraFSM", "!Application.CameraIndependent", "!Application.CameraEntity"], "to": "Actions.Yaw" }, { "from": { "makeAxis" : ["Keyboard.MouseMoveLeft", "Keyboard.MouseMoveRight"] }, - "when": "Keyboard.RightMouseButton", + "when": ["Keyboard.RightMouseButton", "!Application.CaptureMouse"], "to": "Actions.DeltaYaw", "filters": [ @@ -213,8 +125,17 @@ ] }, + { "from": { "makeAxis" : ["Keyboard.MouseMoveLeft", "Keyboard.MouseMoveRight"] }, + "to": "Actions.DeltaYaw", + "when": "Application.CaptureMouse", + "filters": + [ + { "type": "scale", "scale": 0.2 } + ] + }, + { "from": { "makeAxis" : ["Keyboard.MouseMoveUp", "Keyboard.MouseMoveDown"] }, - "when": ["!Application.CameraSelfie", "!Application.CameraLookAt", "Keyboard.RightMouseButton"], + "when": ["!Application.CameraSelfie", "!Application.CameraLookAt", "!Application.CaptureMouse", "Keyboard.RightMouseButton"], "to": "Actions.DeltaPitch", "filters": [ @@ -222,6 +143,15 @@ ] }, + { "from": { "makeAxis" : ["Keyboard.MouseMoveUp", "Keyboard.MouseMoveDown"] }, + "to": "Actions.DeltaPitch", + "when": "Application.CaptureMouse", + "filters": + [ + { "type": "scale", "scale": 0.2 } + ] + }, + { "from": { "makeAxis" : ["Keyboard.MouseMoveUp", "Keyboard.MouseMoveDown"] }, "when": ["Application.CameraLookAt", "Keyboard.RightMouseButton"], "to": "Actions.DeltaPitch", diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4e6ed35d2c..b76e3f8dca 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -681,6 +681,9 @@ private: *
CameraIndependent
CameraEntity
InHMD
CaptureMouse
AdvancedMovement
StrafeEnabled
true
, the mouse is invisible and cannot leave the bounds of
+ * Interface, as long as Interface is the active window and no menu item is selected. When false
, the mouse
+ * behaves normally.
+ * @property {number} sensitivity - The current camera sensitivity. Must be positive.
*/
Q_PROPERTY(QUuid cameraEntity READ getCameraEntity WRITE setCameraEntity)
diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp
index 9f8a8ec013..79d9ebaa5c 100644
--- a/interface/src/ui/PreferencesDialog.cpp
+++ b/interface/src/ui/PreferencesDialog.cpp
@@ -358,6 +358,16 @@ void setupPreferences() {
preference->setItems(items);
preferences->addPreference(preference);
}
+ {
+ auto getter = [myAvatar]()->float { return qApp->getCamera().getSensitivity(); };
+ auto setter = [myAvatar](float value) { qApp->getCamera().setSensitivity(value); };
+ auto preference = new SpinnerSliderPreference(VR_MOVEMENT, "Camera Sensitivity", getter, setter);
+ preference->setMin(0.01f);
+ preference->setMax(5.0f);
+ preference->setStep(0.1);
+ preference->setDecimals(2);
+ preferences->addPreference(preference);
+ }
{
auto getter = [myAvatar]()->int { return myAvatar->getControlScheme(); };
auto setter = [myAvatar](int index) { myAvatar->setControlScheme(index); };
diff --git a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp
index a1138b3018..9b6946bbcc 100644
--- a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp
+++ b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp
@@ -1,6 +1,7 @@
//
// Created by Benjamin Arnold on 5/27/14.
// Copyright 2014 High Fidelity, Inc.
+// Copyright 2020 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@@ -213,7 +214,6 @@ void CompositorHelper::setAllowMouseCapture(bool capture) {
_allowMouseCapture = capture;
emit allowMouseCaptureChanged();
}
- _allowMouseCapture = capture;
}
void CompositorHelper::handleLeaveEvent() {
diff --git a/libraries/display-plugins/src/display-plugins/CompositorHelper.h b/libraries/display-plugins/src/display-plugins/CompositorHelper.h
index 1279050a57..c45119fd63 100644
--- a/libraries/display-plugins/src/display-plugins/CompositorHelper.h
+++ b/libraries/display-plugins/src/display-plugins/CompositorHelper.h
@@ -1,6 +1,7 @@
//
// Created by Bradley Austin Davis Arnold on 2015/06/13
// Copyright 2015 High Fidelity, Inc.
+// Copyright 2020 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp
index c436a5b510..c7c5543d44 100755
--- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp
+++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp
@@ -4,6 +4,7 @@
//
// Created by Sam Gateau on 4/27/15.
// Copyright 2015 High Fidelity, Inc.
+// Copyright 2020 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@@ -36,13 +37,12 @@ void KeyboardMouseDevice::pluginUpdate(float deltaTime, const controller::InputC
_inputDevice->_axisStateMap[MOUSE_AXIS_X].value = _lastCursor.x();
_inputDevice->_axisStateMap[MOUSE_AXIS_Y].value = _lastCursor.y();
- QPoint currentMove = _lastCursor - _previousCursor;
- updateDeltaAxisValue(MOUSE_AXIS_X_POS, currentMove.x() > 0 ? currentMove.x() : 0.0f);
- updateDeltaAxisValue(MOUSE_AXIS_X_NEG, currentMove.x() < 0 ? -currentMove.x() : 0.0f);
+ updateDeltaAxisValue(MOUSE_AXIS_X_POS, _accumulatedMove.x() > 0 ? _accumulatedMove.x() : 0.0f);
+ updateDeltaAxisValue(MOUSE_AXIS_X_NEG, _accumulatedMove.x() < 0 ? -_accumulatedMove.x() : 0.0f);
// Y mouse is inverted positive is pointing up the screen
- updateDeltaAxisValue(MOUSE_AXIS_Y_POS, currentMove.y() < 0 ? -currentMove.y() : 0.0f);
- updateDeltaAxisValue(MOUSE_AXIS_Y_NEG, currentMove.y() > 0 ? currentMove.y() : 0.0f);
- _previousCursor = _lastCursor;
+ updateDeltaAxisValue(MOUSE_AXIS_Y_POS, _accumulatedMove.y() < 0 ? -_accumulatedMove.y() : 0.0f);
+ updateDeltaAxisValue(MOUSE_AXIS_Y_NEG, _accumulatedMove.y() > 0 ? _accumulatedMove.y() : 0.0f);
+ _accumulatedMove = QPoint(0.0f, 0.0f);
});
// For touch event, we need to check that the last event is not too long ago
@@ -113,9 +113,16 @@ void KeyboardMouseDevice::eraseMouseClicked() {
_inputDevice->_buttonPressedMap.erase(_inputDevice->makeInput(Qt::RightButton, true).getChannel());
}
-void KeyboardMouseDevice::mouseMoveEvent(QMouseEvent* event) {
+void KeyboardMouseDevice::mouseMoveEvent(QMouseEvent* event, bool capture, QPointF captureTarget) {
QPoint currentPos = event->pos();
+ if (!capture) {
+ _accumulatedMove += currentPos - _lastCursor;
+ } else if (!isNaN(captureTarget.x())) {
+ QPointF change = event->globalPos() - captureTarget;
+ _accumulatedMove += QPoint(change.x(), change.y());
+ }
+
// FIXME - this has the characteristic that it will show large jumps when you move the cursor
// outside of the application window, because we don't get MouseEvents when the cursor is outside
// of the application window.
diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h
index 4286ced477..216194a712 100644
--- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h
+++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h
@@ -4,6 +4,7 @@
//
// Created by Sam Gateau on 4/27/15.
// Copyright 2015 High Fidelity, Inc.
+// Copyright 2020 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@@ -79,7 +80,7 @@ public:
void keyPressEvent(QKeyEvent* event);
void keyReleaseEvent(QKeyEvent* event);
- void mouseMoveEvent(QMouseEvent* event);
+ void mouseMoveEvent(QMouseEvent* event, bool capture, QPointF captureTarget);
void mousePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
void eraseMouseClicked();
@@ -123,7 +124,7 @@ public:
protected:
QPoint _lastCursor;
- QPoint _previousCursor;
+ QPoint _accumulatedMove;
QPoint _mousePressPos;
quint64 _mousePressTime;
qreal _lastTotalScaleFactor;
diff --git a/libraries/shared/src/shared/Camera.h b/libraries/shared/src/shared/Camera.h
index 48cd814d86..f494318c73 100644
--- a/libraries/shared/src/shared/Camera.h
+++ b/libraries/shared/src/shared/Camera.h
@@ -3,6 +3,7 @@
// interface/src
//
// Copyright 2013 High Fidelity, Inc.
+// Copyright 2020 Vircadia contributors.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@@ -43,6 +44,8 @@ class Camera : public QObject {
Q_PROPERTY(glm::quat orientation READ getOrientation WRITE setOrientation)
Q_PROPERTY(QString mode READ getModeString WRITE setModeString NOTIFY modeUpdated)
Q_PROPERTY(QVariantMap frustum READ getViewFrustum CONSTANT)
+ Q_PROPERTY(bool captureMouse READ getCaptureMouse WRITE setCaptureMouse NOTIFY captureMouseChanged)
+ Q_PROPERTY(float sensitivity READ getSensitivity WRITE setSensitivity)
public:
Camera();
@@ -110,6 +113,37 @@ public slots:
*/
void setOrientation(const glm::quat& orientation);
+ /**jsdoc
+ * Gets the current mouse capture state.
+ * @function Camera.getCaptureMouse
+ * @returns {boolean} true
if the mouse is captured (is invisible and cannot leave the bounds of Interface,
+ * if Interface is the active window and no menu item is selected), false
if the mouse is behaving normally.
+ */
+ bool getCaptureMouse() const { return _captureMouse; }
+
+ /**jsdoc
+ * Sets the mouse capture state. When true
, the mouse is invisible and cannot leave the bounds of
+ * Interface, as long as Interface is the active window and no menu item is selected. When false
, the mouse
+ * behaves normally.
+ * @function Camera.setCaptureMouse
+ * @param {boolean} captureMouse - true
to capture the mouse, false
to release the mouse.
+ */
+ void setCaptureMouse(bool captureMouse) { _captureMouse = captureMouse; emit captureMouseChanged(captureMouse); }
+
+ /**jsdoc
+ * Gets the current camera sensitivity.
+ * @function Camera.getSensitivity
+ * @returns {number} The current camera sensitivity. Must be positive.
+ */
+ float getSensitivity() const { return _sensitivity; }
+
+ /**jsdoc
+ * Sets the camera sensitivity. Higher values mean that the camera will be more sensitive to mouse movements.
+ * @function Camera.setSensitivity
+ * @param {number} sensitivity - The desired camera sensitivity. Must be positive.
+ */
+ void setSensitivity(float sensitivity) { _sensitivity = glm::max(0.0f, sensitivity); }
+
/**jsdoc
* Computes a {@link PickRay} based on the current camera configuration and the specified x, y
position on the
* screen. The {@link PickRay} can be used in functions such as {@link Entities.findRayIntersection} and
@@ -181,6 +215,20 @@ signals:
*/
void modeUpdated(const QString& newMode);
+ /**jsdoc
+ * Triggered when the camera mouse capture state changes.
+ * @function Camera.captureMouseChanged
+ * @param {boolean} newCaptureMouse - The new mouse capture state.
+ * @returns {Signal}
+ * @example