From c4cb6fba744b2eea540918fb755f91ddc0c162bf Mon Sep 17 00:00:00 2001 From: Zander Otavka Date: Fri, 17 Jul 2015 14:29:53 -0700 Subject: [PATCH] Improve BillboardOverlay::findRayIntersection. --- .../src/ui/overlays/BillboardOverlay.cpp | 94 ++++++++----------- interface/src/ui/overlays/BillboardOverlay.h | 1 + interface/src/ui/overlays/PanelAttachable.cpp | 17 ++++ interface/src/ui/overlays/PanelAttachable.h | 1 + 4 files changed, 60 insertions(+), 53 deletions(-) diff --git a/interface/src/ui/overlays/BillboardOverlay.cpp b/interface/src/ui/overlays/BillboardOverlay.cpp index 18d0307743..be8fab6362 100644 --- a/interface/src/ui/overlays/BillboardOverlay.cpp +++ b/interface/src/ui/overlays/BillboardOverlay.cpp @@ -38,9 +38,11 @@ BillboardOverlay::BillboardOverlay(const BillboardOverlay* billboardOverlay) : } void BillboardOverlay::update(float deltatime) { - glm::vec3 newPos = getTranslatedPosition(Application::getInstance()->getAvatarPosition()); - if (newPos != glm::vec3()) { - setPosition(newPos); + if (getVisible()) { + glm::vec3 newPos = getTranslatedPosition(Application::getInstance()->getAvatarPosition()); + if (newPos != glm::vec3()) { + setPosition(newPos); + } } } @@ -59,46 +61,7 @@ void BillboardOverlay::render(RenderArgs* args) { setPosition(newPos); } - glm::quat rotation; - if (_isFacingAvatar) { - // LOL, quaternions are hard. -// glm::vec3 dPos = getPosition() - args->_viewFrustum->getPosition(); -// dPos = glm::normalize(dPos); -// rotation = glm::quat(0, dPos.x, dPos.y, dPos.z); -// float horizontal = glm::sqrt(dPos.x * dPos.x + dPos.y + dPos.y); -// glm::vec3 zAxis = glm::vec3(0, 0, 1); -// rotation = rotationBetween(zAxis, dPos); -// glm::vec3 euler = safeEulerAngles(rotationBetween(zAxis, dPos)); -// rotation = glm::quat(glm::vec3(euler.x, euler.y, 0)); -// float yaw = (dPos.x == 0.0f && dPos.z == 0.0f) ? 0.0f : glm::atan(dPos.x, dPos.z); -// glm::quat yawQuat = glm::quat(glm::vec3(0, yaw, 0)); -// float pitch = (dPos.y == 0.0f && horizontal == 0.0f) ? 0.0f : glm::atan(dPos.y, horizontal); -// glm::quat pitchQuat = glm::quat(glm::vec3(pitch, 0, 0)); -// glm::mat4x4 matrix = glm::lookAt(args->_viewFrustum->getPosition(), getPosition(), -// glm::vec3(0, 1, 0)); -// rotation = glm::quat_cast(matrix); -// rotation = yawQuat * pitchQuat; -// glm::vec3 pitch = glm::vec3(dPos.x, dPos.y, 0); -// rotation = glm::quat(glm::vec3(pitch, yaw, 0)); - // rotate about vertical to be perpendicular to the camera - rotation = args->_viewFrustum->getOrientation(); - rotation *= glm::angleAxis(glm::pi(), IDENTITY_UP); - rotation *= getRotation(); - } else { - rotation = getRotation(); - if (getAttachedPanel()) { - rotation *= getAttachedPanel()->getOffsetRotation() * - getAttachedPanel()->getFacingRotation(); -// if (getAttachedPanel()->getFacingRotation() != glm::quat(0, 0, 0, 0)) { -// rotation *= getAttachedPanel()->getFacingRotation(); -// } else if (getAttachedPanel()->getOffsetRotation() != glm::quat(0, 0, 0, 0)) { -// rotation *= getAttachedPanel()->getOffsetRotation(); -// } else { -// rotation *= Application::getInstance()->getCamera()->getOrientation() * -// glm::quat(0, 0, 1, 0); -// } - } - } + glm::quat rotation = calculateRotation(args->_viewFrustum->getOrientation()); float imageWidth = _texture->getWidth(); float imageHeight = _texture->getHeight(); @@ -143,8 +106,10 @@ void BillboardOverlay::render(RenderArgs* args) { batch->setModelTransform(transform); batch->setResourceTexture(0, _texture->getGPUTexture()); - DependencyManager::get()->renderQuad(*batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, - glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha)); + DependencyManager::get()->renderQuad( + *batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, + glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha) + ); batch->setResourceTexture(0, args->_whiteTexture); // restore default white color after me } @@ -239,17 +204,40 @@ void BillboardOverlay::setBillboardURL(const QString& url) { _isLoaded = false; } +glm::quat BillboardOverlay::calculateRotation(glm::quat cameraOrientation) const { + if (_isFacingAvatar) { + // LOL, quaternions are hard. + // glm::vec3 dPos = getPosition() - args->_viewFrustum->getPosition(); + // dPos = glm::normalize(dPos); + // rotation = glm::quat(0, dPos.x, dPos.y, dPos.z); + // float horizontal = glm::sqrt(dPos.x * dPos.x + dPos.y + dPos.y); + // glm::vec3 zAxis = glm::vec3(0, 0, 1); + // rotation = rotationBetween(zAxis, dPos); + // glm::vec3 euler = safeEulerAngles(rotationBetween(zAxis, dPos)); + // rotation = glm::quat(glm::vec3(euler.x, euler.y, 0)); + // float yaw = (dPos.x == 0.0f && dPos.z == 0.0f) ? 0.0f : glm::atan(dPos.x, dPos.z); + // glm::quat yawQuat = glm::quat(glm::vec3(0, yaw, 0)); + // float pitch = (dPos.y == 0.0f && horizontal == 0.0f) ? 0.0f : glm::atan(dPos.y, horizontal); + // glm::quat pitchQuat = glm::quat(glm::vec3(pitch, 0, 0)); + // glm::mat4x4 matrix = glm::lookAt(args->_viewFrustum->getPosition(), getPosition(), + // glm::vec3(0, 1, 0)); + // rotation = glm::quat_cast(matrix); + // rotation = yawQuat * pitchQuat; + // glm::vec3 pitch = glm::vec3(dPos.x, dPos.y, 0); + // rotation = glm::quat(glm::vec3(pitch, yaw, 0)); + // rotate about vertical to be perpendicular to the camera + glm::quat rotation = cameraOrientation; + rotation *= glm::angleAxis(glm::pi(), IDENTITY_UP); + return rotation * getRotation(); + } + return getTranslatedRotation(getRotation()); +} + bool BillboardOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) { - if (_texture && _texture->isLoaded()) { - glm::quat rotation = getRotation(); - if (_isFacingAvatar) { - // rotate about vertical to face the camera - rotation = Application::getInstance()->getCamera()->getRotation(); - rotation *= glm::angleAxis(glm::pi(), glm::vec3(0.0f, 1.0f, 0.0f)); - } - + glm::quat rotation = + calculateRotation(Application::getInstance()->getCamera()->getRotation()); // Produce the dimensions of the billboard based on the image's aspect ratio and the overlay's scale. bool isNull = _fromImage.isNull(); float width = isNull ? _texture->getWidth() : _fromImage.width(); diff --git a/interface/src/ui/overlays/BillboardOverlay.h b/interface/src/ui/overlays/BillboardOverlay.h index f7bbfd1817..73e9db4c1b 100644 --- a/interface/src/ui/overlays/BillboardOverlay.h +++ b/interface/src/ui/overlays/BillboardOverlay.h @@ -41,6 +41,7 @@ public: private: void setBillboardURL(const QString& url); + glm::quat calculateRotation(glm::quat cameraOrientation) const; QString _url; NetworkTexturePointer _texture; diff --git a/interface/src/ui/overlays/PanelAttachable.cpp b/interface/src/ui/overlays/PanelAttachable.cpp index 172880db97..1beea6b74e 100644 --- a/interface/src/ui/overlays/PanelAttachable.cpp +++ b/interface/src/ui/overlays/PanelAttachable.cpp @@ -31,3 +31,20 @@ glm::vec3 PanelAttachable::getTranslatedPosition(glm::vec3 avatarPosition) const } return glm::vec3(); } + +glm::quat PanelAttachable::getTranslatedRotation(glm::quat offsetRotation) const { + glm::quat rotation = offsetRotation; + if (getAttachedPanel()) { + rotation *= getAttachedPanel()->getOffsetRotation() * + getAttachedPanel()->getFacingRotation(); + // if (getAttachedPanel()->getFacingRotation() != glm::quat(0, 0, 0, 0)) { + // rotation *= getAttachedPanel()->getFacingRotation(); + // } else if (getAttachedPanel()->getOffsetRotation() != glm::quat(0, 0, 0, 0)) { + // rotation *= getAttachedPanel()->getOffsetRotation(); + // } else { + // rotation *= Application::getInstance()->getCamera()->getOrientation() * + // glm::quat(0, 0, 1, 0); + // } + } + return rotation; +} diff --git a/interface/src/ui/overlays/PanelAttachable.h b/interface/src/ui/overlays/PanelAttachable.h index 29b0673157..ab8b8a4276 100644 --- a/interface/src/ui/overlays/PanelAttachable.h +++ b/interface/src/ui/overlays/PanelAttachable.h @@ -28,6 +28,7 @@ public: void setAttachedPanel(FloatingUIPanel* panel) { _attachedPanel = panel; } glm::vec3 getTranslatedPosition(glm::vec3 avatarPosition) const; + glm::quat getTranslatedRotation(glm::quat offsetRotation) const; private: FloatingUIPanel* _attachedPanel;