History

Cleaning up diff

Brad Davis committed 11 years ago

Commit 948d5da1 parent ba58e951 file · +227 −224Browse files

Showing the changes to interface/src/Application.cpp (1 of 1 file). Show all

Unified · Split

interface/src/Application.cpp+227−224
@@ -144,7 +144,7 @@ · 143 unmodified lines
144144 #include "ui/AddressBarDialog.h"
145145 #include "ui/UpdateDialog.h"
146146
147−#include <qopenglcontext.h>
147+//#include <qopenglcontext.h>
148148
149149 // ON WIndows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
150150 #if defined(Q_OS_WIN)
@@ -2281,7 +2281,7 @@ void Application::updateMouseRay() { · 2130 unmodified lines
22812281 PerformanceWarning warn(showWarnings, "Application::updateMouseRay()");
22822282
22832283 // make sure the frustum is up-to-date
2284− _myCamera.loadViewFrustum(_viewFrustum);
2284+ loadViewFrustum(_myCamera, _viewFrustum);
22852285
22862286 PickRay pickRay = computePickRay(getTrueMouseX(), getTrueMouseY());
22872287 _mouseRayOrigin = pickRay.origin;
@@ -2665,7 +2665,7 @@ void Application::update(float deltaTime) { · 377 unmodified lines
26652665 // to the server.
26662666 {
26672667 PerformanceTimer perfTimer("loadViewFrustum");
2668− _myCamera.loadViewFrustum(_viewFrustum);
2668+ loadViewFrustum(_myCamera, _viewFrustum);
26692669 }
26702670
26712671 quint64 now = usecTimestampNow();
@@ -2713,192 +2713,6 @@ void Application::update(float deltaTime) { · 41 unmodified lines
27132713 _myAvatar->updateSensorToWorldMatrix();
27142714 }
27152715
2716−void Application::setPalmData(Hand* hand, UserInputMapper::PoseValue pose, float deltaTime, int index) {
2717− PalmData* palm;
2718− bool foundHand = false;
2719− for (size_t j = 0; j < hand->getNumPalms(); j++) {
2720− if (hand->getPalms()[j].getSixenseID() == index) {
2721− palm = &(hand->getPalms()[j]);
2722− foundHand = true;
2723− break;
2724− }
2725− }
2726− if (!foundHand) {
2727− PalmData newPalm(hand);
2728− hand->getPalms().push_back(newPalm);
2729− palm = &(hand->getPalms()[hand->getNumPalms() - 1]);
2730− palm->setSixenseID(index);
2731− }
2732−
2733− palm->setActive(pose.isValid());
2734−
2735− // transform from sensor space, to world space, to avatar model space.
2736− glm::mat4 poseMat = createMatFromQuatAndPos(pose.getRotation(), pose.getTranslation());
2737− glm::mat4 sensorToWorldMat = _myAvatar->getSensorToWorldMatrix();
2738− glm::mat4 modelMat = createMatFromQuatAndPos(_myAvatar->getOrientation(), _myAvatar->getPosition());
2739− glm::mat4 objectPose = glm::inverse(modelMat) * sensorToWorldMat * poseMat;
2740−
2741− glm::vec3 position = extractTranslation(objectPose);
2742− glm::quat rotation = glm::quat_cast(objectPose);
2743−
2744− // Compute current velocity from position change
2745− glm::vec3 rawVelocity;
2746− if (deltaTime > 0.0f) {
2747− rawVelocity = (position - palm->getRawPosition()) / deltaTime;
2748− } else {
2749− rawVelocity = glm::vec3(0.0f);
2750− }
2751− palm->setRawVelocity(rawVelocity); // meters/sec
2752−
2753− // Angular Velocity of Palm
2754− glm::quat deltaRotation = rotation * glm::inverse(palm->getRawRotation());
2755− glm::vec3 angularVelocity(0.0f);
2756− float rotationAngle = glm::angle(deltaRotation);
2757− if ((rotationAngle > EPSILON) && (deltaTime > 0.0f)) {
2758− angularVelocity = glm::normalize(glm::axis(deltaRotation));
2759− angularVelocity *= (rotationAngle / deltaTime);
2760− palm->setRawAngularVelocity(angularVelocity);
2761− } else {
2762− palm->setRawAngularVelocity(glm::vec3(0.0f));
2763− }
2764−
2765− if (InputDevice::getLowVelocityFilter()) {
2766− // Use a velocity sensitive filter to damp small motions and preserve large ones with
2767− // no latency.
2768− float velocityFilter = glm::clamp(1.0f - glm::length(rawVelocity), 0.0f, 1.0f);
2769− position = palm->getRawPosition() * velocityFilter + position * (1.0f - velocityFilter);
2770− rotation = safeMix(palm->getRawRotation(), rotation, 1.0f - velocityFilter);
2771− }
2772− palm->setRawPosition(position);
2773− palm->setRawRotation(rotation);
2774−
2775− // Store the one fingertip in the palm structure so we can track velocity
2776− const float FINGER_LENGTH = 0.3f; // meters
2777− const glm::vec3 FINGER_VECTOR(0.0f, 0.0f, FINGER_LENGTH);
2778− const glm::vec3 newTipPosition = position + rotation * FINGER_VECTOR;
2779− glm::vec3 oldTipPosition = palm->getTipRawPosition();
2780− if (deltaTime > 0.0f) {
2781− palm->setTipVelocity((newTipPosition - oldTipPosition) / deltaTime);
2782− } else {
2783− palm->setTipVelocity(glm::vec3(0.0f));
2784− }
2785− palm->setTipPosition(newTipPosition);
2786−}
2787−
2788−void Application::emulateMouse(Hand* hand, float click, float shift, int index) {
2789− // Locate the palm, if it exists and is active
2790− PalmData* palm;
2791− bool foundHand = false;
2792− for (size_t j = 0; j < hand->getNumPalms(); j++) {
2793− if (hand->getPalms()[j].getSixenseID() == index) {
2794− palm = &(hand->getPalms()[j]);
2795− foundHand = true;
2796− break;
2797− }
2798− }
2799− if (!foundHand || !palm->isActive()) {
2800− return;
2801− }
2802−
2803− // Process the mouse events
2804− QPoint pos;
2805−
2806− unsigned int deviceID = index == 0 ? CONTROLLER_0_EVENT : CONTROLLER_1_EVENT;
2807−
2808− if (qApp->isHMDMode()) {
2809− pos = qApp->getApplicationCompositor().getPalmClickLocation(palm);
2810− }
2811− else {
2812− // Get directon relative to avatar orientation
2813− glm::vec3 direction = glm::inverse(_myAvatar->getOrientation()) * palm->getFingerDirection();
2814−
2815− // Get the angles, scaled between (-0.5,0.5)
2816− float xAngle = (atan2(direction.z, direction.x) + M_PI_2);
2817− float yAngle = 0.5f - ((atan2f(direction.z, direction.y) + (float)M_PI_2));
2818− auto canvasSize = qApp->getCanvasSize();
2819− // Get the pixel range over which the xAngle and yAngle are scaled
2820− float cursorRange = canvasSize.x * InputDevice::getCursorPixelRangeMult();
2821−
2822− pos.setX(canvasSize.x / 2.0f + cursorRange * xAngle);
2823− pos.setY(canvasSize.y / 2.0f + cursorRange * yAngle);
2824−
2825− }
2826−
2827− //If we are off screen then we should stop processing, and if a trigger or bumper is pressed,
2828− //we should unpress them.
2829− if (pos.x() == INT_MAX) {
2830− if (_oldHandLeftClick[index]) {
2831− QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, 0);
2832−
2833− qApp->mouseReleaseEvent(&mouseEvent, deviceID);
2834−
2835− _oldHandLeftClick[index] = false;
2836− }
2837− if (_oldHandRightClick[index]) {
2838− QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::RightButton, Qt::RightButton, 0);
2839−
2840− qApp->mouseReleaseEvent(&mouseEvent, deviceID);
2841−
2842− _oldHandRightClick[index] = false;
2843− }
2844− return;
2845− }
2846−
2847− //If position has changed, emit a mouse move to the application
2848− if (pos.x() != _oldHandMouseX[index] || pos.y() != _oldHandMouseY[index]) {
2849− QMouseEvent mouseEvent(QEvent::MouseMove, pos, Qt::NoButton, Qt::NoButton, 0);
2850−
2851− // Only send the mouse event if the opposite left button isnt held down.
2852− // Is this check necessary?
2853− if (!_oldHandLeftClick[(int)(!index)]) {
2854− qApp->mouseMoveEvent(&mouseEvent, deviceID);
2855− }
2856− }
2857− _oldHandMouseX[index] = pos.x();
2858− _oldHandMouseY[index] = pos.y();
2859−
2860− //We need separate coordinates for clicks, since we need to check if
2861− //a magnification window was clicked on
2862− int clickX = pos.x();
2863− int clickY = pos.y();
2864− //Set pos to the new click location, which may be the same if no magnification window is open
2865− pos.setX(clickX);
2866− pos.setY(clickY);
2867−
2868− // Right click
2869− if (shift == 1.0f && click == 1.0f) {
2870− if (!_oldHandRightClick[index]) {
2871− _oldHandRightClick[index] = true;
2872−
2873− QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, Qt::RightButton, Qt::RightButton, 0);
2874−
2875− qApp->mousePressEvent(&mouseEvent, deviceID);
2876− }
2877− } else if (_oldHandRightClick[index]) {
2878− QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::RightButton, Qt::RightButton, 0);
2879−
2880− qApp->mouseReleaseEvent(&mouseEvent, deviceID);
2881−
2882− _oldHandRightClick[index] = false;
2883− }
2884−
2885− // Left click
2886− if (shift != 1.0f && click == 1.0f) {
2887− if (!_oldHandLeftClick[index]) {
2888− _oldHandLeftClick[index] = true;
2889−
2890− QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, 0);
2891−
2892− qApp->mousePressEvent(&mouseEvent, deviceID);
2893− }
2894− } else if (_oldHandLeftClick[index]) {
2895− QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, 0);
2896−
2897− qApp->mouseReleaseEvent(&mouseEvent, deviceID);
2898−
2899− _oldHandLeftClick[index] = false;
2900− }
2901−}
29022716
29032717 int Application::sendNackPackets() {
29042718
@@ -3138,6 +2952,35 @@ void Application::queryOctree(NodeType_t serverType, PacketType::Value packetTyp · 233 unmodified lines
31382952 });
31392953 }
31402954
2955+
2956+bool Application::isHMDMode() const {
2957+ return getActiveDisplayPlugin()->isHmd();
2958+}
2959+
2960+QRect Application::getDesirableApplicationGeometry() {
2961+ QRect applicationGeometry = getWindow()->geometry();
2962+
2963+ // If our parent window is on the HMD, then don't use its geometry, instead use
2964+ // the "main screen" geometry.
2965+ HMDToolsDialog* hmdTools = DependencyManager::get<DialogsManager>()->getHMDToolsDialog();
2966+ if (hmdTools && hmdTools->hasHMDScreen()) {
2967+ QScreen* hmdScreen = hmdTools->getHMDScreen();
2968+ QWindow* appWindow = getWindow()->windowHandle();
2969+ QScreen* appScreen = appWindow->screen();
2970+
2971+ // if our app's screen is the hmd screen, we don't want to place the
2972+ // running scripts widget on it. So we need to pick a better screen.
2973+ // we will use the screen for the HMDTools since it's a guarenteed
2974+ // better screen.
2975+ if (appScreen == hmdScreen) {
2976+ QScreen* betterScreen = hmdTools->windowHandle()->screen();
2977+ applicationGeometry = betterScreen->geometry();
2978+ }
2979+ }
2980+ return applicationGeometry;
2981+}
2982+
2983+/////////////////////////////////////////////////////////////////////////////////////
31412984 // loadViewFrustum()
31422985 //
31432986 // Description: this will load the view frustum bounds for EITHER the head
@@ -3156,14 +2999,6 @@ void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) { · 12 unmodified lines
31562999 viewFrustum.calculate();
31573000 }
31583001
3159−bool Application::isHMDMode() const {
3160− return getActiveDisplayPlugin()->isHmd();
3161−}
3162−
3163−QRect Application::getDesirableApplicationGeometry() {
3164− return getWindow()->geometry();
3165−}
3166−
31673002 glm::vec3 Application::getSunDirection() {
31683003 // Sun direction is in fact just the location of the sun relative to the origin
31693004 auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
@@ -3593,27 +3428,6 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi · 423 unmodified lines
35933428 }
35943429 renderArgs->_viewport = viewport;
35953430
3596−#if 0
3597− auto origRenderMode = renderArgs->_renderMode;
3598− renderArgs->_renderMode = RenderArgs::MIRROR_RENDER_MODE;
3599−
3600− {
3601− gpu::Batch batch;
3602− batch.setViewportTransform(viewport);
3603− batch.setStateScissorRect(viewport);
3604− batch.clearFramebuffer(
3605− gpu::Framebuffer::BUFFER_COLOR0 |
3606− gpu::Framebuffer::BUFFER_COLOR1 |
3607− gpu::Framebuffer::BUFFER_COLOR2 |
3608− gpu::Framebuffer::BUFFER_DEPTH,
3609− vec4(vec3(0), 1), 1.0, 0.0, true);
3610− renderArgs->_context->render(batch);
3611− }
3612−
3613− bool updateViewFrustum = false;
3614− loadViewFrustum(_mirrorCamera, _viewFrustum);
3615−#endif
3616−
36173431 // render rear mirror view
36183432 displaySide(renderArgs, _mirrorCamera, true, billboard);
36193433
@@ -3625,7 +3439,11 @@ void Application::resetSensors() { · 5 unmodified lines
36253439 DependencyManager::get<DdeFaceTracker>()->reset();
36263440
36273441 getActiveDisplayPlugin()->resetSensors();
3628− //_leapmotion.reset();
3442+
3443+ QScreen* currentScreen = _window->windowHandle()->screen();
3444+ QWindow* mainWindow = _window->windowHandle();
3445+ QPoint windowCenter = mainWindow->geometry().center();
3446+ _glWidget->cursor().setPos(currentScreen, windowCenter);
36293447
36303448 _myAvatar->reset();
36313449
@@ -4383,7 +4201,7 @@ void Application::setPreviousScriptLocation(const QString& previousScriptLocatio · 751 unmodified lines
43834201
43844202 void Application::loadDialog() {
43854203
4386− QString fileNameString = QFileDialog::getOpenFileName(desktop(),
4204+ QString fileNameString = QFileDialog::getOpenFileName(_glWidget,
43874205 tr("Open Script"),
43884206 getPreviousScriptLocation(),
43894207 tr("JavaScript Files (*.js)"));
@@ -4424,7 +4242,7 @@ void Application::setScriptsLocation(const QString& scriptsLocation) { · 34 unmodified lines
44244242
44254243 void Application::toggleLogDialog() {
44264244 if (! _logDialog) {
4427− _logDialog = new LogDialog(desktop(), getLogger());
4245+ _logDialog = new LogDialog(_glWidget, getLogger());
44284246 }
44294247
44304248 if (_logDialog->isVisible()) {
@@ -4435,7 +4253,6 @@ void Application::toggleLogDialog() { · 4 unmodified lines
44354253 }
44364254
44374255 void Application::takeSnapshot() {
4438−#if 0
44394256 QMediaPlayer* player = new QMediaPlayer();
44404257 QFileInfo inf = QFileInfo(PathUtils::resourcesPath() + "sounds/snap.wav");
44414258 player->setMedia(QUrl::fromLocalFile(inf.absoluteFilePath()));
@@ -4449,10 +4266,9 @@ void Application::takeSnapshot() { · 7 unmodified lines
44494266 }
44504267
44514268 if (!_snapshotShareDialog) {
4452− _snapshotShareDialog = new SnapshotShareDialog(fileName, desktop());
4269+ _snapshotShareDialog = new SnapshotShareDialog(fileName, _glWidget);
44534270 }
44544271 _snapshotShareDialog->show();
4455−#endif
44564272
44574273 }
44584274
@@ -4910,3 +4726,190 @@ void Application::setActiveDisplayPlugin(const QString& pluginName) { · 451 unmodified lines
49104726 }
49114727 updateDisplayMode();
49124728 }
4729+
4730+void Application::setPalmData(Hand* hand, UserInputMapper::PoseValue pose, float deltaTime, int index) {
4731+ PalmData* palm;
4732+ bool foundHand = false;
4733+ for (size_t j = 0; j < hand->getNumPalms(); j++) {
4734+ if (hand->getPalms()[j].getSixenseID() == index) {
4735+ palm = &(hand->getPalms()[j]);
4736+ foundHand = true;
4737+ break;
4738+ }
4739+ }
4740+ if (!foundHand) {
4741+ PalmData newPalm(hand);
4742+ hand->getPalms().push_back(newPalm);
4743+ palm = &(hand->getPalms()[hand->getNumPalms() - 1]);
4744+ palm->setSixenseID(index);
4745+ }
4746+
4747+ palm->setActive(pose.isValid());
4748+
4749+ // transform from sensor space, to world space, to avatar model space.
4750+ glm::mat4 poseMat = createMatFromQuatAndPos(pose.getRotation(), pose.getTranslation());
4751+ glm::mat4 sensorToWorldMat = _myAvatar->getSensorToWorldMatrix();
4752+ glm::mat4 modelMat = createMatFromQuatAndPos(_myAvatar->getOrientation(), _myAvatar->getPosition());
4753+ glm::mat4 objectPose = glm::inverse(modelMat) * sensorToWorldMat * poseMat;
4754+
4755+ glm::vec3 position = extractTranslation(objectPose);
4756+ glm::quat rotation = glm::quat_cast(objectPose);
4757+
4758+ // Compute current velocity from position change
4759+ glm::vec3 rawVelocity;
4760+ if (deltaTime > 0.0f) {
4761+ rawVelocity = (position - palm->getRawPosition()) / deltaTime;
4762+ } else {
4763+ rawVelocity = glm::vec3(0.0f);
4764+ }
4765+ palm->setRawVelocity(rawVelocity); // meters/sec
4766+
4767+ // Angular Velocity of Palm
4768+ glm::quat deltaRotation = rotation * glm::inverse(palm->getRawRotation());
4769+ glm::vec3 angularVelocity(0.0f);
4770+ float rotationAngle = glm::angle(deltaRotation);
4771+ if ((rotationAngle > EPSILON) && (deltaTime > 0.0f)) {
4772+ angularVelocity = glm::normalize(glm::axis(deltaRotation));
4773+ angularVelocity *= (rotationAngle / deltaTime);
4774+ palm->setRawAngularVelocity(angularVelocity);
4775+ } else {
4776+ palm->setRawAngularVelocity(glm::vec3(0.0f));
4777+ }
4778+
4779+ if (InputDevice::getLowVelocityFilter()) {
4780+ // Use a velocity sensitive filter to damp small motions and preserve large ones with
4781+ // no latency.
4782+ float velocityFilter = glm::clamp(1.0f - glm::length(rawVelocity), 0.0f, 1.0f);
4783+ position = palm->getRawPosition() * velocityFilter + position * (1.0f - velocityFilter);
4784+ rotation = safeMix(palm->getRawRotation(), rotation, 1.0f - velocityFilter);
4785+ }
4786+ palm->setRawPosition(position);
4787+ palm->setRawRotation(rotation);
4788+
4789+ // Store the one fingertip in the palm structure so we can track velocity
4790+ const float FINGER_LENGTH = 0.3f; // meters
4791+ const glm::vec3 FINGER_VECTOR(0.0f, 0.0f, FINGER_LENGTH);
4792+ const glm::vec3 newTipPosition = position + rotation * FINGER_VECTOR;
4793+ glm::vec3 oldTipPosition = palm->getTipRawPosition();
4794+ if (deltaTime > 0.0f) {
4795+ palm->setTipVelocity((newTipPosition - oldTipPosition) / deltaTime);
4796+ } else {
4797+ palm->setTipVelocity(glm::vec3(0.0f));
4798+ }
4799+ palm->setTipPosition(newTipPosition);
4800+}
4801+
4802+void Application::emulateMouse(Hand* hand, float click, float shift, int index) {
4803+ // Locate the palm, if it exists and is active
4804+ PalmData* palm;
4805+ bool foundHand = false;
4806+ for (size_t j = 0; j < hand->getNumPalms(); j++) {
4807+ if (hand->getPalms()[j].getSixenseID() == index) {
4808+ palm = &(hand->getPalms()[j]);
4809+ foundHand = true;
4810+ break;
4811+ }
4812+ }
4813+ if (!foundHand || !palm->isActive()) {
4814+ return;
4815+ }
4816+
4817+ // Process the mouse events
4818+ QPoint pos;
4819+
4820+ unsigned int deviceID = index == 0 ? CONTROLLER_0_EVENT : CONTROLLER_1_EVENT;
4821+
4822+ if (qApp->isHMDMode()) {
4823+ pos = qApp->getApplicationCompositor().getPalmClickLocation(palm);
4824+ }
4825+ else {
4826+ // Get directon relative to avatar orientation
4827+ glm::vec3 direction = glm::inverse(_myAvatar->getOrientation()) * palm->getFingerDirection();
4828+
4829+ // Get the angles, scaled between (-0.5,0.5)
4830+ float xAngle = (atan2(direction.z, direction.x) + M_PI_2);
4831+ float yAngle = 0.5f - ((atan2f(direction.z, direction.y) + (float)M_PI_2));
4832+ auto canvasSize = qApp->getCanvasSize();
4833+ // Get the pixel range over which the xAngle and yAngle are scaled
4834+ float cursorRange = canvasSize.x * InputDevice::getCursorPixelRangeMult();
4835+
4836+ pos.setX(canvasSize.x / 2.0f + cursorRange * xAngle);
4837+ pos.setY(canvasSize.y / 2.0f + cursorRange * yAngle);
4838+
4839+ }
4840+
4841+ //If we are off screen then we should stop processing, and if a trigger or bumper is pressed,
4842+ //we should unpress them.
4843+ if (pos.x() == INT_MAX) {
4844+ if (_oldHandLeftClick[index]) {
4845+ QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, 0);
4846+
4847+ qApp->mouseReleaseEvent(&mouseEvent, deviceID);
4848+
4849+ _oldHandLeftClick[index] = false;
4850+ }
4851+ if (_oldHandRightClick[index]) {
4852+ QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::RightButton, Qt::RightButton, 0);
4853+
4854+ qApp->mouseReleaseEvent(&mouseEvent, deviceID);
4855+
4856+ _oldHandRightClick[index] = false;
4857+ }
4858+ return;
4859+ }
4860+
4861+ //If position has changed, emit a mouse move to the application
4862+ if (pos.x() != _oldHandMouseX[index] || pos.y() != _oldHandMouseY[index]) {
4863+ QMouseEvent mouseEvent(QEvent::MouseMove, pos, Qt::NoButton, Qt::NoButton, 0);
4864+
4865+ // Only send the mouse event if the opposite left button isnt held down.
4866+ // Is this check necessary?
4867+ if (!_oldHandLeftClick[(int)(!index)]) {
4868+ qApp->mouseMoveEvent(&mouseEvent, deviceID);
4869+ }
4870+ }
4871+ _oldHandMouseX[index] = pos.x();
4872+ _oldHandMouseY[index] = pos.y();
4873+
4874+ //We need separate coordinates for clicks, since we need to check if
4875+ //a magnification window was clicked on
4876+ int clickX = pos.x();
4877+ int clickY = pos.y();
4878+ //Set pos to the new click location, which may be the same if no magnification window is open
4879+ pos.setX(clickX);
4880+ pos.setY(clickY);
4881+
4882+ // Right click
4883+ if (shift == 1.0f && click == 1.0f) {
4884+ if (!_oldHandRightClick[index]) {
4885+ _oldHandRightClick[index] = true;
4886+
4887+ QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, Qt::RightButton, Qt::RightButton, 0);
4888+
4889+ qApp->mousePressEvent(&mouseEvent, deviceID);
4890+ }
4891+ } else if (_oldHandRightClick[index]) {
4892+ QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::RightButton, Qt::RightButton, 0);
4893+
4894+ qApp->mouseReleaseEvent(&mouseEvent, deviceID);
4895+
4896+ _oldHandRightClick[index] = false;
4897+ }
4898+
4899+ // Left click
4900+ if (shift != 1.0f && click == 1.0f) {
4901+ if (!_oldHandLeftClick[index]) {
4902+ _oldHandLeftClick[index] = true;
4903+
4904+ QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, 0);
4905+
4906+ qApp->mousePressEvent(&mouseEvent, deviceID);
4907+ }
4908+ } else if (_oldHandLeftClick[index]) {
4909+ QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, 0);
4910+
4911+ qApp->mouseReleaseEvent(&mouseEvent, deviceID);
4912+
4913+ _oldHandLeftClick[index] = false;
4914+ }
4915+}