Update 3D overlays to only use one list

This commit is contained in:
Ryan Huffman 2014-11-25 09:49:10 -08:00
parent 4febc45b6a
commit 649ae4a448
5 changed files with 37 additions and 104 deletions

View file

@ -2836,12 +2836,12 @@ void Application::updateShadowMap() {
// render JS/scriptable overlays // render JS/scriptable overlays
{ {
PerformanceTimer perfTimer("3dOverlays"); PerformanceTimer perfTimer("3dOverlays");
_overlays.render3D(RenderArgs::SHADOW_RENDER_MODE); _overlays.render3D(false, RenderArgs::SHADOW_RENDER_MODE);
} }
{ {
PerformanceTimer perfTimer("3dOverlaysFront"); PerformanceTimer perfTimer("3dOverlaysFront");
_overlays.render3DFront(RenderArgs::SHADOW_RENDER_MODE); _overlays.render3D(true, RenderArgs::SHADOW_RENDER_MODE);
} }
glDisable(GL_POLYGON_OFFSET_FILL); glDisable(GL_POLYGON_OFFSET_FILL);
@ -3056,7 +3056,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly, RenderAr
// render JS/scriptable overlays // render JS/scriptable overlays
{ {
PerformanceTimer perfTimer("3dOverlays"); PerformanceTimer perfTimer("3dOverlays");
_overlays.render3D(); _overlays.render3D(false);
} }
// render the ambient occlusion effect if enabled // render the ambient occlusion effect if enabled
@ -3145,7 +3145,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly, RenderAr
{ {
PerformanceTimer perfTimer("3dOverlaysFront"); PerformanceTimer perfTimer("3dOverlaysFront");
glClear(GL_DEPTH_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT);
_overlays.render3DFront(); _overlays.render3D(true);
} }
} }

View file

@ -46,13 +46,6 @@ Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) :
Base3DOverlay::~Base3DOverlay() { Base3DOverlay::~Base3DOverlay() {
} }
void Base3DOverlay::setDrawInFront(bool value) {
if (value != _drawInFront) {
_drawInFront = value;
emit drawInFrontUpdated(value);
}
}
void Base3DOverlay::setProperties(const QScriptValue& properties) { void Base3DOverlay::setProperties(const QScriptValue& properties) {
Overlay::setProperties(properties); Overlay::setProperties(properties);

View file

@ -45,7 +45,7 @@ public:
void setIsDashedLine(bool isDashedLine) { _isDashedLine = isDashedLine; } void setIsDashedLine(bool isDashedLine) { _isDashedLine = isDashedLine; }
void setRotation(const glm::quat& value) { _rotation = value; } void setRotation(const glm::quat& value) { _rotation = value; }
void setIgnoreRayIntersection(bool value) { _ignoreRayIntersection = value; } void setIgnoreRayIntersection(bool value) { _ignoreRayIntersection = value; }
void setDrawInFront(bool value); void setDrawInFront(bool value) { _drawInFront = value; }
virtual void setProperties(const QScriptValue& properties); virtual void setProperties(const QScriptValue& properties);
virtual QScriptValue getProperty(const QString& property); virtual QScriptValue getProperty(const QString& property);
@ -57,9 +57,6 @@ public:
return findRayIntersection(origin, direction, distance, face); return findRayIntersection(origin, direction, distance, face);
} }
signals:
void drawInFrontUpdated(bool newValue);
protected: protected:
void drawDashedLine(const glm::vec3& start, const glm::vec3& end); void drawDashedLine(const glm::vec3& start, const glm::vec3& end);

View file

@ -29,8 +29,7 @@
#include "TextOverlay.h" #include "TextOverlay.h"
#include "Text3DOverlay.h" #include "Text3DOverlay.h"
Overlays::Overlays() : _nextOverlayID(1), _overlaySignalMapper() { Overlays::Overlays() : _nextOverlayID(1) {
connect(&_overlaySignalMapper, SIGNAL(mapped(int)), this, SLOT(handleOverlayDrawInFrontUpdated(unsigned int)));
} }
Overlays::~Overlays() { Overlays::~Overlays() {
@ -71,9 +70,6 @@ void Overlays::update(float deltatime) {
foreach(Overlay* thisOverlay, _overlays3D) { foreach(Overlay* thisOverlay, _overlays3D) {
thisOverlay->update(deltatime); thisOverlay->update(deltatime);
} }
foreach(Overlay* thisOverlay, _overlays3DFront) {
thisOverlay->update(deltatime);
}
} }
if (!_overlaysToDelete.isEmpty()) { if (!_overlaysToDelete.isEmpty()) {
@ -97,17 +93,9 @@ void Overlays::render2D() {
} }
} }
void Overlays::render3D(RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) { void Overlays::render3D(bool drawFront, RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) {
render3DOverlays(_overlays3D, renderMode, renderSide);
}
void Overlays::render3DFront(RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) {
render3DOverlays(_overlays3DFront, renderMode, renderSide);
}
void Overlays::render3DOverlays(QMap<unsigned int, Overlay*>& overlays, RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) {
QReadLocker lock(&_lock); QReadLocker lock(&_lock);
if (overlays.size() == 0) { if (_overlays3D.size() == 0) {
return; return;
} }
bool myAvatarComputed = false; bool myAvatarComputed = false;
@ -123,7 +111,11 @@ void Overlays::render3DOverlays(QMap<unsigned int, Overlay*>& overlays, RenderAr
renderMode, renderSide, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; renderMode, renderSide, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
foreach(Overlay* thisOverlay, overlays) { foreach(Overlay* thisOverlay, _overlays3D) {
Base3DOverlay* overlay3D = static_cast<Base3DOverlay*>(thisOverlay);
if (overlay3D->getDrawInFront() != drawFront) {
continue;
}
glPushMatrix(); glPushMatrix();
switch (thisOverlay->getAnchor()) { switch (thisOverlay->getAnchor()) {
case Overlay::MY_AVATAR: case Overlay::MY_AVATAR:
@ -200,15 +192,7 @@ unsigned int Overlays::addOverlay(Overlay* overlay) {
unsigned int thisID = _nextOverlayID; unsigned int thisID = _nextOverlayID;
_nextOverlayID++; _nextOverlayID++;
if (overlay->is3D()) { if (overlay->is3D()) {
Base3DOverlay* overlay3D = static_cast<Base3DOverlay*>(overlay); _overlays3D[thisID] = overlay;
if (overlay3D->getDrawInFront()) {
_overlays3DFront[thisID] = overlay;
} else {
_overlays3D[thisID] = overlay;
}
_overlaySignalMapper.setMapping(overlay3D, thisID);
connect(overlay3D, SIGNAL(drawInFrontUpdated(bool)), &_overlaySignalMapper, SLOT(map()));
} else { } else {
_overlays2D[thisID] = overlay; _overlays2D[thisID] = overlay;
} }
@ -233,8 +217,6 @@ bool Overlays::editOverlay(unsigned int id, const QScriptValue& properties) {
thisOverlay = _overlays2D[id]; thisOverlay = _overlays2D[id];
} else if (_overlays3D.contains(id)) { } else if (_overlays3D.contains(id)) {
thisOverlay = _overlays3D[id]; thisOverlay = _overlays3D[id];
} else if (_overlays3DFront.contains(id)) {
thisOverlay = _overlays3DFront[id];
} }
if (thisOverlay) { if (thisOverlay) {
thisOverlay->setProperties(properties); thisOverlay->setProperties(properties);
@ -252,8 +234,6 @@ void Overlays::deleteOverlay(unsigned int id) {
overlayToDelete = _overlays2D.take(id); overlayToDelete = _overlays2D.take(id);
} else if (_overlays3D.contains(id)) { } else if (_overlays3D.contains(id)) {
overlayToDelete = _overlays3D.take(id); overlayToDelete = _overlays3D.take(id);
} else if (_overlays3DFront.contains(id)) {
overlayToDelete = _overlays3DFront.take(id);
} else { } else {
return; return;
} }
@ -263,22 +243,6 @@ void Overlays::deleteOverlay(unsigned int id) {
_overlaysToDelete.push_back(overlayToDelete); _overlaysToDelete.push_back(overlayToDelete);
} }
void Overlays::handleOverlayDrawInFrontUpdated(int overlayID) {
if (_overlays3D.contains(overlayID)) {
Base3DOverlay* overlay = static_cast<Base3DOverlay*>(_overlays3D[overlayID]);
if (overlay->getDrawInFront()) {
_overlays3D.remove(overlayID);
_overlays3DFront[overlayID] = overlay;
}
} else if (_overlays3DFront.contains(overlayID)) {
Base3DOverlay* overlay = static_cast<Base3DOverlay*>(_overlays3DFront[overlayID]);
if (!overlay->getDrawInFront()) {
_overlays3DFront.remove(overlayID);
_overlays3D[overlayID] = overlay;
}
}
}
unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) { unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) {
QReadLocker lock(&_lock); QReadLocker lock(&_lock);
QMapIterator<unsigned int, Overlay*> i(_overlays2D); QMapIterator<unsigned int, Overlay*> i(_overlays2D);
@ -302,8 +266,6 @@ OverlayPropertyResult Overlays::getProperty(unsigned int id, const QString& prop
thisOverlay = _overlays2D[id]; thisOverlay = _overlays2D[id];
} else if (_overlays3D.contains(id)) { } else if (_overlays3D.contains(id)) {
thisOverlay = _overlays3D[id]; thisOverlay = _overlays3D[id];
} else if (_overlays3DFront.contains(id)) {
thisOverlay = _overlays3DFront[id];
} }
if (thisOverlay) { if (thisOverlay) {
result.value = thisOverlay->getProperty(property); result.value = thisOverlay->getProperty(property);
@ -342,39 +304,33 @@ void OverlayPropertyResultFromScriptValue(const QScriptValue& value, OverlayProp
} }
RayToOverlayIntersectionResult Overlays::findRayIntersection(const PickRay& ray) { RayToOverlayIntersectionResult Overlays::findRayIntersection(const PickRay& ray) {
QMap<unsigned int, Overlay*>* overlayMaps[] = { &_overlays3DFront, &_overlays3D };
float bestDistance = std::numeric_limits<float>::max(); float bestDistance = std::numeric_limits<float>::max();
float bestIsFront = false;
RayToOverlayIntersectionResult result; RayToOverlayIntersectionResult result;
for (int idx = 0; idx < 2; idx++) { QMapIterator<unsigned int, Overlay*> i(_overlays3D);
QMapIterator<unsigned int, Overlay*> i(*overlayMaps[idx]); 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()); if (thisOverlay->getVisible() && !thisOverlay->getIgnoreRayIntersection() && thisOverlay->isLoaded()) {
if (thisOverlay->getVisible() && !thisOverlay->getIgnoreRayIntersection() && thisOverlay->isLoaded()) { float thisDistance;
float thisDistance; BoxFace thisFace;
BoxFace thisFace; QString thisExtraInfo;
QString thisExtraInfo; if (thisOverlay->findRayIntersectionExtraInfo(ray.origin, ray.direction, thisDistance, thisFace, thisExtraInfo)) {
if (thisOverlay->findRayIntersectionExtraInfo(ray.origin, ray.direction, thisDistance, thisFace, thisExtraInfo)) { bool isDrawInFront = thisOverlay->getDrawInFront();
if (thisDistance < bestDistance) { if (thisDistance < bestDistance && (!bestIsFront || isDrawInFront)) {
bestDistance = thisDistance; bestIsFront = isDrawInFront;
result.intersects = true; bestDistance = thisDistance;
result.distance = thisDistance; result.intersects = true;
result.face = thisFace; result.distance = thisDistance;
result.overlayID = thisID; result.face = thisFace;
result.intersection = ray.origin + (ray.direction * thisDistance); result.overlayID = thisID;
result.extraInfo = thisExtraInfo; result.intersection = ray.origin + (ray.direction * thisDistance);
} result.extraInfo = thisExtraInfo;
} }
} }
} }
if (result.intersects) {
// We first check the front overlays - if one has been intersected, prefer
// it over any other overlays and return it immediately.
break;
}
} }
return result; return result;
} }
@ -463,8 +419,6 @@ bool Overlays::isLoaded(unsigned int id) {
thisOverlay = _overlays2D[id]; thisOverlay = _overlays2D[id];
} else if (_overlays3D.contains(id)) { } else if (_overlays3D.contains(id)) {
thisOverlay = _overlays3D[id]; thisOverlay = _overlays3D[id];
} else if (_overlays3DFront.contains(id)) {
thisOverlay = _overlays3DFront[id];
} else { } else {
return false; // not found return false; // not found
} }

View file

@ -52,9 +52,7 @@ public:
~Overlays(); ~Overlays();
void init(QGLWidget* parent); void init(QGLWidget* parent);
void update(float deltatime); void update(float deltatime);
void render3D(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, void render3D(bool drawFront, RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE,
RenderArgs::RenderSide renderSide = RenderArgs::MONO);
void render3DFront(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE,
RenderArgs::RenderSide renderSide = RenderArgs::MONO); RenderArgs::RenderSide renderSide = RenderArgs::MONO);
void render2D(); void render2D();
@ -91,19 +89,10 @@ public slots:
/// overlay; in meters if it is a 3D text overlay /// overlay; in meters if it is a 3D text overlay
float textWidth(unsigned int id, const QString& text) const; float textWidth(unsigned int id, const QString& text) const;
protected:
void render3DOverlays(QMap<unsigned int, Overlay*>& overlays, RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide);
private slots:
/// QSignalMapper unfortunately does not work with unsigned integers.
void handleOverlayDrawInFrontUpdated(int overlayID);
private: private:
QMap<unsigned int, Overlay*> _overlays2D; QMap<unsigned int, Overlay*> _overlays2D;
QMap<unsigned int, Overlay*> _overlays3D; QMap<unsigned int, Overlay*> _overlays3D;
QMap<unsigned int, Overlay*> _overlays3DFront;
QList<Overlay*> _overlaysToDelete; QList<Overlay*> _overlaysToDelete;
QSignalMapper _overlaySignalMapper;
unsigned int _nextOverlayID; unsigned int _nextOverlayID;
QGLWidget* _parent; QGLWidget* _parent;
QReadWriteLock _lock; QReadWriteLock _lock;