diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 64020355d8..73816571fa 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -89,11 +89,14 @@ protected: virtual void mousePressEvent(QMouseEvent* event); virtual void mouseReleaseEvent(QMouseEvent* event); + virtual bool event(QEvent* event); + virtual void wheelEvent(QWheelEvent* event); }; void GLCanvas::initializeGL() { Application::getInstance()->initializeGL(); + setAttribute(Qt::WA_AcceptTouchEvents); } void GLCanvas::paintGL() { @@ -124,6 +127,25 @@ void GLCanvas::mouseReleaseEvent(QMouseEvent* event) { Application::getInstance()->mouseReleaseEvent(event); } +int updateTime = 0; +bool GLCanvas::event(QEvent* event) { + switch (event->type()) { + case QEvent::TouchBegin: + Application::getInstance()->touchBeginEvent(static_cast(event)); + event->accept(); + return true; + case QEvent::TouchEnd: + Application::getInstance()->touchEndEvent(static_cast(event)); + return true; + case QEvent::TouchUpdate: + Application::getInstance()->touchUpdateEvent(static_cast(event)); + return true; + default: + break; + } + return QGLWidget::event(event); +} + void GLCanvas::wheelEvent(QWheelEvent* event) { Application::getInstance()->wheelEvent(event); } @@ -146,6 +168,9 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _audioScope(256, 200, true), _mouseX(0), _mouseY(0), + _touchAvgX(0.0f), + _touchAvgY(0.0f), + _isTouchPressed(false), _mousePressed(false), _mouseVoxelScale(1.0f / 1024.0f), _justEditedVoxel(false), @@ -754,6 +779,40 @@ void Application::mouseReleaseEvent(QMouseEvent* event) { } } +void Application::touchUpdateEvent(QTouchEvent* event) { + bool validTouch = false; + if (activeWindow() == _window) { + const QList& tPoints = event->touchPoints(); + _touchAvgX = 0.0f; + _touchAvgY = 0.0f; + int numTouches = tPoints.count(); + if (numTouches > 1) { + for (int i = 0; i < numTouches; ++i) { + _touchAvgX += tPoints[i].pos().x(); + _touchAvgY += tPoints[i].pos().y(); + } + _touchAvgX /= (float)(numTouches); + _touchAvgY /= (float)(numTouches); + validTouch = true; + } + } + if (!_isTouchPressed) { + _touchDragStartedAvgX = _touchAvgX; + _touchDragStartedAvgY = _touchAvgY; + } + _isTouchPressed = validTouch; +} + +void Application::touchBeginEvent(QTouchEvent* event) { + touchUpdateEvent(event); +} + +void Application::touchEndEvent(QTouchEvent* event) { + _touchDragStartedAvgX = _touchAvgX; + _touchDragStartedAvgY = _touchAvgY; + _isTouchPressed = false; +} + void Application::wheelEvent(QWheelEvent* event) { if (activeWindow() == _window) { if (checkedVoxelModeAction() == 0) { @@ -1256,6 +1315,8 @@ void Application::initMenu() { _gyroLook->setChecked(false); (_mouseLook = optionsMenu->addAction("Mouse Look"))->setCheckable(true); _mouseLook->setChecked(true); + (_touchLook = optionsMenu->addAction("Touch Look"))->setCheckable(true); + _touchLook->setChecked(false); (_showHeadMouse = optionsMenu->addAction("Head Mouse"))->setCheckable(true); _showHeadMouse->setChecked(false); (_transmitterDrives = optionsMenu->addAction("Transmitter Drive"))->setCheckable(true); @@ -1581,6 +1642,12 @@ void Application::update(float deltaTime) { _glWidget->height()); } + // Update from Touch + if (_isTouchPressed && _touchLook->isChecked()) { + _myAvatar.updateFromTouch(_touchAvgX - _touchDragStartedAvgX, + _touchAvgY - _touchDragStartedAvgY); + } + // Read serial port interface devices if (_serialHeadSensor.isActive()) { _serialHeadSensor.readData(deltaTime); diff --git a/interface/src/Application.h b/interface/src/Application.h index b7211187de..06d48b9b4f 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -66,6 +67,10 @@ public: void mousePressEvent(QMouseEvent* event); void mouseReleaseEvent(QMouseEvent* event); + void touchBeginEvent(QTouchEvent* event); + void touchEndEvent(QTouchEvent* event); + void touchUpdateEvent(QTouchEvent* event); + void wheelEvent(QWheelEvent* event); const glm::vec3 getMouseVoxelWorldCoordinates(const VoxelDetail _mouseVoxel); @@ -183,6 +188,7 @@ private: QAction* _gyroLook; // Whether to allow the gyro data from head to move your view QAction* _renderAvatarBalls; // Switch between voxels and joints/balls for avatar render QAction* _mouseLook; // Whether the have the mouse near edge of screen move your view + QAction* _touchLook; // Whether a 2-finger touch may be used to control look direction QAction* _showHeadMouse; // Whether the have the mouse near edge of screen move your view QAction* _transmitterDrives; // Whether to have Transmitter data move/steer the Avatar QAction* _gravityUse; // Whether gravity is on or not @@ -268,6 +274,13 @@ private: int _mouseY; int _mouseDragStartedX; int _mouseDragStartedY; + + float _touchAvgX; + float _touchAvgY; + float _touchDragStartedAvgX; + float _touchDragStartedAvgY; + bool _isTouchPressed; // true if multitouch has been pressed (clear when finished) + VoxelDetail _mouseVoxelDragging; glm::vec3 _voxelThrust; bool _mousePressed; // true if mouse has been pressed (clear when finished) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index ab4417a927..dc8e1dbc40 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -350,6 +350,14 @@ void Avatar::updateFromMouse(int mouseX, int mouseY, int screenWidth, int scree } } +void Avatar::updateFromTouch(float touchAvgDistX, float touchAvgDistY) { + const float TOUCH_ROTATE_SPEED = 0.01f; + const float TOUCH_PITCH_SPEED = 0.02f; + + _head.addYaw(-touchAvgDistX * TOUCH_ROTATE_SPEED); + _head.addPitch(-touchAvgDistY * TOUCH_PITCH_SPEED); +} + void Avatar::updateThrust(float deltaTime, Transmitter * transmitter) { // // Gather thrust information from keyboard and sensors to apply to avatar motion diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index aefeb91187..b7d424de29 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -88,6 +88,7 @@ public: void updateThrust(float deltaTime, Transmitter * transmitter); void updateHeadFromGyrosAndOrWebcam(); void updateFromMouse(int mouseX, int mouseY, int screenWidth, int screenHeight); + void updateFromTouch(float touchAvgDistX, float touchAvgDistY); void addBodyYaw(float y) {_bodyYaw += y;}; void render(bool lookingInMirror, bool renderAvatarBalls);