From 1d37df47754f24ce87ce735a5900b157d9fa3e22 Mon Sep 17 00:00:00 2001 From: Zander Otavka Date: Mon, 20 Jul 2015 17:49:06 -0700 Subject: [PATCH] Improve and optimize panel transformations. --- .../src/ui/overlays/BillboardOverlay.cpp | 94 +++++++------------ interface/src/ui/overlays/BillboardOverlay.h | 7 +- interface/src/ui/overlays/PanelAttachable.cpp | 33 ++----- interface/src/ui/overlays/PanelAttachable.h | 18 ++-- 4 files changed, 57 insertions(+), 95 deletions(-) diff --git a/interface/src/ui/overlays/BillboardOverlay.cpp b/interface/src/ui/overlays/BillboardOverlay.cpp index c5e73a73e2..d8da58485c 100644 --- a/interface/src/ui/overlays/BillboardOverlay.cpp +++ b/interface/src/ui/overlays/BillboardOverlay.cpp @@ -39,13 +39,21 @@ BillboardOverlay::BillboardOverlay(const BillboardOverlay* billboardOverlay) : { } -void BillboardOverlay::update(float deltatime) { - if (getVisible()) { - glm::vec3 newPos = getTranslatedPosition(Application::getInstance()->getAvatarPosition()); - if (newPos != glm::vec3()) { - setPosition(newPos); +bool BillboardOverlay::setTransforms(Transform *transform) { + PanelAttachable::setTransforms(transform); + if (_isFacingAvatar) { + glm::quat rotation = Application::getInstance()->getCamera()->getOrientation(); + rotation *= glm::angleAxis(glm::pi(), IDENTITY_UP); + setRotation(rotation); + return true; } - } + return false; +// } +// return true; +} + +void BillboardOverlay::update(float deltatime) { + setTransforms(&_transform); } void BillboardOverlay::render(RenderArgs* args) { @@ -58,12 +66,8 @@ void BillboardOverlay::render(RenderArgs* args) { return; } - glm::vec3 newPos = getTranslatedPosition(Application::getInstance()->getAvatarPosition()); - if (newPos != glm::vec3()) { - setPosition(newPos); - } - - glm::quat rotation = calculateRotation(args->_viewFrustum->getOrientation()); + Q_ASSERT(args->_batch); + auto batch = args->_batch; float imageWidth = _texture->getWidth(); float imageHeight = _texture->getHeight(); @@ -98,24 +102,20 @@ void BillboardOverlay::render(RenderArgs* args) { xColor color = getColor(); float alpha = getAlpha(); - auto batch = args->_batch; + setTransforms(&_transform); + Transform transform = _transform; + transform.postScale(glm::vec3(getDimensions(), 1.0f)); - if (batch) { - Transform transform = _transform; - transform.setRotation(rotation); - transform.postScale(glm::vec3(getDimensions(), 1.0f)); - - batch->setModelTransform(transform); - batch->setResourceTexture(0, _texture->getGPUTexture()); - - DependencyManager::get()->bindSimpleProgram(*batch, true, true, true); - DependencyManager::get()->renderQuad( - *batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, - glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha) - ); + batch->setModelTransform(transform); + batch->setResourceTexture(0, _texture->getGPUTexture()); - batch->setResourceTexture(0, args->_whiteTexture); // restore default white color after me - } + DependencyManager::get()->bindSimpleProgram(*batch, true, true, false); + 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 } void BillboardOverlay::setProperties(const QScriptValue &properties) { @@ -207,40 +207,12 @@ 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) { + float& distance, BoxFace& face) { if (_texture && _texture->isLoaded()) { - glm::quat rotation = - calculateRotation(Application::getInstance()->getCamera()->getRotation()); + // Make sure position and rotation is updated. + setTransforms(&_transform); + // 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(); @@ -248,7 +220,7 @@ bool BillboardOverlay::findRayIntersection(const glm::vec3& origin, const glm::v float maxSize = glm::max(width, height); glm::vec2 dimensions = _dimensions * glm::vec2(width / maxSize, height / maxSize); - return findRayRectangleIntersection(origin, direction, rotation, getPosition(), dimensions, distance); + return findRayRectangleIntersection(origin, direction, getRotation(), getPosition(), dimensions, distance); } return false; diff --git a/interface/src/ui/overlays/BillboardOverlay.h b/interface/src/ui/overlays/BillboardOverlay.h index 73e9db4c1b..3f8e18a0ef 100644 --- a/interface/src/ui/overlays/BillboardOverlay.h +++ b/interface/src/ui/overlays/BillboardOverlay.h @@ -39,10 +39,13 @@ public: virtual BillboardOverlay* createClone() const; +protected: + bool setTransforms(Transform* transform); + private: void setBillboardURL(const QString& url); - glm::quat calculateRotation(glm::quat cameraOrientation) const; - +// 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 1beea6b74e..7e2ce19099 100644 --- a/interface/src/ui/overlays/PanelAttachable.cpp +++ b/interface/src/ui/overlays/PanelAttachable.cpp @@ -20,31 +20,14 @@ PanelAttachable::PanelAttachable(const PanelAttachable* panelAttachable) : { } -glm::vec3 PanelAttachable::getTranslatedPosition(glm::vec3 avatarPosition) const { +bool PanelAttachable::setTransforms(Transform* transform) { + Q_ASSERT(transform != nullptr); if (getAttachedPanel()) { - glm::vec3 totalOffsetPosition = - getAttachedPanel()->getFacingRotation() * getOffsetPosition() + - getAttachedPanel()->getOffsetPosition(); - - return getAttachedPanel()->getOffsetRotation() * totalOffsetPosition + - avatarPosition; + transform->setTranslation(getAttachedPanel()->getAnchorPosition()); + transform->setRotation(getAttachedPanel()->getOffsetRotation()); + transform->postTranslate(getOffsetPosition() + getAttachedPanel()->getOffsetPosition()); + transform->postRotate(getFacingRotation() * getAttachedPanel()->getFacingRotation()); + return true; } - 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; + return false; } diff --git a/interface/src/ui/overlays/PanelAttachable.h b/interface/src/ui/overlays/PanelAttachable.h index ab8b8a4276..d44504f5d4 100644 --- a/interface/src/ui/overlays/PanelAttachable.h +++ b/interface/src/ui/overlays/PanelAttachable.h @@ -15,24 +15,28 @@ #include "FloatingUIPanel.h" #include +#include class PanelAttachable { public: PanelAttachable(); PanelAttachable(const PanelAttachable* panelAttachable); - glm::vec3 getOffsetPosition() const { return _offsetPosition; } - void setOffsetPosition(glm::vec3 position) { _offsetPosition = position; } - FloatingUIPanel* getAttachedPanel() const { return _attachedPanel; } - void setAttachedPanel(FloatingUIPanel* panel) { _attachedPanel = panel; } + glm::vec3 getOffsetPosition() const { return _offsetPosition; } + glm::quat getFacingRotation() const { return _facingRotation; } - glm::vec3 getTranslatedPosition(glm::vec3 avatarPosition) const; - glm::quat getTranslatedRotation(glm::quat offsetRotation) const; + void setAttachedPanel(FloatingUIPanel* panel) { _attachedPanel = panel; } + void setOffsetPosition(glm::vec3 position) { _offsetPosition = position; } + void setFacingRotation(glm::quat rotation) { _facingRotation = rotation; } + +protected: + bool setTransforms(Transform* transform); private: FloatingUIPanel* _attachedPanel; - glm::vec3 _offsetPosition = glm::vec3(0, 0, 0); + glm::vec3 _offsetPosition; + glm::quat _facingRotation; }; #endif // hifi_PanelAttachable_h