//Caculate the click location using one of the sixense controllers. Scale is not applied QPoint ApplicationCompositor::getPalmClickLocation(const PalmData *palm) const { QPoint rv; auto canvasSize = qApp->getCanvasSize(); if (qApp->isHMDMode()) { glm::vec2 polar = getPolarCoordinates(*palm); glm::vec2 point = sphericalToScreen(-polar); rv.rx() = point.x; rv.ry() = point.y; } else { MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar(); glm::dmat4 projection; qApp->getProjectionMatrix(&projection); glm::quat invOrientation = glm::inverse(myAvatar->getOrientation()); glm::vec3 eyePos = myAvatar->getDefaultEyePosition(); glm::vec3 tip = myAvatar->getLaserPointerTipPosition(palm); glm::vec3 tipPos = invOrientation * (tip - eyePos); glm::vec4 clipSpacePos = glm::vec4(projection * glm::dvec4(tipPos, 1.0)); glm::vec3 ndcSpacePos; if (clipSpacePos.w != 0) { ndcSpacePos = glm::vec3(clipSpacePos) / clipSpacePos.w; } rv.setX(((ndcSpacePos.x + 1.0) / 2.0) * canvasSize.x); rv.setY((1.0 - ((ndcSpacePos.y + 1.0) / 2.0)) * canvasSize.y); } return rv; }
//Renders optional pointers void ApplicationOverlay::renderPointers() { Application* application = Application::getInstance(); //lazily load crosshair texture if (_crosshairTexture == 0) { _crosshairTexture = Application::getInstance()->getGLWidget()->bindTexture(QImage(Application::resourcesPath() + "images/sixense-reticle.png")); } glEnable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, _crosshairTexture); if (OculusManager::isConnected() && !application->getLastMouseMoveWasSimulated()) { //If we are in oculus, render reticle later if (_lastMouseMove == 0) { _lastMouseMove = usecTimestampNow(); } QPoint position = QPoint(application->getTrueMouseX(), application->getTrueMouseY()); static const int MAX_IDLE_TIME = 3; if (_reticlePosition[MOUSE] != position) { _lastMouseMove = usecTimestampNow(); } else if (usecTimestampNow() - _lastMouseMove > MAX_IDLE_TIME * USECS_PER_SECOND) { float pitch, yaw, roll; OculusManager::getEulerAngles(yaw, pitch, roll); glm::vec2 screenPos = sphericalToScreen(glm::vec2(yaw, -pitch)); position = QPoint(screenPos.x, screenPos.y); application->getGLWidget()->cursor().setPos(application->getGLWidget()->mapToGlobal(position)); } _reticlePosition[MOUSE] = position; _reticleActive[MOUSE] = true; _magActive[MOUSE] = true; _reticleActive[LEFT_CONTROLLER] = false; _reticleActive[RIGHT_CONTROLLER] = false; } else if (application->getLastMouseMoveWasSimulated() && Menu::getInstance()->isOptionChecked(MenuOption::SixenseMouseInput)) { _lastMouseMove = 0; //only render controller pointer if we aren't already rendering a mouse pointer _reticleActive[MOUSE] = false; _magActive[MOUSE] = false; renderControllerPointers(); } glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); }
glm::vec2 ApplicationCompositor::overlayToScreen(const glm::vec2& overlayPos) const { return sphericalToScreen(overlayToSpherical(overlayPos)); }
glm::vec2 ApplicationOverlay::overlayToScreen(glm::vec2 overlayPos) const { return sphericalToScreen(overlayToSpherical(overlayPos)); }