Move overlay rendering to Scene

This commit is contained in:
Ryan Huffman 2015-05-29 08:51:25 -07:00
parent 1c3398f27e
commit 1089490658
8 changed files with 111 additions and 34 deletions

View file

@ -49,6 +49,11 @@ Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) :
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) { void Base3DOverlay::setProperties(const QScriptValue& properties) {
Overlay::setProperties(properties); Overlay::setProperties(properties);

View file

@ -49,6 +49,8 @@ public:
void setDrawInFront(bool value) { _drawInFront = value; } void setDrawInFront(bool value) { _drawInFront = value; }
void setDrawOnHUD(bool value) { _drawOnHUD = value; } void setDrawOnHUD(bool value) { _drawOnHUD = value; }
virtual AABox getBounds() const;
virtual void setProperties(const QScriptValue& properties); virtual void setProperties(const QScriptValue& properties);
virtual QScriptValue getProperty(const QString& property); virtual QScriptValue getProperty(const QString& property);

View file

@ -225,3 +225,8 @@ float Overlay::updatePulse() {
return _pulse; return _pulse;
} }
AABox Overlay::getBounds() const {
return AABox();
}

View file

@ -21,6 +21,8 @@
#include <RegisteredMetaTypes.h> #include <RegisteredMetaTypes.h>
#include <SharedUtil.h> // for xColor #include <SharedUtil.h> // for xColor
#include <RenderArgs.h> #include <RenderArgs.h>
#include <AABox.h>
#include <render/Scene.h>
const xColor DEFAULT_OVERLAY_COLOR = { 255, 255, 255 }; const xColor DEFAULT_OVERLAY_COLOR = { 255, 255, 255 };
const float DEFAULT_ALPHA = 0.7f; const float DEFAULT_ALPHA = 0.7f;
@ -34,6 +36,11 @@ public:
MY_AVATAR MY_AVATAR
}; };
typedef std::shared_ptr<Overlay> Pointer;
typedef render::Payload<Overlay> Payload;
typedef std::shared_ptr<render::Item::PayloadInterface> PayloadPointer;
Overlay(); Overlay();
Overlay(const Overlay* overlay); Overlay(const Overlay* overlay);
~Overlay(); ~Overlay();
@ -50,6 +57,8 @@ public:
float getGlowLevel(); float getGlowLevel();
Anchor getAnchor() const { return _anchor; } Anchor getAnchor() const { return _anchor; }
virtual AABox getBounds() const = 0;
float getPulseMax() const { return _pulseMax; } float getPulseMax() const { return _pulseMax; }
float getPulseMin() const { return _pulseMin; } float getPulseMin() const { return _pulseMin; }
@ -81,9 +90,14 @@ public:
virtual Overlay* createClone() const = 0; virtual Overlay* createClone() const = 0;
virtual QScriptValue getProperty(const QString& property); virtual QScriptValue getProperty(const QString& property);
render::ItemID getRenderItemID() const { return _renderItemID; }
void setRenderItemID(render::ItemID renderItemID) { _renderItemID = renderItemID; }
protected: protected:
float updatePulse(); float updatePulse();
render::ItemID _renderItemID;
bool _isLoaded; bool _isLoaded;
float _alpha; float _alpha;
float _glowLevel; float _glowLevel;

View file

@ -28,6 +28,10 @@ Overlay2D::Overlay2D(const Overlay2D* overlay2D) :
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) { void Overlay2D::setProperties(const QScriptValue& properties) {
Overlay::setProperties(properties); Overlay::setProperties(properties);

View file

@ -38,6 +38,7 @@ public:
int getWidth() const { return _bounds.width(); } int getWidth() const { return _bounds.width(); }
int getHeight() const { return _bounds.height(); } int getHeight() const { return _bounds.height(); }
const QRect& getBounds() const { return _bounds; } const QRect& getBounds() const { return _bounds; }
virtual AABox getBounds() const;
// setters // setters
void setX(int x) { _bounds.setX(x); } void setX(int x) { _bounds.setX(x); }

View file

@ -31,6 +31,45 @@
#include "TextOverlay.h" #include "TextOverlay.h"
#include "Text3DOverlay.h" #include "Text3DOverlay.h"
namespace render {
template <> const ItemKey payloadGetKey(const Overlay::Pointer& overlay) {
if (overlay->is3D() && !static_cast<Base3DOverlay*>(overlay.get())->getDrawOnHUD()) {
if (static_cast<Base3DOverlay*>(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*>(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<AvatarManager>()->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) { Overlays::Overlays() : _nextOverlayID(1) {
} }
@ -38,20 +77,14 @@ Overlays::~Overlays() {
{ {
QWriteLocker lock(&_lock); QWriteLocker lock(&_lock);
foreach(Overlay* thisOverlay, _overlaysHUD) {
delete thisOverlay;
}
_overlaysHUD.clear(); _overlaysHUD.clear();
foreach(Overlay* thisOverlay, _overlaysWorld) {
delete thisOverlay;
}
_overlaysWorld.clear(); _overlaysWorld.clear();
} }
if (!_overlaysToDelete.isEmpty()) { if (!_overlaysToDelete.isEmpty()) {
QWriteLocker lock(&_deleteLock); QWriteLocker lock(&_deleteLock);
do { do {
delete _overlaysToDelete.takeLast(); _overlaysToDelete.takeLast().reset();
} while (!_overlaysToDelete.isEmpty()); } while (!_overlaysToDelete.isEmpty());
} }
@ -65,10 +98,10 @@ void Overlays::update(float deltatime) {
{ {
QWriteLocker lock(&_lock); QWriteLocker lock(&_lock);
foreach(Overlay* thisOverlay, _overlaysHUD) { foreach(Overlay::Pointer thisOverlay, _overlaysHUD) {
thisOverlay->update(deltatime); thisOverlay->update(deltatime);
} }
foreach(Overlay* thisOverlay, _overlaysWorld) { foreach(Overlay::Pointer thisOverlay, _overlaysWorld) {
thisOverlay->update(deltatime); thisOverlay->update(deltatime);
} }
} }
@ -76,7 +109,7 @@ void Overlays::update(float deltatime) {
if (!_overlaysToDelete.isEmpty()) { if (!_overlaysToDelete.isEmpty()) {
QWriteLocker lock(&_deleteLock); QWriteLocker lock(&_deleteLock);
do { do {
delete _overlaysToDelete.takeLast(); _overlaysToDelete.takeLast().reset();
} while (!_overlaysToDelete.isEmpty()); } while (!_overlaysToDelete.isEmpty());
} }
@ -87,7 +120,7 @@ void Overlays::renderHUD(RenderArgs* renderArgs) {
auto lodManager = DependencyManager::get<LODManager>(); auto lodManager = DependencyManager::get<LODManager>();
foreach(Overlay* thisOverlay, _overlaysHUD) { foreach(Overlay::Pointer thisOverlay, _overlaysHUD) {
if (thisOverlay->is3D()) { if (thisOverlay->is3D()) {
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING); glEnable(GL_LIGHTING);
@ -103,6 +136,7 @@ void Overlays::renderHUD(RenderArgs* renderArgs) {
} }
void Overlays::renderWorld(RenderArgs* renderArgs, bool drawFront) { void Overlays::renderWorld(RenderArgs* renderArgs, bool drawFront) {
return;
QReadLocker lock(&_lock); QReadLocker lock(&_lock);
if (_overlaysWorld.size() == 0) { if (_overlaysWorld.size() == 0) {
return; return;
@ -117,8 +151,8 @@ void Overlays::renderWorld(RenderArgs* renderArgs, bool drawFront) {
auto lodManager = DependencyManager::get<LODManager>(); auto lodManager = DependencyManager::get<LODManager>();
foreach(Overlay* thisOverlay, _overlaysWorld) { foreach(Overlay::Pointer thisOverlay, _overlaysWorld) {
Base3DOverlay* overlay3D = static_cast<Base3DOverlay*>(thisOverlay); Base3DOverlay* overlay3D = static_cast<Base3DOverlay*>(thisOverlay.get());
if (overlay3D->getDrawInFront() != drawFront) { if (overlay3D->getDrawInFront() != drawFront) {
continue; continue;
} }
@ -189,6 +223,7 @@ unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& prope
} }
unsigned int Overlays::addOverlay(Overlay* overlay) { unsigned int Overlays::addOverlay(Overlay* overlay) {
Overlay::Pointer overlayPointer(overlay);
overlay->init(_scriptEngine); overlay->init(_scriptEngine);
QWriteLocker lock(&_lock); QWriteLocker lock(&_lock);
@ -197,19 +232,30 @@ unsigned int Overlays::addOverlay(Overlay* overlay) {
if (overlay->is3D()) { if (overlay->is3D()) {
Base3DOverlay* overlay3D = static_cast<Base3DOverlay*>(overlay); Base3DOverlay* overlay3D = static_cast<Base3DOverlay*>(overlay);
if (overlay3D->getDrawOnHUD()) { if (overlay3D->getDrawOnHUD()) {
_overlaysHUD[thisID] = overlay; _overlaysHUD[thisID] = overlayPointer;
} else { } 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 { } else {
_overlaysHUD[thisID] = overlay; _overlaysHUD[thisID] = overlayPointer;
} }
return thisID; return thisID;
} }
unsigned int Overlays::cloneOverlay(unsigned int id) { unsigned int Overlays::cloneOverlay(unsigned int id) {
Overlay* thisOverlay = NULL; Overlay::Pointer thisOverlay = NULL;
if (_overlaysHUD.contains(id)) { if (_overlaysHUD.contains(id)) {
thisOverlay = _overlaysHUD[id]; thisOverlay = _overlaysHUD[id];
} else if (_overlaysWorld.contains(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) { bool Overlays::editOverlay(unsigned int id, const QScriptValue& properties) {
QWriteLocker lock(&_lock); QWriteLocker lock(&_lock);
Overlay* thisOverlay = NULL; Overlay::Pointer thisOverlay;
if (_overlaysHUD.contains(id)) { if (_overlaysHUD.contains(id)) {
thisOverlay = _overlaysHUD[id]; thisOverlay = _overlaysHUD[id];
@ -235,7 +281,7 @@ bool Overlays::editOverlay(unsigned int id, const QScriptValue& properties) {
if (thisOverlay) { if (thisOverlay) {
if (thisOverlay->is3D()) { if (thisOverlay->is3D()) {
Base3DOverlay* overlay3D = static_cast<Base3DOverlay*>(thisOverlay); Base3DOverlay* overlay3D = static_cast<Base3DOverlay*>(thisOverlay.get());
bool oldDrawOnHUD = overlay3D->getDrawOnHUD(); bool oldDrawOnHUD = overlay3D->getDrawOnHUD();
thisOverlay->setProperties(properties); thisOverlay->setProperties(properties);
@ -260,7 +306,7 @@ bool Overlays::editOverlay(unsigned int id, const QScriptValue& properties) {
} }
void Overlays::deleteOverlay(unsigned int id) { void Overlays::deleteOverlay(unsigned int id) {
Overlay* overlayToDelete; Overlay::Pointer overlayToDelete;
{ {
QWriteLocker lock(&_lock); QWriteLocker lock(&_lock);
@ -284,7 +330,7 @@ unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) {
} }
QReadLocker lock(&_lock); QReadLocker lock(&_lock);
QMapIterator<unsigned int, Overlay*> i(_overlaysHUD); QMapIterator<unsigned int, Overlay::Pointer> i(_overlaysHUD);
i.toBack(); i.toBack();
const float LARGE_NEGATIVE_FLOAT = -9999999; const float LARGE_NEGATIVE_FLOAT = -9999999;
@ -297,14 +343,14 @@ unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) {
i.previous(); i.previous();
unsigned int thisID = i.key(); unsigned int thisID = i.key();
if (i.value()->is3D()) { if (i.value()->is3D()) {
Base3DOverlay* thisOverlay = static_cast<Base3DOverlay*>(i.value()); Base3DOverlay* thisOverlay = static_cast<Base3DOverlay*>(i.value().get());
if (!thisOverlay->getIgnoreRayIntersection()) { if (!thisOverlay->getIgnoreRayIntersection()) {
if (thisOverlay->findRayIntersection(origin, direction, distance, thisFace)) { if (thisOverlay->findRayIntersection(origin, direction, distance, thisFace)) {
return thisID; return thisID;
} }
} }
} else { } else {
Overlay2D* thisOverlay = static_cast<Overlay2D*>(i.value()); Overlay2D* thisOverlay = static_cast<Overlay2D*>(i.value().get());
if (thisOverlay->getVisible() && thisOverlay->isLoaded() && if (thisOverlay->getVisible() && thisOverlay->isLoaded() &&
thisOverlay->getBounds().contains(pointCopy.x, pointCopy.y, false)) { thisOverlay->getBounds().contains(pointCopy.x, pointCopy.y, false)) {
return thisID; return thisID;
@ -317,7 +363,7 @@ unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) {
OverlayPropertyResult Overlays::getProperty(unsigned int id, const QString& property) { OverlayPropertyResult Overlays::getProperty(unsigned int id, const QString& property) {
OverlayPropertyResult result; OverlayPropertyResult result;
Overlay* thisOverlay = NULL; Overlay::Pointer thisOverlay;
QReadLocker lock(&_lock); QReadLocker lock(&_lock);
if (_overlaysHUD.contains(id)) { if (_overlaysHUD.contains(id)) {
thisOverlay = _overlaysHUD[id]; thisOverlay = _overlaysHUD[id];
@ -364,12 +410,12 @@ RayToOverlayIntersectionResult Overlays::findRayIntersection(const PickRay& ray)
float bestDistance = std::numeric_limits<float>::max(); float bestDistance = std::numeric_limits<float>::max();
bool bestIsFront = false; bool bestIsFront = false;
RayToOverlayIntersectionResult result; RayToOverlayIntersectionResult result;
QMapIterator<unsigned int, Overlay*> i(_overlaysWorld); QMapIterator<unsigned int, Overlay::Pointer> i(_overlaysWorld);
i.toBack(); i.toBack();
while (i.hasPrevious()) { while (i.hasPrevious()) {
i.previous(); i.previous();
unsigned int thisID = i.key(); unsigned int thisID = i.key();
Base3DOverlay* thisOverlay = static_cast<Base3DOverlay*>(i.value()); Base3DOverlay* thisOverlay = static_cast<Base3DOverlay*>(i.value().get());
if (thisOverlay->getVisible() && !thisOverlay->getIgnoreRayIntersection() && thisOverlay->isLoaded()) { if (thisOverlay->getVisible() && !thisOverlay->getIgnoreRayIntersection() && thisOverlay->isLoaded()) {
float thisDistance; float thisDistance;
BoxFace thisFace; BoxFace thisFace;
@ -471,7 +517,7 @@ void RayToOverlayIntersectionResultFromScriptValue(const QScriptValue& object, R
bool Overlays::isLoaded(unsigned int id) { bool Overlays::isLoaded(unsigned int id) {
QReadLocker lock(&_lock); QReadLocker lock(&_lock);
Overlay* thisOverlay = NULL; Overlay::Pointer thisOverlay = NULL;
if (_overlaysHUD.contains(id)) { if (_overlaysHUD.contains(id)) {
thisOverlay = _overlaysHUD[id]; thisOverlay = _overlaysHUD[id];
} else if (_overlaysWorld.contains(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 { QSizeF Overlays::textSize(unsigned int id, const QString& text) const {
Overlay* thisOverlay = _overlaysHUD[id]; Overlay::Pointer thisOverlay = _overlaysHUD[id];
if (thisOverlay) { if (thisOverlay) {
if (typeid(*thisOverlay) == typeid(TextOverlay)) { if (typeid(*thisOverlay) == typeid(TextOverlay)) {
return static_cast<TextOverlay*>(thisOverlay)->textSize(text); return static_cast<TextOverlay*>(thisOverlay.get())->textSize(text);
} }
} else { } else {
thisOverlay = _overlaysWorld[id]; thisOverlay = _overlaysWorld[id];
if (thisOverlay) { if (thisOverlay) {
if (typeid(*thisOverlay) == typeid(Text3DOverlay)) { if (typeid(*thisOverlay) == typeid(Text3DOverlay)) {
return static_cast<Text3DOverlay*>(thisOverlay)->textSize(text); return static_cast<Text3DOverlay*>(thisOverlay.get())->textSize(text);
} }
} }
} }

View file

@ -90,9 +90,9 @@ public slots:
QSizeF textSize(unsigned int id, const QString& text) const; QSizeF textSize(unsigned int id, const QString& text) const;
private: private:
QMap<unsigned int, Overlay*> _overlaysHUD; QMap<unsigned int, Overlay::Pointer> _overlaysHUD;
QMap<unsigned int, Overlay*> _overlaysWorld; QMap<unsigned int, Overlay::Pointer> _overlaysWorld;
QList<Overlay*> _overlaysToDelete; QList<Overlay::Pointer> _overlaysToDelete;
unsigned int _nextOverlayID; unsigned int _nextOverlayID;
QReadWriteLock _lock; QReadWriteLock _lock;
QReadWriteLock _deleteLock; QReadWriteLock _deleteLock;