History

first cut at simulating mouse/reticle behavior with input contorllers

Brad Hefta-Gaub committed 10 years ago

Commit 3dcdfbc1 parent 205bc1b13 files · +123 −353Browse files

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

Unified · Split

interface/src/Application.cpp+43−143
@@ -382,7 +382,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : · 381 unmodified lines
382 _scaleMirror(1.0f),382 _scaleMirror(1.0f),
383 _rotateMirror(0.0f),383 _rotateMirror(0.0f),
384 _raiseMirror(0.0f),384 _raiseMirror(0.0f),
385 _lastMouseMoveWasSimulated(false),
386 _enableProcessOctreeThread(true),385 _enableProcessOctreeThread(true),
387 _runningScriptsWidget(NULL),386 _runningScriptsWidget(NULL),
388 _runningScriptsWidgetWasVisible(false),387 _runningScriptsWidgetWasVisible(false),
@@ -664,6 +663,21 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : · 275 unmodified lines
664 // Setup the userInputMapper with the actions663 // Setup the userInputMapper with the actions
665 auto userInputMapper = DependencyManager::get<UserInputMapper>();664 auto userInputMapper = DependencyManager::get<UserInputMapper>();
666 connect(userInputMapper.data(), &UserInputMapper::actionEvent, [this](int action, float state) {665 connect(userInputMapper.data(), &UserInputMapper::actionEvent, [this](int action, float state) {
666 if (action == controller::toInt(controller::Action::RETICLE_CLICK)) {
667 auto globalPos = getReticlePosition();
668 auto localPos = _glWidget->mapFromGlobal(globalPos);
669 if (state) {
670 QMouseEvent mousePress(QEvent::MouseButtonPress, localPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
671 sendEvent(_glWidget, &mousePress);
672 _reticleClickPressed = true;
673 } else {
674 QMouseEvent mouseRelease(QEvent::MouseButtonRelease, localPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
675 sendEvent(_glWidget, &mouseRelease);
676 _reticleClickPressed = false;
677 }
678 return; // nothing else to do
679 }
680
667 if (state) {681 if (state) {
668 if (action == controller::toInt(controller::Action::TOGGLE_MUTE)) {682 if (action == controller::toInt(controller::Action::TOGGLE_MUTE)) {
669 DependencyManager::get<AudioClient>()->toggleMute();683 DependencyManager::get<AudioClient>()->toggleMute();
@@ -671,6 +685,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : · 1 unmodified line
671 cycleCamera();685 cycleCamera();
672 } else if (action == controller::toInt(controller::Action::CONTEXT_MENU)) {686 } else if (action == controller::toInt(controller::Action::CONTEXT_MENU)) {
673 VrMenu::toggle(); // show context menu even on non-stereo displays687 VrMenu::toggle(); // show context menu even on non-stereo displays
688 } else if (action == controller::toInt(controller::Action::RETICLE_X)) {
689 auto reticlePos = getReticlePosition();
690 reticlePos.setX(reticlePos.x() + state);
691 setReticlePosition(reticlePos);
692 } else if (action == controller::toInt(controller::Action::RETICLE_Y)) {
693 auto reticlePos = getReticlePosition();
694 reticlePos.setY(reticlePos.y() + state);
695 setReticlePosition(reticlePos);
674 }696 }
675 }697 }
676 });698 });
@@ -692,8 +714,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : · 15 unmodified lines
692 714
693 // Setup the keyboardMouseDevice and the user input mapper with the default bindings715 // Setup the keyboardMouseDevice and the user input mapper with the default bindings
694 userInputMapper->registerDevice(_keyboardMouseDevice->getInputDevice());716 userInputMapper->registerDevice(_keyboardMouseDevice->getInputDevice());
695
696
697 userInputMapper->loadDefaultMapping(userInputMapper->getStandardDeviceID());717 userInputMapper->loadDefaultMapping(userInputMapper->getStandardDeviceID());
698 718
699 // check first run...719 // check first run...
@@ -745,15 +765,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : · 45 unmodified lines
745 setActiveEyeTracker();765 setActiveEyeTracker();
746#endif766#endif
747 767
748 _oldHandMouseX[0] = -1;
749 _oldHandMouseY[0] = -1;
750 _oldHandMouseX[1] = -1;
751 _oldHandMouseY[1] = -1;
752 _oldHandLeftClick[0] = false;
753 _oldHandRightClick[0] = false;
754 _oldHandLeftClick[1] = false;
755 _oldHandRightClick[1] = false;
756
757 auto applicationUpdater = DependencyManager::get<AutoUpdater>();768 auto applicationUpdater = DependencyManager::get<AutoUpdater>();
758 connect(applicationUpdater.data(), &AutoUpdater::newVersionIsAvailable, dialogsManager.data(), &DialogsManager::showUpdateDialog);769 connect(applicationUpdater.data(), &AutoUpdater::newVersionIsAvailable, dialogsManager.data(), &DialogsManager::showUpdateDialog);
759 applicationUpdater->checkForUpdate();770 applicationUpdater->checkForUpdate();
@@ -1940,8 +1951,6 @@ void Application::focusOutEvent(QFocusEvent* event) { · 1180 unmodified lines
1940 1951
1941void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) {1952void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) {
1942 PROFILE_RANGE(__FUNCTION__);1953 PROFILE_RANGE(__FUNCTION__);
1943 // Used by application overlay to determine how to draw cursor(s)
1944 _lastMouseMoveWasSimulated = deviceID > 0;
1945 1954
1946 if (_aboutToQuit) {1955 if (_aboutToQuit) {
1947 return;1956 return;
@@ -1969,11 +1978,20 @@ void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) { · 21 unmodified lines
1969 1978
1970 auto offscreenUi = DependencyManager::get<OffscreenUi>();1979 auto offscreenUi = DependencyManager::get<OffscreenUi>();
1971 QPointF transformedPos = offscreenUi->mapToVirtualScreen(event->localPos(), _glWidget);1980 QPointF transformedPos = offscreenUi->mapToVirtualScreen(event->localPos(), _glWidget);
1981 auto button = event->button();
1982 auto buttons = event->buttons();
1983 // Determine if the ReticleClick Action is 1 and if so, fake include the LeftMouseButton
1984 if (_reticleClickPressed) {
1985 if (button == Qt::NoButton) {
1986 button = Qt::LeftButton;
1987 }
1988 buttons |= Qt::LeftButton;
1989 }
1990
1972 QMouseEvent mappedEvent(event->type(),1991 QMouseEvent mappedEvent(event->type(),
1973 transformedPos,1992 transformedPos,
1974 event->screenPos(), event->button(),1993 event->screenPos(), button,
1975 event->buttons(), event->modifiers());1994 buttons, event->modifiers());
1976
1977 1995
1978 getEntities()->mouseMoveEvent(&mappedEvent, deviceID);1996 getEntities()->mouseMoveEvent(&mappedEvent, deviceID);
1979 _controllerScriptingInterface->emitMouseMoveEvent(&mappedEvent, deviceID); // send events to any registered scripts1997 _controllerScriptingInterface->emitMouseMoveEvent(&mappedEvent, deviceID); // send events to any registered scripts
@@ -2877,13 +2895,6 @@ void Application::update(float deltaTime) { · 897 unmodified lines
2877 Hand* hand = DependencyManager::get<AvatarManager>()->getMyAvatar()->getHand();2895 Hand* hand = DependencyManager::get<AvatarManager>()->getMyAvatar()->getHand();
2878 setPalmData(hand, leftHand, deltaTime, HandData::LeftHand, userInputMapper->getActionState(controller::Action::LEFT_HAND_CLICK));2896 setPalmData(hand, leftHand, deltaTime, HandData::LeftHand, userInputMapper->getActionState(controller::Action::LEFT_HAND_CLICK));
2879 setPalmData(hand, rightHand, deltaTime, HandData::RightHand, userInputMapper->getActionState(controller::Action::RIGHT_HAND_CLICK));2897 setPalmData(hand, rightHand, deltaTime, HandData::RightHand, userInputMapper->getActionState(controller::Action::RIGHT_HAND_CLICK));
2880 if (Menu::getInstance()->isOptionChecked(MenuOption::EnableHandMouseInput)) {
2881 emulateMouse(hand, userInputMapper->getActionState(controller::Action::LEFT_HAND_CLICK),
2882 userInputMapper->getActionState(controller::Action::SHIFT), HandData::LeftHand);
2883 emulateMouse(hand, userInputMapper->getActionState(controller::Action::RIGHT_HAND_CLICK),
2884 userInputMapper->getActionState(controller::Action::SHIFT), HandData::RightHand);
2885 }
2886
2887 updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process...2898 updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process...
2888 updateDialogs(deltaTime); // update various stats dialogs if present2899 updateDialogs(deltaTime); // update various stats dialogs if present
2889 2900
@@ -4742,6 +4753,14 @@ bool Application::isThrottleRendering() const { · 1852 unmodified lines
4742 return getActiveDisplayPlugin()->isThrottled();4753 return getActiveDisplayPlugin()->isThrottled();
4743}4754}
4744 4755
4756QPoint Application::getReticlePosition() const {
4757 return QCursor::pos();
4758}
4759
4760void Application::setReticlePosition(QPoint position) {
4761 QCursor::setPos(position);
4762}
4763
4745ivec2 Application::getTrueMouse() const {4764ivec2 Application::getTrueMouse() const {
4746 return toGlm(_glWidget->mapFromGlobal(QCursor::pos()));4765 return toGlm(_glWidget->mapFromGlobal(QCursor::pos()));
4747}4766}
@@ -5062,125 +5081,6 @@ void Application::setPalmData(Hand* hand, const controller::Pose& pose, float de · 314 unmodified lines
5062 });5081 });
5063}5082}
5064 5083
5065void Application::emulateMouse(Hand* hand, float click, float shift, HandData::Hand whichHand) {
5066 auto palms = hand->getCopyOfPalms();
5067
5068 // Locate the palm, if it exists and is active
5069 PalmData* palm;
5070 bool foundHand = false;
5071 for (size_t j = 0; j < palms.size(); j++) {
5072 if (palms[j].whichHand() == whichHand) {
5073 palm = &(palms[j]);
5074 foundHand = true;
5075 break;
5076 }
5077 }
5078 if (!foundHand || !palm->isActive()) {
5079 return;
5080 }
5081
5082 // Process the mouse events
5083 QPoint pos;
5084
5085
5086 // FIXME - this mouse emulation stuff needs to be reworked for new controller input plugins
5087 unsigned int deviceID = whichHand == HandData::LeftHand ? CONTROLLER_0_EVENT : CONTROLLER_1_EVENT;
5088 int index = (int)whichHand; // FIXME - hack attack
5089
5090 if (isHMDMode()) {
5091 pos = getApplicationCompositor().getPalmClickLocation(palm);
5092 } else {
5093 // Get directon relative to avatar orientation
5094 glm::vec3 direction = glm::inverse(getMyAvatar()->getOrientation()) * palm->getFingerDirection();
5095
5096 // Get the angles, scaled between (-0.5,0.5)
5097 float xAngle = (atan2f(direction.z, direction.x) + (float)M_PI_2);
5098 float yAngle = 0.5f - ((atan2f(direction.z, direction.y) + (float)M_PI_2));
5099 auto canvasSize = getCanvasSize();
5100 // Get the pixel range over which the xAngle and yAngle are scaled
5101 float cursorRange = canvasSize.x * controller::InputDevice::getCursorPixelRangeMult();
5102
5103 pos.setX(canvasSize.x / 2.0f + cursorRange * xAngle);
5104 pos.setY(canvasSize.y / 2.0f + cursorRange * yAngle);
5105
5106 }
5107
5108 //If we are off screen then we should stop processing, and if a trigger or bumper is pressed,
5109 //we should unpress them.
5110 if (pos.x() == INT_MAX) {
5111 if (_oldHandLeftClick[index]) {
5112 QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, 0);
5113
5114 mouseReleaseEvent(&mouseEvent, deviceID);
5115
5116 _oldHandLeftClick[index] = false;
5117 }
5118 if (_oldHandRightClick[index]) {
5119 QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::RightButton, Qt::RightButton, 0);
5120
5121 mouseReleaseEvent(&mouseEvent, deviceID);
5122
5123 _oldHandRightClick[index] = false;
5124 }
5125 return;
5126 }
5127
5128 //If position has changed, emit a mouse move to the application
5129 if (pos.x() != _oldHandMouseX[index] || pos.y() != _oldHandMouseY[index]) {
5130 QMouseEvent mouseEvent(QEvent::MouseMove, pos, Qt::NoButton, Qt::NoButton, 0);
5131
5132 // Only send the mouse event if the opposite left button isnt held down.
5133 // Is this check necessary?
5134 if (!_oldHandLeftClick[(int)(!index)]) {
5135 mouseMoveEvent(&mouseEvent, deviceID);
5136 }
5137 }
5138 _oldHandMouseX[index] = pos.x();
5139 _oldHandMouseY[index] = pos.y();
5140
5141 //We need separate coordinates for clicks, since we need to check if
5142 //a magnification window was clicked on
5143 int clickX = pos.x();
5144 int clickY = pos.y();
5145 //Set pos to the new click location, which may be the same if no magnification window is open
5146 pos.setX(clickX);
5147 pos.setY(clickY);
5148
5149 // Right click
5150 if (shift == 1.0f && click == 1.0f) {
5151 if (!_oldHandRightClick[index]) {
5152 _oldHandRightClick[index] = true;
5153
5154 QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, Qt::RightButton, Qt::RightButton, 0);
5155
5156 mousePressEvent(&mouseEvent, deviceID);
5157 }
5158 } else if (_oldHandRightClick[index]) {
5159 QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::RightButton, Qt::RightButton, 0);
5160
5161 mouseReleaseEvent(&mouseEvent, deviceID);
5162
5163 _oldHandRightClick[index] = false;
5164 }
5165
5166 // Left click
5167 if (shift != 1.0f && click == 1.0f) {
5168 if (!_oldHandLeftClick[index]) {
5169 _oldHandLeftClick[index] = true;
5170
5171 QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, 0);
5172
5173 mousePressEvent(&mouseEvent, deviceID);
5174 }
5175 } else if (_oldHandLeftClick[index]) {
5176 QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, 0);
5177
5178 mouseReleaseEvent(&mouseEvent, deviceID);
5179
5180 _oldHandLeftClick[index] = false;
5181 }
5182}
5183
5184void Application::crashApplication() {5084void Application::crashApplication() {
5185 qCDebug(interfaceapp) << "Intentionally crashed Interface";5085 qCDebug(interfaceapp) << "Intentionally crashed Interface";
5186 QObject* object = nullptr;5086 QObject* object = nullptr;