From a120e50cc03e5ba8d5082993c98cce7246b860a6 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 6 Apr 2015 18:29:02 +0200 Subject: [PATCH 1/5] Account for actual eye position in oculus pick ray --- interface/src/ui/ApplicationOverlay.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 633eafc202..af00c1c558 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -428,15 +428,18 @@ void ApplicationOverlay::displayOverlayTexture3DTV(Camera& whichCamera, float as } void ApplicationOverlay::computeOculusPickRay(float x, float y, glm::vec3& origin, glm::vec3& direction) const { + const MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); const float pitch = (0.5f - y) * MOUSE_PITCH_RANGE; const float yaw = (0.5f - x) * MOUSE_YAW_RANGE; const glm::quat orientation(glm::vec3(pitch, yaw, 0.0f)); const glm::vec3 localDirection = orientation * IDENTITY_FRONT; - //Rotate the UI pick ray by the avatar orientation - const MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); - origin = myAvatar->getDefaultEyePosition(); - direction = myAvatar->getOrientation() * localDirection; + // Get cursor position + const glm::vec3 cursorPos = myAvatar->getDefaultEyePosition() + myAvatar->getOrientation() * localDirection; + + // Ray start where the eye position is and stop where the cursor is + origin = myAvatar->getEyePosition(); + direction = cursorPos - origin; } //Caculate the click location using one of the sixense controllers. Scale is not applied From 73f9276c7459aa85b04787ef1f6c2e44f4b0480d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 7 Apr 2015 17:10:31 +0200 Subject: [PATCH 2/5] Fix warning --- interface/src/ui/ApplicationOverlay.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index af00c1c558..93a8a55164 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -28,8 +28,6 @@ #include "Util.h" #include "ui/Stats.h" -// Used to fade the UI -const float FADE_SPEED = 0.08f; // Used to animate the magnification windows const float MAG_SPEED = 0.08f; From ae6ee5456976ab7a7baafaafb98ae8a6fc44a671 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 7 Apr 2015 17:11:02 +0200 Subject: [PATCH 3/5] Fix ray collision not using inverse rot --- interface/src/ui/ApplicationOverlay.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 93a8a55164..7fc3ba170d 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -501,10 +501,10 @@ QPoint ApplicationOverlay::getPalmClickLocation(const PalmData *palm) const { bool ApplicationOverlay::calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction, glm::vec3& result) const { MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); - glm::quat orientation = myAvatar->getOrientation(); + glm::quat inverseOrientation = glm::inverse(myAvatar->getOrientation()); - glm::vec3 relativePosition = orientation * (position - myAvatar->getDefaultEyePosition()); - glm::vec3 relativeDirection = orientation * direction; + glm::vec3 relativePosition = inverseOrientation * (position - myAvatar->getDefaultEyePosition()); + glm::vec3 relativeDirection = glm::normalize(inverseOrientation * direction); float t; if (raySphereIntersect(relativeDirection, relativePosition, _oculusUIRadius * myAvatar->getScale(), &t)){ @@ -515,8 +515,6 @@ bool ApplicationOverlay::calculateRayUICollisionPoint(const glm::vec3& position, return false; } - - //Renders optional pointers void ApplicationOverlay::renderPointers() { auto glCanvas = Application::getInstance()->getGLWidget(); From 1cc438440445274fada0645c996fe23c6b81e4c2 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 7 Apr 2015 17:13:30 +0200 Subject: [PATCH 4/5] Add new frame of reference for cursor --- interface/src/ui/ApplicationOverlay.cpp | 21 +++++++++++++++++++++ interface/src/ui/ApplicationOverlay.h | 3 +++ 2 files changed, 24 insertions(+) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 7fc3ba170d..e11b46ad95 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -1125,6 +1126,26 @@ void ApplicationOverlay::TexturedHemisphere::render() { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } +glm::vec2 ApplicationOverlay::directionToSpherical(glm::vec3 direction) const { + glm::vec2 result; + // Compute yaw + glm::vec3 normalProjection = glm::normalize(glm::vec3(direction.x, 0.0f, direction.z)); + result.x = glm::acos(glm::dot(IDENTITY_FRONT, normalProjection)); + if (glm::dot(IDENTITY_RIGHT, normalProjection) > 0.0f) { + result.x = -glm::abs(result.x); + } else { + result.x = glm::abs(result.x); + } + // Compute pitch + result.y = angleBetween(IDENTITY_UP, direction) - PI_OVER_TWO; + + return result; +} + +glm::vec3 ApplicationOverlay::sphericalToDirection(glm::vec2 sphericalPos) const { + glm::quat rotation(glm::vec3(sphericalPos.y, sphericalPos.x, 0.0f)); + return rotation * IDENTITY_FRONT; +} glm::vec2 ApplicationOverlay::screenToSpherical(glm::vec2 screenPos) const { QSize screenSize = Application::getInstance()->getGLWidget()->getDeviceSize(); diff --git a/interface/src/ui/ApplicationOverlay.h b/interface/src/ui/ApplicationOverlay.h index 58b79adcda..cc424d0c8f 100644 --- a/interface/src/ui/ApplicationOverlay.h +++ b/interface/src/ui/ApplicationOverlay.h @@ -45,11 +45,14 @@ public: // Converter from one frame of reference to another. // Frame of reference: + // Direction: Ray that represents the spherical values // Screen: Position on the screen (x,y) // Spherical: Pitch and yaw that gives the position on the sphere we project on (yaw,pitch) // Overlay: Position on the overlay (x,y) // (x,y) in Overlay are similar than (x,y) in Screen except they can be outside of the bound of te screen. // This allows for picking outside of the screen projection in 3D. + glm::vec2 directionToSpherical(glm::vec3 direction) const; + glm::vec3 sphericalToDirection(glm::vec2 sphericalPos) const; glm::vec2 screenToSpherical(glm::vec2 screenPos) const; glm::vec2 sphericalToScreen(glm::vec2 sphericalPos) const; glm::vec2 sphericalToOverlay(glm::vec2 sphericalPos) const; From 5e3ed1c8e4be3389ef9d0c8da10c743eee8630ca Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 7 Apr 2015 17:15:16 +0200 Subject: [PATCH 5/5] Compute correct mouse position --- interface/src/ui/ApplicationOverlay.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index e11b46ad95..f08df229cc 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -540,12 +540,23 @@ void ApplicationOverlay::renderPointers() { if (_reticlePosition[MOUSE] != position) { _lastMouseMove = usecTimestampNow(); } else if (usecTimestampNow() - _lastMouseMove > MAX_IDLE_TIME * USECS_PER_SECOND) { - float pitch, yaw, roll; + float pitch = 0.0f, yaw = 0.0f, roll = 0.0f; // radians OculusManager::getEulerAngles(yaw, pitch, roll); - glm::vec2 screenPos = sphericalToScreen(glm::vec2(yaw, -pitch)); + glm::quat orientation(glm::vec3(pitch, yaw, roll)); + glm::vec3 result; - position = QPoint(screenPos.x, screenPos.y); - glCanvas->cursor().setPos(glCanvas->mapToGlobal(position)); + MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); + if (calculateRayUICollisionPoint(myAvatar->getEyePosition(), + myAvatar->getOrientation() * orientation * IDENTITY_FRONT, + result)) { + glm::vec3 lookAtDirection = glm::inverse(myAvatar->getOrientation()) * (result - myAvatar->getDefaultEyePosition()); + glm::vec2 spericalPos = directionToSpherical(glm::normalize(lookAtDirection)); + glm::vec2 screenPos = sphericalToScreen(spericalPos); + position = QPoint(screenPos.x, screenPos.y); + glCanvas->cursor().setPos(glCanvas->mapToGlobal(position)); + } else { + qDebug() << "No collision point"; + } } _reticlePosition[MOUSE] = position;