mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-07 18:02:31 +02:00
Merge pull request #16505 from luiscuenca/zoomAndOrbitCamUsingTouchPad
Touchpad improvements: pinch to zoom camera, two finger swipe to look around, bug fixes
This commit is contained in:
commit
3b9c997317
4 changed files with 103 additions and 8 deletions
|
@ -269,6 +269,8 @@
|
|||
{ "from": "Keyboard.MouseWheelDown", "to": "Actions.LATERAL_LEFT" },
|
||||
{ "from": "Keyboard.MouseWheelLeft", "to": "Actions.BOOM_OUT", "filters": [ { "type": "scale", "scale": 0.02 } ]},
|
||||
{ "from": "Keyboard.MouseWheelRight", "to": "Actions.BOOM_IN", "filters": [ { "type": "scale", "scale": 0.02 } ]},
|
||||
{ "from": "Keyboard.GesturePinchOut", "to": "Actions.BOOM_OUT"},
|
||||
{ "from": "Keyboard.GesturePinchIn", "to": "Actions.BOOM_IN"},
|
||||
|
||||
{ "from": "Keyboard.Space", "to": "Actions.VERTICAL_UP" },
|
||||
{ "from": "Keyboard.R", "to": "Actions.ACTION1" },
|
||||
|
|
|
@ -4871,6 +4871,9 @@ void Application::touchEndEvent(QTouchEvent* event) {
|
|||
}
|
||||
|
||||
void Application::touchGestureEvent(QGestureEvent* event) {
|
||||
if (_keyboardMouseDevice->isActive()) {
|
||||
_keyboardMouseDevice->touchGestureEvent(event);
|
||||
}
|
||||
if (_touchscreenDevice && _touchscreenDevice->isActive()) {
|
||||
_touchscreenDevice->touchGestureEvent(event);
|
||||
}
|
||||
|
@ -6262,7 +6265,7 @@ void Application::update(float deltaTime) {
|
|||
myAvatar->setDriveKey(MyAvatar::TRANSLATE_Z, -1.0f * userInputMapper->getActionState(controller::Action::TRANSLATE_Z));
|
||||
myAvatar->setDriveKey(MyAvatar::TRANSLATE_Y, userInputMapper->getActionState(controller::Action::TRANSLATE_Y));
|
||||
myAvatar->setDriveKey(MyAvatar::TRANSLATE_X, userInputMapper->getActionState(controller::Action::TRANSLATE_X));
|
||||
if (deltaTime > FLT_EPSILON) {
|
||||
if (deltaTime > FLT_EPSILON && userInputMapper->getActionState(controller::Action::TRANSLATE_CAMERA_Z) == 0.0f) {
|
||||
myAvatar->setDriveKey(MyAvatar::PITCH, -1.0f * userInputMapper->getActionState(controller::Action::PITCH));
|
||||
myAvatar->setDriveKey(MyAvatar::YAW, -1.0f * userInputMapper->getActionState(controller::Action::YAW));
|
||||
myAvatar->setDriveKey(MyAvatar::DELTA_PITCH, -1.0f * userInputMapper->getActionState(controller::Action::DELTA_PITCH));
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <QtGui/QKeyEvent>
|
||||
#include <QtGui/QMouseEvent>
|
||||
#include <QtGui/QTouchEvent>
|
||||
#include <QGesture>
|
||||
|
||||
#include <controllers/UserInputMapper.h>
|
||||
#include <PathUtils.h>
|
||||
|
@ -126,12 +127,60 @@ void KeyboardMouseDevice::mouseMoveEvent(QMouseEvent* event) {
|
|||
}
|
||||
}
|
||||
|
||||
void KeyboardMouseDevice::wheelEvent(QWheelEvent* event) {
|
||||
auto currentMove = event->angleDelta() / 120.0f;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_X_POS).getChannel()].value = currentMove.x() > 0 ? currentMove.x() : 0;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_X_NEG).getChannel()].value = currentMove.x() < 0 ? -currentMove.x() : 0;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_Y_POS).getChannel()].value = currentMove.y() > 0 ? currentMove.y() : 0;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_Y_NEG).getChannel()].value = currentMove.y() < 0 ? -currentMove.y() : 0;
|
||||
bool KeyboardMouseDevice::isWheelByTouchPad(QWheelEvent* event) {
|
||||
// This function is only used to track two finger swipe using the touchPad on Windows.
|
||||
// That gesture gets sent as a wheel event. This wheel delta values are used to orbit the camera.
|
||||
// On MacOS the two finger swipe fires touch events and wheel events.
|
||||
// In that case we always return false to avoid interference between both.
|
||||
#ifdef Q_OS_MAC
|
||||
return false;
|
||||
#endif
|
||||
QPoint delta = event->angleDelta();
|
||||
int deltaValueX = abs(delta.x());
|
||||
int deltaValueY = abs(delta.y());
|
||||
const int MAX_WHEEL_DELTA_REPEAT = 20;
|
||||
const int COMMON_WHEEL_DELTA_VALUE = 120;
|
||||
if (deltaValueX != 0) {
|
||||
if (abs(_lastWheelDelta.x()) == deltaValueX) {
|
||||
_wheelDeltaRepeatCount.setX(_wheelDeltaRepeatCount.x() + 1);
|
||||
} else {
|
||||
_wheelDeltaRepeatCount.setX(0);
|
||||
}
|
||||
return deltaValueX != COMMON_WHEEL_DELTA_VALUE && _wheelDeltaRepeatCount.x() < MAX_WHEEL_DELTA_REPEAT;
|
||||
}
|
||||
if (deltaValueY != 0) {
|
||||
if (abs(_lastWheelDelta.y()) == deltaValueY) {
|
||||
_wheelDeltaRepeatCount.setY(_wheelDeltaRepeatCount.y() + 1);
|
||||
} else {
|
||||
_wheelDeltaRepeatCount.setY(0);
|
||||
}
|
||||
return deltaValueY != COMMON_WHEEL_DELTA_VALUE && _wheelDeltaRepeatCount.y() < MAX_WHEEL_DELTA_REPEAT;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void KeyboardMouseDevice::wheelEvent(QWheelEvent* event) {
|
||||
if (isWheelByTouchPad(event)) {
|
||||
// Check for horizontal and vertical scroll not triggered by the mouse.
|
||||
// These are most likelly triggered by two fingers gesture on touchpad for windows.
|
||||
QPoint delta = event->angleDelta();
|
||||
float deltaX = (float)delta.x();
|
||||
float deltaY = (float)delta.y();
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_POS).getChannel()].value = (deltaX > 0 ? deltaX : 0.0f);
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_NEG).getChannel()].value = (deltaX < 0 ? -deltaX : 0.0f);
|
||||
// Y mouse is inverted positive is pointing up the screen
|
||||
const float WHEEL_Y_ATTENUATION = 0.02f;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_POS).getChannel()].value = (deltaY < 0 ? -WHEEL_Y_ATTENUATION * deltaY : 0.0f);
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_NEG).getChannel()].value = (deltaY > 0 ? WHEEL_Y_ATTENUATION * deltaY : 0.0f);
|
||||
} else {
|
||||
auto currentMove = event->angleDelta() / 120.0f;
|
||||
float currentMoveX = (float)currentMove.x();
|
||||
float currentMoveY = (float)currentMove.y();
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_X_POS).getChannel()].value = currentMoveX > 0 ? currentMoveX : 0.0f;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_X_NEG).getChannel()].value = currentMoveX < 0 ? -currentMoveX : 0.0f;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_Y_POS).getChannel()].value = currentMoveY > 0 ? currentMoveY : 0.0f;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_Y_NEG).getChannel()].value = currentMoveY < 0 ? -currentMoveY : 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec2 evalAverageTouchPoints(const QList<QTouchEvent::TouchPoint>& points) {
|
||||
|
@ -145,6 +194,37 @@ glm::vec2 evalAverageTouchPoints(const QList<QTouchEvent::TouchPoint>& points) {
|
|||
return averagePoint;
|
||||
}
|
||||
|
||||
void KeyboardMouseDevice::touchGestureEvent(const QGestureEvent* event) {
|
||||
QPinchGesture* pinchGesture = (QPinchGesture*) event->gesture(Qt::PinchGesture);
|
||||
|
||||
if (pinchGesture) {
|
||||
switch (pinchGesture->state()) {
|
||||
case Qt::GestureStarted:
|
||||
_lastTotalScaleFactor = pinchGesture->totalScaleFactor();
|
||||
break;
|
||||
|
||||
case Qt::GestureUpdated: {
|
||||
const float PINCH_DELTA_STEP = 0.04f;
|
||||
qreal totalScaleFactor = pinchGesture->totalScaleFactor();
|
||||
qreal scaleFactorDelta = _lastTotalScaleFactor - totalScaleFactor;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_POS).getChannel()].value = scaleFactorDelta > 0.0 ? PINCH_DELTA_STEP : 0.0f;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_NEG).getChannel()].value = scaleFactorDelta < 0.0 ? PINCH_DELTA_STEP : 0.0f;
|
||||
_lastTotalScaleFactor = totalScaleFactor;
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::GestureFinished: {
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_POS).getChannel()].value = 0.0f;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_NEG).getChannel()].value = 0.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KeyboardMouseDevice::touchBeginEvent(const QTouchEvent* event) {
|
||||
if (_enableTouch) {
|
||||
_isTouching = event->touchPointStates().testFlag(Qt::TouchPointPressed);
|
||||
|
@ -167,7 +247,7 @@ void KeyboardMouseDevice::touchUpdateEvent(const QTouchEvent* event) {
|
|||
_lastTouchTime = _clock.now();
|
||||
|
||||
if (!_isTouching) {
|
||||
_isTouching = event->touchPointStates().testFlag(Qt::TouchPointPressed);
|
||||
_isTouching = true;
|
||||
} else {
|
||||
auto currentMove = currentPos - _lastTouch;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_POS).getChannel()].value = (currentMove.x > 0 ? currentMove.x : 0.0f);
|
||||
|
@ -344,6 +424,8 @@ controller::Input::NamedVector KeyboardMouseDevice::InputDevice::getAvailableInp
|
|||
availableInputs.append(Input::NamedPair(makeInput(TOUCH_AXIS_X_NEG), "TouchpadLeft"));
|
||||
availableInputs.append(Input::NamedPair(makeInput(TOUCH_AXIS_Y_POS), "TouchpadUp"));
|
||||
availableInputs.append(Input::NamedPair(makeInput(TOUCH_AXIS_Y_NEG), "TouchpadDown"));
|
||||
availableInputs.append(Input::NamedPair(makeInput(TOUCH_GESTURE_PINCH_POS), "GesturePinchOut"));
|
||||
availableInputs.append(Input::NamedPair(makeInput(TOUCH_GESTURE_PINCH_NEG), "GesturePinchIn"));
|
||||
});
|
||||
return availableInputs;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ class QTouchEvent;
|
|||
class QKeyEvent;
|
||||
class QMouseEvent;
|
||||
class QWheelEvent;
|
||||
class QGestureEvent;
|
||||
|
||||
class KeyboardMouseDevice : public InputPlugin {
|
||||
Q_OBJECT
|
||||
|
@ -60,6 +61,8 @@ public:
|
|||
TOUCH_AXIS_X_NEG,
|
||||
TOUCH_AXIS_Y_POS,
|
||||
TOUCH_AXIS_Y_NEG,
|
||||
TOUCH_GESTURE_PINCH_POS,
|
||||
TOUCH_GESTURE_PINCH_NEG,
|
||||
};
|
||||
|
||||
enum TouchButtonChannel {
|
||||
|
@ -81,11 +84,13 @@ public:
|
|||
void mouseReleaseEvent(QMouseEvent* event);
|
||||
void eraseMouseClicked();
|
||||
|
||||
void touchGestureEvent(const QGestureEvent* event);
|
||||
void touchBeginEvent(const QTouchEvent* event);
|
||||
void touchEndEvent(const QTouchEvent* event);
|
||||
void touchUpdateEvent(const QTouchEvent* event);
|
||||
|
||||
void wheelEvent(QWheelEvent* event);
|
||||
bool isWheelByTouchPad(QWheelEvent* event);
|
||||
|
||||
static void enableTouch(bool enableTouch) { _enableTouch = enableTouch; }
|
||||
|
||||
|
@ -121,6 +126,7 @@ protected:
|
|||
QPoint _previousCursor;
|
||||
QPoint _mousePressPos;
|
||||
quint64 _mousePressTime;
|
||||
qreal _lastTotalScaleFactor;
|
||||
bool _clickDeadspotActive;
|
||||
glm::vec2 _lastTouch;
|
||||
std::shared_ptr<InputDevice> _inputDevice { std::make_shared<InputDevice>() };
|
||||
|
@ -130,6 +136,8 @@ protected:
|
|||
std::chrono::high_resolution_clock::time_point _lastTouchTime;
|
||||
|
||||
static bool _enableTouch;
|
||||
QPoint _lastWheelDelta;
|
||||
QPoint _wheelDeltaRepeatCount;
|
||||
|
||||
private:
|
||||
void updateDeltaAxisValue(int channel, float value);
|
||||
|
|
Loading…
Reference in a new issue