From d0b1880ee4e65a87a3c78d14ab0bfaae2ed17604 Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Thu, 12 Jun 2014 10:20:35 -0700 Subject: [PATCH 1/8] Experimenting with ambidextrous sixense mouse input --- interface/src/devices/SixenseManager.cpp | 96 ++++++++++------- interface/src/devices/SixenseManager.h | 12 +-- interface/src/ui/ApplicationOverlay.cpp | 126 ++++++++++++----------- 3 files changed, 132 insertions(+), 102 deletions(-) diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index abbb32ec5e..37bad28093 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -39,10 +39,14 @@ SixenseManager::SixenseManager() { sixenseInit(); #endif - _triggerPressed = false; - _bumperPressed = false; - _oldX = -1; - _oldY = -1; + _triggerPressed[0] = false; + _bumperPressed[0] = false; + _oldX[0] = -1; + _oldY[0] = -1; + _triggerPressed[1] = false; + _bumperPressed[1] = false; + _oldX[1] = -1; + _oldY[1] = -1; } SixenseManager::~SixenseManager() { @@ -115,9 +119,9 @@ void SixenseManager::update(float deltaTime) { // Emulate the mouse so we can use scripts if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseMouseInput)) { // Check if we are on the correct palm - if ((Menu::getInstance()->isOptionChecked(MenuOption::SixenseLeftHanded) && numActiveControllers == 1) || numActiveControllers == 2) { - emulateMouse(palm); - } + //if ((Menu::getInstance()->isOptionChecked(MenuOption::SixenseLeftHanded) && numActiveControllers == 1) || numActiveControllers == 2) { + emulateMouse(palm, numActiveControllers - 1); + //} } // NOTE: Sixense API returns pos data in millimeters but we IMMEDIATELY convert to meters. @@ -328,30 +332,13 @@ void SixenseManager::updateCalibration(const sixenseControllerData* controllers) } //Injecting mouse movements and clicks -void SixenseManager::emulateMouse(PalmData *palm) { +void SixenseManager::emulateMouse(PalmData* palm, int index) { MyAvatar* avatar = Application::getInstance()->getAvatar(); + QGLWidget* widget = Application::getInstance()->getGLWidget(); QPoint pos; // Get directon relative to avatar orientation glm::vec3 direction = glm::inverse(avatar->getOrientation()) * palm->getFingerDirection(); - // Get the angles, scaled between 0-1 - float xAngle = (atan2(direction.z, direction.x) + M_PI_2) + 0.5f; - float yAngle = 1.0f - ((atan2(direction.z, direction.y) + M_PI_2) + 0.5f); - - float cursorRange = Application::getInstance()->getGLWidget()->width(); - - pos.setX(cursorRange * xAngle); - pos.setY(cursorRange * yAngle); - - //If position has changed, emit a mouse move to the application - if (pos.x() != _oldX || pos.y() != _oldY) { - QMouseEvent mouseEvent(static_cast(CONTROLLER_MOVE_EVENT), pos, Qt::NoButton, Qt::NoButton, 0); - - Application::getInstance()->mouseMoveEvent(&mouseEvent); - } - _oldX = pos.x(); - _oldY = pos.y(); - Qt::MouseButton bumperButton; Qt::MouseButton triggerButton; @@ -362,42 +349,79 @@ void SixenseManager::emulateMouse(PalmData *palm) { bumperButton = Qt::RightButton; triggerButton = Qt::LeftButton; } + + // Get the angles, scaled between 0-1 + float xAngle = (atan2(direction.z, direction.x) + M_PI_2) + 0.5f; + float yAngle = 1.0f - ((atan2(direction.z, direction.y) + M_PI_2) + 0.5f); + + float cursorRange = widget->width(); + + + pos.setX(cursorRange * xAngle); + pos.setY(cursorRange * yAngle); + + //If we are off screen then we should stop processing, and if a trigger or bumper is pressed, + //we should unpress them. + if (pos.x() < 0 || pos.x() > widget->width() || pos.y() < 0 || pos.y() > widget->height()) { + if (_bumperPressed[index]) { + QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, bumperButton, bumperButton, 0); + + Application::getInstance()->mouseReleaseEvent(&mouseEvent); + + _bumperPressed[index] = false; + } + if (_triggerPressed[index]) { + QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, triggerButton, triggerButton, 0); + + Application::getInstance()->mouseReleaseEvent(&mouseEvent); + + _triggerPressed[index] = false; + } + return; + } + + //If position has changed, emit a mouse move to the application + if (pos.x() != _oldX[index] || pos.y() != _oldY[index]) { + QMouseEvent mouseEvent(static_cast(CONTROLLER_MOVE_EVENT), pos, Qt::NoButton, Qt::NoButton, 0); + + Application::getInstance()->mouseMoveEvent(&mouseEvent); + } + _oldX[index] = pos.x(); + _oldY[index] = pos.y(); //Check for bumper press ( Right Click ) if (palm->getControllerButtons() & BUTTON_FWD) { - if (!_bumperPressed) { - _bumperPressed = true; + if (!_bumperPressed[index]) { + _bumperPressed[index] = true; QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, bumperButton, bumperButton, 0); Application::getInstance()->mousePressEvent(&mouseEvent); } - } else if (_bumperPressed) { + } else if (_bumperPressed[index]) { QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, bumperButton, bumperButton, 0); Application::getInstance()->mouseReleaseEvent(&mouseEvent); - _bumperPressed = false; + _bumperPressed[index] = false; } //Check for trigger press ( Left Click ) if (palm->getTrigger() == 1.0f) { - if (!_triggerPressed) { - _triggerPressed = true; + if (!_triggerPressed[index]) { + _triggerPressed[index] = true; QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, triggerButton, triggerButton, 0); Application::getInstance()->mousePressEvent(&mouseEvent); } - } else if (_triggerPressed) { + } else if (_triggerPressed[index]) { QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, triggerButton, triggerButton, 0); Application::getInstance()->mouseReleaseEvent(&mouseEvent); - _triggerPressed = false; + _triggerPressed[index] = false; } - - } #endif // HAVE_SIXENSE diff --git a/interface/src/devices/SixenseManager.h b/interface/src/devices/SixenseManager.h index 93888ce944..f3c5633f90 100644 --- a/interface/src/devices/SixenseManager.h +++ b/interface/src/devices/SixenseManager.h @@ -47,7 +47,7 @@ public slots: private: #ifdef HAVE_SIXENSE void updateCalibration(const sixenseControllerData* controllers); - void emulateMouse(PalmData *palm); + void emulateMouse(PalmData* palm, int index); int _calibrationState; @@ -70,11 +70,11 @@ private: quint64 _lastMovement; glm::vec3 _amountMoved; - // for mouse emulation - bool _triggerPressed; - bool _bumperPressed; - int _oldX; - int _oldY; + // for mouse emulation with the two controllers + bool _triggerPressed[2]; + bool _bumperPressed[2]; + int _oldX[2]; + int _oldY[2]; }; #endif // hifi_SixenseManager_h diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 924c2e9d84..1deab117ac 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -45,70 +45,76 @@ void renderControllerPointer() { int palmIndex; - if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLeftHanded)) { + /*if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLeftHanded)) { palmIndex = 2; } else { palmIndex = 3; + }*/ + for (palmIndex = 2; palmIndex < 4; palmIndex++) { + const PalmData* palmData = NULL; + + if (palmIndex >= handData->getPalms().size()) { + return; + } + + if (handData->getPalms()[palmIndex].isActive()) { + palmData = &handData->getPalms()[palmIndex]; + } else { + return; + } + + // Get directon relative to avatar orientation + glm::vec3 direction = glm::inverse(myAvatar->getOrientation()) * palmData->getFingerDirection(); + + // Get the angles, scaled between 0-1 + float xAngle = (atan2(direction.z, direction.x) + M_PI_2) + 0.5f; + float yAngle = 1.0f - ((atan2(direction.z, direction.y) + M_PI_2) + 0.5f); + + float cursorRange = glWidget->width(); + + int mouseX = cursorRange * xAngle; + int mouseY = cursorRange * yAngle; + + if (mouseX < 0) { + //mouseX = 0; + continue; + } else if (mouseX > glWidget->width()) { + //mouseX = glWidget->width(); + continue; + } + if (mouseY < 0) { + //mouseY = 0; + continue; + } else if (mouseY > glWidget->width()) { + //mouseY = glWidget->width(); + continue; + } + + const float pointerWidth = 40; + const float pointerHeight = 40; + const float crossPad = 16; + + mouseX -= pointerWidth / 2.0f; + mouseY += pointerHeight / 2.0f; + + glBegin(GL_QUADS); + + glColor3f(0.0f, 0.0f, 1.0f); + + //Horizontal crosshair + glVertex2i(mouseX, mouseY - crossPad); + glVertex2i(mouseX + pointerWidth, mouseY - crossPad); + glVertex2i(mouseX + pointerWidth, mouseY - pointerHeight + crossPad); + glVertex2i(mouseX, mouseY - pointerHeight + crossPad); + + //Vertical crosshair + glVertex2i(mouseX + crossPad, mouseY); + glVertex2i(mouseX + pointerWidth - crossPad, mouseY); + glVertex2i(mouseX + pointerWidth - crossPad, mouseY - pointerHeight); + glVertex2i(mouseX + crossPad, mouseY - pointerHeight); + + glEnd(); } - const PalmData* palmData = NULL; - - if (palmIndex >= handData->getPalms().size()) { - return; - } - - if (handData->getPalms()[palmIndex].isActive()) { - palmData = &handData->getPalms()[palmIndex]; - } else { - return; - } - - // Get directon relative to avatar orientation - glm::vec3 direction = glm::inverse(myAvatar->getOrientation()) * palmData->getFingerDirection(); - - // Get the angles, scaled between 0-1 - float xAngle = (atan2(direction.z, direction.x) + M_PI_2) + 0.5f; - float yAngle = 1.0f - ((atan2(direction.z, direction.y) + M_PI_2) + 0.5f); - - float cursorRange = glWidget->width(); - - int mouseX = cursorRange * xAngle; - int mouseY = cursorRange * yAngle; - - if (mouseX < 0) { - mouseX = 0; - } else if (mouseX > glWidget->width()) { - mouseX = glWidget->width(); - } - if (mouseY < 0) { - mouseY = 0; - } else if (mouseY > glWidget->width()) { - mouseY = glWidget->width(); - } - - const float pointerWidth = 40; - const float pointerHeight = 40; - const float crossPad = 16; - - mouseX -= pointerWidth / 2.0f; - mouseY += pointerHeight / 2.0f; - - glBegin(GL_QUADS); - - glColor3f(0, 0, 1); - - //Horizontal crosshair - glVertex2i(mouseX, mouseY - crossPad); - glVertex2i(mouseX + pointerWidth, mouseY - crossPad); - glVertex2i(mouseX + pointerWidth, mouseY - pointerHeight + crossPad); - glVertex2i(mouseX, mouseY - pointerHeight + crossPad); - - //Vertical crosshair - glVertex2i(mouseX + crossPad, mouseY); - glVertex2i(mouseX + pointerWidth - crossPad, mouseY); - glVertex2i(mouseX + pointerWidth - crossPad, mouseY - pointerHeight); - glVertex2i(mouseX + crossPad, mouseY - pointerHeight); - - glEnd(); } // Renders the overlays either to a texture or to the screen From db94ae7449adeb9f117295567681b724197c7ccf Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Thu, 12 Jun 2014 10:27:54 -0700 Subject: [PATCH 2/8] Invert hydra move view and thrust controllers to match consoles --- examples/hydraMove.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/hydraMove.js b/examples/hydraMove.js index f211a450a3..675a885b6d 100644 --- a/examples/hydraMove.js +++ b/examples/hydraMove.js @@ -19,8 +19,8 @@ var damping = 0.9; var position = { x: MyAvatar.position.x, y: MyAvatar.position.y, z: MyAvatar.position.z }; var joysticksCaptured = false; -var THRUST_CONTROLLER = 1; -var VIEW_CONTROLLER = 0; +var THRUST_CONTROLLER = 0; +var VIEW_CONTROLLER = 1; var INITIAL_THRUST_MULTPLIER = 1.0; var THRUST_INCREASE_RATE = 1.05; var MAX_THRUST_MULTIPLIER = 75.0; From 762751ef6a35e19ed82f97aa1211209a1efd39e6 Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Thu, 12 Jun 2014 10:47:11 -0700 Subject: [PATCH 3/8] Store the last mouse move input type for application overlay --- interface/src/Application.cpp | 4 ++++ interface/src/Application.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 24fcb3dc70..9f9cdb698c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -150,6 +150,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _mouseX(0), _mouseY(0), _lastMouseMove(usecTimestampNow()), + _lastMouseMoveType(QEvent::MouseMove), _mouseHidden(false), _seenMouseMove(false), _touchAvgX(0.0f), @@ -1096,6 +1097,9 @@ void Application::mouseMoveEvent(QMouseEvent* event) { showMouse = false; } + // Used by application overlay to determine how to draw cursor(s) + _lastMouseMoveType = event->type(); + _controllerScriptingInterface.emitMouseMoveEvent(event); // send events to any registered scripts // if one of our scripts have asked to capture this event, then stop processing it diff --git a/interface/src/Application.h b/interface/src/Application.h index 2889dcb301..536a54e65d 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -206,6 +206,7 @@ public: const glm::vec3& getMouseRayDirection() const { return _mouseRayDirection; } int getMouseX() const { return _mouseX; } int getMouseY() const { return _mouseY; } + unsigned int getLastMouseMoveType() const { return _lastMouseMoveType; } Faceplus* getFaceplus() { return &_faceplus; } Faceshift* getFaceshift() { return &_faceshift; } Visage* getVisage() { return &_visage; } @@ -505,6 +506,7 @@ private: int _mouseDragStartedX; int _mouseDragStartedY; quint64 _lastMouseMove; + unsigned int _lastMouseMoveType; bool _mouseHidden; bool _seenMouseMove; @@ -521,6 +523,7 @@ private: QSet _keysPressed; + GeometryCache _geometryCache; AnimationCache _animationCache; TextureCache _textureCache; From 18543ff3130a0051ab0d23a83b95b1dbd976e53e Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Thu, 12 Jun 2014 12:07:25 -0700 Subject: [PATCH 4/8] Support for multiple oculus overlay magnifiers --- interface/src/ui/ApplicationOverlay.cpp | 256 +++++++++++++----------- interface/src/ui/ApplicationOverlay.h | 4 + 2 files changed, 139 insertions(+), 121 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 1deab117ac..83b6dde93b 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -16,6 +16,7 @@ #include "Application.h" #include "ApplicationOverlay.h" +#include "devices/OculusManager.h" #include "ui/Stats.h" @@ -35,7 +36,7 @@ ApplicationOverlay::~ApplicationOverlay() { const float WHITE_TEXT[] = { 0.93f, 0.93f, 0.93f }; -void renderControllerPointer() { +void ApplicationOverlay::renderControllerPointer() { Application* application = Application::getInstance(); QGLWidget* glWidget = application->getGLWidget(); MyAvatar* myAvatar = application->getAvatar(); @@ -60,7 +61,7 @@ void renderControllerPointer() { if (handData->getPalms()[palmIndex].isActive()) { palmData = &handData->getPalms()[palmIndex]; } else { - return; + continue; } // Get directon relative to avatar orientation @@ -75,24 +76,25 @@ void renderControllerPointer() { int mouseX = cursorRange * xAngle; int mouseY = cursorRange * yAngle; - if (mouseX < 0) { - //mouseX = 0; - continue; - } else if (mouseX > glWidget->width()) { - //mouseX = glWidget->width(); - continue; - } - if (mouseY < 0) { - //mouseY = 0; - continue; - } else if (mouseY > glWidget->width()) { - //mouseY = glWidget->width(); + if (mouseX < 0 || mouseX >= glWidget->width() || mouseY < 0 || mouseY >= glWidget->height()) { continue; } - const float pointerWidth = 40; - const float pointerHeight = 40; - const float crossPad = 16; + float pointerWidth = 40; + float pointerHeight = 40; + float crossPad = 16; + //if we have the oculus, we should make the cursor smaller since it will be + //magnified + if (OculusManager::isConnected()) { + pointerWidth /= 4; + pointerHeight /= 4; + crossPad /= 4; + + _mouseX[_numMagnifiers] = mouseX; + _mouseY[_numMagnifiers] = mouseY; + _numMagnifiers++; + + } mouseX -= pointerWidth / 2.0f; mouseY += pointerHeight / 2.0f; @@ -131,6 +133,8 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) { BandwidthMeter* bandwidthMeter = application->getBandwidthMeter(); NodeBounds& nodeBoundsDisplay = application->getNodeBoundsDisplay(); + _numMagnifiers = 0; + int mouseX = application->getMouseX(); int mouseY = application->getMouseY(); bool renderPointer = renderToTexture; @@ -310,15 +314,21 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) { overlays.render2D(); - // Render a crosshair over the pointer when in Oculus - if (renderPointer) { + // Render a crosshair over the mouse when in Oculus + if (renderPointer && application->getLastMouseMoveType() == QEvent::MouseMove) { const float pointerWidth = 10; const float pointerHeight = 10; const float crossPad = 4; + + _numMagnifiers = 1; + _mouseX[0] = application->getMouseX(); + _mouseY[0] = application->getMouseY(); + mouseX -= pointerWidth / 2.0f; mouseY += pointerHeight / 2.0f; + glBegin(GL_QUADS); glColor3f(1, 0, 0); @@ -336,7 +346,7 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) { glVertex2i(mouseX + crossPad, mouseY - pointerHeight); glEnd(); - } else if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseMouseInput)) { + } else if (application->getLastMouseMoveType() == CONTROLLER_MOVE_EVENT && Menu::getInstance()->isOptionChecked(MenuOption::SixenseMouseInput)) { //only render controller pointer if we aren't already rendering a mouse pointer renderControllerPointer(); } @@ -418,12 +428,8 @@ void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) { MyAvatar* myAvatar = application->getAvatar(); const glm::vec3& viewMatrixTranslation = application->getViewMatrixTranslation(); - int mouseX = application->getMouseX(); - int mouseY = application->getMouseY(); const int widgetWidth = glWidget->width(); const int widgetHeight = glWidget->height(); - float magnifyWidth = 80.0f; - float magnifyHeight = 60.0f; const float magnification = 4.0f; // Get vertical FoV of the displayed overlay texture @@ -480,114 +486,122 @@ void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) { glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.01f); - //Draw the magnifying glass - - mouseX -= magnifyWidth / 2; - mouseY -= magnifyHeight / 2; - - //clamp the magnification - if (mouseX < 0) { - magnifyWidth += mouseX; - mouseX = 0; - } else if (mouseX + magnifyWidth > widgetWidth) { - magnifyWidth = widgetWidth - mouseX; - } - if (mouseY < 0) { - magnifyHeight += mouseY; - mouseY = 0; - } else if (mouseY + magnifyHeight > widgetHeight) { - magnifyHeight = widgetHeight - mouseY; - } - - const float halfMagnifyHeight = magnifyHeight / 2.0f; - - float newWidth = magnifyWidth * magnification; - float newHeight = magnifyHeight * magnification; - - // Magnification Texture Coordinates - float magnifyULeft = mouseX / (float)widgetWidth; - float magnifyURight = (mouseX + magnifyWidth) / (float)widgetWidth; - float magnifyVBottom = 1.0f - mouseY / (float)widgetHeight; - float magnifyVTop = 1.0f - (mouseY + magnifyHeight) / (float)widgetHeight; - - // Coordinates of magnification overlay - float newMouseX = (mouseX + magnifyWidth / 2) - newWidth / 2.0f; - float newMouseY = (mouseY + magnifyHeight / 2) + newHeight / 2.0f; - - // Get angle on the UI - float leftAngle = (newMouseX / (float)widgetWidth) * horizontalAngle - halfHorizontalAngle; - float rightAngle = ((newMouseX + newWidth) / (float)widgetWidth) * horizontalAngle - halfHorizontalAngle; - - float bottomAngle = (newMouseY / (float)widgetHeight) * _oculusAngle - halfVerticalAngle; - float topAngle = ((newMouseY - newHeight) / (float)widgetHeight) * _oculusAngle - halfVerticalAngle; - float leftX, rightX, leftZ, rightZ, topZ, bottomZ; - - // Get position on hemisphere using angle - if (_uiType == HEMISPHERE) { - //Get new UV coordinates from our magnification window - float newULeft = newMouseX / widgetWidth; - float newURight = (newMouseX + newWidth) / widgetWidth; - float newVBottom = 1.0 - newMouseY / widgetHeight; - float newVTop = 1.0 - (newMouseY - newHeight) / widgetHeight; + //Draw the magnifiers + for (int i = 0; i < _numMagnifiers; i++) { - // Project our position onto the hemisphere using the UV coordinates - float lX = sin((newULeft - 0.5f) * textureFov); - float rX = sin((newURight - 0.5f) * textureFov); - float bY = sin((newVBottom - 0.5f) * textureFov); - float tY = sin((newVTop - 0.5f) * textureFov); - - float dist; - //Bottom Left - dist = sqrt(lX * lX + bY * bY); - float blZ = sqrt(1.0f - dist * dist); - //Top Left - dist = sqrt(lX * lX + tY * tY); - float tlZ = sqrt(1.0f - dist * dist); - //Bottom Right - dist = sqrt(rX * rX + bY * bY); - float brZ = sqrt(1.0f - dist * dist); - //Top Right - dist = sqrt(rX * rX + tY * tY); - float trZ = sqrt(1.0f - dist * dist); + float magnifyWidth = 80.0f; + float magnifyHeight = 60.0f; - glBegin(GL_QUADS); + int mouseX = _mouseX[i]; + int mouseY = _mouseY[i]; + mouseX -= magnifyWidth / 2; + mouseY -= magnifyHeight / 2; - glTexCoord2f(magnifyULeft, magnifyVBottom); glVertex3f(lX, tY, -tlZ); - glTexCoord2f(magnifyURight, magnifyVBottom); glVertex3f(rX, tY, -trZ); - glTexCoord2f(magnifyURight, magnifyVTop); glVertex3f(rX, bY, -brZ); - glTexCoord2f(magnifyULeft, magnifyVTop); glVertex3f(lX, bY, -blZ); - - glEnd(); - - } else { - leftX = sin(leftAngle) * _distance; - rightX = sin(rightAngle) * _distance; - leftZ = -cos(leftAngle) * _distance; - rightZ = -cos(rightAngle) * _distance; - if (_uiType == CURVED_SEMICIRCLE) { - topZ = -cos(topAngle * overlayAspectRatio) * _distance; - bottomZ = -cos(bottomAngle * overlayAspectRatio) * _distance; - } else { - // Dont want to use topZ or bottomZ for SEMICIRCLE - topZ = -99999; - bottomZ = -99999; + //clamp the magnification + if (mouseX < 0) { + magnifyWidth += mouseX; + mouseX = 0; + } else if (mouseX + magnifyWidth > widgetWidth) { + magnifyWidth = widgetWidth - mouseX; + } + if (mouseY < 0) { + magnifyHeight += mouseY; + mouseY = 0; + } else if (mouseY + magnifyHeight > widgetHeight) { + magnifyHeight = widgetHeight - mouseY; } - float bottomY = (1.0 - newMouseY / (float)widgetHeight) * halfOverlayHeight * 2.0f - halfOverlayHeight; - float topY = bottomY + (newHeight / widgetHeight) * halfOverlayHeight * 2; + const float halfMagnifyHeight = magnifyHeight / 2.0f; - //TODO: Remove immediate mode in favor of VBO - glBegin(GL_QUADS); + float newWidth = magnifyWidth * magnification; + float newHeight = magnifyHeight * magnification; - glTexCoord2f(magnifyULeft, magnifyVBottom); glVertex3f(leftX, topY, max(topZ, leftZ)); - glTexCoord2f(magnifyURight, magnifyVBottom); glVertex3f(rightX, topY, max(topZ, rightZ)); - glTexCoord2f(magnifyURight, magnifyVTop); glVertex3f(rightX, bottomY, max(bottomZ, rightZ)); - glTexCoord2f(magnifyULeft, magnifyVTop); glVertex3f(leftX, bottomY, max(bottomZ, leftZ)); + // Magnification Texture Coordinates + float magnifyULeft = mouseX / (float)widgetWidth; + float magnifyURight = (mouseX + magnifyWidth) / (float)widgetWidth; + float magnifyVBottom = 1.0f - mouseY / (float)widgetHeight; + float magnifyVTop = 1.0f - (mouseY + magnifyHeight) / (float)widgetHeight; - glEnd(); + // Coordinates of magnification overlay + float newMouseX = (mouseX + magnifyWidth / 2) - newWidth / 2.0f; + float newMouseY = (mouseY + magnifyHeight / 2) + newHeight / 2.0f; + + // Get angle on the UI + float leftAngle = (newMouseX / (float)widgetWidth) * horizontalAngle - halfHorizontalAngle; + float rightAngle = ((newMouseX + newWidth) / (float)widgetWidth) * horizontalAngle - halfHorizontalAngle; + + float bottomAngle = (newMouseY / (float)widgetHeight) * _oculusAngle - halfVerticalAngle; + float topAngle = ((newMouseY - newHeight) / (float)widgetHeight) * _oculusAngle - halfVerticalAngle; + + // Get position on hemisphere using angle + if (_uiType == HEMISPHERE) { + + //Get new UV coordinates from our magnification window + float newULeft = newMouseX / widgetWidth; + float newURight = (newMouseX + newWidth) / widgetWidth; + float newVBottom = 1.0 - newMouseY / widgetHeight; + float newVTop = 1.0 - (newMouseY - newHeight) / widgetHeight; + + // Project our position onto the hemisphere using the UV coordinates + float lX = sin((newULeft - 0.5f) * textureFov); + float rX = sin((newURight - 0.5f) * textureFov); + float bY = sin((newVBottom - 0.5f) * textureFov); + float tY = sin((newVTop - 0.5f) * textureFov); + + float dist; + //Bottom Left + dist = sqrt(lX * lX + bY * bY); + float blZ = sqrt(1.0f - dist * dist); + //Top Left + dist = sqrt(lX * lX + tY * tY); + float tlZ = sqrt(1.0f - dist * dist); + //Bottom Right + dist = sqrt(rX * rX + bY * bY); + float brZ = sqrt(1.0f - dist * dist); + //Top Right + dist = sqrt(rX * rX + tY * tY); + float trZ = sqrt(1.0f - dist * dist); + + glBegin(GL_QUADS); + + glTexCoord2f(magnifyULeft, magnifyVBottom); glVertex3f(lX, tY, -tlZ); + glTexCoord2f(magnifyURight, magnifyVBottom); glVertex3f(rX, tY, -trZ); + glTexCoord2f(magnifyURight, magnifyVTop); glVertex3f(rX, bY, -brZ); + glTexCoord2f(magnifyULeft, magnifyVTop); glVertex3f(lX, bY, -blZ); + + glEnd(); + + } else { + leftX = sin(leftAngle) * _distance; + rightX = sin(rightAngle) * _distance; + leftZ = -cos(leftAngle) * _distance; + rightZ = -cos(rightAngle) * _distance; + if (_uiType == CURVED_SEMICIRCLE) { + topZ = -cos(topAngle * overlayAspectRatio) * _distance; + bottomZ = -cos(bottomAngle * overlayAspectRatio) * _distance; + } else { + // Dont want to use topZ or bottomZ for SEMICIRCLE + topZ = -99999; + bottomZ = -99999; + } + + float bottomY = (1.0 - newMouseY / (float)widgetHeight) * halfOverlayHeight * 2.0f - halfOverlayHeight; + float topY = bottomY + (newHeight / widgetHeight) * halfOverlayHeight * 2; + + //TODO: Remove immediate mode in favor of VBO + glBegin(GL_QUADS); + + glTexCoord2f(magnifyULeft, magnifyVBottom); glVertex3f(leftX, topY, max(topZ, leftZ)); + glTexCoord2f(magnifyURight, magnifyVBottom); glVertex3f(rightX, topY, max(topZ, rightZ)); + glTexCoord2f(magnifyURight, magnifyVTop); glVertex3f(rightX, bottomY, max(bottomZ, rightZ)); + glTexCoord2f(magnifyULeft, magnifyVTop); glVertex3f(leftX, bottomY, max(bottomZ, leftZ)); + + glEnd(); + } } + glDepthMask(GL_FALSE); glDisable(GL_ALPHA_TEST); diff --git a/interface/src/ui/ApplicationOverlay.h b/interface/src/ui/ApplicationOverlay.h index 1bf0e18816..6dbcaa7afb 100644 --- a/interface/src/ui/ApplicationOverlay.h +++ b/interface/src/ui/ApplicationOverlay.h @@ -46,6 +46,7 @@ private: typedef QPair VerticesIndices; + void renderControllerPointer(); void renderTexturedHemisphere(); QOpenGLFramebufferObject* _framebufferObject; @@ -53,6 +54,9 @@ private: float _oculusAngle; float _distance; UIType _uiType; + int _mouseX[2]; + int _mouseY[2]; + int _numMagnifiers; }; #endif // hifi_ApplicationOverlay_h \ No newline at end of file From bc293071d6193d68734c0cc5a152046caae76d44 Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Thu, 12 Jun 2014 12:25:22 -0700 Subject: [PATCH 5/8] Removed left handed menu option --- interface/src/Menu.cpp | 1 - interface/src/Menu.h | 1 - interface/src/devices/SixenseManager.cpp | 3 --- interface/src/ui/ApplicationOverlay.cpp | 10 ++-------- 4 files changed, 2 insertions(+), 13 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 6cf99418e3..0c6a3efa24 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -382,7 +382,6 @@ Menu::Menu() : QMenu* sixenseOptionsMenu = developerMenu->addMenu("Sixense Options"); addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu, MenuOption::SixenseMouseInput, 0, true); - addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu, MenuOption::SixenseLeftHanded, 0, false); addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu, MenuOption::SixenseInvertInputButtons, 0, false); QMenu* handOptionsMenu = developerMenu->addMenu("Hand Options"); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 8415fb68c4..47ada75287 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -400,7 +400,6 @@ namespace MenuOption { const QString SettingsImport = "Import Settings"; const QString SimpleShadows = "Simple"; const QString SixenseInvertInputButtons = "Invert Sixense Mouse Input Buttons"; - const QString SixenseLeftHanded = "Left Handed Sixense Mouse Input"; const QString SixenseMouseInput = "Enable Sixense Mouse Input"; const QString ShowBordersVoxelNodes = "Show Voxel Nodes"; const QString ShowBordersModelNodes = "Show Model Nodes"; diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 37bad28093..bce55ae362 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -118,10 +118,7 @@ void SixenseManager::update(float deltaTime) { // Emulate the mouse so we can use scripts if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseMouseInput)) { - // Check if we are on the correct palm - //if ((Menu::getInstance()->isOptionChecked(MenuOption::SixenseLeftHanded) && numActiveControllers == 1) || numActiveControllers == 2) { emulateMouse(palm, numActiveControllers - 1); - //} } // NOTE: Sixense API returns pos data in millimeters but we IMMEDIATELY convert to meters. diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 83b6dde93b..873f7c29f3 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -44,14 +44,7 @@ void ApplicationOverlay::renderControllerPointer() { const HandData* handData = Application::getInstance()->getAvatar()->getHandData(); int numberOfPalms = handData->getNumPalms(); - - int palmIndex; - /*if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLeftHanded)) { - palmIndex = 2; - } else { - palmIndex = 3; - }*/ - for (palmIndex = 2; palmIndex < 4; palmIndex++) { + for (int palmIndex = 2; palmIndex < 4; palmIndex++) { const PalmData* palmData = NULL; if (palmIndex >= handData->getPalms().size()) { @@ -76,6 +69,7 @@ void ApplicationOverlay::renderControllerPointer() { int mouseX = cursorRange * xAngle; int mouseY = cursorRange * yAngle; + //If the cursor is out of the screen then don't render it if (mouseX < 0 || mouseX >= glWidget->width() || mouseY < 0 || mouseY >= glWidget->height()) { continue; } From a13ef5c3bf4e4dc82cb49f66e32592de3c7f2a0b Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Thu, 12 Jun 2014 13:19:02 -0700 Subject: [PATCH 6/8] Made applicationoverlay more readable --- interface/src/ui/ApplicationOverlay.cpp | 812 +++++++++++++----------- interface/src/ui/ApplicationOverlay.h | 5 + 2 files changed, 439 insertions(+), 378 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 873f7c29f3..9af3ed6d02 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -20,10 +20,20 @@ #include "ui/Stats.h" +// Fast helper functions +inline float max(float a, float b) { + return (a > b) ? a : b; +} + +inline float min(float a, float b) { + return (a < b) ? a : b; +} + ApplicationOverlay::ApplicationOverlay() : _framebufferObject(NULL), _oculusAngle(65.0f * RADIANS_PER_DEGREE), _distance(0.5f), + _textureFov(PI / 2.5f), _uiType(HEMISPHERE) { } @@ -36,6 +46,273 @@ ApplicationOverlay::~ApplicationOverlay() { const float WHITE_TEXT[] = { 0.93f, 0.93f, 0.93f }; +// Renders the overlays either to a texture or to the screen +void ApplicationOverlay::renderOverlay(bool renderToTexture) { + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()"); + + Application* application = Application::getInstance(); + + Overlays& overlays = application->getOverlays(); + QGLWidget* glWidget = application->getGLWidget(); + MyAvatar* myAvatar = application->getAvatar(); + + if (renderToTexture) { + getFramebufferObject()->bind(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // Render 2D overlay + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + + glLoadIdentity(); + gluOrtho2D(0, glWidget->width(), glWidget->height(), 0); + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + + renderAudioMeter(); + + if (Menu::getInstance()->isOptionChecked(MenuOption::HeadMouse)) { + myAvatar->renderHeadMouse(glWidget->width(), glWidget->height()); + } + + renderStatsAndLogs(); + + // give external parties a change to hook in + emit application->renderingOverlay(); + + overlays.render2D(); + + renderPointers(); + + glPopMatrix(); + + glMatrixMode(GL_MODELVIEW); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); + + if (renderToTexture) { + getFramebufferObject()->release(); + } +} + +// Draws the FBO texture for the screen +void ApplicationOverlay::displayOverlayTexture(Camera& whichCamera) { + + Application* application = Application::getInstance(); + QGLWidget* glWidget = application->getGLWidget(); + + glEnable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, getFramebufferObject()->texture()); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + + glLoadIdentity(); + gluOrtho2D(0, glWidget->width(), glWidget->height(), 0); + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2i(0, glWidget->height()); + glTexCoord2f(1, 0); glVertex2i(glWidget->width(), glWidget->height()); + glTexCoord2f(1, 1); glVertex2i(glWidget->width(), 0); + glTexCoord2f(0, 1); glVertex2i(0, 0); + glEnd(); + + glPopMatrix(); + glDisable(GL_TEXTURE_2D); +} + +void ApplicationOverlay::computeOculusPickRay(float x, float y, glm::vec3& direction) const { + glm::quat rot = Application::getInstance()->getAvatar()->getOrientation(); + + //invert y direction + y = 1.0 - y; + + //Get position on hemisphere UI + x = sin((x - 0.5f) * _textureFov); + y = sin((y - 0.5f) * _textureFov); + + float dist = sqrt(x * x + y * y); + float z = -sqrt(1.0f - dist * dist); + + //Rotate the UI pick ray by the avatar orientation + direction = glm::normalize(rot * glm::vec3(x, y, z)); +} + +// Draws the FBO texture for Oculus rift. TODO: Draw a curved texture instead of plane. +void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) { + + Application* application = Application::getInstance(); + + QGLWidget* glWidget = application->getGLWidget(); + MyAvatar* myAvatar = application->getAvatar(); + const glm::vec3& viewMatrixTranslation = application->getViewMatrixTranslation(); + + const int widgetWidth = glWidget->width(); + const int widgetHeight = glWidget->height(); + const float magnification = 4.0f; + + // Get vertical FoV of the displayed overlay texture + const float halfVerticalAngle = _oculusAngle / 2.0f; + const float overlayAspectRatio = glWidget->width() / (float)glWidget->height(); + const float halfOverlayHeight = _distance * tan(halfVerticalAngle); + const float overlayHeight = halfOverlayHeight * 2.0f; + + // The more vertices, the better the curve + const int numHorizontalVertices = 20; + const int numVerticalVertices = 20; + // U texture coordinate width at each quad + const float quadTexWidth = 1.0f / (numHorizontalVertices - 1); + const float quadTexHeight = 1.0f / (numVerticalVertices - 1); + + // Get horizontal angle and angle increment from vertical angle and aspect ratio + const float horizontalAngle = halfVerticalAngle * 2.0f * overlayAspectRatio; + const float angleIncrement = horizontalAngle / (numHorizontalVertices - 1); + const float halfHorizontalAngle = horizontalAngle / 2; + + const float verticalAngleIncrement = _oculusAngle / (numVerticalVertices - 1); + + glActiveTexture(GL_TEXTURE0); + + glEnable(GL_BLEND); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); + glBindTexture(GL_TEXTURE_2D, getFramebufferObject()->texture()); + glEnable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glEnable(GL_TEXTURE_2D); + + glMatrixMode(GL_MODELVIEW); + + glPushMatrix(); + glLoadIdentity(); + // Transform to world space + glm::quat rotation = whichCamera.getRotation(); + glm::vec3 axis2 = glm::axis(rotation); + glRotatef(-glm::degrees(glm::angle(rotation)), axis2.x, axis2.y, axis2.z); + glTranslatef(viewMatrixTranslation.x, viewMatrixTranslation.y, viewMatrixTranslation.z); + + // Translate to the front of the camera + glm::vec3 pos = whichCamera.getPosition(); + glm::quat rot = myAvatar->getOrientation(); + glm::vec3 axis = glm::axis(rot); + + glTranslatef(pos.x, pos.y, pos.z); + glRotatef(glm::degrees(glm::angle(rot)), axis.x, axis.y, axis.z); + + glColor3f(1.0f, 1.0f, 1.0f); + + glDepthMask(GL_TRUE); + + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.01f); + + float leftX, rightX, leftZ, rightZ, topZ, bottomZ; + + //Draw the magnifiers + for (int i = 0; i < _numMagnifiers; i++) { + renderMagnifier(_mouseX[i], _mouseY[i]); + } + + glDepthMask(GL_FALSE); + glDisable(GL_ALPHA_TEST); + + //TODO: Remove immediate mode in favor of VBO + if (_uiType == HEMISPHERE) { + renderTexturedHemisphere(); + } else{ + glBegin(GL_QUADS); + // Place the vertices in a semicircle curve around the camera + for (int i = 0; i < numHorizontalVertices - 1; i++) { + for (int j = 0; j < numVerticalVertices - 1; j++) { + + // Calculate the X and Z coordinates from the angles and radius from camera + leftX = sin(angleIncrement * i - halfHorizontalAngle) * _distance; + rightX = sin(angleIncrement * (i + 1) - halfHorizontalAngle) * _distance; + leftZ = -cos(angleIncrement * i - halfHorizontalAngle) * _distance; + rightZ = -cos(angleIncrement * (i + 1) - halfHorizontalAngle) * _distance; + if (_uiType == 2) { + topZ = -cos((verticalAngleIncrement * (j + 1) - halfVerticalAngle) * overlayAspectRatio) * _distance; + bottomZ = -cos((verticalAngleIncrement * j - halfVerticalAngle) * overlayAspectRatio) * _distance; + } else { + topZ = -99999; + bottomZ = -99999; + } + + glTexCoord2f(quadTexWidth * i, (j + 1) * quadTexHeight); + glVertex3f(leftX, (j + 1) * quadTexHeight * overlayHeight - halfOverlayHeight, max(topZ, leftZ)); + glTexCoord2f(quadTexWidth * (i + 1), (j + 1) * quadTexHeight); + glVertex3f(rightX, (j + 1) * quadTexHeight * overlayHeight - halfOverlayHeight, max(topZ, rightZ)); + glTexCoord2f(quadTexWidth * (i + 1), j * quadTexHeight); + glVertex3f(rightX, j * quadTexHeight * overlayHeight - halfOverlayHeight, max(bottomZ, rightZ)); + glTexCoord2f(quadTexWidth * i, j * quadTexHeight); + glVertex3f(leftX, j * quadTexHeight * overlayHeight - halfOverlayHeight, max(bottomZ, leftZ)); + } + } + + glEnd(); + } + + glPopMatrix(); + + glDepthMask(GL_TRUE); + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); + + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); + glEnable(GL_LIGHTING); + +} + +//Renders optional pointers +void ApplicationOverlay::renderPointers() { + Application* application = Application::getInstance(); + // Render a crosshair over the mouse when in Oculus + _numMagnifiers = 0; + int mouseX = application->getMouseX(); + int mouseY = application->getMouseY(); + + if (OculusManager::isConnected() && application->getLastMouseMoveType() == QEvent::MouseMove) { + const float pointerWidth = 10; + const float pointerHeight = 10; + const float crossPad = 4; + + _numMagnifiers = 1; + _mouseX[0] = application->getMouseX(); + _mouseY[0] = application->getMouseY(); + + mouseX -= pointerWidth / 2.0f; + mouseY += pointerHeight / 2.0f; + + + glBegin(GL_QUADS); + + glColor3f(1, 0, 0); + + //Horizontal crosshair + glVertex2i(mouseX, mouseY - crossPad); + glVertex2i(mouseX + pointerWidth, mouseY - crossPad); + glVertex2i(mouseX + pointerWidth, mouseY - pointerHeight + crossPad); + glVertex2i(mouseX, mouseY - pointerHeight + crossPad); + + //Vertical crosshair + glVertex2i(mouseX + crossPad, mouseY); + glVertex2i(mouseX + pointerWidth - crossPad, mouseY); + glVertex2i(mouseX + pointerWidth - crossPad, mouseY - pointerHeight); + glVertex2i(mouseX + crossPad, mouseY - pointerHeight); + + glEnd(); + } else if (application->getLastMouseMoveType() == CONTROLLER_MOVE_EVENT && Menu::getInstance()->isOptionChecked(MenuOption::SixenseMouseInput)) { + //only render controller pointer if we aren't already rendering a mouse pointer + renderControllerPointer(); + } +} + void ApplicationOverlay::renderControllerPointer() { Application* application = Application::getInstance(); QGLWidget* glWidget = application->getGLWidget(); @@ -87,7 +364,7 @@ void ApplicationOverlay::renderControllerPointer() { _mouseX[_numMagnifiers] = mouseX; _mouseY[_numMagnifiers] = mouseY; _numMagnifiers++; - + } mouseX -= pointerWidth / 2.0f; @@ -113,41 +390,154 @@ void ApplicationOverlay::renderControllerPointer() { } } -// Renders the overlays either to a texture or to the screen -void ApplicationOverlay::renderOverlay(bool renderToTexture) { - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()"); +//Renders a small magnification of the currently bound texture at the coordinates +void ApplicationOverlay::renderMagnifier(int mouseX, int mouseY) +{ + Application* application = Application::getInstance(); + QGLWidget* glWidget = application->getGLWidget(); + MyAvatar* myAvatar = application->getAvatar(); + const glm::vec3& viewMatrixTranslation = application->getViewMatrixTranslation(); + + float leftX, rightX, leftZ, rightZ, topZ, bottomZ; + + const int widgetWidth = glWidget->width(); + const int widgetHeight = glWidget->height(); + const float magnification = 4.0f; + + // Get vertical FoV of the displayed overlay texture + const float halfVerticalAngle = _oculusAngle / 2.0f; + const float overlayAspectRatio = glWidget->width() / (float)glWidget->height(); + const float halfOverlayHeight = _distance * tan(halfVerticalAngle); + const float overlayHeight = halfOverlayHeight * 2.0f; + + // The more vertices, the better the curve + const int numHorizontalVertices = 20; + const int numVerticalVertices = 20; + // U texture coordinate width at each quad + const float quadTexWidth = 1.0f / (numHorizontalVertices - 1); + const float quadTexHeight = 1.0f / (numVerticalVertices - 1); + + // Get horizontal angle and angle increment from vertical angle and aspect ratio + const float horizontalAngle = halfVerticalAngle * 2.0f * overlayAspectRatio; + const float angleIncrement = horizontalAngle / (numHorizontalVertices - 1); + const float halfHorizontalAngle = horizontalAngle / 2; + + + float magnifyWidth = 80.0f; + float magnifyHeight = 60.0f; + + mouseX -= magnifyWidth / 2; + mouseY -= magnifyHeight / 2; + + //clamp the magnification + if (mouseX < 0) { + magnifyWidth += mouseX; + mouseX = 0; + } else if (mouseX + magnifyWidth > widgetWidth) { + magnifyWidth = widgetWidth - mouseX; + } + if (mouseY < 0) { + magnifyHeight += mouseY; + mouseY = 0; + } else if (mouseY + magnifyHeight > widgetHeight) { + magnifyHeight = widgetHeight - mouseY; + } + + const float halfMagnifyHeight = magnifyHeight / 2.0f; + + float newWidth = magnifyWidth * magnification; + float newHeight = magnifyHeight * magnification; + + // Magnification Texture Coordinates + float magnifyULeft = mouseX / (float)widgetWidth; + float magnifyURight = (mouseX + magnifyWidth) / (float)widgetWidth; + float magnifyVBottom = 1.0f - mouseY / (float)widgetHeight; + float magnifyVTop = 1.0f - (mouseY + magnifyHeight) / (float)widgetHeight; + + // Coordinates of magnification overlay + float newMouseX = (mouseX + magnifyWidth / 2) - newWidth / 2.0f; + float newMouseY = (mouseY + magnifyHeight / 2) + newHeight / 2.0f; + + // Get angle on the UI + float leftAngle = (newMouseX / (float)widgetWidth) * horizontalAngle - halfHorizontalAngle; + float rightAngle = ((newMouseX + newWidth) / (float)widgetWidth) * horizontalAngle - halfHorizontalAngle; + + float bottomAngle = (newMouseY / (float)widgetHeight) * _oculusAngle - halfVerticalAngle; + float topAngle = ((newMouseY - newHeight) / (float)widgetHeight) * _oculusAngle - halfVerticalAngle; + + // Get position on hemisphere using angle + if (_uiType == HEMISPHERE) { + + //Get new UV coordinates from our magnification window + float newULeft = newMouseX / widgetWidth; + float newURight = (newMouseX + newWidth) / widgetWidth; + float newVBottom = 1.0 - newMouseY / widgetHeight; + float newVTop = 1.0 - (newMouseY - newHeight) / widgetHeight; + + // Project our position onto the hemisphere using the UV coordinates + float lX = sin((newULeft - 0.5f) * _textureFov); + float rX = sin((newURight - 0.5f) * _textureFov); + float bY = sin((newVBottom - 0.5f) * _textureFov); + float tY = sin((newVTop - 0.5f) * _textureFov); + + float dist; + //Bottom Left + dist = sqrt(lX * lX + bY * bY); + float blZ = sqrt(1.0f - dist * dist); + //Top Left + dist = sqrt(lX * lX + tY * tY); + float tlZ = sqrt(1.0f - dist * dist); + //Bottom Right + dist = sqrt(rX * rX + bY * bY); + float brZ = sqrt(1.0f - dist * dist); + //Top Right + dist = sqrt(rX * rX + tY * tY); + float trZ = sqrt(1.0f - dist * dist); + + glBegin(GL_QUADS); + + glTexCoord2f(magnifyULeft, magnifyVBottom); glVertex3f(lX, tY, -tlZ); + glTexCoord2f(magnifyURight, magnifyVBottom); glVertex3f(rX, tY, -trZ); + glTexCoord2f(magnifyURight, magnifyVTop); glVertex3f(rX, bY, -brZ); + glTexCoord2f(magnifyULeft, magnifyVTop); glVertex3f(lX, bY, -blZ); + + glEnd(); + + } else { + leftX = sin(leftAngle) * _distance; + rightX = sin(rightAngle) * _distance; + leftZ = -cos(leftAngle) * _distance; + rightZ = -cos(rightAngle) * _distance; + if (_uiType == CURVED_SEMICIRCLE) { + topZ = -cos(topAngle * overlayAspectRatio) * _distance; + bottomZ = -cos(bottomAngle * overlayAspectRatio) * _distance; + } else { + // Dont want to use topZ or bottomZ for SEMICIRCLE + topZ = -99999; + bottomZ = -99999; + } + + float bottomY = (1.0 - newMouseY / (float)widgetHeight) * halfOverlayHeight * 2.0f - halfOverlayHeight; + float topY = bottomY + (newHeight / widgetHeight) * halfOverlayHeight * 2; + + //TODO: Remove immediate mode in favor of VBO + glBegin(GL_QUADS); + + glTexCoord2f(magnifyULeft, magnifyVBottom); glVertex3f(leftX, topY, max(topZ, leftZ)); + glTexCoord2f(magnifyURight, magnifyVBottom); glVertex3f(rightX, topY, max(topZ, rightZ)); + glTexCoord2f(magnifyURight, magnifyVTop); glVertex3f(rightX, bottomY, max(bottomZ, rightZ)); + glTexCoord2f(magnifyULeft, magnifyVTop); glVertex3f(leftX, bottomY, max(bottomZ, leftZ)); + + glEnd(); + } +} + +void ApplicationOverlay::renderAudioMeter() { Application* application = Application::getInstance(); - Overlays& overlays = application->getOverlays(); QGLWidget* glWidget = application->getGLWidget(); - MyAvatar* myAvatar = application->getAvatar(); Audio* audio = application->getAudio(); - const OctreePacketProcessor& octreePacketProcessor = application->getOctreePacketProcessor(); - BandwidthMeter* bandwidthMeter = application->getBandwidthMeter(); - NodeBounds& nodeBoundsDisplay = application->getNodeBoundsDisplay(); - - _numMagnifiers = 0; - - int mouseX = application->getMouseX(); - int mouseY = application->getMouseY(); - bool renderPointer = renderToTexture; - - if (renderToTexture) { - getFramebufferObject()->bind(); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - } - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - // Render 2D overlay: I/O level bar graphs and text - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - - glLoadIdentity(); - gluOrtho2D(0, glWidget->width(), glWidget->height(), 0); - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); // Display a single screen-size quad to create an alpha blended 'collision' flash if (audio->getCollisionFlashesScreen()) { @@ -267,11 +657,16 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) { glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET); glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET); glEnd(); +} +void ApplicationOverlay::renderStatsAndLogs() { - if (Menu::getInstance()->isOptionChecked(MenuOption::HeadMouse)) { - myAvatar->renderHeadMouse(glWidget->width(), glWidget->height()); - } + Application* application = Application::getInstance(); + + QGLWidget* glWidget = application->getGLWidget(); + const OctreePacketProcessor& octreePacketProcessor = application->getOctreePacketProcessor(); + BandwidthMeter* bandwidthMeter = application->getBandwidthMeter(); + NodeBounds& nodeBoundsDisplay = application->getNodeBoundsDisplay(); // Display stats and log text onscreen glLineWidth(1.0f); @@ -302,357 +697,18 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) { drawText(glWidget->width() - 100, glWidget->height() - timerBottom, 0.30f, 0.0f, 0, frameTimer, WHITE_TEXT); } nodeBoundsDisplay.drawOverlay(); - - // give external parties a change to hook in - emit application->renderingOverlay(); - - overlays.render2D(); - - // Render a crosshair over the mouse when in Oculus - if (renderPointer && application->getLastMouseMoveType() == QEvent::MouseMove) { - const float pointerWidth = 10; - const float pointerHeight = 10; - const float crossPad = 4; - - - _numMagnifiers = 1; - _mouseX[0] = application->getMouseX(); - _mouseY[0] = application->getMouseY(); - - mouseX -= pointerWidth / 2.0f; - mouseY += pointerHeight / 2.0f; - - - glBegin(GL_QUADS); - - glColor3f(1, 0, 0); - - //Horizontal crosshair - glVertex2i(mouseX, mouseY - crossPad); - glVertex2i(mouseX + pointerWidth, mouseY - crossPad); - glVertex2i(mouseX + pointerWidth, mouseY - pointerHeight + crossPad); - glVertex2i(mouseX, mouseY - pointerHeight + crossPad); - - //Vertical crosshair - glVertex2i(mouseX + crossPad, mouseY); - glVertex2i(mouseX + pointerWidth - crossPad, mouseY); - glVertex2i(mouseX + pointerWidth - crossPad, mouseY - pointerHeight); - glVertex2i(mouseX + crossPad, mouseY - pointerHeight); - - glEnd(); - } else if (application->getLastMouseMoveType() == CONTROLLER_MOVE_EVENT && Menu::getInstance()->isOptionChecked(MenuOption::SixenseMouseInput)) { - //only render controller pointer if we aren't already rendering a mouse pointer - renderControllerPointer(); - } - glPopMatrix(); - - glMatrixMode(GL_MODELVIEW); - glEnable(GL_DEPTH_TEST); - glEnable(GL_LIGHTING); - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); - - if (renderToTexture) { - getFramebufferObject()->release(); - } -} - -// Draws the FBO texture for the screen -void ApplicationOverlay::displayOverlayTexture(Camera& whichCamera) { - - Application* application = Application::getInstance(); - QGLWidget* glWidget = application->getGLWidget(); - - glEnable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, getFramebufferObject()->texture()); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - - glLoadIdentity(); - gluOrtho2D(0, glWidget->width(), glWidget->height(), 0); - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2i(0, glWidget->height()); - glTexCoord2f(1, 0); glVertex2i(glWidget->width(), glWidget->height()); - glTexCoord2f(1, 1); glVertex2i(glWidget->width(), 0); - glTexCoord2f(0, 1); glVertex2i(0, 0); - glEnd(); - - glPopMatrix(); - glDisable(GL_TEXTURE_2D); -} - -const float textureFov = PI / 2.5f; - -void ApplicationOverlay::computeOculusPickRay(float x, float y, glm::vec3& direction) const { - glm::quat rot = Application::getInstance()->getAvatar()->getOrientation(); - - //invert y direction - y = 1.0 - y; - - //Get position on hemisphere UI - x = sin((x - 0.5f) * textureFov); - y = sin((y - 0.5f) * textureFov); - - float dist = sqrt(x * x + y * y); - float z = -sqrt(1.0f - dist * dist); - - //Rotate the UI pick ray by the avatar orientation - direction = glm::normalize(rot * glm::vec3(x, y, z)); -} - -// Fast helper functions -inline float max(float a, float b) { - return (a > b) ? a : b; -} - -inline float min(float a, float b) { - return (a < b) ? a : b; -} - -// Draws the FBO texture for Oculus rift. TODO: Draw a curved texture instead of plane. -void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) { - - Application* application = Application::getInstance(); - - QGLWidget* glWidget = application->getGLWidget(); - MyAvatar* myAvatar = application->getAvatar(); - const glm::vec3& viewMatrixTranslation = application->getViewMatrixTranslation(); - - const int widgetWidth = glWidget->width(); - const int widgetHeight = glWidget->height(); - const float magnification = 4.0f; - - // Get vertical FoV of the displayed overlay texture - const float halfVerticalAngle = _oculusAngle / 2.0f; - const float overlayAspectRatio = glWidget->width() / (float)glWidget->height(); - const float halfOverlayHeight = _distance * tan(halfVerticalAngle); - const float overlayHeight = halfOverlayHeight * 2.0f; - - // The more vertices, the better the curve - const int numHorizontalVertices = 20; - const int numVerticalVertices = 20; - // U texture coordinate width at each quad - const float quadTexWidth = 1.0f / (numHorizontalVertices - 1); - const float quadTexHeight = 1.0f / (numVerticalVertices - 1); - - // Get horizontal angle and angle increment from vertical angle and aspect ratio - const float horizontalAngle = halfVerticalAngle * 2.0f * overlayAspectRatio; - const float angleIncrement = horizontalAngle / (numHorizontalVertices - 1); - const float halfHorizontalAngle = horizontalAngle / 2; - - const float verticalAngleIncrement = _oculusAngle / (numVerticalVertices - 1); - - glActiveTexture(GL_TEXTURE0); - - glEnable(GL_BLEND); - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); - glBindTexture(GL_TEXTURE_2D, getFramebufferObject()->texture()); - glEnable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glEnable(GL_TEXTURE_2D); - - glMatrixMode(GL_MODELVIEW); - - glPushMatrix(); - glLoadIdentity(); - // Transform to world space - glm::quat rotation = whichCamera.getRotation(); - glm::vec3 axis2 = glm::axis(rotation); - glRotatef(-glm::degrees(glm::angle(rotation)), axis2.x, axis2.y, axis2.z); - glTranslatef(viewMatrixTranslation.x, viewMatrixTranslation.y, viewMatrixTranslation.z); - - // Translate to the front of the camera - glm::vec3 pos = whichCamera.getPosition(); - glm::quat rot = myAvatar->getOrientation(); - glm::vec3 axis = glm::axis(rot); - - glTranslatef(pos.x, pos.y, pos.z); - glRotatef(glm::degrees(glm::angle(rot)), axis.x, axis.y, axis.z); - - glColor3f(1.0f, 1.0f, 1.0f); - - glDepthMask(GL_TRUE); - - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.01f); - - float leftX, rightX, leftZ, rightZ, topZ, bottomZ; - - //Draw the magnifiers - for (int i = 0; i < _numMagnifiers; i++) { - - float magnifyWidth = 80.0f; - float magnifyHeight = 60.0f; - - int mouseX = _mouseX[i]; - int mouseY = _mouseY[i]; - mouseX -= magnifyWidth / 2; - mouseY -= magnifyHeight / 2; - - //clamp the magnification - if (mouseX < 0) { - magnifyWidth += mouseX; - mouseX = 0; - } else if (mouseX + magnifyWidth > widgetWidth) { - magnifyWidth = widgetWidth - mouseX; - } - if (mouseY < 0) { - magnifyHeight += mouseY; - mouseY = 0; - } else if (mouseY + magnifyHeight > widgetHeight) { - magnifyHeight = widgetHeight - mouseY; - } - - const float halfMagnifyHeight = magnifyHeight / 2.0f; - - float newWidth = magnifyWidth * magnification; - float newHeight = magnifyHeight * magnification; - - // Magnification Texture Coordinates - float magnifyULeft = mouseX / (float)widgetWidth; - float magnifyURight = (mouseX + magnifyWidth) / (float)widgetWidth; - float magnifyVBottom = 1.0f - mouseY / (float)widgetHeight; - float magnifyVTop = 1.0f - (mouseY + magnifyHeight) / (float)widgetHeight; - - // Coordinates of magnification overlay - float newMouseX = (mouseX + magnifyWidth / 2) - newWidth / 2.0f; - float newMouseY = (mouseY + magnifyHeight / 2) + newHeight / 2.0f; - - // Get angle on the UI - float leftAngle = (newMouseX / (float)widgetWidth) * horizontalAngle - halfHorizontalAngle; - float rightAngle = ((newMouseX + newWidth) / (float)widgetWidth) * horizontalAngle - halfHorizontalAngle; - - float bottomAngle = (newMouseY / (float)widgetHeight) * _oculusAngle - halfVerticalAngle; - float topAngle = ((newMouseY - newHeight) / (float)widgetHeight) * _oculusAngle - halfVerticalAngle; - - // Get position on hemisphere using angle - if (_uiType == HEMISPHERE) { - - //Get new UV coordinates from our magnification window - float newULeft = newMouseX / widgetWidth; - float newURight = (newMouseX + newWidth) / widgetWidth; - float newVBottom = 1.0 - newMouseY / widgetHeight; - float newVTop = 1.0 - (newMouseY - newHeight) / widgetHeight; - - // Project our position onto the hemisphere using the UV coordinates - float lX = sin((newULeft - 0.5f) * textureFov); - float rX = sin((newURight - 0.5f) * textureFov); - float bY = sin((newVBottom - 0.5f) * textureFov); - float tY = sin((newVTop - 0.5f) * textureFov); - - float dist; - //Bottom Left - dist = sqrt(lX * lX + bY * bY); - float blZ = sqrt(1.0f - dist * dist); - //Top Left - dist = sqrt(lX * lX + tY * tY); - float tlZ = sqrt(1.0f - dist * dist); - //Bottom Right - dist = sqrt(rX * rX + bY * bY); - float brZ = sqrt(1.0f - dist * dist); - //Top Right - dist = sqrt(rX * rX + tY * tY); - float trZ = sqrt(1.0f - dist * dist); - - glBegin(GL_QUADS); - - glTexCoord2f(magnifyULeft, magnifyVBottom); glVertex3f(lX, tY, -tlZ); - glTexCoord2f(magnifyURight, magnifyVBottom); glVertex3f(rX, tY, -trZ); - glTexCoord2f(magnifyURight, magnifyVTop); glVertex3f(rX, bY, -brZ); - glTexCoord2f(magnifyULeft, magnifyVTop); glVertex3f(lX, bY, -blZ); - - glEnd(); - - } else { - leftX = sin(leftAngle) * _distance; - rightX = sin(rightAngle) * _distance; - leftZ = -cos(leftAngle) * _distance; - rightZ = -cos(rightAngle) * _distance; - if (_uiType == CURVED_SEMICIRCLE) { - topZ = -cos(topAngle * overlayAspectRatio) * _distance; - bottomZ = -cos(bottomAngle * overlayAspectRatio) * _distance; - } else { - // Dont want to use topZ or bottomZ for SEMICIRCLE - topZ = -99999; - bottomZ = -99999; - } - - float bottomY = (1.0 - newMouseY / (float)widgetHeight) * halfOverlayHeight * 2.0f - halfOverlayHeight; - float topY = bottomY + (newHeight / widgetHeight) * halfOverlayHeight * 2; - - //TODO: Remove immediate mode in favor of VBO - glBegin(GL_QUADS); - - glTexCoord2f(magnifyULeft, magnifyVBottom); glVertex3f(leftX, topY, max(topZ, leftZ)); - glTexCoord2f(magnifyURight, magnifyVBottom); glVertex3f(rightX, topY, max(topZ, rightZ)); - glTexCoord2f(magnifyURight, magnifyVTop); glVertex3f(rightX, bottomY, max(bottomZ, rightZ)); - glTexCoord2f(magnifyULeft, magnifyVTop); glVertex3f(leftX, bottomY, max(bottomZ, leftZ)); - - glEnd(); - } - } - - glDepthMask(GL_FALSE); - glDisable(GL_ALPHA_TEST); - - //TODO: Remove immediate mode in favor of VBO - if (_uiType == HEMISPHERE) { - renderTexturedHemisphere(); - } else{ - glBegin(GL_QUADS); - // Place the vertices in a semicircle curve around the camera - for (int i = 0; i < numHorizontalVertices - 1; i++) { - for (int j = 0; j < numVerticalVertices - 1; j++) { - - // Calculate the X and Z coordinates from the angles and radius from camera - leftX = sin(angleIncrement * i - halfHorizontalAngle) * _distance; - rightX = sin(angleIncrement * (i + 1) - halfHorizontalAngle) * _distance; - leftZ = -cos(angleIncrement * i - halfHorizontalAngle) * _distance; - rightZ = -cos(angleIncrement * (i + 1) - halfHorizontalAngle) * _distance; - if (_uiType == 2) { - topZ = -cos((verticalAngleIncrement * (j + 1) - halfVerticalAngle) * overlayAspectRatio) * _distance; - bottomZ = -cos((verticalAngleIncrement * j - halfVerticalAngle) * overlayAspectRatio) * _distance; - } else { - topZ = -99999; - bottomZ = -99999; - } - - glTexCoord2f(quadTexWidth * i, (j + 1) * quadTexHeight); - glVertex3f(leftX, (j + 1) * quadTexHeight * overlayHeight - halfOverlayHeight, max(topZ, leftZ)); - glTexCoord2f(quadTexWidth * (i + 1), (j + 1) * quadTexHeight); - glVertex3f(rightX, (j + 1) * quadTexHeight * overlayHeight - halfOverlayHeight, max(topZ, rightZ)); - glTexCoord2f(quadTexWidth * (i + 1), j * quadTexHeight); - glVertex3f(rightX, j * quadTexHeight * overlayHeight - halfOverlayHeight, max(bottomZ, rightZ)); - glTexCoord2f(quadTexWidth * i, j * quadTexHeight); - glVertex3f(leftX, j * quadTexHeight * overlayHeight - halfOverlayHeight, max(bottomZ, leftZ)); - } - } - - glEnd(); - } - - glPopMatrix(); - - glDepthMask(GL_TRUE); - glBindTexture(GL_TEXTURE_2D, 0); - glDisable(GL_TEXTURE_2D); - - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); - glEnable(GL_LIGHTING); - } +//Renders a hemisphere with texture coordinates. void ApplicationOverlay::renderTexturedHemisphere() { const int slices = 80; const int stacks = 80; + //UV mapping source: http://www.mvps.org/directx/articles/spheremap.htm static VerticesIndices vbo(0, 0); int vertices = slices * (stacks - 1) + 1; int indices = slices * 2 * 3 * (stacks - 2) + slices * 3; + //We only generate the VBO once if (vbo.first == 0) { TextureVertex* vertexData = new TextureVertex[vertices]; TextureVertex* vertex = vertexData; @@ -666,8 +722,8 @@ void ApplicationOverlay::renderTexturedHemisphere() { vertex->position.x = sinf(theta) * radius; vertex->position.y = cosf(theta) * radius; vertex->position.z = z; - vertex->uv.x = asin(vertex->position.x) / (textureFov) + 0.5f; - vertex->uv.y = asin(vertex->position.y) / (textureFov) + 0.5f; + vertex->uv.x = asin(vertex->position.x) / (_textureFov) + 0.5f; + vertex->uv.y = asin(vertex->position.y) / (_textureFov) + 0.5f; vertex++; } } diff --git a/interface/src/ui/ApplicationOverlay.h b/interface/src/ui/ApplicationOverlay.h index 6dbcaa7afb..03a323cd5d 100644 --- a/interface/src/ui/ApplicationOverlay.h +++ b/interface/src/ui/ApplicationOverlay.h @@ -46,13 +46,18 @@ private: typedef QPair VerticesIndices; + void renderPointers(); void renderControllerPointer(); + void renderMagnifier(int mouseX, int mouseY); + void renderAudioMeter(); + void renderStatsAndLogs(); void renderTexturedHemisphere(); QOpenGLFramebufferObject* _framebufferObject; float _trailingAudioLoudness; float _oculusAngle; float _distance; + float _textureFov; UIType _uiType; int _mouseX[2]; int _mouseY[2]; From 91f23fcf2d7ac3c918e63e838d5c8e22d591cdc9 Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Thu, 12 Jun 2014 15:39:40 -0700 Subject: [PATCH 7/8] Fix for click and drag with sixense --- interface/src/devices/SixenseManager.cpp | 12 +++++++++++- interface/src/ui/ApplicationOverlay.cpp | 1 - 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index bce55ae362..4df08c6966 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -381,7 +381,17 @@ void SixenseManager::emulateMouse(PalmData* palm, int index) { if (pos.x() != _oldX[index] || pos.y() != _oldY[index]) { QMouseEvent mouseEvent(static_cast(CONTROLLER_MOVE_EVENT), pos, Qt::NoButton, Qt::NoButton, 0); - Application::getInstance()->mouseMoveEvent(&mouseEvent); + //Only send the mouse event if the opposite left button isnt held down. + //This is specifically for edit voxels + if (triggerButton == Qt::LeftButton) { + if (!_triggerPressed[(int)(!index)]) { + Application::getInstance()->mouseMoveEvent(&mouseEvent); + } + } else { + if (!_bumperPressed[(int)(!index)]) { + Application::getInstance()->mouseMoveEvent(&mouseEvent); + } + } } _oldX[index] = pos.x(); _oldY[index] = pos.y(); diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 9af3ed6d02..ae6b49c560 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -289,7 +289,6 @@ void ApplicationOverlay::renderPointers() { mouseX -= pointerWidth / 2.0f; mouseY += pointerHeight / 2.0f; - glBegin(GL_QUADS); glColor3f(1, 0, 0); From 16f9b8c3ed0a836435f246ef146a9ebdd70b091c Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Thu, 12 Jun 2014 15:49:00 -0700 Subject: [PATCH 8/8] Removed some unused variables. --- interface/src/devices/SixenseManager.cpp | 1 - interface/src/ui/ApplicationOverlay.cpp | 15 ++------------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 4df08c6966..fa902be46f 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -353,7 +353,6 @@ void SixenseManager::emulateMouse(PalmData* palm, int index) { float cursorRange = widget->width(); - pos.setX(cursorRange * xAngle); pos.setY(cursorRange * yAngle); diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index ae6b49c560..95ac803e37 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -154,9 +154,7 @@ void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) { MyAvatar* myAvatar = application->getAvatar(); const glm::vec3& viewMatrixTranslation = application->getViewMatrixTranslation(); - const int widgetWidth = glWidget->width(); - const int widgetHeight = glWidget->height(); - const float magnification = 4.0f; + // Get vertical FoV of the displayed overlay texture const float halfVerticalAngle = _oculusAngle / 2.0f; @@ -320,7 +318,7 @@ void ApplicationOverlay::renderControllerPointer() { const HandData* handData = Application::getInstance()->getAvatar()->getHandData(); int numberOfPalms = handData->getNumPalms(); - for (int palmIndex = 2; palmIndex < 4; palmIndex++) { + for (unsigned int palmIndex = 2; palmIndex < 4; palmIndex++) { const PalmData* palmData = NULL; if (palmIndex >= handData->getPalms().size()) { @@ -407,18 +405,9 @@ void ApplicationOverlay::renderMagnifier(int mouseX, int mouseY) const float halfVerticalAngle = _oculusAngle / 2.0f; const float overlayAspectRatio = glWidget->width() / (float)glWidget->height(); const float halfOverlayHeight = _distance * tan(halfVerticalAngle); - const float overlayHeight = halfOverlayHeight * 2.0f; - - // The more vertices, the better the curve - const int numHorizontalVertices = 20; - const int numVerticalVertices = 20; - // U texture coordinate width at each quad - const float quadTexWidth = 1.0f / (numHorizontalVertices - 1); - const float quadTexHeight = 1.0f / (numVerticalVertices - 1); // Get horizontal angle and angle increment from vertical angle and aspect ratio const float horizontalAngle = halfVerticalAngle * 2.0f * overlayAspectRatio; - const float angleIncrement = horizontalAngle / (numHorizontalVertices - 1); const float halfHorizontalAngle = horizontalAngle / 2;