void ApplicationOverlay::renderPointersOculus(const glm::vec3& eyePos) { glBindTexture(GL_TEXTURE_2D, _crosshairTexture); glDisable(GL_DEPTH_TEST); glMatrixMode(GL_MODELVIEW); //Controller Pointers MyAvatar* myAvatar = Application::getInstance()->getAvatar(); for (int i = 0; i < (int)myAvatar->getHand()->getNumPalms(); i++) { PalmData& palm = myAvatar->getHand()->getPalms()[i]; if (palm.isActive()) { glm::vec3 tip = myAvatar->getLaserPointerTipPosition(&palm); glm::vec3 tipDirection = glm::normalize(glm::inverse(myAvatar->getOrientation()) * (tip - eyePos)); float pitch = -glm::asin(tipDirection.y); float yawSign = glm::sign(-tipDirection.x); float yaw = glm::acos(-tipDirection.z) * ((yawSign == 0.0f) ? 1.0f : yawSign); glm::quat orientation = glm::quat(glm::vec3(pitch, yaw, 0.0f)); renderReticle(orientation, _alpha); } } //Mouse Pointer if (_reticleActive[MOUSE]) { glm::vec2 projection = screenToSpherical(glm::vec2(_reticlePosition[MOUSE].x(), _reticlePosition[MOUSE].y())); glm::quat orientation(glm::vec3(-projection.y, projection.x, 0.0f)); renderReticle(orientation, _alpha); } glEnable(GL_DEPTH_TEST); }
void ApplicationCompositor::computeHmdPickRay(glm::vec2 cursorPos, glm::vec3& origin, glm::vec3& direction) const { cursorPos *= qApp->getCanvasSize(); const glm::vec2 projection = screenToSpherical(cursorPos); // The overlay space orientation of the mouse coordinates const glm::quat orientation(glm::vec3(-projection.y, projection.x, 0.0f)); // FIXME We now have the direction of the ray FROM THE DEFAULT HEAD POSE. // Now we need to account for the actual camera position relative to the overlay glm::vec3 overlaySpaceDirection = glm::normalize(orientation * IDENTITY_FRONT); // We need the RAW camera orientation and position, because this is what the overlay is // rendered relative to const glm::vec3 overlayPosition = qApp->getCamera()->getPosition(); const glm::quat overlayOrientation = qApp->getCamera()->getRotation(); // Intersection UI overlay space glm::vec3 worldSpaceDirection = overlayOrientation * overlaySpaceDirection; glm::vec3 worldSpaceIntersection = (glm::normalize(worldSpaceDirection) * _oculusUIRadius) + overlayPosition; glm::vec3 worldSpaceHeadPosition = (overlayOrientation * glm::vec3(qApp->getHeadPose()[3])) + overlayPosition; // Intersection in world space origin = worldSpaceHeadPosition; direction = glm::normalize(worldSpaceIntersection - worldSpaceHeadPosition); }
glm::vec2 ApplicationCompositor::screenToOverlay(const glm::vec2& screenPos) const { return sphericalToOverlay(screenToSpherical(screenPos)); }
// Draws the FBO texture for Oculus rift. void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int eye) { if (_alpha == 0.0f) { return; } GLuint texture = qApp->getApplicationOverlay().getOverlayTexture(); if (!texture) { return; } updateTooltips(); vec2 canvasSize = qApp->getCanvasSize(); _textureAspectRatio = aspect(canvasSize); renderArgs->_context->syncCache(); auto geometryCache = DependencyManager::get<GeometryCache>(); gpu::Batch batch; geometryCache->useSimpleDrawPipeline(batch); batch._glDisable(GL_DEPTH_TEST); batch._glDisable(GL_CULL_FACE); batch._glBindTexture(GL_TEXTURE_2D, texture); batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); batch.setViewTransform(Transform()); batch.setProjectionTransform(qApp->getEyeProjection(eye)); mat4 eyePose = qApp->getEyePose(eye); glm::mat4 overlayXfm = glm::inverse(eyePose); #ifdef DEBUG_OVERLAY { batch.setModelTransform(glm::translate(mat4(), vec3(0, 0, -2))); geometryCache->renderUnitQuad(batch, glm::vec4(1)); } #else { batch.setModelTransform(overlayXfm); drawSphereSection(batch); } #endif // Doesn't actually render renderPointers(batch); vec3 reticleScale = vec3(Cursor::Manager::instance().getScale() * reticleSize); bindCursorTexture(batch); MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar(); //Controller Pointers for (int i = 0; i < (int)myAvatar->getHand()->getNumPalms(); i++) { PalmData& palm = myAvatar->getHand()->getPalms()[i]; if (palm.isActive()) { glm::vec2 polar = getPolarCoordinates(palm); // Convert to quaternion mat4 pointerXfm = glm::mat4_cast(quat(vec3(polar.y, -polar.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1)); mat4 reticleXfm = overlayXfm * pointerXfm; reticleXfm = glm::scale(reticleXfm, reticleScale); batch.setModelTransform(reticleXfm); // Render reticle at location geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad); } } //Mouse Pointer if (_reticleActive[MOUSE]) { glm::vec2 projection = screenToSpherical(glm::vec2(_reticlePosition[MOUSE].x(), _reticlePosition[MOUSE].y())); mat4 pointerXfm = glm::mat4_cast(quat(vec3(-projection.y, projection.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1)); mat4 reticleXfm = overlayXfm * pointerXfm; reticleXfm = glm::scale(reticleXfm, reticleScale); batch.setModelTransform(reticleXfm); geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad); } renderArgs->_context->render(batch); }
glm::vec2 ApplicationOverlay::screenToOverlay(glm::vec2 screenPos) const { return sphericalToOverlay(screenToSpherical(screenPos)); }