From fde01e094e34cb76e3b8aa9e1b613204c8d26d53 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Wed, 27 Jan 2016 17:47:36 +0000 Subject: [PATCH 01/32] integrate touch screen camera manipulation controls Set Avatar _driveKeys via touch manipulation --- interface/src/Application.cpp | 52 +++++++++++++++++++++++++++++++++-- interface/src/Application.h | 2 ++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c202331041..496c1c4278 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2343,6 +2343,7 @@ void Application::touchBeginEvent(QTouchEvent* event) { TouchEvent thisEvent(*event); // on touch begin, we don't compare to last event _controllerScriptingInterface->emitTouchBeginEvent(thisEvent); // send events to any registered scripts + _currentTouchEvent = thisEvent; // and we reset our current event to this event before we call our update _lastTouchEvent = thisEvent; // and we reset our last event to this event before we call our update touchUpdateEvent(event); @@ -2361,7 +2362,9 @@ void Application::touchEndEvent(QTouchEvent* event) { _altPressed = false; TouchEvent thisEvent(*event, _lastTouchEvent); _controllerScriptingInterface->emitTouchEndEvent(thisEvent); // send events to any registered scripts + _currentTouchEvent = TouchEvent(); _lastTouchEvent = thisEvent; + _lastTouchTimeout = 30; // timeout used as gestures can be misinterpreted for some frames // if one of our scripts have asked to capture this event, then stop processing it if (_controllerScriptingInterface->isTouchCaptured()) { @@ -3154,12 +3157,55 @@ void Application::update(float deltaTime) { myAvatar->setDriveKeys(TRANSLATE_Y, userInputMapper->getActionState(controller::Action::TRANSLATE_Y)); myAvatar->setDriveKeys(TRANSLATE_X, userInputMapper->getActionState(controller::Action::TRANSLATE_X)); if (deltaTime > FLT_EPSILON) { - myAvatar->setDriveKeys(PITCH, -1.0f * userInputMapper->getActionState(controller::Action::PITCH)); - myAvatar->setDriveKeys(YAW, -1.0f * userInputMapper->getActionState(controller::Action::YAW)); + if (_currentTouchEvent.isPressed == false) { + if (_lastTouchTimeout > 0) { + --_lastTouchTimeout; // disable non-touch input for some frames to disallow interpretation as movement + } else { + myAvatar->setDriveKeys(PITCH, -1.0f * userInputMapper->getActionState(controller::Action::PITCH)); + myAvatar->setDriveKeys(YAW, -1.0f * userInputMapper->getActionState(controller::Action::YAW)); + } + } else { + const bool allowTouchPan = _lastTouchEvent.isPinching == false && _lastTouchEvent.isPinchOpening == false + && _lastTouchEvent.x - _currentTouchEvent.x != 0; + if (_lastTouchEvent.x > _currentTouchEvent.x && allowTouchPan) { + myAvatar->setDriveKeys(YAW, -1.0f); + } else if (_lastTouchEvent.x < _currentTouchEvent.x && allowTouchPan) { + myAvatar->setDriveKeys(YAW, 1.0f); + } + } myAvatar->setDriveKeys(STEP_YAW, -1.0f * userInputMapper->getActionState(controller::Action::STEP_YAW)); } } - myAvatar->setDriveKeys(ZOOM, userInputMapper->getActionState(controller::Action::TRANSLATE_CAMERA_Z)); + + if (_currentTouchEvent.isPressed == true) { + static const float TOUCH_ZOOM_THRESHOLD = 5.0f; + const float boomLength = myAvatar->getBoomLength(); + QScreen* windowScreen = getWindow()->windowHandle()->screen(); + const float dpiScale = glm::clamp((float)(windowScreen->physicalDotsPerInchY() / 100.0f), 1.0f, 10.0f) * 15.0f; // at DPI 100 divide radius by 15 + + float scaledRadius = _lastTouchEvent.radius / dpiScale; + if (scaledRadius < TOUCH_ZOOM_THRESHOLD) { + const float extraRadiusScale = TOUCH_ZOOM_THRESHOLD / scaledRadius; + scaledRadius = _lastTouchEvent.radius / (dpiScale * extraRadiusScale); + } + + if (_lastTouchEvent.isPinching == true) { + const bool boomChangeValid = boomLength - scaledRadius < 2.0f; // restrict changes to small increments to negate large jumps + if (boomChangeValid && scaledRadius < boomLength && scaledRadius > MyAvatar::ZOOM_MIN) { + myAvatar->setBoomLength(scaledRadius); + } else if (scaledRadius <= MyAvatar::ZOOM_MIN) { + _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); + myAvatar->setBoomLength(MyAvatar::ZOOM_MIN); + } + } else if (_lastTouchEvent.isPinchOpening == true) { + const bool boomChangeValid = scaledRadius - boomLength < 2.0f; // restrict changes to small increments to negate large jumps + if (boomChangeValid && scaledRadius > boomLength && scaledRadius < MyAvatar::ZOOM_MAX) { + myAvatar->setBoomLength(scaledRadius); + } + } + } else { + myAvatar->setDriveKeys(ZOOM, userInputMapper->getActionState(controller::Action::TRANSLATE_CAMERA_Z)); + } } controller::Pose leftHand = userInputMapper->getPoseState(controller::Action::LEFT_HAND); diff --git a/interface/src/Application.h b/interface/src/Application.h index d5b677302a..aed4308491 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -453,7 +453,9 @@ private: FileLogger* _logger; + TouchEvent _currentTouchEvent; TouchEvent _lastTouchEvent; + int _lastTouchTimeout; quint64 _lastNackTime; quint64 _lastSendDownstreamAudioStats; From 9d03f0eb66b71a186401340c3aad8842c9d0edc5 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Tue, 2 Feb 2016 16:24:01 +0000 Subject: [PATCH 02/32] Revert "integrate touch screen camera manipulation controls" This reverts commit 4855511512d6df09691d7d54d48a341512d92392. --- interface/src/Application.cpp | 52 ++--------------------------------- interface/src/Application.h | 2 -- 2 files changed, 3 insertions(+), 51 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 496c1c4278..c202331041 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2343,7 +2343,6 @@ void Application::touchBeginEvent(QTouchEvent* event) { TouchEvent thisEvent(*event); // on touch begin, we don't compare to last event _controllerScriptingInterface->emitTouchBeginEvent(thisEvent); // send events to any registered scripts - _currentTouchEvent = thisEvent; // and we reset our current event to this event before we call our update _lastTouchEvent = thisEvent; // and we reset our last event to this event before we call our update touchUpdateEvent(event); @@ -2362,9 +2361,7 @@ void Application::touchEndEvent(QTouchEvent* event) { _altPressed = false; TouchEvent thisEvent(*event, _lastTouchEvent); _controllerScriptingInterface->emitTouchEndEvent(thisEvent); // send events to any registered scripts - _currentTouchEvent = TouchEvent(); _lastTouchEvent = thisEvent; - _lastTouchTimeout = 30; // timeout used as gestures can be misinterpreted for some frames // if one of our scripts have asked to capture this event, then stop processing it if (_controllerScriptingInterface->isTouchCaptured()) { @@ -3157,55 +3154,12 @@ void Application::update(float deltaTime) { myAvatar->setDriveKeys(TRANSLATE_Y, userInputMapper->getActionState(controller::Action::TRANSLATE_Y)); myAvatar->setDriveKeys(TRANSLATE_X, userInputMapper->getActionState(controller::Action::TRANSLATE_X)); if (deltaTime > FLT_EPSILON) { - if (_currentTouchEvent.isPressed == false) { - if (_lastTouchTimeout > 0) { - --_lastTouchTimeout; // disable non-touch input for some frames to disallow interpretation as movement - } else { - myAvatar->setDriveKeys(PITCH, -1.0f * userInputMapper->getActionState(controller::Action::PITCH)); - myAvatar->setDriveKeys(YAW, -1.0f * userInputMapper->getActionState(controller::Action::YAW)); - } - } else { - const bool allowTouchPan = _lastTouchEvent.isPinching == false && _lastTouchEvent.isPinchOpening == false - && _lastTouchEvent.x - _currentTouchEvent.x != 0; - if (_lastTouchEvent.x > _currentTouchEvent.x && allowTouchPan) { - myAvatar->setDriveKeys(YAW, -1.0f); - } else if (_lastTouchEvent.x < _currentTouchEvent.x && allowTouchPan) { - myAvatar->setDriveKeys(YAW, 1.0f); - } - } + myAvatar->setDriveKeys(PITCH, -1.0f * userInputMapper->getActionState(controller::Action::PITCH)); + myAvatar->setDriveKeys(YAW, -1.0f * userInputMapper->getActionState(controller::Action::YAW)); myAvatar->setDriveKeys(STEP_YAW, -1.0f * userInputMapper->getActionState(controller::Action::STEP_YAW)); } } - - if (_currentTouchEvent.isPressed == true) { - static const float TOUCH_ZOOM_THRESHOLD = 5.0f; - const float boomLength = myAvatar->getBoomLength(); - QScreen* windowScreen = getWindow()->windowHandle()->screen(); - const float dpiScale = glm::clamp((float)(windowScreen->physicalDotsPerInchY() / 100.0f), 1.0f, 10.0f) * 15.0f; // at DPI 100 divide radius by 15 - - float scaledRadius = _lastTouchEvent.radius / dpiScale; - if (scaledRadius < TOUCH_ZOOM_THRESHOLD) { - const float extraRadiusScale = TOUCH_ZOOM_THRESHOLD / scaledRadius; - scaledRadius = _lastTouchEvent.radius / (dpiScale * extraRadiusScale); - } - - if (_lastTouchEvent.isPinching == true) { - const bool boomChangeValid = boomLength - scaledRadius < 2.0f; // restrict changes to small increments to negate large jumps - if (boomChangeValid && scaledRadius < boomLength && scaledRadius > MyAvatar::ZOOM_MIN) { - myAvatar->setBoomLength(scaledRadius); - } else if (scaledRadius <= MyAvatar::ZOOM_MIN) { - _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); - myAvatar->setBoomLength(MyAvatar::ZOOM_MIN); - } - } else if (_lastTouchEvent.isPinchOpening == true) { - const bool boomChangeValid = scaledRadius - boomLength < 2.0f; // restrict changes to small increments to negate large jumps - if (boomChangeValid && scaledRadius > boomLength && scaledRadius < MyAvatar::ZOOM_MAX) { - myAvatar->setBoomLength(scaledRadius); - } - } - } else { - myAvatar->setDriveKeys(ZOOM, userInputMapper->getActionState(controller::Action::TRANSLATE_CAMERA_Z)); - } + myAvatar->setDriveKeys(ZOOM, userInputMapper->getActionState(controller::Action::TRANSLATE_CAMERA_Z)); } controller::Pose leftHand = userInputMapper->getPoseState(controller::Action::LEFT_HAND); diff --git a/interface/src/Application.h b/interface/src/Application.h index aed4308491..d5b677302a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -453,9 +453,7 @@ private: FileLogger* _logger; - TouchEvent _currentTouchEvent; TouchEvent _lastTouchEvent; - int _lastTouchTimeout; quint64 _lastNackTime; quint64 _lastSendDownstreamAudioStats; From 087e2e7f66d57e61a1c7d394fe3dc9435096b0a4 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Tue, 2 Feb 2016 18:05:17 +0000 Subject: [PATCH 03/32] revise touchscreen camera control manipulation Touchscreen camera control is now via a touchscreen device. Input must be enabled with the menu option. Currently supports dragging and gesturing to control avatar camera. Gesturing is handled by integration of the Qt implementation. --- .../resources/controllers/touchscreen.json | 24 ++++ interface/src/Application.cpp | 24 +++- interface/src/Application.h | 3 + libraries/gl/src/gl/GLWidget.cpp | 2 + .../src/input-plugins/InputPlugin.cpp | 2 + .../src/input-plugins/KeyboardMouseDevice.cpp | 67 +++++----- .../src/input-plugins/KeyboardMouseDevice.h | 4 + .../src/input-plugins/TouchscreenDevice.cpp | 119 ++++++++++++++++++ .../src/input-plugins/TouchscreenDevice.h | 81 ++++++++++++ tests/controllers/src/main.cpp | 4 + 10 files changed, 299 insertions(+), 31 deletions(-) create mode 100644 interface/resources/controllers/touchscreen.json create mode 100644 libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp create mode 100644 libraries/input-plugins/src/input-plugins/TouchscreenDevice.h diff --git a/interface/resources/controllers/touchscreen.json b/interface/resources/controllers/touchscreen.json new file mode 100644 index 0000000000..041259bd36 --- /dev/null +++ b/interface/resources/controllers/touchscreen.json @@ -0,0 +1,24 @@ +{ + "name": "Touchscreen to Actions", + "channels": [ + + { "from": "Touchscreen.GesturePinchOut", "to": "Actions.BoomOut", "filters": [ { "type": "scale", "scale": 0.02 } ]}, + { "from": "Touchscreen.GesturePinchIn", "to": "Actions.BoomIn", "filters": [ { "type": "scale", "scale": 0.02 } ]}, + + { "from": { "makeAxis" : [ + [ "Touchscreen.DragLeft" ], + [ "Touchscreen.DragRight" ] + ] + }, + "to": "Actions.Yaw" + }, + + { "from": { "makeAxis" : [ + [ "Touchscreen.DragUp" ], + [ "Touchscreen.DragDown" ] + ] + }, + "to": "Actions.Pitch" + } + ] +} diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c202331041..40bef91ba5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -862,8 +862,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : userInputMapper->registerDevice(_applicationStateDevice); - // Setup the keyboardMouseDevice and the user input mapper with the default bindings + // Setup the _keyboardMouseDevice, _touchscreenDevice and the user input mapper with the default bindings userInputMapper->registerDevice(_keyboardMouseDevice->getInputDevice()); + userInputMapper->registerDevice(_touchscreenDevice->getInputDevice()); userInputMapper->loadDefaultMapping(userInputMapper->getStandardDeviceID()); // force the model the look at the correct directory (weird order of operations issue) @@ -1308,6 +1309,9 @@ void Application::initializeUi() { if (name == KeyboardMouseDevice::NAME) { _keyboardMouseDevice = std::dynamic_pointer_cast(inputPlugin); } + if (name == TouchscreenDevice::NAME) { + _touchscreenDevice = std::dynamic_pointer_cast(inputPlugin); + } } updateInputModes(); } @@ -1790,6 +1794,9 @@ bool Application::event(QEvent* event) { case QEvent::TouchUpdate: touchUpdateEvent(static_cast(event)); return true; + case QEvent::Gesture: + touchGestureEvent((QGestureEvent*)event); + return true; case QEvent::Wheel: wheelEvent(static_cast(event)); return true; @@ -2336,6 +2343,9 @@ void Application::touchUpdateEvent(QTouchEvent* event) { if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) { _keyboardMouseDevice->touchUpdateEvent(event); } + if (Menu::getInstance()->isOptionChecked(TouchscreenDevice::NAME)) { + _touchscreenDevice->touchUpdateEvent(event); + } } void Application::touchBeginEvent(QTouchEvent* event) { @@ -2354,6 +2364,9 @@ void Application::touchBeginEvent(QTouchEvent* event) { if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) { _keyboardMouseDevice->touchBeginEvent(event); } + if (Menu::getInstance()->isOptionChecked(TouchscreenDevice::NAME)) { + _touchscreenDevice->touchBeginEvent(event); + } } @@ -2371,10 +2384,19 @@ void Application::touchEndEvent(QTouchEvent* event) { if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) { _keyboardMouseDevice->touchEndEvent(event); } + if (Menu::getInstance()->isOptionChecked(TouchscreenDevice::NAME)) { + _touchscreenDevice->touchEndEvent(event); + } // put any application specific touch behavior below here.. } +void Application::touchGestureEvent(QGestureEvent* event) { + if (Menu::getInstance()->isOptionChecked(TouchscreenDevice::NAME)) { + _touchscreenDevice->touchGestureEvent(event); + } +} + void Application::wheelEvent(QWheelEvent* event) { _altPressed = false; _controllerScriptingInterface->emitWheelEvent(event); // send events to any registered scripts diff --git a/interface/src/Application.h b/interface/src/Application.h index d5b677302a..26df5c8b0c 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -376,6 +377,7 @@ private: void touchBeginEvent(QTouchEvent* event); void touchEndEvent(QTouchEvent* event); void touchUpdateEvent(QTouchEvent* event); + void touchGestureEvent(QGestureEvent* event); void wheelEvent(QWheelEvent* event); void dropEvent(QDropEvent* event); @@ -421,6 +423,7 @@ private: std::shared_ptr _applicationStateDevice; // Default ApplicationDevice reflecting the state of different properties of the session std::shared_ptr _keyboardMouseDevice; // Default input device, the good old keyboard mouse and maybe touchpad + std::shared_ptr _touchscreenDevice; // the good old touchscreen AvatarUpdate* _avatarUpdate {nullptr}; SimpleMovingAverage _avatarSimsPerSecond {10}; int _avatarSimsPerSecondReport {0}; diff --git a/libraries/gl/src/gl/GLWidget.cpp b/libraries/gl/src/gl/GLWidget.cpp index c67dec1e51..8618fad58c 100644 --- a/libraries/gl/src/gl/GLWidget.cpp +++ b/libraries/gl/src/gl/GLWidget.cpp @@ -43,6 +43,7 @@ int GLWidget::getDeviceHeight() const { void GLWidget::initializeGL() { setAttribute(Qt::WA_AcceptTouchEvents); + grabGesture(Qt::PinchGesture); setAcceptDrops(true); // Note, we *DO NOT* want Qt to automatically swap buffers for us. This results in the "ringing" bug mentioned in WL#19514 when we're throttling the framerate. setAutoBufferSwap(false); @@ -76,6 +77,7 @@ bool GLWidget::event(QEvent* event) { case QEvent::TouchBegin: case QEvent::TouchEnd: case QEvent::TouchUpdate: + case QEvent::Gesture: case QEvent::Wheel: case QEvent::DragEnter: case QEvent::Drop: diff --git a/libraries/input-plugins/src/input-plugins/InputPlugin.cpp b/libraries/input-plugins/src/input-plugins/InputPlugin.cpp index 4d59adb602..28c1d3e0e0 100644 --- a/libraries/input-plugins/src/input-plugins/InputPlugin.cpp +++ b/libraries/input-plugins/src/input-plugins/InputPlugin.cpp @@ -13,11 +13,13 @@ #include #include "KeyboardMouseDevice.h" +#include "TouchscreenDevice.h" // TODO migrate to a DLL model where plugins are discovered and loaded at runtime by the PluginManager class InputPluginList getInputPlugins() { InputPlugin* PLUGIN_POOL[] = { new KeyboardMouseDevice(), + new TouchscreenDevice(), nullptr }; diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp index c3d2f7c51c..6457f923a7 100755 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp @@ -19,6 +19,7 @@ #include const QString KeyboardMouseDevice::NAME = "Keyboard/Mouse"; +bool KeyboardMouseDevice::_enableMouse = true; void KeyboardMouseDevice::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) { _inputDevice->update(deltaTime, inputCalibrationData, jointsCaptured); @@ -58,28 +59,32 @@ void KeyboardMouseDevice::keyReleaseEvent(QKeyEvent* event) { } void KeyboardMouseDevice::mousePressEvent(QMouseEvent* event, unsigned int deviceID) { - auto input = _inputDevice->makeInput((Qt::MouseButton) event->button()); - auto result = _inputDevice->_buttonPressedMap.insert(input.getChannel()); - if (!result.second) { - // key pressed again ? without catching the release event ? - } - _lastCursor = event->pos(); - _mousePressTime = usecTimestampNow(); - _mouseMoved = false; + if (_enableMouse) { + auto input = _inputDevice->makeInput((Qt::MouseButton) event->button()); + auto result = _inputDevice->_buttonPressedMap.insert(input.getChannel()); + if (!result.second) { + // key pressed again ? without catching the release event ? + } + _lastCursor = event->pos(); + _mousePressTime = usecTimestampNow(); + _mouseMoved = false; - eraseMouseClicked(); + eraseMouseClicked(); + } } void KeyboardMouseDevice::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) { - auto input = _inputDevice->makeInput((Qt::MouseButton) event->button()); - _inputDevice->_buttonPressedMap.erase(input.getChannel()); + if (_enableMouse) { + auto input = _inputDevice->makeInput((Qt::MouseButton) event->button()); + _inputDevice->_buttonPressedMap.erase(input.getChannel()); - // if we pressed and released at the same location within a small time window, then create a "_CLICKED" - // input for this button we might want to add some small tolerance to this so if you do a small drag it - // till counts as a clicked. - static const int CLICK_TIME = USECS_PER_MSEC * 500; // 500 ms to click - if (!_mouseMoved && (usecTimestampNow() - _mousePressTime < CLICK_TIME)) { - _inputDevice->_buttonPressedMap.insert(_inputDevice->makeInput((Qt::MouseButton) event->button(), true).getChannel()); + // if we pressed and released at the same location within a small time window, then create a "_CLICKED" + // input for this button we might want to add some small tolerance to this so if you do a small drag it + // still counts as a click. + static const int CLICK_TIME = USECS_PER_MSEC * 500; // 500 ms to click + if (!_mouseMoved && (usecTimestampNow() - _mousePressTime < CLICK_TIME)) { + _inputDevice->_buttonPressedMap.insert(_inputDevice->makeInput((Qt::MouseButton) event->button(), true).getChannel()); + } } } @@ -90,22 +95,24 @@ void KeyboardMouseDevice::eraseMouseClicked() { } void KeyboardMouseDevice::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) { - QPoint currentPos = event->pos(); - QPoint currentMove = currentPos - _lastCursor; + if (_enableMouse) { + QPoint currentPos = event->pos(); + QPoint currentMove = currentPos - _lastCursor; - _inputDevice->_axisStateMap[MOUSE_AXIS_X_POS] = (currentMove.x() > 0 ? currentMove.x() : 0.0f); - _inputDevice->_axisStateMap[MOUSE_AXIS_X_NEG] = (currentMove.x() < 0 ? -currentMove.x() : 0.0f); - // Y mouse is inverted positive is pointing up the screen - _inputDevice->_axisStateMap[MOUSE_AXIS_Y_POS] = (currentMove.y() < 0 ? -currentMove.y() : 0.0f); - _inputDevice->_axisStateMap[MOUSE_AXIS_Y_NEG] = (currentMove.y() > 0 ? currentMove.y() : 0.0f); + _inputDevice->_axisStateMap[MOUSE_AXIS_X_POS] = (currentMove.x() > 0 ? currentMove.x() : 0.0f); + _inputDevice->_axisStateMap[MOUSE_AXIS_X_NEG] = (currentMove.x() < 0 ? -currentMove.x() : 0.0f); + // Y mouse is inverted positive is pointing up the screen + _inputDevice->_axisStateMap[MOUSE_AXIS_Y_POS] = (currentMove.y() < 0 ? -currentMove.y() : 0.0f); + _inputDevice->_axisStateMap[MOUSE_AXIS_Y_NEG] = (currentMove.y() > 0 ? currentMove.y() : 0.0f); - // 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. - _lastCursor = currentPos; - _mouseMoved = true; + // 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. + _lastCursor = currentPos; + _mouseMoved = true; - eraseMouseClicked(); + eraseMouseClicked(); + } } void KeyboardMouseDevice::wheelEvent(QWheelEvent* event) { diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h index 55ca9a1704..3cbb2a9244 100644 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h @@ -85,6 +85,8 @@ public: void touchUpdateEvent(const QTouchEvent* event); void wheelEvent(QWheelEvent* event); + + static void enableMouse(bool enableMouse) { _enableMouse = enableMouse; } static const QString NAME; @@ -123,6 +125,8 @@ protected: bool _isTouching = false; std::chrono::high_resolution_clock _clock; std::chrono::high_resolution_clock::time_point _lastTouchTime; + + static bool _enableMouse; }; #endif // hifi_KeyboardMouseDevice_h diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp new file mode 100644 index 0000000000..987ff2cac4 --- /dev/null +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp @@ -0,0 +1,119 @@ +// +// TouchscreenDevice.cpp +// input-plugins/src/input-plugins +// +// Created by Triplelexx on 01/31/16. +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#include "TouchscreenDevice.h" +#include "KeyboardMouseDevice.h" + +#include +#include +#include +#include + +#include +#include +#include + +const QString TouchscreenDevice::NAME = "Touchscreen"; + +void TouchscreenDevice::pluginUpdate(float deltaTime, bool jointsCaptured) { + _inputDevice->update(deltaTime, jointsCaptured); + + // at DPI 100 use these arbitrary values to divide dragging distance + static const float DPI_SCALE_X = glm::clamp((float)(qApp->primaryScreen()->physicalDotsPerInchX() / 100.0f), 1.0f, 10.0f) + * 600.0f; + static const float DPI_SCALE_Y = glm::clamp((float)(qApp->primaryScreen()->physicalDotsPerInchY() / 100.0f), 1.0f, 10.0f) + * 200.0f; + + float distanceScaleX, distanceScaleY; + if (_touchPointCount == 1) { + if (_firstTouchVec.x < _currentTouchVec.x) { + distanceScaleX = (_currentTouchVec.x - _firstTouchVec.x) / DPI_SCALE_X; + _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_POS).getChannel()] = distanceScaleX; + } else if (_firstTouchVec.x > _currentTouchVec.x) { + distanceScaleX = (_firstTouchVec.x - _currentTouchVec.x) / DPI_SCALE_X; + _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_NEG).getChannel()] = distanceScaleX; + } + // Y axis is inverted, positive is pointing up the screen + if (_firstTouchVec.y > _currentTouchVec.y) { + distanceScaleY = (_firstTouchVec.y - _currentTouchVec.y) / DPI_SCALE_Y; + _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_POS).getChannel()] = distanceScaleY; + } else if (_firstTouchVec.y < _currentTouchVec.y) { + distanceScaleY = (_currentTouchVec.y - _firstTouchVec.y) / DPI_SCALE_Y; + _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_NEG).getChannel()] = distanceScaleY; + } + } +} + +void TouchscreenDevice::InputDevice::update(float deltaTime, bool jointsCaptured) { + _axisStateMap.clear(); +} + +void TouchscreenDevice::InputDevice::focusOutEvent() { +} + +void TouchscreenDevice::touchBeginEvent(const QTouchEvent* event) { + const QTouchEvent::TouchPoint& point = event->touchPoints().at(0); + _firstTouchVec = glm::vec2(point.pos().x(), point.pos().y()); + KeyboardMouseDevice::enableMouse(false); +} + +void TouchscreenDevice::touchEndEvent(const QTouchEvent* event) { + _touchPointCount = 0; + KeyboardMouseDevice::enableMouse(true); +} + +void TouchscreenDevice::touchUpdateEvent(const QTouchEvent* event) { + const QTouchEvent::TouchPoint& point = event->touchPoints().at(0); + _currentTouchVec = glm::vec2(point.pos().x(), point.pos().y()); + _touchPointCount = event->touchPoints().count(); +} + +void TouchscreenDevice::touchGestureEvent(const QGestureEvent* event) { + // pinch gesture + if (QGesture* gesture = event->gesture(Qt::PinchGesture)) { + QPinchGesture* pinch = static_cast(gesture); + qreal scaleFactor = pinch->totalScaleFactor(); + if (scaleFactor > _lastPinchScale && scaleFactor != 0) { + _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_POS).getChannel()] = 1.0f; + } else if (scaleFactor != 0) { + _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_NEG).getChannel()] = 1.0f; + } + _lastPinchScale = scaleFactor; + } +} + +controller::Input TouchscreenDevice::InputDevice::makeInput(TouchscreenDevice::TouchAxisChannel axis) const { + return controller::Input(_deviceID, axis, controller::ChannelType::AXIS); +} + +controller::Input TouchscreenDevice::InputDevice::makeInput(TouchscreenDevice::TouchGestureAxisChannel gesture) const { + return controller::Input(_deviceID, gesture, controller::ChannelType::AXIS); +} + +controller::Input::NamedVector TouchscreenDevice::InputDevice::getAvailableInputs() const { + using namespace controller; + static QVector availableInputs; + static std::once_flag once; + std::call_once(once, [&] { + availableInputs.append(Input::NamedPair(makeInput(TOUCH_AXIS_X_POS), "DragRight")); + availableInputs.append(Input::NamedPair(makeInput(TOUCH_AXIS_X_NEG), "DragLeft")); + availableInputs.append(Input::NamedPair(makeInput(TOUCH_AXIS_Y_POS), "DragUp")); + availableInputs.append(Input::NamedPair(makeInput(TOUCH_AXIS_Y_NEG), "DragDown")); + + availableInputs.append(Input::NamedPair(makeInput(TOUCH_GESTURE_PINCH_POS), "GesturePinchOut")); + availableInputs.append(Input::NamedPair(makeInput(TOUCH_GESTURE_PINCH_NEG), "GesturePinchIn")); + }); + return availableInputs; +} + +QString TouchscreenDevice::InputDevice::getDefaultMappingConfig() const { + static const QString MAPPING_JSON = PathUtils::resourcesPath() + "/controllers/touchscreen.json"; + return MAPPING_JSON; +} \ No newline at end of file diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h new file mode 100644 index 0000000000..c0d1ec0112 --- /dev/null +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h @@ -0,0 +1,81 @@ +// +// TouchscreenDevice.h +// input-plugins/src/input-plugins +// +// Created by Triplelexx on 1/31/16. +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_TouchscreenDevice_h +#define hifi_TouchscreenDevice_h + +#include +#include "InputPlugin.h" + +class QTouchEvent; +class QGestureEvent; + +class TouchscreenDevice : public InputPlugin { + Q_OBJECT +public: + + enum TouchAxisChannel { + TOUCH_AXIS_X_POS = 0, + TOUCH_AXIS_X_NEG, + TOUCH_AXIS_Y_POS, + TOUCH_AXIS_Y_NEG, + }; + + enum TouchGestureAxisChannel { + TOUCH_GESTURE_PINCH_POS = TOUCH_AXIS_Y_NEG + 1, + TOUCH_GESTURE_PINCH_NEG, + }; + + // Plugin functions + virtual bool isSupported() const override { return true; } + virtual bool isJointController() const override { return false; } + virtual const QString& getName() const override { return NAME; } + + virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); } + virtual void pluginUpdate(float deltaTime, bool jointsCaptured) override; + + void touchBeginEvent(const QTouchEvent* event); + void touchEndEvent(const QTouchEvent* event); + void touchUpdateEvent(const QTouchEvent* event); + void touchGestureEvent(const QGestureEvent* event); + + static const QString NAME; + +protected: + + class InputDevice : public controller::InputDevice { + public: + InputDevice() : controller::InputDevice("Touchscreen") {} + private: + // Device functions + virtual controller::Input::NamedVector getAvailableInputs() const override; + virtual QString getDefaultMappingConfig() const override; + virtual void update(float deltaTime, bool jointsCaptured) override; + virtual void focusOutEvent() override; + + controller::Input makeInput(TouchAxisChannel axis) const; + controller::Input makeInput(TouchGestureAxisChannel gesture) const; + + friend class TouchscreenDevice; + }; + +public: + const std::shared_ptr& getInputDevice() const { return _inputDevice; } + +protected: + qreal _lastPinchScale; + glm::vec2 _firstTouchVec; + glm::vec2 _currentTouchVec; + int _touchPointCount; + std::shared_ptr _inputDevice { std::make_shared() }; +}; + +#endif // hifi_TouchscreenDevice_h diff --git a/tests/controllers/src/main.cpp b/tests/controllers/src/main.cpp index 13b6b51d82..41746be9d8 100644 --- a/tests/controllers/src/main.cpp +++ b/tests/controllers/src/main.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -153,6 +154,9 @@ int main(int argc, char** argv) { if (name == KeyboardMouseDevice::NAME) { userInputMapper->registerDevice(std::dynamic_pointer_cast(inputPlugin)->getInputDevice()); } + if (name == TouchscreenDevice::NAME) { + userInputMapper->registerDevice(std::dynamic_pointer_cast(inputPlugin)->getInputDevice()); + } inputPlugin->pluginUpdate(0, calibrationData, false); } rootContext->setContextProperty("Controllers", new MyControllerScriptingInterface()); From 9db45c01cc9560bf480f3d6e5b6f49c13ac4e271 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Wed, 3 Feb 2016 00:13:45 +0000 Subject: [PATCH 04/32] indentation fixes caught some inconsistencies --- .../src/input-plugins/TouchscreenDevice.cpp | 27 +++++++++---------- .../src/input-plugins/TouchscreenDevice.h | 6 ++--- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp index 987ff2cac4..788a75dc76 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp @@ -76,17 +76,16 @@ void TouchscreenDevice::touchUpdateEvent(const QTouchEvent* event) { } void TouchscreenDevice::touchGestureEvent(const QGestureEvent* event) { - // pinch gesture - if (QGesture* gesture = event->gesture(Qt::PinchGesture)) { - QPinchGesture* pinch = static_cast(gesture); - qreal scaleFactor = pinch->totalScaleFactor(); - if (scaleFactor > _lastPinchScale && scaleFactor != 0) { - _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_POS).getChannel()] = 1.0f; - } else if (scaleFactor != 0) { - _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_NEG).getChannel()] = 1.0f; - } - _lastPinchScale = scaleFactor; - } + if (QGesture* gesture = event->gesture(Qt::PinchGesture)) { + QPinchGesture* pinch = static_cast(gesture); + qreal scaleFactor = pinch->totalScaleFactor(); + if (scaleFactor > _lastPinchScale && scaleFactor != 0) { + _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_POS).getChannel()] = 1.0f; + } else if (scaleFactor != 0) { + _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_NEG).getChannel()] = 1.0f; + } + _lastPinchScale = scaleFactor; + } } controller::Input TouchscreenDevice::InputDevice::makeInput(TouchscreenDevice::TouchAxisChannel axis) const { @@ -94,7 +93,7 @@ controller::Input TouchscreenDevice::InputDevice::makeInput(TouchscreenDevice::T } controller::Input TouchscreenDevice::InputDevice::makeInput(TouchscreenDevice::TouchGestureAxisChannel gesture) const { - return controller::Input(_deviceID, gesture, controller::ChannelType::AXIS); + return controller::Input(_deviceID, gesture, controller::ChannelType::AXIS); } controller::Input::NamedVector TouchscreenDevice::InputDevice::getAvailableInputs() const { @@ -107,8 +106,8 @@ controller::Input::NamedVector TouchscreenDevice::InputDevice::getAvailableInput availableInputs.append(Input::NamedPair(makeInput(TOUCH_AXIS_Y_POS), "DragUp")); availableInputs.append(Input::NamedPair(makeInput(TOUCH_AXIS_Y_NEG), "DragDown")); - availableInputs.append(Input::NamedPair(makeInput(TOUCH_GESTURE_PINCH_POS), "GesturePinchOut")); - availableInputs.append(Input::NamedPair(makeInput(TOUCH_GESTURE_PINCH_NEG), "GesturePinchIn")); + availableInputs.append(Input::NamedPair(makeInput(TOUCH_GESTURE_PINCH_POS), "GesturePinchOut")); + availableInputs.append(Input::NamedPair(makeInput(TOUCH_GESTURE_PINCH_NEG), "GesturePinchIn")); }); return availableInputs; } diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h index c0d1ec0112..8cc59c2532 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h @@ -31,7 +31,7 @@ public: enum TouchGestureAxisChannel { TOUCH_GESTURE_PINCH_POS = TOUCH_AXIS_Y_NEG + 1, - TOUCH_GESTURE_PINCH_NEG, + TOUCH_GESTURE_PINCH_NEG, }; // Plugin functions @@ -45,7 +45,7 @@ public: void touchBeginEvent(const QTouchEvent* event); void touchEndEvent(const QTouchEvent* event); void touchUpdateEvent(const QTouchEvent* event); - void touchGestureEvent(const QGestureEvent* event); + void touchGestureEvent(const QGestureEvent* event); static const QString NAME; @@ -62,7 +62,7 @@ protected: virtual void focusOutEvent() override; controller::Input makeInput(TouchAxisChannel axis) const; - controller::Input makeInput(TouchGestureAxisChannel gesture) const; + controller::Input makeInput(TouchGestureAxisChannel gesture) const; friend class TouchscreenDevice; }; From b291e32b7cd35ca73f2befeccbd1fd66f8840cac Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Fri, 19 Feb 2016 13:54:13 +0000 Subject: [PATCH 05/32] update TouchscreenDevice pass inputCalibrationData to update --- libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp | 2 +- libraries/input-plugins/src/input-plugins/TouchscreenDevice.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp index 788a75dc76..6abf2a9fae 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp @@ -51,7 +51,7 @@ void TouchscreenDevice::pluginUpdate(float deltaTime, bool jointsCaptured) { } } -void TouchscreenDevice::InputDevice::update(float deltaTime, bool jointsCaptured) { +void TouchscreenDevice::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) { _axisStateMap.clear(); } diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h index 8cc59c2532..568dedf7b4 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h @@ -40,7 +40,7 @@ public: virtual const QString& getName() const override { return NAME; } virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); } - virtual void pluginUpdate(float deltaTime, bool jointsCaptured) override; + virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override; void touchBeginEvent(const QTouchEvent* event); void touchEndEvent(const QTouchEvent* event); From 742f741095712595b3e318f33a8d80a60781eaea Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Sun, 21 Feb 2016 21:27:21 +0000 Subject: [PATCH 06/32] update TouchscreenDevice again added passing of inputCalibrationData missed from last commit --- .../input-plugins/src/input-plugins/TouchscreenDevice.cpp | 4 ++-- libraries/input-plugins/src/input-plugins/TouchscreenDevice.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp index 6abf2a9fae..8fb1f6bd0a 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp @@ -22,8 +22,8 @@ const QString TouchscreenDevice::NAME = "Touchscreen"; -void TouchscreenDevice::pluginUpdate(float deltaTime, bool jointsCaptured) { - _inputDevice->update(deltaTime, jointsCaptured); +void TouchscreenDevice::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) { + _inputDevice->update(deltaTime, inputCalibrationData, jointsCaptured); // at DPI 100 use these arbitrary values to divide dragging distance static const float DPI_SCALE_X = glm::clamp((float)(qApp->primaryScreen()->physicalDotsPerInchX() / 100.0f), 1.0f, 10.0f) diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h index 568dedf7b4..acd7d89333 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h @@ -58,7 +58,7 @@ protected: // Device functions virtual controller::Input::NamedVector getAvailableInputs() const override; virtual QString getDefaultMappingConfig() const override; - virtual void update(float deltaTime, bool jointsCaptured) override; + virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override; virtual void focusOutEvent() override; controller::Input makeInput(TouchAxisChannel axis) const; From fb242be50fc986c61fabee75b3b91f13db1992f3 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Sun, 3 Apr 2016 22:59:48 +0100 Subject: [PATCH 07/32] resolved merge conflict got to stick to command line, this should have been added with add command at merge.... --- interface/src/Application.h | 73 ++++++++++--------- .../src/procedural/ProceduralSkybox.slv | 39 ---------- 2 files changed, 39 insertions(+), 73 deletions(-) delete mode 100644 libraries/procedural/src/procedural/ProceduralSkybox.slv diff --git a/interface/src/Application.h b/interface/src/Application.h index 96887e300d..6eaab7039c 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -41,7 +41,6 @@ #include #include -#include "avatar/AvatarUpdate.h" #include "avatar/MyAvatar.h" #include "Bookmarks.h" #include "Camera.h" @@ -52,7 +51,6 @@ #include "render/Engine.h" #include "scripting/ControllerScriptingInterface.h" #include "scripting/DialogsManagerScriptingInterface.h" -#include "ui/ApplicationCompositor.h" #include "ui/ApplicationOverlay.h" #include "ui/AudioStatsDialog.h" #include "ui/BandwidthDialog.h" @@ -68,6 +66,7 @@ class GLCanvas; class FaceTracker; class MainWindow; class AssetUpload; +class CompositorHelper; namespace controller { class StateController; @@ -121,9 +120,12 @@ public: QSize getDeviceSize() const; bool hasFocus() const; + void showCursor(const QCursor& cursor); + bool isThrottleRendering() const; Camera* getCamera() { return &_myCamera; } + const Camera* getCamera() const { return &_myCamera; } // Represents the current view frustum of the avatar. ViewFrustum* getViewFrustum(); const ViewFrustum* getViewFrustum() const; @@ -148,8 +150,8 @@ public: ApplicationOverlay& getApplicationOverlay() { return _applicationOverlay; } const ApplicationOverlay& getApplicationOverlay() const { return _applicationOverlay; } - ApplicationCompositor& getApplicationCompositor() { return _compositor; } - const ApplicationCompositor& getApplicationCompositor() const { return _compositor; } + CompositorHelper& getApplicationCompositor() const; + Overlays& getOverlays() { return _overlays; } bool isForeground() const { return _isForeground; } @@ -210,31 +212,31 @@ public: render::EnginePointer getRenderEngine() override { return _renderEngine; } gpu::ContextPointer getGPUContext() const { return _gpuContext; } + virtual void pushPreRenderLambda(void* key, std::function func) override; + const QRect& getMirrorViewRect() const { return _mirrorViewRect; } void updateMyAvatarLookAtPosition(); - AvatarUpdate* getAvatarUpdater() { return _avatarUpdate; } float getAvatarSimrate(); void setAvatarSimrateSample(float sample); float getAverageSimsPerSecond(); - void fakeMouseEvent(QMouseEvent* event); - signals: void svoImportRequested(const QString& url); void checkBackgroundDownloads(); - void domainConnectionRefused(const QString& reason); void fullAvatarURLChanged(const QString& newValue, const QString& modelName); void beforeAboutToQuit(); void activeDisplayPluginChanged(); + void uploadRequest(QString path); + public slots: QVector pasteEntities(float x, float y, float z); - bool exportEntities(const QString& filename, const QVector& entityIDs); + bool exportEntities(const QString& filename, const QVector& entityIDs, const glm::vec3* givenOffset = nullptr); bool exportEntities(const QString& filename, float x, float y, float z, float scale); bool importEntities(const QString& url); @@ -243,6 +245,7 @@ public slots: Q_INVOKABLE void loadScriptURLDialog(); void toggleLogDialog(); void toggleRunningScriptsWidget(); + void toggleAssetServerWidget(QString filePath = ""); void handleLocalServerConnection(); void readArgumentsFromLocalSocket(); @@ -251,11 +254,6 @@ public slots: void openUrl(const QUrl& url); - void setAvatarUpdateThreading(); - void setAvatarUpdateThreading(bool isThreaded); - void setRawAvatarUpdateThreading(); - void setRawAvatarUpdateThreading(bool isThreaded); - void resetSensors(bool andReload = false); void setActiveFaceTracker(); @@ -271,40 +269,41 @@ public slots: void cycleCamera(); void cameraMenuChanged(); + void toggleOverlays(); + void setOverlaysVisible(bool visible); void reloadResourceCaches(); + void updateHeartbeat(); + void crashApplication(); + void deadlockApplication(); void rotationModeChanged(); void runTests(); private slots: + void showDesktop(); void clearDomainOctreeDetails(); void idle(uint64_t now); void aboutToQuit(); - void connectedToDomain(const QString& hostname); + void resettingDomain(); void audioMuteToggled(); void faceTrackerMuteToggled(); void activeChanged(Qt::ApplicationState state); - void domainSettingsReceived(const QJsonObject& domainSettingsObject); - void handleDomainConnectionDeniedPacket(QSharedPointer message); - void notifyPacketVersionMismatch(); void loadSettings(); void saveSettings(); - + bool acceptSnapshot(const QString& urlString); bool askToSetAvatarUrl(const QString& url); bool askToLoadScript(const QString& scriptFilenameOrURL); - bool askToUploadAsset(const QString& asset); - void modelUploadFinished(AssetUpload* upload, const QString& hash); bool askToWearAvatarAttachmentUrl(const QString& url); void displayAvatarAttachmentWarning(const QString& message) const; @@ -314,6 +313,7 @@ private slots: void domainChanged(const QString& domainHostname); void updateWindowTitle(); void nodeAdded(SharedNodePointer node); + void nodeActivated(SharedNodePointer node); void nodeKilled(SharedNodePointer node); void packetSent(quint64 length); void updateDisplayMode(); @@ -325,12 +325,8 @@ private: void cleanupBeforeQuit(); - void emptyLocalCache(); - void update(float deltaTime); - void setPalmData(Hand* hand, const controller::Pose& pose, float deltaTime, HandData::Hand whichHand, float triggerValue); - // Various helper functions called during update() void updateLOD(); void updateThreads(float deltaTime); @@ -352,7 +348,6 @@ private: void checkSkeleton(); void initializeAcceptedFiles(); - int getRenderAmbientLight() const; void displaySide(RenderArgs* renderArgs, Camera& whichCamera, bool selfAvatarOnly = false); @@ -386,16 +381,18 @@ private: void maybeToggleMenuVisible(QMouseEvent* event); - bool _dependencyManagerIsSetup; + MainWindow* _window; + QElapsedTimer& _sessionRunTimer; + + bool _previousSessionCrashed; OffscreenGLCanvas* _offscreenContext { nullptr }; DisplayPluginPointer _displayPlugin; + std::mutex _displayPluginLock; InputPluginList _activeInputPlugins; bool _activatingDisplayPlugin { false }; - QMap _lockedFramebufferMap; - - MainWindow* _window; + QMap _lockedFramebufferMap; QUndoStack _undoStack; UndoStackScriptingInterface _undoStackScriptingInterface; @@ -425,7 +422,6 @@ private: std::shared_ptr _applicationStateDevice; // Default ApplicationDevice reflecting the state of different properties of the session std::shared_ptr _keyboardMouseDevice; // Default input device, the good old keyboard mouse and maybe touchpad std::shared_ptr _touchscreenDevice; // the good old touchscreen - AvatarUpdate* _avatarUpdate {nullptr}; SimpleMovingAverage _avatarSimsPerSecond {10}; int _avatarSimsPerSecondReport {0}; quint64 _lastAvatarSimsPerSecondUpdate {0}; @@ -476,7 +472,6 @@ private: typedef bool (Application::* AcceptURLMethod)(const QString &); static const QHash _acceptedExtensions; - QList _domainConnectionRefusals; glm::uvec2 _renderResolution; int _maxOctreePPS = DEFAULT_MAX_OCTREE_PPS; @@ -489,7 +484,6 @@ private: Overlays _overlays; ApplicationOverlay _applicationOverlay; - ApplicationCompositor _compositor; OverlayConductor _overlayConductor; DialogsManagerScriptingInterface* _dialogsManagerScriptingInterface = new DialogsManagerScriptingInterface(); @@ -512,10 +506,21 @@ private: int _avatarAttachmentRequest = 0; bool _settingsLoaded { false }; - bool _pendingPaint { false }; QTimer* _idleTimer { nullptr }; bool _fakedMouseEvent { false }; + + void checkChangeCursor(); + mutable QMutex _changeCursorLock { QMutex::Recursive }; + QCursor _desiredCursor{ Qt::BlankCursor }; + bool _cursorNeedsChanging { false }; + + QThread* _deadlockWatchdogThread; + + std::map> _preRenderLambdas; + std::mutex _preRenderLambdasLock; + + std::atomic _processOctreeStatsCounter { 0 }; }; #endif // hifi_Application_h diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.slv b/libraries/procedural/src/procedural/ProceduralSkybox.slv deleted file mode 100644 index 810afb1033..0000000000 --- a/libraries/procedural/src/procedural/ProceduralSkybox.slv +++ /dev/null @@ -1,39 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// skybox.vert -// vertex shader -// -// Created by Sam Gateau on 5/5/2015. -// Copyright 2015 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -<@include gpu/Transform.slh@> - -<$declareStandardTransform()$> - -out vec3 _normal; - -void main(void) { - const float depth = 0.0; - const vec4 UNIT_QUAD[4] = vec4[4]( - vec4(-1.0, -1.0, depth, 1.0), - vec4(1.0, -1.0, depth, 1.0), - vec4(-1.0, 1.0, depth, 1.0), - vec4(1.0, 1.0, depth, 1.0) - ); - vec4 inPosition = UNIT_QUAD[gl_VertexID]; - - // standard transform - TransformCamera cam = getTransformCamera(); - vec3 clipDir = vec3(inPosition.xy, 0.0); - vec3 eyeDir; - <$transformClipToEyeDir(cam, clipDir, eyeDir)$> - <$transformEyeToWorldDir(cam, eyeDir, _normal)$> - - // Position is supposed to come in clip space - gl_Position = vec4(inPosition.xy, 0.0, 1.0); -} \ No newline at end of file From bc0ea315343c564d8978671f8c0db660df42e3bb Mon Sep 17 00:00:00 2001 From: Lexx Date: Mon, 4 Apr 2016 00:32:05 +0100 Subject: [PATCH 08/32] Rename Skybox.slf to skybox.slf --- libraries/model/src/model/{Skybox.slf => skybox.slf} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename libraries/model/src/model/{Skybox.slf => skybox.slf} (100%) diff --git a/libraries/model/src/model/Skybox.slf b/libraries/model/src/model/skybox.slf similarity index 100% rename from libraries/model/src/model/Skybox.slf rename to libraries/model/src/model/skybox.slf From 0b313afd74757d195eceeb60352ed17e2ab7fcd8 Mon Sep 17 00:00:00 2001 From: Lexx Date: Mon, 4 Apr 2016 00:32:20 +0100 Subject: [PATCH 09/32] Rename Skybox.slv to skybox.slv --- libraries/model/src/model/{Skybox.slv => skybox.slv} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename libraries/model/src/model/{Skybox.slv => skybox.slv} (99%) diff --git a/libraries/model/src/model/Skybox.slv b/libraries/model/src/model/skybox.slv similarity index 99% rename from libraries/model/src/model/Skybox.slv rename to libraries/model/src/model/skybox.slv index 810afb1033..5df1aa0a4a 100755 --- a/libraries/model/src/model/Skybox.slv +++ b/libraries/model/src/model/skybox.slv @@ -36,4 +36,4 @@ void main(void) { // Position is supposed to come in clip space gl_Position = vec4(inPosition.xy, 0.0, 1.0); -} \ No newline at end of file +} From b5d50e8b3f21824a3c11b85e98d2093f72ce74b3 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Tue, 5 Apr 2016 00:35:12 +0100 Subject: [PATCH 10/32] attempt at resolving build warnings make both values operated on double before casting --- libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp index 8fb1f6bd0a..be42957eb8 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp @@ -26,9 +26,7 @@ void TouchscreenDevice::pluginUpdate(float deltaTime, const controller::InputCal _inputDevice->update(deltaTime, inputCalibrationData, jointsCaptured); // at DPI 100 use these arbitrary values to divide dragging distance - static const float DPI_SCALE_X = glm::clamp((float)(qApp->primaryScreen()->physicalDotsPerInchX() / 100.0f), 1.0f, 10.0f) * 600.0f; - static const float DPI_SCALE_Y = glm::clamp((float)(qApp->primaryScreen()->physicalDotsPerInchY() / 100.0f), 1.0f, 10.0f) * 200.0f; float distanceScaleX, distanceScaleY; From 3501749896d161c3efc3a490e77dca7ac2baf119 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Tue, 5 Apr 2016 00:37:14 +0100 Subject: [PATCH 11/32] attempt at resolving build warning make both values operated on double before casting --- libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp index be42957eb8..f8da94e5e6 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp @@ -26,7 +26,9 @@ void TouchscreenDevice::pluginUpdate(float deltaTime, const controller::InputCal _inputDevice->update(deltaTime, inputCalibrationData, jointsCaptured); // at DPI 100 use these arbitrary values to divide dragging distance + static const float DPI_SCALE_X = glm::clamp((float)(qApp->primaryScreen()->physicalDotsPerInchX() / 100.0), 1.0f, 10.0f) * 600.0f; + static const float DPI_SCALE_Y = glm::clamp((float)(qApp->primaryScreen()->physicalDotsPerInchY() / 100.0), 1.0f, 10.0f) * 200.0f; float distanceScaleX, distanceScaleY; From 6542604d1307234167e5a5e0ab67aadd37475773 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Fri, 24 Jun 2016 05:19:28 +0100 Subject: [PATCH 12/32] resolve conflicts with TouchscreenDevice updated to master --- interface/src/Application.cpp | 2 +- .../input-plugins/src/input-plugins/TouchscreenDevice.cpp | 8 +++++--- .../input-plugins/src/input-plugins/TouchscreenDevice.h | 5 ++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2d1dc64bcb..7858679583 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1593,7 +1593,7 @@ void Application::initializeUi() { if (KeyboardMouseDevice::NAME == inputPlugin->getName()) { _keyboardMouseDevice = std::dynamic_pointer_cast(inputPlugin); } - if (name == TouchscreenDevice::NAME) { + if (TouchscreenDevice::NAME == inputPlugin->getName()) { _touchscreenDevice = std::dynamic_pointer_cast(inputPlugin); } } diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp index f8da94e5e6..16b5947426 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp @@ -22,8 +22,10 @@ const QString TouchscreenDevice::NAME = "Touchscreen"; -void TouchscreenDevice::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) { - _inputDevice->update(deltaTime, inputCalibrationData, jointsCaptured); +void TouchscreenDevice::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { + auto userInputMapper = DependencyManager::get(); + userInputMapper->withLock([&, this]() { + _inputDevice->update(deltaTime, inputCalibrationData); // at DPI 100 use these arbitrary values to divide dragging distance static const float DPI_SCALE_X = glm::clamp((float)(qApp->primaryScreen()->physicalDotsPerInchX() / 100.0), 1.0f, 10.0f) @@ -51,7 +53,7 @@ void TouchscreenDevice::pluginUpdate(float deltaTime, const controller::InputCal } } -void TouchscreenDevice::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) { +void TouchscreenDevice::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { _axisStateMap.clear(); } diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h index acd7d89333..772776348f 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h @@ -36,11 +36,10 @@ public: // Plugin functions virtual bool isSupported() const override { return true; } - virtual bool isJointController() const override { return false; } virtual const QString& getName() const override { return NAME; } virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); } - virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override; + virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; void touchBeginEvent(const QTouchEvent* event); void touchEndEvent(const QTouchEvent* event); @@ -58,7 +57,7 @@ protected: // Device functions virtual controller::Input::NamedVector getAvailableInputs() const override; virtual QString getDefaultMappingConfig() const override; - virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override; + virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; virtual void focusOutEvent() override; controller::Input makeInput(TouchAxisChannel axis) const; From 8928854820c6f13302e094ac305a43b55dd066af Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Fri, 24 Jun 2016 05:20:47 +0100 Subject: [PATCH 13/32] lost change --- libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp index 16b5947426..9430f1d23a 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp @@ -26,6 +26,7 @@ void TouchscreenDevice::pluginUpdate(float deltaTime, const controller::InputCal auto userInputMapper = DependencyManager::get(); userInputMapper->withLock([&, this]() { _inputDevice->update(deltaTime, inputCalibrationData); + }); // at DPI 100 use these arbitrary values to divide dragging distance static const float DPI_SCALE_X = glm::clamp((float)(qApp->primaryScreen()->physicalDotsPerInchX() / 100.0), 1.0f, 10.0f) From 90cd335bdabcc1d3e7679da0b3d7a0ef0fc5868b Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Fri, 24 Jun 2016 10:48:25 +0100 Subject: [PATCH 14/32] missed a brace --- tests/controllers/src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/controllers/src/main.cpp b/tests/controllers/src/main.cpp index dbb17fd63f..1a4f8742e9 100644 --- a/tests/controllers/src/main.cpp +++ b/tests/controllers/src/main.cpp @@ -92,7 +92,7 @@ public: virtual QOpenGLContext* getPrimaryContext() override { return nullptr; } virtual ui::Menu* getPrimaryMenu() override { return nullptr; } virtual bool isForeground() const override { return true; } - virtual DisplayPluginPointer getActiveDisplayPlugin() const override { return DisplayPluginPointer(); } + virtual DisplayPluginPointer getActiveDisplayPlugin() const override { return DisplayPluginPointer(); } }; class MyControllerScriptingInterface : public controller::ScriptingInterface { @@ -144,6 +144,7 @@ int main(int argc, char** argv) { auto userInputMapper = DependencyManager::get(); if (name == KeyboardMouseDevice::NAME) { userInputMapper->registerDevice(std::dynamic_pointer_cast(inputPlugin)->getInputDevice()); + } if (name == TouchscreenDevice::NAME) { userInputMapper->registerDevice(std::dynamic_pointer_cast(inputPlugin)->getInputDevice()); } From aae3555b63c964e6a484bdcd0dfcecac83b18b92 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Mon, 27 Jun 2016 21:01:06 +0100 Subject: [PATCH 15/32] update TouchscreenDevice * fix threading issue with zoom gesture * KeyboardMouseDevice touchpad disabled to prevent interference * device supported based on QTouchDevice::devices().count() --- interface/src/Application.cpp | 13 +- .../src/input-plugins/KeyboardMouseDevice.cpp | 117 +++++++++--------- .../src/input-plugins/KeyboardMouseDevice.h | 4 +- .../src/input-plugins/TouchscreenDevice.cpp | 21 ++-- .../src/input-plugins/TouchscreenDevice.h | 6 +- 5 files changed, 84 insertions(+), 77 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7858679583..7680112462 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -961,7 +961,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : // Setup the _keyboardMouseDevice, _touchscreenDevice and the user input mapper with the default bindings userInputMapper->registerDevice(_keyboardMouseDevice->getInputDevice()); - userInputMapper->registerDevice(_touchscreenDevice->getInputDevice()); + // if the _touchscreenDevice is not supported it will not be registered + if (_touchscreenDevice) { + userInputMapper->registerDevice(_touchscreenDevice->getInputDevice()); + } // force the model the look at the correct directory (weird order of operations issue) scriptEngines->setScriptsLocation(scriptEngines->getScriptsLocation()); @@ -2712,7 +2715,7 @@ void Application::touchUpdateEvent(QTouchEvent* event) { if (_keyboardMouseDevice->isActive()) { _keyboardMouseDevice->touchUpdateEvent(event); } - if (Menu::getInstance()->isOptionChecked(TouchscreenDevice::NAME)) { + if (_touchscreenDevice->isActive()) { _touchscreenDevice->touchUpdateEvent(event); } } @@ -2733,7 +2736,7 @@ void Application::touchBeginEvent(QTouchEvent* event) { if (_keyboardMouseDevice->isActive()) { _keyboardMouseDevice->touchBeginEvent(event); } - if (Menu::getInstance()->isOptionChecked(TouchscreenDevice::NAME)) { + if (_touchscreenDevice->isActive()) { _touchscreenDevice->touchBeginEvent(event); } @@ -2753,7 +2756,7 @@ void Application::touchEndEvent(QTouchEvent* event) { if (_keyboardMouseDevice->isActive()) { _keyboardMouseDevice->touchEndEvent(event); } - if (Menu::getInstance()->isOptionChecked(TouchscreenDevice::NAME)) { + if (_touchscreenDevice->isActive()) { _touchscreenDevice->touchEndEvent(event); } @@ -2761,7 +2764,7 @@ void Application::touchEndEvent(QTouchEvent* event) { } void Application::touchGestureEvent(QGestureEvent* event) { - if (Menu::getInstance()->isOptionChecked(TouchscreenDevice::NAME)) { + if (_touchscreenDevice->isActive()) { _touchscreenDevice->touchGestureEvent(event); } } diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp index cc4117ffc0..550d127198 100755 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp @@ -19,7 +19,7 @@ #include const QString KeyboardMouseDevice::NAME = "Keyboard/Mouse"; -bool KeyboardMouseDevice::_enableMouse = true; +bool KeyboardMouseDevice::_enableTouchpad = true; void KeyboardMouseDevice::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { auto userInputMapper = DependencyManager::get(); @@ -62,32 +62,28 @@ void KeyboardMouseDevice::keyReleaseEvent(QKeyEvent* event) { } void KeyboardMouseDevice::mousePressEvent(QMouseEvent* event) { - if (_enableMouse) { - auto input = _inputDevice->makeInput((Qt::MouseButton) event->button()); - auto result = _inputDevice->_buttonPressedMap.insert(input.getChannel()); - if (!result.second) { - // key pressed again ? without catching the release event ? - } - _lastCursor = event->pos(); - _mousePressTime = usecTimestampNow(); - _mouseMoved = false; - - eraseMouseClicked(); + auto input = _inputDevice->makeInput((Qt::MouseButton) event->button()); + auto result = _inputDevice->_buttonPressedMap.insert(input.getChannel()); + if (!result.second) { + // key pressed again ? without catching the release event ? } + _lastCursor = event->pos(); + _mousePressTime = usecTimestampNow(); + _mouseMoved = false; + + eraseMouseClicked(); } void KeyboardMouseDevice::mouseReleaseEvent(QMouseEvent* event) { - if (_enableMouse) { - auto input = _inputDevice->makeInput((Qt::MouseButton) event->button()); - _inputDevice->_buttonPressedMap.erase(input.getChannel()); + auto input = _inputDevice->makeInput((Qt::MouseButton) event->button()); + _inputDevice->_buttonPressedMap.erase(input.getChannel()); - // if we pressed and released at the same location within a small time window, then create a "_CLICKED" - // input for this button we might want to add some small tolerance to this so if you do a small drag it - // still counts as a click. - static const int CLICK_TIME = USECS_PER_MSEC * 500; // 500 ms to click - if (!_mouseMoved && (usecTimestampNow() - _mousePressTime < CLICK_TIME)) { - _inputDevice->_buttonPressedMap.insert(_inputDevice->makeInput((Qt::MouseButton) event->button(), true).getChannel()); - } + // if we pressed and released at the same location within a small time window, then create a "_CLICKED" + // input for this button we might want to add some small tolerance to this so if you do a small drag it + // still counts as a click. + static const int CLICK_TIME = USECS_PER_MSEC * 500; // 500 ms to click + if (!_mouseMoved && (usecTimestampNow() - _mousePressTime < CLICK_TIME)) { + _inputDevice->_buttonPressedMap.insert(_inputDevice->makeInput((Qt::MouseButton) event->button(), true).getChannel()); } } @@ -98,24 +94,22 @@ void KeyboardMouseDevice::eraseMouseClicked() { } void KeyboardMouseDevice::mouseMoveEvent(QMouseEvent* event) { - if (_enableMouse) { - QPoint currentPos = event->pos(); - QPoint currentMove = currentPos - _lastCursor; + QPoint currentPos = event->pos(); + QPoint currentMove = currentPos - _lastCursor; - _inputDevice->_axisStateMap[MOUSE_AXIS_X_POS] = (currentMove.x() > 0 ? currentMove.x() : 0.0f); - _inputDevice->_axisStateMap[MOUSE_AXIS_X_NEG] = (currentMove.x() < 0 ? -currentMove.x() : 0.0f); - // Y mouse is inverted positive is pointing up the screen - _inputDevice->_axisStateMap[MOUSE_AXIS_Y_POS] = (currentMove.y() < 0 ? -currentMove.y() : 0.0f); - _inputDevice->_axisStateMap[MOUSE_AXIS_Y_NEG] = (currentMove.y() > 0 ? currentMove.y() : 0.0f); + _inputDevice->_axisStateMap[MOUSE_AXIS_X_POS] = (currentMove.x() > 0 ? currentMove.x() : 0.0f); + _inputDevice->_axisStateMap[MOUSE_AXIS_X_NEG] = (currentMove.x() < 0 ? -currentMove.x() : 0.0f); + // Y mouse is inverted positive is pointing up the screen + _inputDevice->_axisStateMap[MOUSE_AXIS_Y_POS] = (currentMove.y() < 0 ? -currentMove.y() : 0.0f); + _inputDevice->_axisStateMap[MOUSE_AXIS_Y_NEG] = (currentMove.y() > 0 ? currentMove.y() : 0.0f); - // 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. - _lastCursor = currentPos; - _mouseMoved = true; + // 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. + _lastCursor = currentPos; + _mouseMoved = true; - eraseMouseClicked(); - } + eraseMouseClicked(); } void KeyboardMouseDevice::wheelEvent(QWheelEvent* event) { @@ -139,34 +133,41 @@ glm::vec2 evalAverageTouchPoints(const QList& points) { } void KeyboardMouseDevice::touchBeginEvent(const QTouchEvent* event) { - _isTouching = event->touchPointStates().testFlag(Qt::TouchPointPressed); - _lastTouch = evalAverageTouchPoints(event->touchPoints()); - _lastTouchTime = _clock.now(); + if (_enableTouchpad) { + _isTouching = event->touchPointStates().testFlag(Qt::TouchPointPressed); + _lastTouch = evalAverageTouchPoints(event->touchPoints()); + _lastTouchTime = _clock.now(); + } } void KeyboardMouseDevice::touchEndEvent(const QTouchEvent* event) { - _isTouching = false; - _lastTouch = evalAverageTouchPoints(event->touchPoints()); - _lastTouchTime = _clock.now(); + if (_enableTouchpad) { + _isTouching = false; + _lastTouch = evalAverageTouchPoints(event->touchPoints()); + _lastTouchTime = _clock.now(); + } } void KeyboardMouseDevice::touchUpdateEvent(const QTouchEvent* event) { - auto currentPos = evalAverageTouchPoints(event->touchPoints()); - _lastTouchTime = _clock.now(); - - if (!_isTouching) { - _isTouching = event->touchPointStates().testFlag(Qt::TouchPointPressed); - } else { - auto currentMove = currentPos - _lastTouch; - - _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_POS).getChannel()] = (currentMove.x > 0 ? currentMove.x : 0.0f); - _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_NEG).getChannel()] = (currentMove.x < 0 ? -currentMove.x : 0.0f); - // Y mouse is inverted positive is pointing up the screen - _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_POS).getChannel()] = (currentMove.y < 0 ? -currentMove.y : 0.0f); - _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_NEG).getChannel()] = (currentMove.y > 0 ? currentMove.y : 0.0f); - } + if (_enableTouchpad) { + auto currentPos = evalAverageTouchPoints(event->touchPoints()); + _lastTouchTime = _clock.now(); - _lastTouch = currentPos; + if (!_isTouching) { + _isTouching = event->touchPointStates().testFlag(Qt::TouchPointPressed); + } + else { + auto currentMove = currentPos - _lastTouch; + + _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_POS).getChannel()] = (currentMove.x > 0 ? currentMove.x : 0.0f); + _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_NEG).getChannel()] = (currentMove.x < 0 ? -currentMove.x : 0.0f); + // Y mouse is inverted positive is pointing up the screen + _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_POS).getChannel()] = (currentMove.y < 0 ? -currentMove.y : 0.0f); + _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_NEG).getChannel()] = (currentMove.y > 0 ? currentMove.y : 0.0f); + } + + _lastTouch = currentPos; + } } controller::Input KeyboardMouseDevice::InputDevice::makeInput(Qt::Key code) const { diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h index fc2ad44a6d..d88c410ade 100644 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h @@ -85,7 +85,7 @@ public: void wheelEvent(QWheelEvent* event); - static void enableMouse(bool enableMouse) { _enableMouse = enableMouse; } + static void enableTouchpad(bool enableTouchpad) { _enableTouchpad = enableTouchpad; } static const QString NAME; @@ -125,7 +125,7 @@ protected: std::chrono::high_resolution_clock _clock; std::chrono::high_resolution_clock::time_point _lastTouchTime; - static bool _enableMouse; + static bool _enableTouchpad; }; #endif // hifi_KeyboardMouseDevice_h diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp index 9430f1d23a..8e3eea4cf6 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp @@ -51,6 +51,13 @@ void TouchscreenDevice::pluginUpdate(float deltaTime, const controller::InputCal distanceScaleY = (_currentTouchVec.y - _firstTouchVec.y) / DPI_SCALE_Y; _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_NEG).getChannel()] = distanceScaleY; } + } else if (_touchPointCount == 2) { + if (_scaleFactor > _lastPinchScale && _scaleFactor != 0) { + _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_POS).getChannel()] = 1.0f; + } else if (_scaleFactor != 0) { + _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_NEG).getChannel()] = 1.0f; + } + _lastPinchScale = _scaleFactor; } } @@ -64,12 +71,12 @@ void TouchscreenDevice::InputDevice::focusOutEvent() { void TouchscreenDevice::touchBeginEvent(const QTouchEvent* event) { const QTouchEvent::TouchPoint& point = event->touchPoints().at(0); _firstTouchVec = glm::vec2(point.pos().x(), point.pos().y()); - KeyboardMouseDevice::enableMouse(false); + KeyboardMouseDevice::enableTouchpad(false); } void TouchscreenDevice::touchEndEvent(const QTouchEvent* event) { _touchPointCount = 0; - KeyboardMouseDevice::enableMouse(true); + KeyboardMouseDevice::enableTouchpad(true); } void TouchscreenDevice::touchUpdateEvent(const QTouchEvent* event) { @@ -81,13 +88,7 @@ void TouchscreenDevice::touchUpdateEvent(const QTouchEvent* event) { void TouchscreenDevice::touchGestureEvent(const QGestureEvent* event) { if (QGesture* gesture = event->gesture(Qt::PinchGesture)) { QPinchGesture* pinch = static_cast(gesture); - qreal scaleFactor = pinch->totalScaleFactor(); - if (scaleFactor > _lastPinchScale && scaleFactor != 0) { - _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_POS).getChannel()] = 1.0f; - } else if (scaleFactor != 0) { - _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_NEG).getChannel()] = 1.0f; - } - _lastPinchScale = scaleFactor; + _scaleFactor = pinch->totalScaleFactor(); } } @@ -118,4 +119,4 @@ controller::Input::NamedVector TouchscreenDevice::InputDevice::getAvailableInput QString TouchscreenDevice::InputDevice::getDefaultMappingConfig() const { static const QString MAPPING_JSON = PathUtils::resourcesPath() + "/controllers/touchscreen.json"; return MAPPING_JSON; -} \ No newline at end of file +} diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h index 772776348f..53dba19b00 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h @@ -14,6 +14,7 @@ #include #include "InputPlugin.h" +#include class QTouchEvent; class QGestureEvent; @@ -32,10 +33,10 @@ public: enum TouchGestureAxisChannel { TOUCH_GESTURE_PINCH_POS = TOUCH_AXIS_Y_NEG + 1, TOUCH_GESTURE_PINCH_NEG, - }; + }; // Plugin functions - virtual bool isSupported() const override { return true; } + virtual bool isSupported() const override { return QTouchDevice::devices().count() > 0; } virtual const QString& getName() const override { return NAME; } virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); } @@ -71,6 +72,7 @@ public: protected: qreal _lastPinchScale; + qreal _scaleFactor; glm::vec2 _firstTouchVec; glm::vec2 _currentTouchVec; int _touchPointCount; From 480b1a1263c83225496004cda781c1872f458b83 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Mon, 27 Jun 2016 21:06:06 +0100 Subject: [PATCH 16/32] extra line in KeyboardMouse Device there's 2 blank lines at the end of the file --- .../input-plugins/src/input-plugins/KeyboardMouseDevice.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp index 550d127198..6edaddb24a 100755 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp @@ -255,4 +255,3 @@ QString KeyboardMouseDevice::InputDevice::getDefaultMappingConfig() const { static const QString MAPPING_JSON = PathUtils::resourcesPath() + "/controllers/keyboardMouse.json"; return MAPPING_JSON; } - From ab52fc5b3cd244e87729aecb116f57ba127de6cb Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Mon, 27 Jun 2016 21:42:32 +0100 Subject: [PATCH 17/32] json indentation fix --- interface/resources/controllers/touchscreen.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/resources/controllers/touchscreen.json b/interface/resources/controllers/touchscreen.json index 041259bd36..284a7a3914 100644 --- a/interface/resources/controllers/touchscreen.json +++ b/interface/resources/controllers/touchscreen.json @@ -2,8 +2,8 @@ "name": "Touchscreen to Actions", "channels": [ - { "from": "Touchscreen.GesturePinchOut", "to": "Actions.BoomOut", "filters": [ { "type": "scale", "scale": 0.02 } ]}, - { "from": "Touchscreen.GesturePinchIn", "to": "Actions.BoomIn", "filters": [ { "type": "scale", "scale": 0.02 } ]}, + { "from": "Touchscreen.GesturePinchOut", "to": "Actions.BoomOut", "filters": [ { "type": "scale", "scale": 0.02 } ] }, + { "from": "Touchscreen.GesturePinchIn", "to": "Actions.BoomIn", "filters": [ { "type": "scale", "scale": 0.02 } ] }, { "from": { "makeAxis" : [ [ "Touchscreen.DragLeft" ], @@ -13,7 +13,7 @@ "to": "Actions.Yaw" }, - { "from": { "makeAxis" : [ + { "from": { "makeAxis" : [ [ "Touchscreen.DragUp" ], [ "Touchscreen.DragDown" ] ] From 19b6a04175bf302ff2056a0db2917d232741bdcd Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Mon, 27 Jun 2016 23:33:12 +0100 Subject: [PATCH 18/32] indentation causing some issue is this resolved? Hard to tell. --- interface/resources/controllers/touchscreen.json | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/interface/resources/controllers/touchscreen.json b/interface/resources/controllers/touchscreen.json index 284a7a3914..1b4e9723ce 100644 --- a/interface/resources/controllers/touchscreen.json +++ b/interface/resources/controllers/touchscreen.json @@ -1,18 +1,17 @@ { "name": "Touchscreen to Actions", "channels": [ - { "from": "Touchscreen.GesturePinchOut", "to": "Actions.BoomOut", "filters": [ { "type": "scale", "scale": 0.02 } ] }, { "from": "Touchscreen.GesturePinchIn", "to": "Actions.BoomIn", "filters": [ { "type": "scale", "scale": 0.02 } ] }, - + { "from": { "makeAxis" : [ - [ "Touchscreen.DragLeft" ], - [ "Touchscreen.DragRight" ] - ] - }, + [ "Touchscreen.DragLeft" ], + [ "Touchscreen.DragRight" ] + ] + }, "to": "Actions.Yaw" }, - + { "from": { "makeAxis" : [ [ "Touchscreen.DragUp" ], [ "Touchscreen.DragDown" ] From cc6dca853c98cd3e6136f2aeaef17ba2e24d4cda Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Tue, 28 Jun 2016 16:47:13 +0100 Subject: [PATCH 19/32] change TouchScreenDevice based on CR feedback * device support is based on detection of QTouchDevice::TouchScreen * DPI scale is calculated using the screen that generates the touch event --- .../src/input-plugins/TouchscreenDevice.cpp | 33 +++++++++++++------ .../src/input-plugins/TouchscreenDevice.h | 4 ++- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp index 8e3eea4cf6..10bca75e0a 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -22,33 +23,36 @@ const QString TouchscreenDevice::NAME = "Touchscreen"; +bool TouchscreenDevice::isSupported() const { + for (auto touchDevice : QTouchDevice::devices()) { + if (touchDevice->type() == QTouchDevice::TouchScreen) { + return true; + } + } + return false; +} + void TouchscreenDevice::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { auto userInputMapper = DependencyManager::get(); userInputMapper->withLock([&, this]() { _inputDevice->update(deltaTime, inputCalibrationData); }); - // at DPI 100 use these arbitrary values to divide dragging distance - static const float DPI_SCALE_X = glm::clamp((float)(qApp->primaryScreen()->physicalDotsPerInchX() / 100.0), 1.0f, 10.0f) - * 600.0f; - static const float DPI_SCALE_Y = glm::clamp((float)(qApp->primaryScreen()->physicalDotsPerInchY() / 100.0), 1.0f, 10.0f) - * 200.0f; - float distanceScaleX, distanceScaleY; if (_touchPointCount == 1) { if (_firstTouchVec.x < _currentTouchVec.x) { - distanceScaleX = (_currentTouchVec.x - _firstTouchVec.x) / DPI_SCALE_X; + distanceScaleX = (_currentTouchVec.x - _firstTouchVec.x) / _screenDPIScale.x; _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_POS).getChannel()] = distanceScaleX; } else if (_firstTouchVec.x > _currentTouchVec.x) { - distanceScaleX = (_firstTouchVec.x - _currentTouchVec.x) / DPI_SCALE_X; + distanceScaleX = (_firstTouchVec.x - _currentTouchVec.x) / _screenDPIScale.x; _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_NEG).getChannel()] = distanceScaleX; } // Y axis is inverted, positive is pointing up the screen if (_firstTouchVec.y > _currentTouchVec.y) { - distanceScaleY = (_firstTouchVec.y - _currentTouchVec.y) / DPI_SCALE_Y; + distanceScaleY = (_firstTouchVec.y - _currentTouchVec.y) / _screenDPIScale.y; _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_POS).getChannel()] = distanceScaleY; } else if (_firstTouchVec.y < _currentTouchVec.y) { - distanceScaleY = (_currentTouchVec.y - _firstTouchVec.y) / DPI_SCALE_Y; + distanceScaleY = (_currentTouchVec.y - _firstTouchVec.y) / _screenDPIScale.y; _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_NEG).getChannel()] = distanceScaleY; } } else if (_touchPointCount == 2) { @@ -72,6 +76,15 @@ void TouchscreenDevice::touchBeginEvent(const QTouchEvent* event) { const QTouchEvent::TouchPoint& point = event->touchPoints().at(0); _firstTouchVec = glm::vec2(point.pos().x(), point.pos().y()); KeyboardMouseDevice::enableTouchpad(false); + if (_screenDPI != event->window()->screen()->physicalDotsPerInch()) { + // at DPI 100 use these arbitrary values to divide dragging distance + // the value is clamped from 1 to 10 so up to 1000 DPI would be supported atm + _screenDPIScale.x = glm::clamp((float)(qApp->primaryScreen()->physicalDotsPerInchX() / 100.0), 1.0f, 10.0f) + * 600.0f; + _screenDPIScale.y = glm::clamp((float)(qApp->primaryScreen()->physicalDotsPerInchY() / 100.0), 1.0f, 10.0f) + * 200.0f; + _screenDPI = event->window()->screen()->physicalDotsPerInch(); + } } void TouchscreenDevice::touchEndEvent(const QTouchEvent* event) { diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h index 53dba19b00..b354b7e9ec 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h @@ -36,7 +36,7 @@ public: }; // Plugin functions - virtual bool isSupported() const override { return QTouchDevice::devices().count() > 0; } + virtual bool isSupported() const override; virtual const QString& getName() const override { return NAME; } virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); } @@ -73,6 +73,8 @@ public: protected: qreal _lastPinchScale; qreal _scaleFactor; + qreal _screenDPI; + glm::vec2 _screenDPIScale; glm::vec2 _firstTouchVec; glm::vec2 _currentTouchVec; int _touchPointCount; From efdee523fbdb8e266e081de5c91b523697cb9304 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Tue, 28 Jun 2016 17:57:38 +0100 Subject: [PATCH 20/32] coding standard fix and renaming --- interface/resources/controllers/touchscreen.json | 2 +- .../src/input-plugins/KeyboardMouseDevice.cpp | 11 +++++------ .../src/input-plugins/KeyboardMouseDevice.h | 4 ++-- .../src/input-plugins/TouchscreenDevice.cpp | 12 ++++++------ .../src/input-plugins/TouchscreenDevice.h | 2 +- 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/interface/resources/controllers/touchscreen.json b/interface/resources/controllers/touchscreen.json index 1b4e9723ce..21362ce8fb 100644 --- a/interface/resources/controllers/touchscreen.json +++ b/interface/resources/controllers/touchscreen.json @@ -12,7 +12,7 @@ "to": "Actions.Yaw" }, - { "from": { "makeAxis" : [ + { "from": { "makeAxis" : [ [ "Touchscreen.DragUp" ], [ "Touchscreen.DragDown" ] ] diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp index 6edaddb24a..56894efc4c 100755 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp @@ -19,7 +19,7 @@ #include const QString KeyboardMouseDevice::NAME = "Keyboard/Mouse"; -bool KeyboardMouseDevice::_enableTouchpad = true; +bool KeyboardMouseDevice::_enableTouch = true; void KeyboardMouseDevice::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { auto userInputMapper = DependencyManager::get(); @@ -133,7 +133,7 @@ glm::vec2 evalAverageTouchPoints(const QList& points) { } void KeyboardMouseDevice::touchBeginEvent(const QTouchEvent* event) { - if (_enableTouchpad) { + if (_enableTouch) { _isTouching = event->touchPointStates().testFlag(Qt::TouchPointPressed); _lastTouch = evalAverageTouchPoints(event->touchPoints()); _lastTouchTime = _clock.now(); @@ -141,7 +141,7 @@ void KeyboardMouseDevice::touchBeginEvent(const QTouchEvent* event) { } void KeyboardMouseDevice::touchEndEvent(const QTouchEvent* event) { - if (_enableTouchpad) { + if (_enableTouch) { _isTouching = false; _lastTouch = evalAverageTouchPoints(event->touchPoints()); _lastTouchTime = _clock.now(); @@ -149,14 +149,13 @@ void KeyboardMouseDevice::touchEndEvent(const QTouchEvent* event) { } void KeyboardMouseDevice::touchUpdateEvent(const QTouchEvent* event) { - if (_enableTouchpad) { + if (_enableTouch) { auto currentPos = evalAverageTouchPoints(event->touchPoints()); _lastTouchTime = _clock.now(); if (!_isTouching) { _isTouching = event->touchPointStates().testFlag(Qt::TouchPointPressed); - } - else { + } else { auto currentMove = currentPos - _lastTouch; _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_POS).getChannel()] = (currentMove.x > 0 ? currentMove.x : 0.0f); diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h index d88c410ade..2fdecf0bba 100644 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h @@ -85,7 +85,7 @@ public: void wheelEvent(QWheelEvent* event); - static void enableTouchpad(bool enableTouchpad) { _enableTouchpad = enableTouchpad; } + static void enableTouch(bool enableTouch) { _enableTouch = enableTouch; } static const QString NAME; @@ -125,7 +125,7 @@ protected: std::chrono::high_resolution_clock _clock; std::chrono::high_resolution_clock::time_point _lastTouchTime; - static bool _enableTouchpad; + static bool _enableTouch; }; #endif // hifi_KeyboardMouseDevice_h diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp index 10bca75e0a..e9553c1785 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp @@ -56,12 +56,12 @@ void TouchscreenDevice::pluginUpdate(float deltaTime, const controller::InputCal _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_NEG).getChannel()] = distanceScaleY; } } else if (_touchPointCount == 2) { - if (_scaleFactor > _lastPinchScale && _scaleFactor != 0) { + if (_pinchScale > _lastPinchScale && _pinchScale != 0) { _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_POS).getChannel()] = 1.0f; - } else if (_scaleFactor != 0) { + } else if (_pinchScale != 0) { _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_NEG).getChannel()] = 1.0f; } - _lastPinchScale = _scaleFactor; + _lastPinchScale = _pinchScale; } } @@ -75,7 +75,7 @@ void TouchscreenDevice::InputDevice::focusOutEvent() { void TouchscreenDevice::touchBeginEvent(const QTouchEvent* event) { const QTouchEvent::TouchPoint& point = event->touchPoints().at(0); _firstTouchVec = glm::vec2(point.pos().x(), point.pos().y()); - KeyboardMouseDevice::enableTouchpad(false); + KeyboardMouseDevice::enableTouch(false); if (_screenDPI != event->window()->screen()->physicalDotsPerInch()) { // at DPI 100 use these arbitrary values to divide dragging distance // the value is clamped from 1 to 10 so up to 1000 DPI would be supported atm @@ -89,7 +89,7 @@ void TouchscreenDevice::touchBeginEvent(const QTouchEvent* event) { void TouchscreenDevice::touchEndEvent(const QTouchEvent* event) { _touchPointCount = 0; - KeyboardMouseDevice::enableTouchpad(true); + KeyboardMouseDevice::enableTouch(true); } void TouchscreenDevice::touchUpdateEvent(const QTouchEvent* event) { @@ -101,7 +101,7 @@ void TouchscreenDevice::touchUpdateEvent(const QTouchEvent* event) { void TouchscreenDevice::touchGestureEvent(const QGestureEvent* event) { if (QGesture* gesture = event->gesture(Qt::PinchGesture)) { QPinchGesture* pinch = static_cast(gesture); - _scaleFactor = pinch->totalScaleFactor(); + _pinchScale = pinch->totalScaleFactor(); } } diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h index b354b7e9ec..f89f247ce8 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h @@ -72,7 +72,7 @@ public: protected: qreal _lastPinchScale; - qreal _scaleFactor; + qreal _pinchScale; qreal _screenDPI; glm::vec2 _screenDPIScale; glm::vec2 _firstTouchVec; From 97e90ed798625bb9b06a81cefc32453a70cd310f Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Wed, 29 Jun 2016 03:45:54 +0100 Subject: [PATCH 21/32] TouchscreenDevice DPI scaling now handled via JSON mapping do the arbitrary scaling in the mapping file --- interface/resources/controllers/touchscreen.json | 4 ++-- .../input-plugins/src/input-plugins/TouchscreenDevice.cpp | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/interface/resources/controllers/touchscreen.json b/interface/resources/controllers/touchscreen.json index 21362ce8fb..5b2ff62a8d 100644 --- a/interface/resources/controllers/touchscreen.json +++ b/interface/resources/controllers/touchscreen.json @@ -9,7 +9,7 @@ [ "Touchscreen.DragRight" ] ] }, - "to": "Actions.Yaw" + "to": "Actions.Yaw", "filters": [ { "type": "scale", "scale": 0.12 } ] }, { "from": { "makeAxis" : [ @@ -17,7 +17,7 @@ [ "Touchscreen.DragDown" ] ] }, - "to": "Actions.Pitch" + "to": "Actions.Pitch", "filters": [ { "type": "scale", "scale": 0.04 } ] } ] } diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp index e9553c1785..271a3bb732 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp @@ -77,12 +77,6 @@ void TouchscreenDevice::touchBeginEvent(const QTouchEvent* event) { _firstTouchVec = glm::vec2(point.pos().x(), point.pos().y()); KeyboardMouseDevice::enableTouch(false); if (_screenDPI != event->window()->screen()->physicalDotsPerInch()) { - // at DPI 100 use these arbitrary values to divide dragging distance - // the value is clamped from 1 to 10 so up to 1000 DPI would be supported atm - _screenDPIScale.x = glm::clamp((float)(qApp->primaryScreen()->physicalDotsPerInchX() / 100.0), 1.0f, 10.0f) - * 600.0f; - _screenDPIScale.y = glm::clamp((float)(qApp->primaryScreen()->physicalDotsPerInchY() / 100.0), 1.0f, 10.0f) - * 200.0f; _screenDPI = event->window()->screen()->physicalDotsPerInch(); } } From 2c56d29a68e508020941794f8a5bb17b65013d14 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Wed, 29 Jun 2016 03:47:20 +0100 Subject: [PATCH 22/32] git add seemed to miss a change use event window, not primaryScreen --- libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp index 271a3bb732..12e990757d 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp @@ -77,6 +77,8 @@ void TouchscreenDevice::touchBeginEvent(const QTouchEvent* event) { _firstTouchVec = glm::vec2(point.pos().x(), point.pos().y()); KeyboardMouseDevice::enableTouch(false); if (_screenDPI != event->window()->screen()->physicalDotsPerInch()) { + _screenDPIScale.x = (float)event->window()->screen()->physicalDotsPerInchX(); + _screenDPIScale.y = (float)event->window()->screen()->physicalDotsPerInchY(); _screenDPI = event->window()->screen()->physicalDotsPerInch(); } } From 9b993b266528bee8a4b39c7e93b791ceb417ebff Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Wed, 29 Jun 2016 03:58:17 +0100 Subject: [PATCH 23/32] store pointer to event->window()->screen() save the planet! --- .../src/input-plugins/TouchscreenDevice.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp index 12e990757d..64f02b5df3 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp @@ -76,10 +76,11 @@ void TouchscreenDevice::touchBeginEvent(const QTouchEvent* event) { const QTouchEvent::TouchPoint& point = event->touchPoints().at(0); _firstTouchVec = glm::vec2(point.pos().x(), point.pos().y()); KeyboardMouseDevice::enableTouch(false); - if (_screenDPI != event->window()->screen()->physicalDotsPerInch()) { - _screenDPIScale.x = (float)event->window()->screen()->physicalDotsPerInchX(); - _screenDPIScale.y = (float)event->window()->screen()->physicalDotsPerInchY(); - _screenDPI = event->window()->screen()->physicalDotsPerInch(); + QScreen* eventScreen = event->window()->screen(); + if (_screenDPI != eventScreen->physicalDotsPerInch()) { + _screenDPIScale.x = (float)eventScreen->physicalDotsPerInchX(); + _screenDPIScale.y = (float)eventScreen->physicalDotsPerInchY(); + _screenDPI = eventScreen->physicalDotsPerInch(); } } From a07970f05357fcf563845578cd5b2c4d99fe13aa Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 6 Jul 2016 14:09:55 -0700 Subject: [PATCH 24/32] Fix for one-frame glitch when changing dimensions of a model entity. This was due to Model::setScaleToFit being called on the script thread instead of the main thread. --- interface/src/ui/overlays/ModelOverlay.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index adf08934f0..b07e8bb48a 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -100,7 +100,9 @@ void ModelOverlay::setProperties(const QVariantMap& properties) { if (newScale.x <= 0 || newScale.y <= 0 || newScale.z <= 0) { setDimensions(scale); } else { - _model->setScaleToFit(true, getDimensions()); + QMetaObject::invokeMethod(_model.get(), "setScaleToFit", Qt::AutoConnection, + Q_ARG(const bool&, true), + Q_ARG(const glm::vec3&, getDimensions())); _updateModel = true; } } From 2db8160568cb01520cf1cf777cfbad0113de70d7 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 6 Jul 2016 15:46:14 -0700 Subject: [PATCH 25/32] handControllerGrab improvements * Made handControllerGrab eslint clean * A model overlay is used instead of a sphere to draw equip hotspots. * The equip hotspot model will grow in size by 10% when hand is near enough to equip it. * The hand controller will now perform a haptic pulse when your hand is near enough to an equip hotspot. * Near triggers events will also perform a haptic pulse --- .../system/controllers/handControllerGrab.js | 315 ++++++++++-------- 1 file changed, 180 insertions(+), 135 deletions(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index ecece8c4f7..869ea98b34 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -72,6 +72,9 @@ var LINE_ENTITY_DIMENSIONS = { var LINE_LENGTH = 500; var PICK_MAX_DISTANCE = 500; // max length of pick-ray +var EQUIP_RADIUS_TO_MODEL_SCALE_FACTOR = 0.75; +var EQUIP_RADIUS_EMBIGGEN_FACTOR = 1.1; + // // near grabbing // @@ -269,17 +272,17 @@ function restore2DMode() { function EntityPropertiesCache() { this.cache = {}; } -EntityPropertiesCache.prototype.clear = function() { +EntityPropertiesCache.prototype.clear = function () { this.cache = {}; }; -EntityPropertiesCache.prototype.findEntities = function(position, radius) { +EntityPropertiesCache.prototype.findEntities = function (position, radius) { var entities = Entities.findEntities(position, radius); var _this = this; - entities.forEach(function(x) { + entities.forEach(function (x) { _this.updateEntity(x); }); }; -EntityPropertiesCache.prototype.updateEntity = function(entityID) { +EntityPropertiesCache.prototype.updateEntity = function (entityID) { var props = Entities.getEntityProperties(entityID, GRABBABLE_PROPERTIES); // convert props.userData from a string to an object. @@ -295,14 +298,14 @@ EntityPropertiesCache.prototype.updateEntity = function(entityID) { this.cache[entityID] = props; }; -EntityPropertiesCache.prototype.getEntities = function() { +EntityPropertiesCache.prototype.getEntities = function () { return Object.keys(this.cache); }; -EntityPropertiesCache.prototype.getProps = function(entityID) { +EntityPropertiesCache.prototype.getProps = function (entityID) { var obj = this.cache[entityID]; return obj ? obj : undefined; }; -EntityPropertiesCache.prototype.getGrabbableProps = function(entityID) { +EntityPropertiesCache.prototype.getGrabbableProps = function (entityID) { var props = this.cache[entityID]; if (props) { return props.userData.grabbableKey ? props.userData.grabbableKey : DEFAULT_GRABBABLE_DATA; @@ -310,7 +313,7 @@ EntityPropertiesCache.prototype.getGrabbableProps = function(entityID) { return undefined; } }; -EntityPropertiesCache.prototype.getGrabProps = function(entityID) { +EntityPropertiesCache.prototype.getGrabProps = function (entityID) { var props = this.cache[entityID]; if (props) { return props.userData.grabKey ? props.userData.grabKey : {}; @@ -318,7 +321,7 @@ EntityPropertiesCache.prototype.getGrabProps = function(entityID) { return undefined; } }; -EntityPropertiesCache.prototype.getWearableProps = function(entityID) { +EntityPropertiesCache.prototype.getWearableProps = function (entityID) { var props = this.cache[entityID]; if (props) { return props.userData.wearable ? props.userData.wearable : {}; @@ -326,7 +329,7 @@ EntityPropertiesCache.prototype.getWearableProps = function(entityID) { return undefined; } }; -EntityPropertiesCache.prototype.getEquipHotspotsProps = function(entityID) { +EntityPropertiesCache.prototype.getEquipHotspotsProps = function (entityID) { var props = this.cache[entityID]; if (props) { return props.userData.equipHotspots ? props.userData.equipHotspots : {}; @@ -344,7 +347,7 @@ function MyController(hand) { this.getHandPosition = MyAvatar.getLeftPalmPosition; // this.getHandRotation = MyAvatar.getLeftPalmRotation; } - this.getHandRotation = function() { + this.getHandRotation = function () { var controllerHandInput = (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand; return Quat.multiply(MyAvatar.orientation, Controller.getPoseValue(controllerHandInput).rotation); }; @@ -389,13 +392,13 @@ function MyController(hand) { var _this = this; var suppressedIn2D = [STATE_OFF, STATE_SEARCHING]; - this.ignoreInput = function() { + this.ignoreInput = function () { // We've made the decision to use 'this' for new code, even though it is fragile, // in order to keep/ the code uniform without making any no-op line changes. return (-1 !== suppressedIn2D.indexOf(this.state)) && isIn2DMode(); }; - this.update = function(deltaTime) { + this.update = function (deltaTime) { this.updateSmoothedTrigger(); @@ -417,12 +420,12 @@ function MyController(hand) { } }; - this.callEntityMethodOnGrabbed = function(entityMethodName) { + this.callEntityMethodOnGrabbed = function (entityMethodName) { var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; Entities.callEntityMethod(this.grabbedEntity, entityMethodName, args); }; - this.setState = function(newState, reason) { + this.setState = function (newState, reason) { if (WANT_DEBUG || WANT_DEBUG_STATE) { var oldStateName = stateToName(this.state); @@ -455,7 +458,7 @@ function MyController(hand) { } }; - this.debugLine = function(closePoint, farPoint, color) { + this.debugLine = function (closePoint, farPoint, color) { Entities.addEntity({ type: "Line", name: "Grab Debug Entity", @@ -475,7 +478,7 @@ function MyController(hand) { }); }; - this.lineOn = function(closePoint, farPoint, color) { + this.lineOn = function (closePoint, farPoint, color) { // draw a line if (this.pointer === null) { this.pointer = Entities.addEntity({ @@ -507,7 +510,7 @@ function MyController(hand) { }; var SEARCH_SPHERE_ALPHA = 0.5; - this.searchSphereOn = function(location, size, color) { + this.searchSphereOn = function (location, size, color) { if (this.searchSphere === null) { var sphereProperties = { position: location, @@ -530,7 +533,7 @@ function MyController(hand) { } }; - this.overlayLineOn = function(closePoint, farPoint, color) { + this.overlayLineOn = function (closePoint, farPoint, color) { if (this.overlayLine === null) { var lineProperties = { lineWidth: 5, @@ -558,7 +561,7 @@ function MyController(hand) { } }; - this.searchIndicatorOn = function(distantPickRay) { + this.searchIndicatorOn = function (distantPickRay) { var handPosition = distantPickRay.origin; var SEARCH_SPHERE_SIZE = 0.011; var SEARCH_SPHERE_FOLLOW_RATE = 0.50; @@ -579,7 +582,7 @@ function MyController(hand) { } }; - this.handleDistantParticleBeam = function(handPosition, objectPosition, color) { + this.handleDistantParticleBeam = function (handPosition, objectPosition, color) { var handToObject = Vec3.subtract(objectPosition, handPosition); var finalRotationObject = Quat.rotationBetween(Vec3.multiply(-1, Vec3.UP), handToObject); @@ -595,7 +598,7 @@ function MyController(hand) { } }; - this.createParticleBeam = function(positionObject, orientationObject, color, speed, spread, lifespan) { + this.createParticleBeam = function (positionObject, orientationObject, color, speed, spread, lifespan) { var particleBeamPropertiesObject = { type: "ParticleEffect", @@ -649,7 +652,7 @@ function MyController(hand) { this.particleBeamObject = Entities.addEntity(particleBeamPropertiesObject); }; - this.updateParticleBeam = function(positionObject, orientationObject, color, speed, spread, lifespan) { + this.updateParticleBeam = function (positionObject, orientationObject, color, speed, spread, lifespan) { Entities.editEntity(this.particleBeamObject, { rotation: orientationObject, position: positionObject, @@ -661,7 +664,7 @@ function MyController(hand) { }); }; - this.evalLightWorldTransform = function(modelPos, modelRot) { + this.evalLightWorldTransform = function (modelPos, modelRot) { var MODEL_LIGHT_POSITION = { x: 0, @@ -681,7 +684,7 @@ function MyController(hand) { }; }; - this.handleSpotlight = function(parentID) { + this.handleSpotlight = function (parentID) { var LIFETIME = 100; var modelProperties = Entities.getEntityProperties(parentID, ['position', 'rotation']); @@ -718,7 +721,7 @@ function MyController(hand) { } }; - this.handlePointLight = function(parentID) { + this.handlePointLight = function (parentID) { var LIFETIME = 100; var modelProperties = Entities.getEntityProperties(parentID, ['position', 'rotation']); @@ -750,21 +753,21 @@ function MyController(hand) { } }; - this.lineOff = function() { + this.lineOff = function () { if (this.pointer !== null) { Entities.deleteEntity(this.pointer); } this.pointer = null; }; - this.overlayLineOff = function() { + this.overlayLineOff = function () { if (this.overlayLine !== null) { Overlays.deleteOverlay(this.overlayLine); } this.overlayLine = null; }; - this.searchSphereOff = function() { + this.searchSphereOff = function () { if (this.searchSphere !== null) { Overlays.deleteOverlay(this.searchSphere); this.searchSphere = null; @@ -773,14 +776,14 @@ function MyController(hand) { } }; - this.particleBeamOff = function() { + this.particleBeamOff = function () { if (this.particleBeamObject !== null) { Entities.deleteEntity(this.particleBeamObject); this.particleBeamObject = null; } }; - this.turnLightsOff = function() { + this.turnLightsOff = function () { if (this.spotlight !== null) { Entities.deleteEntity(this.spotlight); this.spotlight = null; @@ -792,7 +795,7 @@ function MyController(hand) { } }; - this.turnOffVisualizations = function() { + this.turnOffVisualizations = function () { if (USE_ENTITY_LINES_FOR_SEARCHING === true || USE_ENTITY_LINES_FOR_MOVING === true) { this.lineOff(); } @@ -809,63 +812,62 @@ function MyController(hand) { }; - this.triggerPress = function(value) { + this.triggerPress = function (value) { _this.rawTriggerValue = value; }; - this.secondaryPress = function(value) { + this.secondaryPress = function (value) { _this.rawSecondaryValue = value; }; - this.updateSmoothedTrigger = function() { + this.updateSmoothedTrigger = function () { var triggerValue = this.rawTriggerValue; // smooth out trigger value this.triggerValue = (this.triggerValue * TRIGGER_SMOOTH_RATIO) + (triggerValue * (1.0 - TRIGGER_SMOOTH_RATIO)); }; - this.triggerSmoothedGrab = function() { + this.triggerSmoothedGrab = function () { return this.triggerValue > TRIGGER_GRAB_VALUE; }; - this.triggerSmoothedSqueezed = function() { + this.triggerSmoothedSqueezed = function () { return this.triggerValue > TRIGGER_ON_VALUE; }; - this.triggerSmoothedReleased = function() { + this.triggerSmoothedReleased = function () { return this.triggerValue < TRIGGER_OFF_VALUE; }; - this.secondarySqueezed = function() { + this.secondarySqueezed = function () { return _this.rawSecondaryValue > BUMPER_ON_VALUE; }; - this.secondaryReleased = function() { + this.secondaryReleased = function () { return _this.rawSecondaryValue < BUMPER_ON_VALUE; }; - // this.triggerOrsecondarySqueezed = function() { + // this.triggerOrsecondarySqueezed = function () { // return triggerSmoothedSqueezed() || secondarySqueezed(); // } - // this.triggerAndSecondaryReleased = function() { + // this.triggerAndSecondaryReleased = function () { // return triggerSmoothedReleased() && secondaryReleased(); // } - this.thumbPress = function(value) { + this.thumbPress = function (value) { _this.rawThumbValue = value; }; - this.thumbPressed = function() { + this.thumbPressed = function () { return _this.rawThumbValue > THUMB_ON_VALUE; }; - this.thumbReleased = function() { + this.thumbReleased = function () { return _this.rawThumbValue < THUMB_ON_VALUE; }; - this.off = function() { - + this.off = function () { if (this.triggerSmoothedReleased()) { this.waitForTriggerRelease = false; } @@ -875,11 +877,21 @@ function MyController(hand) { this.startingHandRotation = Controller.getPoseValue(controllerHandInput).rotation; if (this.triggerSmoothedSqueezed()) { this.setState(STATE_SEARCHING, "trigger squeeze detected"); + return; } } + + if (!this.waitForTriggerRelease) { + // update haptics when hand is near an equip hotspot + this.entityPropertyCache.clear(); + this.entityPropertyCache.findEntities(this.getHandPosition(), NEAR_GRAB_RADIUS); + var candidateEntities = this.entityPropertyCache.getEntities(); + var potentialEquipHotspot = this.chooseBestEquipHotspot(candidateEntities); + this.updateEquipHaptics(potentialEquipHotspot); + } }; - this.createHotspots = function() { + this.createHotspots = function () { var _this = this; var HAND_EQUIP_SPHERE_COLOR = { red: 90, green: 255, blue: 90 }; @@ -890,9 +902,6 @@ function MyController(hand) { var HAND_GRAB_SPHERE_ALPHA = 0.3; var HAND_GRAB_SPHERE_RADIUS = NEAR_GRAB_RADIUS; - var EQUIP_SPHERE_COLOR = { red: 90, green: 255, blue: 90 }; - var EQUIP_SPHERE_ALPHA = 0.3; - var GRAB_BOX_COLOR = { red: 90, green: 90, blue: 255 }; var GRAB_BOX_ALPHA = 0.1; @@ -915,7 +924,9 @@ function MyController(hand) { this.hotspotOverlays.push({ entityID: undefined, overlay: overlay, - type: "hand" + type: "hand", + localPosition: {x: 0, y: 0, z: 0}, + hotspot: {} }); // add larger blue sphere around the palm. @@ -933,7 +944,8 @@ function MyController(hand) { entityID: undefined, overlay: overlay, type: "hand", - localPosition: {x: 0, y: 0, z: 0} + localPosition: {x: 0, y: 0, z: 0}, + hotspot: {} }); } @@ -943,7 +955,7 @@ function MyController(hand) { if (DRAW_GRAB_BOXES) { // add blue box overlays for grabbable entities. - this.entityPropertyCache.getEntities().forEach(function(entityID) { + this.entityPropertyCache.getEntities().forEach(function (entityID) { var props = _this.entityPropertyCache.getProps(entityID); if (_this.entityIsGrabbable(entityID)) { var overlay = Overlays.addOverlay("cube", { @@ -961,50 +973,72 @@ function MyController(hand) { entityID: entityID, overlay: overlay, type: "near", - localPosition: {x: 0, y: 0, z: 0} + localPosition: {x: 0, y: 0, z: 0}, + hotspot: {} }); } }); } // add green spheres for each equippable hotspot. - flatten(this.entityPropertyCache.getEntities().map(function(entityID) { + flatten(this.entityPropertyCache.getEntities().map(function (entityID) { return _this.collectEquipHotspots(entityID); - })).filter(function(hotspot) { + })).filter(function (hotspot) { return _this.hotspotIsEquippable(hotspot); - }).forEach(function(hotspot) { - var overlay = Overlays.addOverlay("sphere", { + }).forEach(function (hotspot) { + var overlay = Overlays.addOverlay("model", { + url: "http://hifi-content.s3.amazonaws.com/alan/dev/equip-ico-2.fbx", position: hotspot.worldPosition, - size: hotspot.radius * 2, - color: EQUIP_SPHERE_COLOR, - alpha: EQUIP_SPHERE_ALPHA, - solid: true, - visible: true, - ignoreRayIntersection: true, - drawInFront: false + rotation: {x: 0, y: 0, z: 0, w: 1}, + dimensions: (hotspot.radius / EQUIP_RADIUS) * EQUIP_RADIUS_TO_MODEL_SCALE_FACTOR, + ignoreRayIntersection: true }); _this.hotspotOverlays.push({ entityID: hotspot.entityID, overlay: overlay, type: "equip", - localPosition: hotspot.localPosition + localPosition: hotspot.localPosition, + hotspot: hotspot }); }); }; - this.updateHotspots = function() { + this.clearEquipHaptics = function () { + this.prevPotentialEquipHotspot = null; + }; + + this.updateEquipHaptics = function (potentialEquipHotspot) { + if (potentialEquipHotspot && !this.prevPotentialEquipHotspot || + !potentialEquipHotspot && this.prevPotentialEquipHotspot) { + Controller.triggerShortHapticPulse(1.0, this.hand); + } + this.prevPotentialEquipHotspot = potentialEquipHotspot; + }; + + this.updateHotspots = function (potentialEquipHotspot) { var _this = this; var props; - this.hotspotOverlays.forEach(function(overlayInfo) { + this.hotspotOverlays.forEach(function (overlayInfo) { if (overlayInfo.type === "hand") { Overlays.editOverlay(overlayInfo.overlay, { position: _this.getHandPosition() }); } else if (overlayInfo.type === "equip") { + + var radius = (overlayInfo.hotspot.radius / EQUIP_RADIUS) * EQUIP_RADIUS_TO_MODEL_SCALE_FACTOR; + + // embiggen the equipHotspot if it maches the potentialEquipHotspot + if (potentialEquipHotspot && overlayInfo.entityID == potentialEquipHotspot.entityID && + Vec3.equal(overlayInfo.localPosition, potentialEquipHotspot.localPosition)) { + radius = (overlayInfo.hotspot.radius / EQUIP_RADIUS) * EQUIP_RADIUS_TO_MODEL_SCALE_FACTOR * + EQUIP_RADIUS_EMBIGGEN_FACTOR; + } + _this.entityPropertyCache.updateEntity(overlayInfo.entityID); props = _this.entityPropertyCache.getProps(overlayInfo.entityID); var entityXform = new Xform(props.rotation, props.position); Overlays.editOverlay(overlayInfo.overlay, { position: entityXform.xformPoint(overlayInfo.localPosition), - rotation: props.rotation + rotation: props.rotation, + dimensions: radius }); } else if (overlayInfo.type === "near") { _this.entityPropertyCache.updateEntity(overlayInfo.entityID); @@ -1014,18 +1048,18 @@ function MyController(hand) { }); }; - this.destroyHotspots = function() { - this.hotspotOverlays.forEach(function(overlayInfo) { + this.destroyHotspots = function () { + this.hotspotOverlays.forEach(function (overlayInfo) { Overlays.deleteOverlay(overlayInfo.overlay); }); this.hotspotOverlays = []; }; - this.searchEnter = function() { + this.searchEnter = function () { this.createHotspots(); }; - this.searchExit = function() { + this.searchExit = function () { this.destroyHotspots(); }; @@ -1033,7 +1067,7 @@ function MyController(hand) { // @param {number} which hand to use, RIGHT_HAND or LEFT_HAND // @returns {object} returns object with two keys entityID and distance // - this.calcRayPickInfo = function(hand) { + this.calcRayPickInfo = function (hand) { var standardControllerValue = (hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand; var pose = Controller.getPoseValue(standardControllerValue); @@ -1091,7 +1125,7 @@ function MyController(hand) { } }; - this.entityWantsTrigger = function(entityID) { + this.entityWantsTrigger = function (entityID) { var grabbableProps = this.entityPropertyCache.getGrabbableProps(entityID); return grabbableProps && grabbableProps.wantsTrigger; }; @@ -1105,7 +1139,7 @@ function MyController(hand) { // * radius {number} radius of equip hotspot // * joints {Object} keys are joint names values are arrays of two elements: // offset position {Vec3} and offset rotation {Quat}, both are in the coordinate system of the joint. - this.collectEquipHotspots = function(entityID) { + this.collectEquipHotspots = function (entityID) { var result = []; var props = this.entityPropertyCache.getProps(entityID); var entityXform = new Xform(props.rotation, props.position); @@ -1139,7 +1173,7 @@ function MyController(hand) { return result; }; - this.hotspotIsEquippable = function(hotspot) { + this.hotspotIsEquippable = function (hotspot) { var props = this.entityPropertyCache.getProps(hotspot.entityID); var grabProps = this.entityPropertyCache.getGrabProps(hotspot.entityID); var debug = (WANT_DEBUG_SEARCH_NAME && props.name === WANT_DEBUG_SEARCH_NAME); @@ -1158,7 +1192,7 @@ function MyController(hand) { return true; }; - this.entityIsGrabbable = function(entityID) { + this.entityIsGrabbable = function (entityID) { var grabbableProps = this.entityPropertyCache.getGrabbableProps(entityID); var grabProps = this.entityPropertyCache.getGrabProps(entityID); var props = this.entityPropertyCache.getProps(entityID); @@ -1210,7 +1244,7 @@ function MyController(hand) { return true; }; - this.entityIsDistanceGrabbable = function(entityID, handPosition) { + this.entityIsDistanceGrabbable = function (entityID, handPosition) { if (!this.entityIsGrabbable(entityID)) { return false; } @@ -1247,7 +1281,7 @@ function MyController(hand) { return true; }; - this.entityIsNearGrabbable = function(entityID, handPosition, maxDistance) { + this.entityIsNearGrabbable = function (entityID, handPosition, maxDistance) { if (!this.entityIsGrabbable(entityID)) { return false; @@ -1268,12 +1302,31 @@ function MyController(hand) { return true; }; - this.search = function() { + this.chooseBestEquipHotspot = function (candidateEntities) { + var equippableHotspots = flatten(candidateEntities.map(function (entityID) { + return _this.collectEquipHotspots(entityID); + })).filter(function (hotspot) { + return (_this.hotspotIsEquippable(hotspot) && + Vec3.distance(hotspot.worldPosition, _this.getHandPosition()) < hotspot.radius); + }); + + if (equippableHotspots.length > 0) { + // sort by distance + equippableHotspots.sort(function (a, b) { + var aDistance = Vec3.distance(a.worldPosition, this.getHandPosition()); + var bDistance = Vec3.distance(b.worldPosition, this.getHandPosition()); + return aDistance - bDistance; + }); + return equippableHotspots[0]; + } else { + return null; + } + }; + + this.search = function () { var _this = this; var name; - this.updateHotspots(); - this.grabbedEntity = null; this.isInitialGrab = false; this.shouldResetParentOnRelease = false; @@ -1291,31 +1344,17 @@ function MyController(hand) { this.entityPropertyCache.findEntities(handPosition, NEAR_GRAB_RADIUS); var candidateEntities = this.entityPropertyCache.getEntities(); - var equippableHotspots = flatten(candidateEntities.map(function(entityID) { - return _this.collectEquipHotspots(entityID); - })).filter(function(hotspot) { - return _this.hotspotIsEquippable(hotspot) && Vec3.distance(hotspot.worldPosition, handPosition) < hotspot.radius; - }); - - var entity; - if (equippableHotspots.length > 0) { - // sort by distance - equippableHotspots.sort(function(a, b) { - var aDistance = Vec3.distance(a.worldPosition, handPosition); - var bDistance = Vec3.distance(b.worldPosition, handPosition); - return aDistance - bDistance; - }); + var potentialEquipHotspot = this.chooseBestEquipHotspot(candidateEntities); + if (potentialEquipHotspot) { if (this.triggerSmoothedGrab()) { - this.grabbedHotspot = equippableHotspots[0]; - this.grabbedEntity = equippableHotspots[0].entityID; + this.grabbedHotspot = potentialEquipHotspot; + this.grabbedEntity = potentialEquipHotspot.entityID; this.setState(STATE_HOLD, "eqipping '" + this.entityPropertyCache.getProps(this.grabbedEntity).name + "'"); return; - } else { - // TODO: highlight the equippable object? } } - var grabbableEntities = candidateEntities.filter(function(entity) { + var grabbableEntities = candidateEntities.filter(function (entity) { return _this.entityIsNearGrabbable(entity, handPosition, NEAR_GRAB_MAX_DISTANCE); }); @@ -1330,9 +1369,10 @@ function MyController(hand) { this.intersectionDistance = 0; } + var entity; if (grabbableEntities.length > 0) { // sort by distance - grabbableEntities.sort(function(a, b) { + grabbableEntities.sort(function (a, b) { var aDistance = Vec3.distance(_this.entityPropertyCache.getProps(a).position, handPosition); var bDistance = Vec3.distance(_this.entityPropertyCache.getProps(b).position, handPosition); return aDistance - bDistance; @@ -1345,11 +1385,10 @@ function MyController(hand) { this.setState(STATE_NEAR_TRIGGER, "near trigger '" + name + "'"); return; } else { - // TODO: highlight the near-triggerable object? + // potentialNearTriggerEntity = entity; } } else { if (this.triggerSmoothedGrab()) { - var props = this.entityPropertyCache.getProps(entity); var grabProps = this.entityPropertyCache.getGrabProps(entity); var refCount = grabProps.refCount ? grabProps.refCount : 0; @@ -1364,10 +1403,9 @@ function MyController(hand) { this.setState(STATE_NEAR_GRABBING, "near grab '" + name + "'"); return; } else { - // TODO: highlight the grabbable object? + // potentialNearGrabEntity = entity; } } - return; } if (rayPickInfo.entityID) { @@ -1379,7 +1417,7 @@ function MyController(hand) { this.setState(STATE_FAR_TRIGGER, "far trigger '" + name + "'"); return; } else { - // TODO: highlight the far-triggerable object? + // potentialFarTriggerEntity = entity; } } else if (this.entityIsDistanceGrabbable(rayPickInfo.entityID, handPosition)) { if (this.triggerSmoothedGrab()) { @@ -1387,11 +1425,14 @@ function MyController(hand) { this.setState(STATE_DISTANCE_HOLDING, "distance hold '" + name + "'"); return; } else { - // TODO: highlight the far-grabbable object? + // potentialFarGrabEntity = entity; } } } + this.updateEquipHaptics(potentialEquipHotspot); + this.updateHotspots(potentialEquipHotspot); + // search line visualizations if (USE_ENTITY_LINES_FOR_SEARCHING === true) { this.lineOn(rayPickInfo.searchRay.origin, @@ -1403,7 +1444,7 @@ function MyController(hand) { Reticle.setVisible(false); }; - this.distanceGrabTimescale = function(mass, distance) { + this.distanceGrabTimescale = function (mass, distance) { var timeScale = DISTANCE_HOLDING_ACTION_TIMEFRAME * mass / DISTANCE_HOLDING_UNITY_MASS * distance / DISTANCE_HOLDING_UNITY_DISTANCE; @@ -1413,11 +1454,13 @@ function MyController(hand) { return timeScale; }; - this.getMass = function(dimensions, density) { + this.getMass = function (dimensions, density) { return (dimensions.x * dimensions.y * dimensions.z) * density; }; - this.distanceHoldingEnter = function() { + this.distanceHoldingEnter = function () { + + this.clearEquipHaptics(); // controller pose is in avatar frame var avatarControllerPose = @@ -1476,7 +1519,7 @@ function MyController(hand) { this.previousControllerRotation = controllerRotation; }; - this.distanceHolding = function() { + this.distanceHolding = function () { if (this.triggerSmoothedReleased()) { this.callEntityMethodOnGrabbed("releaseGrab"); this.setState(STATE_OFF, "trigger released"); @@ -1608,7 +1651,7 @@ function MyController(hand) { this.previousControllerRotation = controllerRotation; }; - this.setupHoldAction = function() { + this.setupHoldAction = function () { this.actionID = Entities.addAction("hold", this.grabbedEntity, { hand: this.hand === RIGHT_HAND ? "right" : "left", timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, @@ -1628,7 +1671,7 @@ function MyController(hand) { return true; }; - this.projectVectorAlongAxis = function(position, axisStart, axisEnd) { + this.projectVectorAlongAxis = function (position, axisStart, axisEnd) { var aPrime = Vec3.subtract(position, axisStart); var bPrime = Vec3.subtract(axisEnd, axisStart); var bPrimeMagnitude = Vec3.length(bPrime); @@ -1644,12 +1687,12 @@ function MyController(hand) { return projection; }; - this.dropGestureReset = function() { + this.dropGestureReset = function () { this.fastHandMoveDetected = false; this.fastHandMoveTimer = 0; }; - this.dropGestureProcess = function(deltaTime) { + this.dropGestureProcess = function (deltaTime) { var standardControllerValue = (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand; var pose = Controller.getPoseValue(standardControllerValue); var worldHandVelocity = Vec3.multiplyQbyV(MyAvatar.orientation, pose.velocity); @@ -1688,12 +1731,13 @@ function MyController(hand) { return (DROP_WITHOUT_SHAKE || this.fastHandMoveDetected) && handIsUpsideDown; }; - this.nearGrabbingEnter = function() { + this.nearGrabbingEnter = function () { this.lineOff(); this.overlayLineOff(); this.dropGestureReset(); + this.clearEquipHaptics(); if (this.entityActivated) { var saveGrabbedID = this.grabbedEntity; @@ -1793,7 +1837,7 @@ function MyController(hand) { this.currentAngularVelocity = ZERO_VEC; }; - this.nearGrabbing = function(deltaTime) { + this.nearGrabbing = function (deltaTime) { var dropDetected = this.dropGestureProcess(deltaTime); @@ -1910,15 +1954,16 @@ function MyController(hand) { } }; - this.nearTriggerEnter = function() { + this.nearTriggerEnter = function () { + Controller.triggerShortHapticPulse(1.0, this.hand); this.callEntityMethodOnGrabbed("startNearTrigger"); }; - this.farTriggerEnter = function() { + this.farTriggerEnter = function () { this.callEntityMethodOnGrabbed("startFarTrigger"); }; - this.nearTrigger = function() { + this.nearTrigger = function () { if (this.triggerSmoothedReleased()) { this.callEntityMethodOnGrabbed("stopNearTrigger"); this.setState(STATE_OFF, "trigger released"); @@ -1927,7 +1972,7 @@ function MyController(hand) { this.callEntityMethodOnGrabbed("continueNearTrigger"); }; - this.farTrigger = function() { + this.farTrigger = function () { if (this.triggerSmoothedReleased()) { this.callEntityMethodOnGrabbed("stopFarTrigger"); this.setState(STATE_OFF, "trigger released"); @@ -1960,11 +2005,11 @@ function MyController(hand) { this.callEntityMethodOnGrabbed("continueFarTrigger"); }; - this.offEnter = function() { + this.offEnter = function () { this.release(); }; - this.release = function() { + this.release = function () { this.turnLightsOff(); this.turnOffVisualizations(); @@ -2002,14 +2047,14 @@ function MyController(hand) { } }; - this.cleanup = function() { + this.cleanup = function () { this.release(); Entities.deleteEntity(this.particleBeamObject); Entities.deleteEntity(this.spotLight); Entities.deleteEntity(this.pointLight); }; - this.heartBeat = function(entityID) { + this.heartBeat = function (entityID) { var now = Date.now(); if (now - this.lastHeartBeat > HEART_BEAT_INTERVAL) { var data = getEntityCustomData(GRAB_USER_DATA_KEY, entityID, {}); @@ -2019,7 +2064,7 @@ function MyController(hand) { } }; - this.resetAbandonedGrab = function(entityID) { + this.resetAbandonedGrab = function (entityID) { print("cleaning up abandoned grab on " + entityID); var data = getEntityCustomData(GRAB_USER_DATA_KEY, entityID, {}); data["refCount"] = 1; @@ -2027,7 +2072,7 @@ function MyController(hand) { this.deactivateEntity(entityID, false); }; - this.activateEntity = function(entityID, grabbedProperties, wasLoaded) { + this.activateEntity = function (entityID, grabbedProperties, wasLoaded) { if (this.entityActivated) { return; } @@ -2089,18 +2134,18 @@ function MyController(hand) { return data; }; - this.checkForStrayChildren = function() { + this.checkForStrayChildren = function () { // sometimes things can get parented to a hand and this script is unaware. Search for such entities and // unhook them. var handJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"); var children = Entities.getChildrenIDsOfJoint(MyAvatar.sessionUUID, handJointIndex); - children.forEach(function(childID) { + children.forEach(function (childID) { print("disconnecting stray child of hand: (" + _this.hand + ") " + childID); Entities.editEntity(childID, {parentID: NULL_UUID}); }); }; - this.deactivateEntity = function(entityID, noVelocity) { + this.deactivateEntity = function (entityID, noVelocity) { var deactiveProps; if (!this.entityActivated) { @@ -2185,7 +2230,7 @@ function MyController(hand) { setEntityCustomData(GRAB_USER_DATA_KEY, entityID, data); }; - this.getOtherHandController = function() { + this.getOtherHandController = function () { return (this.hand === RIGHT_HAND) ? leftController : rightController; }; } @@ -2227,7 +2272,7 @@ Messages.subscribe('Hifi-Hand-Grab'); Messages.subscribe('Hifi-Hand-RayPick-Blacklist'); Messages.subscribe('Hifi-Object-Manipulation'); -var handleHandMessages = function(channel, message, sender) { +var handleHandMessages = function (channel, message, sender) { var data; if (sender === MyAvatar.sessionUUID) { if (channel === 'Hifi-Hand-Disabler') { From 0d454cd45e85d2d188e48d31d1d28f225c2c2e73 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 7 Jul 2016 17:28:23 -0700 Subject: [PATCH 26/32] Equip hotspots render when your hand is near them. --- .../system/controllers/handControllerGrab.js | 295 ++++++++---------- 1 file changed, 130 insertions(+), 165 deletions(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index 869ea98b34..228c4fe483 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -28,7 +28,7 @@ var WANT_DEBUG_SEARCH_NAME = null; var TRIGGER_SMOOTH_RATIO = 0.1; // Time averaging of trigger - 0.0 disables smoothing var TRIGGER_ON_VALUE = 0.4; // Squeezed just enough to activate search or near grab -var TRIGGER_GRAB_VALUE = 0.75; // Squeezed far enough to complete distant grab +var TRIGGER_GRAB_VALUE = 0.85; // Squeezed far enough to complete distant grab var TRIGGER_OFF_VALUE = 0.15; var BUMPER_ON_VALUE = 0.5; @@ -80,6 +80,7 @@ var EQUIP_RADIUS_EMBIGGEN_FACTOR = 1.1; // var EQUIP_RADIUS = 0.1; // radius used for palm vs equip-hotspot for equipping. +var EQUIP_HOTSPOT_RENDER_RADIUS = 0.3; // radius used for palm vs equip-hotspot for rendering hot-spots var NEAR_GRABBING_ACTION_TIMEFRAME = 0.05; // how quickly objects move to their new position @@ -182,9 +183,7 @@ CONTROLLER_STATE_MACHINE[STATE_OFF] = { }; CONTROLLER_STATE_MACHINE[STATE_SEARCHING] = { name: "searching", - updateMethod: "search", - enterMethod: "searchEnter", - exitMethod: "searchExit" + updateMethod: "search" }; CONTROLLER_STATE_MACHINE[STATE_DISTANCE_HOLDING] = { name: "distance_holding", @@ -389,6 +388,8 @@ function MyController(hand) { this.entityPropertyCache = new EntityPropertiesCache(); + this.equipOverlayInfoSetMap = {}; + var _this = this; var suppressedIn2D = [STATE_OFF, STATE_SEARCHING]; @@ -881,126 +882,17 @@ function MyController(hand) { } } + this.entityPropertyCache.clear(); + this.entityPropertyCache.findEntities(this.getHandPosition(), EQUIP_HOTSPOT_RENDER_RADIUS); + var candidateEntities = this.entityPropertyCache.getEntities(); + + var potentialEquipHotspot = this.chooseBestEquipHotspot(candidateEntities); if (!this.waitForTriggerRelease) { - // update haptics when hand is near an equip hotspot - this.entityPropertyCache.clear(); - this.entityPropertyCache.findEntities(this.getHandPosition(), NEAR_GRAB_RADIUS); - var candidateEntities = this.entityPropertyCache.getEntities(); - var potentialEquipHotspot = this.chooseBestEquipHotspot(candidateEntities); this.updateEquipHaptics(potentialEquipHotspot); } - }; - this.createHotspots = function () { - var _this = this; - - var HAND_EQUIP_SPHERE_COLOR = { red: 90, green: 255, blue: 90 }; - var HAND_EQUIP_SPHERE_ALPHA = 0.7; - var HAND_EQUIP_SPHERE_RADIUS = 0.01; - - var HAND_GRAB_SPHERE_COLOR = { red: 90, green: 90, blue: 255 }; - var HAND_GRAB_SPHERE_ALPHA = 0.3; - var HAND_GRAB_SPHERE_RADIUS = NEAR_GRAB_RADIUS; - - var GRAB_BOX_COLOR = { red: 90, green: 90, blue: 255 }; - var GRAB_BOX_ALPHA = 0.1; - - this.hotspotOverlays = []; - - var overlay; - if (DRAW_HAND_SPHERES) { - // add tiny green sphere around the palm. - var handPosition = this.getHandPosition(); - overlay = Overlays.addOverlay("sphere", { - position: handPosition, - size: HAND_EQUIP_SPHERE_RADIUS * 2, - color: HAND_EQUIP_SPHERE_COLOR, - alpha: HAND_EQUIP_SPHERE_ALPHA, - solid: true, - visible: true, - ignoreRayIntersection: true, - drawInFront: false - }); - this.hotspotOverlays.push({ - entityID: undefined, - overlay: overlay, - type: "hand", - localPosition: {x: 0, y: 0, z: 0}, - hotspot: {} - }); - - // add larger blue sphere around the palm. - overlay = Overlays.addOverlay("sphere", { - position: handPosition, - size: HAND_GRAB_SPHERE_RADIUS * 2, - color: HAND_GRAB_SPHERE_COLOR, - alpha: HAND_GRAB_SPHERE_ALPHA, - solid: true, - visible: true, - ignoreRayIntersection: true, - drawInFront: false - }); - this.hotspotOverlays.push({ - entityID: undefined, - overlay: overlay, - type: "hand", - localPosition: {x: 0, y: 0, z: 0}, - hotspot: {} - }); - } - - // find entities near the avatar that might be equipable. - this.entityPropertyCache.clear(); - this.entityPropertyCache.findEntities(MyAvatar.position, HOTSPOT_DRAW_DISTANCE); - - if (DRAW_GRAB_BOXES) { - // add blue box overlays for grabbable entities. - this.entityPropertyCache.getEntities().forEach(function (entityID) { - var props = _this.entityPropertyCache.getProps(entityID); - if (_this.entityIsGrabbable(entityID)) { - var overlay = Overlays.addOverlay("cube", { - rotation: props.rotation, - position: props.position, - size: props.dimensions, - color: GRAB_BOX_COLOR, - alpha: GRAB_BOX_ALPHA, - solid: true, - visible: true, - ignoreRayIntersection: true, - drawInFront: false - }); - _this.hotspotOverlays.push({ - entityID: entityID, - overlay: overlay, - type: "near", - localPosition: {x: 0, y: 0, z: 0}, - hotspot: {} - }); - } - }); - } - - // add green spheres for each equippable hotspot. - flatten(this.entityPropertyCache.getEntities().map(function (entityID) { - return _this.collectEquipHotspots(entityID); - })).filter(function (hotspot) { - return _this.hotspotIsEquippable(hotspot); - }).forEach(function (hotspot) { - var overlay = Overlays.addOverlay("model", { - url: "http://hifi-content.s3.amazonaws.com/alan/dev/equip-ico-2.fbx", - position: hotspot.worldPosition, - rotation: {x: 0, y: 0, z: 0, w: 1}, - dimensions: (hotspot.radius / EQUIP_RADIUS) * EQUIP_RADIUS_TO_MODEL_SCALE_FACTOR, - ignoreRayIntersection: true - }); - _this.hotspotOverlays.push({ - entityID: hotspot.entityID, - overlay: overlay, - type: "equip", - localPosition: hotspot.localPosition, - hotspot: hotspot - }); - }); + var nearEquipHotspots = this.chooseNearEquipHotspots(candidateEntities, EQUIP_HOTSPOT_RENDER_RADIUS); + this.updateEquipHotspotRendering(nearEquipHotspots, potentialEquipHotspot); }; this.clearEquipHaptics = function () { @@ -1010,57 +902,109 @@ function MyController(hand) { this.updateEquipHaptics = function (potentialEquipHotspot) { if (potentialEquipHotspot && !this.prevPotentialEquipHotspot || !potentialEquipHotspot && this.prevPotentialEquipHotspot) { - Controller.triggerShortHapticPulse(1.0, this.hand); + Controller.triggerShortHapticPulse(0.5, this.hand); } this.prevPotentialEquipHotspot = potentialEquipHotspot; }; - this.updateHotspots = function (potentialEquipHotspot) { + this.clearEquipHotspotRendering = function () { + var keys = Object.keys(this.equipOverlayInfoSetMap); + for (var i = 0; i < keys.length; i++) { + var overlayInfoSet = this.equipOverlayInfoSetMap[keys[i]]; + this.deleteOverlayInfoSet(overlayInfoSet); + } + this.equipOverlayInfoSetMap = {}; + }; + + this.createOverlayInfoSet = function (hotspot, timestamp) { + var overlayInfoSet = { + timestamp: timestamp, + entityID: hotspot.entityID, + localPosition: hotspot.localPosition, + hotspot: hotspot, + overlays: [] + }; + + overlayInfoSet.overlays.push(Overlays.addOverlay("model", { + url: "http://hifi-content.s3.amazonaws.com/alan/dev/Equip-Spark.fbx", + position: hotspot.worldPosition, + rotation: {x: 0, y: 0, z: 0, w: 1}, + dimensions: (hotspot.radius / EQUIP_RADIUS) * EQUIP_RADIUS_TO_MODEL_SCALE_FACTOR, + ignoreRayIntersection: true + })); + + // TODO: use shader to achive fresnel effect. + overlayInfoSet.overlays.push(Overlays.addOverlay("model", { + url: "http://hifi-content.s3.amazonaws.com/alan/dev/equip-Fresnel-3.fbx", + position: hotspot.worldPosition, + rotation: {x: 0, y: 0, z: 0, w: 1}, + dimensions: (hotspot.radius / EQUIP_RADIUS) * EQUIP_RADIUS_TO_MODEL_SCALE_FACTOR * 0.5, + ignoreRayIntersection: true + })); + + // TODO: add light + + return overlayInfoSet; + }; + + this.updateOverlayInfoSet = function (overlayInfoSet, timestamp, potentialEquipHotspot) { + overlayInfoSet.timestamp = timestamp; + + var radius = (overlayInfoSet.hotspot.radius / EQUIP_RADIUS) * EQUIP_RADIUS_TO_MODEL_SCALE_FACTOR; + + // embiggen the overlays if it maches the potentialEquipHotspot + if (potentialEquipHotspot && overlayInfoSet.entityID == potentialEquipHotspot.entityID && + Vec3.equal(overlayInfoSet.localPosition, potentialEquipHotspot.localPosition)) { + radius = radius * EQUIP_RADIUS_EMBIGGEN_FACTOR; + } + + var props = _this.entityPropertyCache.getProps(overlayInfoSet.entityID); + var entityXform = new Xform(props.rotation, props.position); + var position = entityXform.xformPoint(overlayInfoSet.localPosition); + + // spark + Overlays.editOverlay(overlayInfoSet.overlays[0], { + position: position, + rotation: props.rotation, + dimensions: radius + }); + + // fresnel sphere + Overlays.editOverlay(overlayInfoSet.overlays[1], { + position: position, + rotation: props.rotation, + dimensions: radius * 0.5 // HACK to adjust sphere size... + }); + }; + + this.deleteOverlayInfoSet = function (overlayInfoSet) { + overlayInfoSet.overlays.forEach(function (overlay) { + Overlays.deleteOverlay(overlay); + }); + }; + + this.updateEquipHotspotRendering = function (hotspots, potentialEquipHotspot) { + var now = Date.now(); var _this = this; - var props; - this.hotspotOverlays.forEach(function (overlayInfo) { - if (overlayInfo.type === "hand") { - Overlays.editOverlay(overlayInfo.overlay, { position: _this.getHandPosition() }); - } else if (overlayInfo.type === "equip") { - var radius = (overlayInfo.hotspot.radius / EQUIP_RADIUS) * EQUIP_RADIUS_TO_MODEL_SCALE_FACTOR; - - // embiggen the equipHotspot if it maches the potentialEquipHotspot - if (potentialEquipHotspot && overlayInfo.entityID == potentialEquipHotspot.entityID && - Vec3.equal(overlayInfo.localPosition, potentialEquipHotspot.localPosition)) { - radius = (overlayInfo.hotspot.radius / EQUIP_RADIUS) * EQUIP_RADIUS_TO_MODEL_SCALE_FACTOR * - EQUIP_RADIUS_EMBIGGEN_FACTOR; - } - - _this.entityPropertyCache.updateEntity(overlayInfo.entityID); - props = _this.entityPropertyCache.getProps(overlayInfo.entityID); - var entityXform = new Xform(props.rotation, props.position); - Overlays.editOverlay(overlayInfo.overlay, { - position: entityXform.xformPoint(overlayInfo.localPosition), - rotation: props.rotation, - dimensions: radius - }); - } else if (overlayInfo.type === "near") { - _this.entityPropertyCache.updateEntity(overlayInfo.entityID); - props = _this.entityPropertyCache.getProps(overlayInfo.entityID); - Overlays.editOverlay(overlayInfo.overlay, { position: props.position, rotation: props.rotation }); + hotspots.forEach(function (hotspot) { + var overlayInfoSet = _this.equipOverlayInfoSetMap[hotspot.key]; + if (overlayInfoSet) { + _this.updateOverlayInfoSet(overlayInfoSet, now, potentialEquipHotspot); + } else { + _this.equipOverlayInfoSetMap[hotspot.key] = _this.createOverlayInfoSet(hotspot, now); } }); - }; - this.destroyHotspots = function () { - this.hotspotOverlays.forEach(function (overlayInfo) { - Overlays.deleteOverlay(overlayInfo.overlay); - }); - this.hotspotOverlays = []; - }; - - this.searchEnter = function () { - this.createHotspots(); - }; - - this.searchExit = function () { - this.destroyHotspots(); + // delete sets with old timestamps. + var keys = Object.keys(this.equipOverlayInfoSetMap); + for (var i = 0; i < keys.length; i++) { + var overlayInfoSet = this.equipOverlayInfoSetMap[keys[i]]; + if (overlayInfoSet.timestamp !== now) { + this.deleteOverlayInfoSet(overlayInfoSet); + delete this.equipOverlayInfoSetMap[keys[i]]; + } + } }; // Performs ray pick test from the hand controller into the world @@ -1133,6 +1077,7 @@ function MyController(hand) { // returns a list of all equip-hotspots assosiated with this entity. // @param {UUID} entityID // @returns {Object[]} array of objects with the following fields. + // * key {string} a string that can be used to uniquely identify this hotspot // * entityID {UUID} // * localPosition {Vec3} position of the hotspot in object space. // * worldPosition {vec3} position of the hotspot in world space. @@ -1150,6 +1095,7 @@ function MyController(hand) { var hotspot = equipHotspotsProps[i]; if (hotspot.position && hotspot.radius && hotspot.joints) { result.push({ + key: entityID.toString() + i.toString(), entityID: entityID, localPosition: hotspot.position, worldPosition: entityXform.xformPoint(hotspot.position), @@ -1162,6 +1108,7 @@ function MyController(hand) { var wearableProps = this.entityPropertyCache.getWearableProps(entityID); if (wearableProps && wearableProps.joints) { result.push({ + key: entityID.toString() + "0", entityID: entityID, localPosition: {x: 0, y: 0, z: 0}, worldPosition: entityXform.pos, @@ -1302,14 +1249,19 @@ function MyController(hand) { return true; }; - this.chooseBestEquipHotspot = function (candidateEntities) { + this.chooseNearEquipHotspots = function (candidateEntities, distance) { var equippableHotspots = flatten(candidateEntities.map(function (entityID) { return _this.collectEquipHotspots(entityID); })).filter(function (hotspot) { return (_this.hotspotIsEquippable(hotspot) && - Vec3.distance(hotspot.worldPosition, _this.getHandPosition()) < hotspot.radius); + Vec3.distance(hotspot.worldPosition, _this.getHandPosition()) < hotspot.radius + distance); }); + return equippableHotspots; + }; + this.chooseBestEquipHotspot = function (candidateEntities) { + var DISTANCE = 0; + var equippableHotspots = this.chooseNearEquipHotspots(candidateEntities, DISTANCE); if (equippableHotspots.length > 0) { // sort by distance equippableHotspots.sort(function (a, b) { @@ -1431,7 +1383,9 @@ function MyController(hand) { } this.updateEquipHaptics(potentialEquipHotspot); - this.updateHotspots(potentialEquipHotspot); + + var nearEquipHotspots = this.chooseNearEquipHotspots(candidateEntities, EQUIP_HOTSPOT_RENDER_RADIUS); + this.updateEquipHotspotRendering(nearEquipHotspots, potentialEquipHotspot); // search line visualizations if (USE_ENTITY_LINES_FOR_SEARCHING === true) { @@ -1460,6 +1414,7 @@ function MyController(hand) { this.distanceHoldingEnter = function () { + this.clearEquipHotspotRendering(); this.clearEquipHaptics(); // controller pose is in avatar frame @@ -1738,6 +1693,9 @@ function MyController(hand) { this.dropGestureReset(); this.clearEquipHaptics(); + this.clearEquipHotspotRendering(); + + Controller.triggerShortHapticPulse(1.0, this.hand); if (this.entityActivated) { var saveGrabbedID = this.grabbedEntity; @@ -1955,11 +1913,18 @@ function MyController(hand) { }; this.nearTriggerEnter = function () { + + this.clearEquipHotspotRendering(); + this.clearEquipHaptics(); + Controller.triggerShortHapticPulse(1.0, this.hand); this.callEntityMethodOnGrabbed("startNearTrigger"); }; this.farTriggerEnter = function () { + this.clearEquipHotspotRendering(); + this.clearEquipHaptics(); + this.callEntityMethodOnGrabbed("startFarTrigger"); }; From 1ec34722303ad8f91a24ad7850448241bf2cfa96 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 8 Jul 2016 11:36:43 -0700 Subject: [PATCH 27/32] Model overlay dimensions fixes At the moment model overlays will ALWAYS scale to fit their dimensions Update handControllerGrab to account for this behavior. --- interface/src/ui/overlays/ModelOverlay.cpp | 25 ++++++------------- .../system/controllers/handControllerGrab.js | 13 +++++----- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index b07e8bb48a..cc3f0dd8e5 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -43,12 +43,14 @@ ModelOverlay::ModelOverlay(const ModelOverlay* modelOverlay) : void ModelOverlay::update(float deltatime) { if (_updateModel) { _updateModel = false; - _model->setSnapModelToCenter(true); - _model->setScale(getDimensions()); _model->setRotation(getRotation()); _model->setTranslation(getPosition()); _model->setURL(_url); + + // dimensions are ALWAYS scale to fit. + _model->setScaleToFit(true, getDimensions()); + _model->simulate(deltatime, true); } else { _model->simulate(deltatime); @@ -87,26 +89,15 @@ void ModelOverlay::render(RenderArgs* args) { void ModelOverlay::setProperties(const QVariantMap& properties) { auto position = getPosition(); auto rotation = getRotation(); - auto scale = getDimensions(); - + Volume3DOverlay::setProperties(properties); - + if (position != getPosition() || rotation != getRotation()) { _updateModel = true; } - if (scale != getDimensions()) { - auto newScale = getDimensions(); - if (newScale.x <= 0 || newScale.y <= 0 || newScale.z <= 0) { - setDimensions(scale); - } else { - QMetaObject::invokeMethod(_model.get(), "setScaleToFit", Qt::AutoConnection, - Q_ARG(const bool&, true), - Q_ARG(const glm::vec3&, getDimensions())); - _updateModel = true; - } - } - + _updateModel = true; + auto urlValue = properties["url"]; if (urlValue.isValid() && urlValue.canConvert()) { _url = urlValue.toString(); diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index 228c4fe483..b98a528882 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -26,6 +26,8 @@ var WANT_DEBUG_SEARCH_NAME = null; // these tune time-averaging and "on" value for analog trigger // +var SPARK_MODEL_SCALE_FACTOR = 0.75; + var TRIGGER_SMOOTH_RATIO = 0.1; // Time averaging of trigger - 0.0 disables smoothing var TRIGGER_ON_VALUE = 0.4; // Squeezed just enough to activate search or near grab var TRIGGER_GRAB_VALUE = 0.85; // Squeezed far enough to complete distant grab @@ -72,7 +74,6 @@ var LINE_ENTITY_DIMENSIONS = { var LINE_LENGTH = 500; var PICK_MAX_DISTANCE = 500; // max length of pick-ray -var EQUIP_RADIUS_TO_MODEL_SCALE_FACTOR = 0.75; var EQUIP_RADIUS_EMBIGGEN_FACTOR = 1.1; // @@ -929,7 +930,7 @@ function MyController(hand) { url: "http://hifi-content.s3.amazonaws.com/alan/dev/Equip-Spark.fbx", position: hotspot.worldPosition, rotation: {x: 0, y: 0, z: 0, w: 1}, - dimensions: (hotspot.radius / EQUIP_RADIUS) * EQUIP_RADIUS_TO_MODEL_SCALE_FACTOR, + dimensions: hotspot.radius * 2 * SPARK_MODEL_SCALE_FACTOR, ignoreRayIntersection: true })); @@ -938,7 +939,7 @@ function MyController(hand) { url: "http://hifi-content.s3.amazonaws.com/alan/dev/equip-Fresnel-3.fbx", position: hotspot.worldPosition, rotation: {x: 0, y: 0, z: 0, w: 1}, - dimensions: (hotspot.radius / EQUIP_RADIUS) * EQUIP_RADIUS_TO_MODEL_SCALE_FACTOR * 0.5, + dimensions: hotspot.radius * 2, ignoreRayIntersection: true })); @@ -950,7 +951,7 @@ function MyController(hand) { this.updateOverlayInfoSet = function (overlayInfoSet, timestamp, potentialEquipHotspot) { overlayInfoSet.timestamp = timestamp; - var radius = (overlayInfoSet.hotspot.radius / EQUIP_RADIUS) * EQUIP_RADIUS_TO_MODEL_SCALE_FACTOR; + var radius = overlayInfoSet.hotspot.radius; // embiggen the overlays if it maches the potentialEquipHotspot if (potentialEquipHotspot && overlayInfoSet.entityID == potentialEquipHotspot.entityID && @@ -966,14 +967,14 @@ function MyController(hand) { Overlays.editOverlay(overlayInfoSet.overlays[0], { position: position, rotation: props.rotation, - dimensions: radius + dimensions: radius * 2 * SPARK_MODEL_SCALE_FACTOR }); // fresnel sphere Overlays.editOverlay(overlayInfoSet.overlays[1], { position: position, rotation: props.rotation, - dimensions: radius * 0.5 // HACK to adjust sphere size... + dimensions: radius * 2 }); }; From 7d1f52da7040f55659b84ad4ea8b951806bea118 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 8 Jul 2016 14:33:22 -0700 Subject: [PATCH 28/32] Added glow effect to search beam --- scripts/system/controllers/handControllerGrab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index cff580a3ec..07bc4ab1b2 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -550,7 +550,7 @@ function MyController(hand) { this.overlayLineOn = function (closePoint, farPoint, color) { if (this.overlayLine === null) { var lineProperties = { - lineWidth: 5, + glow: 1.0, start: closePoint, end: farPoint, color: color, From c8d0decab7d0483d27b8eeda0357bc91c2d1e170 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 8 Jul 2016 14:47:13 -0700 Subject: [PATCH 29/32] Fix for far grab not working until after edit button is pressed --- scripts/system/controllers/handControllerGrab.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index 07bc4ab1b2..a92c59cfed 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -264,7 +264,8 @@ function propsArePhysical(props) { var EXTERNALLY_MANAGED_2D_MINOR_MODE = true; var EDIT_SETTING = "io.highfidelity.isEditting"; function isEditing() { - return EXTERNALLY_MANAGED_2D_MINOR_MODE && Settings.getValue(EDIT_SETTING); + var actualSettingValue = Settings.getValue(EDIT_SETTING) === "false" ? false : !!Settings.getValue(EDIT_SETTING); + return EXTERNALLY_MANAGED_2D_MINOR_MODE && actualSettingValue; } function isIn2DMode() { // In this version, we make our own determination of whether we're aimed a HUD element, From bec71e4af46ad63b0324fbbdc175b887eec254a5 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 8 Jul 2016 17:05:23 -0700 Subject: [PATCH 30/32] Went back to transparent spheres for equip points --- .../system/controllers/handControllerGrab.js | 44 +++++++------------ 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index a92c59cfed..39afe122b7 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -939,25 +939,21 @@ function MyController(hand) { overlays: [] }; - overlayInfoSet.overlays.push(Overlays.addOverlay("model", { - url: "http://hifi-content.s3.amazonaws.com/alan/dev/Equip-Spark.fbx", + var EQUIP_SPHERE_COLOR = { red: 179, green: 120, blue: 211 }; + var EQUIP_SPHERE_ALPHA = 0.3; + + overlayInfoSet.overlays.push(Overlays.addOverlay("sphere", { position: hotspot.worldPosition, rotation: {x: 0, y: 0, z: 0, w: 1}, - dimensions: hotspot.radius * 2 * SPARK_MODEL_SCALE_FACTOR, - ignoreRayIntersection: true + size: hotspot.radius * 2, + color: EQUIP_SPHERE_COLOR, + alpha: EQUIP_SPHERE_ALPHA, + solid: true, + visible: true, + ignoreRayIntersection: true, + drawInFront: false })); - // TODO: use shader to achive fresnel effect. - overlayInfoSet.overlays.push(Overlays.addOverlay("model", { - url: "http://hifi-content.s3.amazonaws.com/alan/dev/equip-Fresnel-3.fbx", - position: hotspot.worldPosition, - rotation: {x: 0, y: 0, z: 0, w: 1}, - dimensions: hotspot.radius * 2, - ignoreRayIntersection: true - })); - - // TODO: add light - return overlayInfoSet; }; @@ -976,18 +972,12 @@ function MyController(hand) { var entityXform = new Xform(props.rotation, props.position); var position = entityXform.xformPoint(overlayInfoSet.localPosition); - // spark - Overlays.editOverlay(overlayInfoSet.overlays[0], { - position: position, - rotation: props.rotation, - dimensions: radius * 2 * SPARK_MODEL_SCALE_FACTOR - }); - - // fresnel sphere - Overlays.editOverlay(overlayInfoSet.overlays[1], { - position: position, - rotation: props.rotation, - dimensions: radius * 2 + overlayInfoSet.overlays.forEach(function (overlay) { + Overlays.editOverlay(overlay, { + position: position, + rotation: props.rotation, + dimensions: radius * 2 + }); }); }; From d933238bda885202ce8aaf3a009039b970b791b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Brisset?= Date: Fri, 8 Jul 2016 18:15:14 -0700 Subject: [PATCH 31/32] Revert "Fix crash in packet list" --- domain-server/src/DomainServer.cpp | 2 -- libraries/networking/src/LimitedNodeList.cpp | 1 - libraries/networking/src/LimitedNodeList.h | 4 ++-- libraries/networking/src/NodeList.cpp | 7 ------- 4 files changed, 2 insertions(+), 12 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 8b3f09d1f7..d75a2c3245 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -389,8 +389,6 @@ void DomainServer::setupNodeListAndAssignments() { const QVariant* idValueVariant = valueForKeyPath(settingsMap, METAVERSE_DOMAIN_ID_KEY_PATH); if (idValueVariant) { nodeList->setSessionUUID(idValueVariant->toString()); - } else { - nodeList->setSessionUUID(QUuid::createUuid()); // Use random UUID } connect(nodeList.data(), &LimitedNodeList::nodeAdded, this, &DomainServer::nodeAdded); diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index a03fa43093..d7a2d47fab 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -522,7 +522,6 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, const NodePermissions& permissions, const QUuid& connectionSecret) { - QReadLocker readLocker(&_nodeMutex); NodeHash::const_iterator it = _nodeHash.find(uuid); if (it != _nodeHash.end()) { diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index c9054ac6d7..483aa0734c 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -131,7 +131,7 @@ public: std::function linkedDataCreateCallback; - size_t size() const { QReadLocker readLock(&_nodeMutex); return _nodeHash.size(); } + size_t size() const { return _nodeHash.size(); } SharedNodePointer nodeWithUUID(const QUuid& nodeUUID); @@ -287,7 +287,7 @@ protected: QUuid _sessionUUID; NodeHash _nodeHash; - mutable QReadWriteLock _nodeMutex; + QReadWriteLock _nodeMutex; udt::Socket _nodeSocket; QUdpSocket* _dtlsSocket; HifiSockAddr _localSockAddr; diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 02350ac23c..fd1442d639 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -513,16 +513,9 @@ void NodeList::processDomainServerConnectionTokenPacket(QSharedPointer message) { if (_domainHandler.getSockAddr().isNull()) { - qWarning() << "IGNORING DomainList packet while not connected to a Domain Server"; // refuse to process this packet if we aren't currently connected to the DS return; } - QUuid domainHandlerUUID = _domainHandler.getUUID(); - QUuid messageSourceUUID = message->getSourceID(); - if (!domainHandlerUUID.isNull() && domainHandlerUUID != messageSourceUUID) { - qWarning() << "IGNORING DomainList packet from" << messageSourceUUID << "while connected to" << domainHandlerUUID; - return; - } // this is a packet from the domain server, reset the count of un-replied check-ins _numNoReplyDomainCheckIns = 0; From 6f6fe5f2443467cedd2a7df5a1a2e97af6aca088 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 8 Jul 2016 18:22:37 -0700 Subject: [PATCH 32/32] reduced radius of grab sphere --- scripts/system/controllers/handControllerGrab.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index 39afe122b7..416e6b10d8 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -45,6 +45,10 @@ var DRAW_GRAB_BOXES = false; var DRAW_HAND_SPHERES = false; var DROP_WITHOUT_SHAKE = false; +var EQUIP_SPHERE_COLOR = { red: 179, green: 120, blue: 211 }; +var EQUIP_SPHERE_ALPHA = 0.15; +var EQUIP_SPHERE_SCALE_FACTOR = 0.65; + // // distant manipulation // @@ -939,13 +943,12 @@ function MyController(hand) { overlays: [] }; - var EQUIP_SPHERE_COLOR = { red: 179, green: 120, blue: 211 }; - var EQUIP_SPHERE_ALPHA = 0.3; + var diameter = hotspot.radius * 2; overlayInfoSet.overlays.push(Overlays.addOverlay("sphere", { position: hotspot.worldPosition, rotation: {x: 0, y: 0, z: 0, w: 1}, - size: hotspot.radius * 2, + dimensions: diameter * EQUIP_SPHERE_SCALE_FACTOR, color: EQUIP_SPHERE_COLOR, alpha: EQUIP_SPHERE_ALPHA, solid: true, @@ -960,12 +963,12 @@ function MyController(hand) { this.updateOverlayInfoSet = function (overlayInfoSet, timestamp, potentialEquipHotspot) { overlayInfoSet.timestamp = timestamp; - var radius = overlayInfoSet.hotspot.radius; + var diameter = overlayInfoSet.hotspot.radius * 2; // embiggen the overlays if it maches the potentialEquipHotspot if (potentialEquipHotspot && overlayInfoSet.entityID == potentialEquipHotspot.entityID && Vec3.equal(overlayInfoSet.localPosition, potentialEquipHotspot.localPosition)) { - radius = radius * EQUIP_RADIUS_EMBIGGEN_FACTOR; + diameter = diameter * EQUIP_RADIUS_EMBIGGEN_FACTOR; } var props = _this.entityPropertyCache.getProps(overlayInfoSet.entityID); @@ -976,7 +979,7 @@ function MyController(hand) { Overlays.editOverlay(overlay, { position: position, rotation: props.rotation, - dimensions: radius * 2 + dimensions: diameter * EQUIP_SPHERE_SCALE_FACTOR }); }); };