diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index f0c49979c8..db252d8a04 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -49,6 +49,11 @@ Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) : Base3DOverlay::~Base3DOverlay() { } +// TODO: Implement accurate getBounds() implementations +AABox Base3DOverlay::getBounds() const { + return AABox(_position, glm::vec3(1.0f)); +} + void Base3DOverlay::setProperties(const QScriptValue& properties) { Overlay::setProperties(properties); diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index bbf850da8e..b24908a0cc 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -49,6 +49,8 @@ public: void setDrawInFront(bool value) { _drawInFront = value; } void setDrawOnHUD(bool value) { _drawOnHUD = value; } + virtual AABox getBounds() const; + virtual void setProperties(const QScriptValue& properties); virtual QScriptValue getProperty(const QString& property); diff --git a/interface/src/ui/overlays/Overlay.cpp b/interface/src/ui/overlays/Overlay.cpp index 024a94e950..258ac0f48e 100644 --- a/interface/src/ui/overlays/Overlay.cpp +++ b/interface/src/ui/overlays/Overlay.cpp @@ -225,3 +225,8 @@ float Overlay::updatePulse() { return _pulse; } + +AABox Overlay::getBounds() const { + return AABox(); +} + diff --git a/interface/src/ui/overlays/Overlay.h b/interface/src/ui/overlays/Overlay.h index 9077605fc4..c1117080e0 100644 --- a/interface/src/ui/overlays/Overlay.h +++ b/interface/src/ui/overlays/Overlay.h @@ -21,6 +21,8 @@ #include #include // for xColor #include +#include +#include const xColor DEFAULT_OVERLAY_COLOR = { 255, 255, 255 }; const float DEFAULT_ALPHA = 0.7f; @@ -33,7 +35,12 @@ public: NO_ANCHOR, MY_AVATAR }; - + + typedef std::shared_ptr Pointer; + + typedef render::Payload Payload; + typedef std::shared_ptr PayloadPointer; + Overlay(); Overlay(const Overlay* overlay); ~Overlay(); @@ -50,6 +57,8 @@ public: float getGlowLevel(); Anchor getAnchor() const { return _anchor; } + virtual AABox getBounds() const = 0; + float getPulseMax() const { return _pulseMax; } float getPulseMin() const { return _pulseMin; } @@ -81,9 +90,14 @@ public: virtual Overlay* createClone() const = 0; virtual QScriptValue getProperty(const QString& property); + render::ItemID getRenderItemID() const { return _renderItemID; } + void setRenderItemID(render::ItemID renderItemID) { _renderItemID = renderItemID; } + protected: float updatePulse(); + render::ItemID _renderItemID; + bool _isLoaded; float _alpha; float _glowLevel; diff --git a/interface/src/ui/overlays/Overlay2D.cpp b/interface/src/ui/overlays/Overlay2D.cpp index f60d44a472..a0674c2da5 100644 --- a/interface/src/ui/overlays/Overlay2D.cpp +++ b/interface/src/ui/overlays/Overlay2D.cpp @@ -28,6 +28,10 @@ Overlay2D::Overlay2D(const Overlay2D* overlay2D) : Overlay2D::~Overlay2D() { } +AABox Overlay2D::getBounds() const { + return AABox(glm::vec3(_bounds.x, _bounds.y, 0.0f), glm::vec3(_bounds.width, _bounds.height, 0.1f)); +} + void Overlay2D::setProperties(const QScriptValue& properties) { Overlay::setProperties(properties); diff --git a/interface/src/ui/overlays/Overlay2D.h b/interface/src/ui/overlays/Overlay2D.h index 20641206c2..fc453e7a91 100644 --- a/interface/src/ui/overlays/Overlay2D.h +++ b/interface/src/ui/overlays/Overlay2D.h @@ -38,6 +38,7 @@ public: int getWidth() const { return _bounds.width(); } int getHeight() const { return _bounds.height(); } const QRect& getBounds() const { return _bounds; } + virtual AABox getBounds() const; // setters void setX(int x) { _bounds.setX(x); } diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 98e081ab66..bde7e1c0a8 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -31,6 +31,45 @@ #include "TextOverlay.h" #include "Text3DOverlay.h" + +namespace render { + template <> const ItemKey payloadGetKey(const Overlay::Pointer& overlay) { + if (overlay->is3D() && !static_cast(overlay.get())->getDrawOnHUD()) { + if (static_cast(overlay.get())->getDrawInFront()) { + return ItemKey::Builder().withTypeShape().withNoDepthSort().build(); + } else { + return ItemKey::Builder::opaqueShape(); + } + } else { + return ItemKey::Builder().withTypeShape().withViewSpace().build(); + } + } + template <> const Item::Bound payloadGetBound(const Overlay::Pointer& overlay) { + return static_cast(overlay.get())->getBounds(); + } + template <> void payloadRender(const Overlay::Pointer& overlay, RenderArgs* args) { + if (args) { + args->_elementsTouched++; + + glPushMatrix(); + if (overlay->getAnchor() == Overlay::MY_AVATAR) { + MyAvatar* avatar = DependencyManager::get()->getMyAvatar(); + glm::quat myAvatarRotation = avatar->getOrientation(); + glm::vec3 myAvatarPosition = avatar->getPosition(); + float angle = glm::degrees(glm::angle(myAvatarRotation)); + glm::vec3 axis = glm::axis(myAvatarRotation); + float myAvatarScale = avatar->getScale(); + + glTranslatef(myAvatarPosition.x, myAvatarPosition.y, myAvatarPosition.z); + glRotatef(angle, axis.x, axis.y, axis.z); + glScalef(myAvatarScale, myAvatarScale, myAvatarScale); + } + overlay->render(args); + glPopMatrix(); + } + } +} + Overlays::Overlays() : _nextOverlayID(1) { } @@ -38,20 +77,14 @@ Overlays::~Overlays() { { QWriteLocker lock(&_lock); - foreach(Overlay* thisOverlay, _overlaysHUD) { - delete thisOverlay; - } _overlaysHUD.clear(); - foreach(Overlay* thisOverlay, _overlaysWorld) { - delete thisOverlay; - } _overlaysWorld.clear(); } if (!_overlaysToDelete.isEmpty()) { QWriteLocker lock(&_deleteLock); do { - delete _overlaysToDelete.takeLast(); + _overlaysToDelete.takeLast().reset(); } while (!_overlaysToDelete.isEmpty()); } @@ -65,10 +98,10 @@ void Overlays::update(float deltatime) { { QWriteLocker lock(&_lock); - foreach(Overlay* thisOverlay, _overlaysHUD) { + foreach(Overlay::Pointer thisOverlay, _overlaysHUD) { thisOverlay->update(deltatime); } - foreach(Overlay* thisOverlay, _overlaysWorld) { + foreach(Overlay::Pointer thisOverlay, _overlaysWorld) { thisOverlay->update(deltatime); } } @@ -76,7 +109,7 @@ void Overlays::update(float deltatime) { if (!_overlaysToDelete.isEmpty()) { QWriteLocker lock(&_deleteLock); do { - delete _overlaysToDelete.takeLast(); + _overlaysToDelete.takeLast().reset(); } while (!_overlaysToDelete.isEmpty()); } @@ -87,7 +120,7 @@ void Overlays::renderHUD(RenderArgs* renderArgs) { auto lodManager = DependencyManager::get(); - foreach(Overlay* thisOverlay, _overlaysHUD) { + foreach(Overlay::Pointer thisOverlay, _overlaysHUD) { if (thisOverlay->is3D()) { glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); @@ -103,6 +136,7 @@ void Overlays::renderHUD(RenderArgs* renderArgs) { } void Overlays::renderWorld(RenderArgs* renderArgs, bool drawFront) { + return; QReadLocker lock(&_lock); if (_overlaysWorld.size() == 0) { return; @@ -117,8 +151,8 @@ void Overlays::renderWorld(RenderArgs* renderArgs, bool drawFront) { auto lodManager = DependencyManager::get(); - foreach(Overlay* thisOverlay, _overlaysWorld) { - Base3DOverlay* overlay3D = static_cast(thisOverlay); + foreach(Overlay::Pointer thisOverlay, _overlaysWorld) { + Base3DOverlay* overlay3D = static_cast(thisOverlay.get()); if (overlay3D->getDrawInFront() != drawFront) { continue; } @@ -189,6 +223,7 @@ unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& prope } unsigned int Overlays::addOverlay(Overlay* overlay) { + Overlay::Pointer overlayPointer(overlay); overlay->init(_scriptEngine); QWriteLocker lock(&_lock); @@ -197,19 +232,30 @@ unsigned int Overlays::addOverlay(Overlay* overlay) { if (overlay->is3D()) { Base3DOverlay* overlay3D = static_cast(overlay); if (overlay3D->getDrawOnHUD()) { - _overlaysHUD[thisID] = overlay; + _overlaysHUD[thisID] = overlayPointer; } else { - _overlaysWorld[thisID] = overlay; + _overlaysWorld[thisID] = overlayPointer; + + render::ScenePointer scene = Application::getInstance()->getMain3DScene(); + auto overlayPayload = new Overlay::Payload(overlayPointer); + auto overlayPayloadPointer = Overlay::PayloadPointer(overlayPayload); + render::ItemID itemID = scene->allocateID(); + overlay->setRenderItemID(itemID); + + render::Scene::PendingChanges pendingChanges; + pendingChanges.resetItem(itemID, overlayPayloadPointer); + + scene->enqueuePendingChanges(pendingChanges); } } else { - _overlaysHUD[thisID] = overlay; + _overlaysHUD[thisID] = overlayPointer; } return thisID; } unsigned int Overlays::cloneOverlay(unsigned int id) { - Overlay* thisOverlay = NULL; + Overlay::Pointer thisOverlay = NULL; if (_overlaysHUD.contains(id)) { thisOverlay = _overlaysHUD[id]; } else if (_overlaysWorld.contains(id)) { @@ -225,7 +271,7 @@ unsigned int Overlays::cloneOverlay(unsigned int id) { bool Overlays::editOverlay(unsigned int id, const QScriptValue& properties) { QWriteLocker lock(&_lock); - Overlay* thisOverlay = NULL; + Overlay::Pointer thisOverlay; if (_overlaysHUD.contains(id)) { thisOverlay = _overlaysHUD[id]; @@ -235,7 +281,7 @@ bool Overlays::editOverlay(unsigned int id, const QScriptValue& properties) { if (thisOverlay) { if (thisOverlay->is3D()) { - Base3DOverlay* overlay3D = static_cast(thisOverlay); + Base3DOverlay* overlay3D = static_cast(thisOverlay.get()); bool oldDrawOnHUD = overlay3D->getDrawOnHUD(); thisOverlay->setProperties(properties); @@ -260,7 +306,7 @@ bool Overlays::editOverlay(unsigned int id, const QScriptValue& properties) { } void Overlays::deleteOverlay(unsigned int id) { - Overlay* overlayToDelete; + Overlay::Pointer overlayToDelete; { QWriteLocker lock(&_lock); @@ -284,7 +330,7 @@ unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) { } QReadLocker lock(&_lock); - QMapIterator i(_overlaysHUD); + QMapIterator i(_overlaysHUD); i.toBack(); const float LARGE_NEGATIVE_FLOAT = -9999999; @@ -297,14 +343,14 @@ unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) { i.previous(); unsigned int thisID = i.key(); if (i.value()->is3D()) { - Base3DOverlay* thisOverlay = static_cast(i.value()); + Base3DOverlay* thisOverlay = static_cast(i.value().get()); if (!thisOverlay->getIgnoreRayIntersection()) { if (thisOverlay->findRayIntersection(origin, direction, distance, thisFace)) { return thisID; } } } else { - Overlay2D* thisOverlay = static_cast(i.value()); + Overlay2D* thisOverlay = static_cast(i.value().get()); if (thisOverlay->getVisible() && thisOverlay->isLoaded() && thisOverlay->getBounds().contains(pointCopy.x, pointCopy.y, false)) { return thisID; @@ -317,7 +363,7 @@ unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) { OverlayPropertyResult Overlays::getProperty(unsigned int id, const QString& property) { OverlayPropertyResult result; - Overlay* thisOverlay = NULL; + Overlay::Pointer thisOverlay; QReadLocker lock(&_lock); if (_overlaysHUD.contains(id)) { thisOverlay = _overlaysHUD[id]; @@ -364,12 +410,12 @@ RayToOverlayIntersectionResult Overlays::findRayIntersection(const PickRay& ray) float bestDistance = std::numeric_limits::max(); bool bestIsFront = false; RayToOverlayIntersectionResult result; - QMapIterator i(_overlaysWorld); + QMapIterator i(_overlaysWorld); i.toBack(); while (i.hasPrevious()) { i.previous(); unsigned int thisID = i.key(); - Base3DOverlay* thisOverlay = static_cast(i.value()); + Base3DOverlay* thisOverlay = static_cast(i.value().get()); if (thisOverlay->getVisible() && !thisOverlay->getIgnoreRayIntersection() && thisOverlay->isLoaded()) { float thisDistance; BoxFace thisFace; @@ -471,7 +517,7 @@ void RayToOverlayIntersectionResultFromScriptValue(const QScriptValue& object, R bool Overlays::isLoaded(unsigned int id) { QReadLocker lock(&_lock); - Overlay* thisOverlay = NULL; + Overlay::Pointer thisOverlay = NULL; if (_overlaysHUD.contains(id)) { thisOverlay = _overlaysHUD[id]; } else if (_overlaysWorld.contains(id)) { @@ -483,16 +529,16 @@ bool Overlays::isLoaded(unsigned int id) { } QSizeF Overlays::textSize(unsigned int id, const QString& text) const { - Overlay* thisOverlay = _overlaysHUD[id]; + Overlay::Pointer thisOverlay = _overlaysHUD[id]; if (thisOverlay) { if (typeid(*thisOverlay) == typeid(TextOverlay)) { - return static_cast(thisOverlay)->textSize(text); + return static_cast(thisOverlay.get())->textSize(text); } } else { thisOverlay = _overlaysWorld[id]; if (thisOverlay) { if (typeid(*thisOverlay) == typeid(Text3DOverlay)) { - return static_cast(thisOverlay)->textSize(text); + return static_cast(thisOverlay.get())->textSize(text); } } } diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 530efd2012..48329dd097 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -90,9 +90,9 @@ public slots: QSizeF textSize(unsigned int id, const QString& text) const; private: - QMap _overlaysHUD; - QMap _overlaysWorld; - QList _overlaysToDelete; + QMap _overlaysHUD; + QMap _overlaysWorld; + QList _overlaysToDelete; unsigned int _nextOverlayID; QReadWriteLock _lock; QReadWriteLock _deleteLock;