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() {
}
// 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);

View file

@ -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);

View file

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

View file

@ -21,6 +21,8 @@
#include <RegisteredMetaTypes.h>
#include <SharedUtil.h> // for xColor
#include <RenderArgs.h>
#include <AABox.h>
#include <render/Scene.h>
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<Overlay> Pointer;
typedef render::Payload<Overlay> Payload;
typedef std::shared_ptr<render::Item::PayloadInterface> 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;

View file

@ -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);

View file

@ -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); }

View file

@ -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<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) {
}
@ -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<LODManager>();
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<LODManager>();
foreach(Overlay* thisOverlay, _overlaysWorld) {
Base3DOverlay* overlay3D = static_cast<Base3DOverlay*>(thisOverlay);
foreach(Overlay::Pointer thisOverlay, _overlaysWorld) {
Base3DOverlay* overlay3D = static_cast<Base3DOverlay*>(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<Base3DOverlay*>(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<Base3DOverlay*>(thisOverlay);
Base3DOverlay* overlay3D = static_cast<Base3DOverlay*>(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<unsigned int, Overlay*> i(_overlaysHUD);
QMapIterator<unsigned int, Overlay::Pointer> 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<Base3DOverlay*>(i.value());
Base3DOverlay* thisOverlay = static_cast<Base3DOverlay*>(i.value().get());
if (!thisOverlay->getIgnoreRayIntersection()) {
if (thisOverlay->findRayIntersection(origin, direction, distance, thisFace)) {
return thisID;
}
}
} else {
Overlay2D* thisOverlay = static_cast<Overlay2D*>(i.value());
Overlay2D* thisOverlay = static_cast<Overlay2D*>(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<float>::max();
bool bestIsFront = false;
RayToOverlayIntersectionResult result;
QMapIterator<unsigned int, Overlay*> i(_overlaysWorld);
QMapIterator<unsigned int, Overlay::Pointer> i(_overlaysWorld);
i.toBack();
while (i.hasPrevious()) {
i.previous();
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()) {
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<TextOverlay*>(thisOverlay)->textSize(text);
return static_cast<TextOverlay*>(thisOverlay.get())->textSize(text);
}
} else {
thisOverlay = _overlaysWorld[id];
if (thisOverlay) {
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;
private:
QMap<unsigned int, Overlay*> _overlaysHUD;
QMap<unsigned int, Overlay*> _overlaysWorld;
QList<Overlay*> _overlaysToDelete;
QMap<unsigned int, Overlay::Pointer> _overlaysHUD;
QMap<unsigned int, Overlay::Pointer> _overlaysWorld;
QList<Overlay::Pointer> _overlaysToDelete;
unsigned int _nextOverlayID;
QReadWriteLock _lock;
QReadWriteLock _deleteLock;