mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 17:14:59 +02:00
Merge pull request #5000 from huffman/scene-overlay
Team Teaching - Move overlay rendering to Scene pipeline
This commit is contained in:
commit
f8a90684ce
10 changed files with 159 additions and 128 deletions
|
@ -3035,17 +3035,6 @@ void Application::updateShadowMap(RenderArgs* renderArgs) {
|
|||
_entities.render(renderArgs);
|
||||
}
|
||||
|
||||
// render JS/scriptable overlays
|
||||
{
|
||||
PerformanceTimer perfTimer("3dOverlays");
|
||||
_overlays.renderWorld(renderArgs, false);
|
||||
}
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("3dOverlaysFront");
|
||||
_overlays.renderWorld(renderArgs, true);
|
||||
}
|
||||
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
glPopMatrix();
|
||||
|
@ -3364,12 +3353,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
DependencyManager::get<DeferredLightingEffect>()->prepare();
|
||||
|
||||
if (!selfAvatarOnly) {
|
||||
|
||||
// render JS/scriptable overlays
|
||||
{
|
||||
PerformanceTimer perfTimer("3dOverlays");
|
||||
_overlays.renderWorld(renderArgs, false);
|
||||
}
|
||||
|
||||
// render models...
|
||||
if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
|
||||
|
@ -3487,13 +3470,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
|
||||
// Render 3D overlays that should be drawn in front
|
||||
{
|
||||
PerformanceTimer perfTimer("3dOverlaysFront");
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
Glower glower(renderArgs); // Sets alpha to 1.0
|
||||
_overlays.renderWorld(renderArgs, true);
|
||||
}
|
||||
activeRenderingThread = nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -637,9 +637,6 @@ private:
|
|||
|
||||
TouchEvent _lastTouchEvent;
|
||||
|
||||
Overlays _overlays;
|
||||
ApplicationOverlay _applicationOverlay;
|
||||
|
||||
RunningScriptsWidget* _runningScriptsWidget;
|
||||
QHash<QString, ScriptEngine*> _scriptEnginesHash;
|
||||
bool _runningScriptsWidgetWasVisible;
|
||||
|
@ -679,6 +676,9 @@ private:
|
|||
|
||||
render::ScenePointer _main3DScene{ new render::Scene() };
|
||||
render::EnginePointer _renderEngine{ new render::Engine() };
|
||||
|
||||
Overlays _overlays;
|
||||
ApplicationOverlay _applicationOverlay;
|
||||
};
|
||||
|
||||
#endif // hifi_Application_h
|
||||
|
|
|
@ -76,7 +76,6 @@ public:
|
|||
|
||||
typedef render::Payload<AvatarData> Payload;
|
||||
typedef std::shared_ptr<render::Item::PayloadInterface> PayloadPointer;
|
||||
typedef Payload::DataPointer Pointer;
|
||||
|
||||
void init();
|
||||
void simulate(float deltaTime);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <NumericalConstants.h>
|
||||
|
||||
Overlay::Overlay() :
|
||||
_renderItemID(render::Item::INVALID_ITEM_ID),
|
||||
_isLoaded(true),
|
||||
_alpha(DEFAULT_ALPHA),
|
||||
_glowLevel(0.0f),
|
||||
|
@ -35,6 +36,7 @@ Overlay::Overlay() :
|
|||
}
|
||||
|
||||
Overlay::Overlay(const Overlay* overlay) :
|
||||
_renderItemID(render::Item::INVALID_ITEM_ID),
|
||||
_isLoaded(overlay->_isLoaded),
|
||||
_alpha(overlay->_alpha),
|
||||
_glowLevel(overlay->_glowLevel),
|
||||
|
@ -225,3 +227,4 @@ float Overlay::updatePulse() {
|
|||
|
||||
return _pulse;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,7 +57,6 @@ public:
|
|||
float getGlowLevel();
|
||||
Anchor getAnchor() const { return _anchor; }
|
||||
|
||||
|
||||
float getPulseMax() const { return _pulseMax; }
|
||||
float getPulseMin() const { return _pulseMin; }
|
||||
float getPulsePeriod() const { return _pulsePeriod; }
|
||||
|
@ -81,9 +87,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;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <Application.h>
|
||||
#include <avatar/AvatarManager.h>
|
||||
#include <LODManager.h>
|
||||
#include <render/Scene.h>
|
||||
|
||||
#include "BillboardOverlay.h"
|
||||
#include "Circle3DOverlay.h"
|
||||
|
@ -31,6 +32,50 @@
|
|||
#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) {
|
||||
if (overlay->is3D()) {
|
||||
return static_cast<Base3DOverlay*>(overlay.get())->getBounds();
|
||||
} else {
|
||||
QRect bounds = static_cast<Overlay2D*>(overlay.get())->getBounds();
|
||||
return AABox(glm::vec3(bounds.x(), bounds.y(), 0.0f), glm::vec3(bounds.width(), bounds.height(), 0.1f));
|
||||
}
|
||||
}
|
||||
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,23 +83,18 @@ Overlays::~Overlays() {
|
|||
|
||||
{
|
||||
QWriteLocker lock(&_lock);
|
||||
foreach(Overlay* thisOverlay, _overlaysHUD) {
|
||||
delete thisOverlay;
|
||||
QWriteLocker deleteLock(&_deleteLock);
|
||||
foreach(Overlay::Pointer overlay, _overlaysHUD) {
|
||||
_overlaysToDelete.push_back(overlay);
|
||||
}
|
||||
foreach(Overlay::Pointer overlay, _overlaysWorld) {
|
||||
_overlaysToDelete.push_back(overlay);
|
||||
}
|
||||
_overlaysHUD.clear();
|
||||
foreach(Overlay* thisOverlay, _overlaysWorld) {
|
||||
delete thisOverlay;
|
||||
}
|
||||
_overlaysWorld.clear();
|
||||
}
|
||||
|
||||
if (!_overlaysToDelete.isEmpty()) {
|
||||
QWriteLocker lock(&_deleteLock);
|
||||
do {
|
||||
delete _overlaysToDelete.takeLast();
|
||||
} while (!_overlaysToDelete.isEmpty());
|
||||
}
|
||||
|
||||
cleanupOverlaysToDelete();
|
||||
}
|
||||
|
||||
void Overlays::init() {
|
||||
|
@ -65,21 +105,39 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
cleanupOverlaysToDelete();
|
||||
}
|
||||
|
||||
void Overlays::cleanupOverlaysToDelete() {
|
||||
if (!_overlaysToDelete.isEmpty()) {
|
||||
QWriteLocker lock(&_deleteLock);
|
||||
do {
|
||||
delete _overlaysToDelete.takeLast();
|
||||
} while (!_overlaysToDelete.isEmpty());
|
||||
render::PendingChanges pendingChanges;
|
||||
|
||||
{
|
||||
QWriteLocker lock(&_deleteLock);
|
||||
|
||||
do {
|
||||
Overlay::Pointer overlay = _overlaysToDelete.takeLast();
|
||||
|
||||
auto itemID = overlay->getRenderItemID();
|
||||
if (itemID != render::Item::INVALID_ITEM_ID) {
|
||||
pendingChanges.removeItem(itemID);
|
||||
}
|
||||
} while (!_overlaysToDelete.isEmpty());
|
||||
}
|
||||
|
||||
if (pendingChanges._removedItems.size() > 0) {
|
||||
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
|
||||
scene->enqueuePendingChanges(pendingChanges);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Overlays::renderHUD(RenderArgs* renderArgs) {
|
||||
|
@ -87,7 +145,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);
|
||||
|
@ -96,57 +154,12 @@ void Overlays::renderHUD(RenderArgs* renderArgs) {
|
|||
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
} else{
|
||||
} else {
|
||||
thisOverlay->render(renderArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Overlays::renderWorld(RenderArgs* renderArgs, bool drawFront) {
|
||||
QReadLocker lock(&_lock);
|
||||
if (_overlaysWorld.size() == 0) {
|
||||
return;
|
||||
}
|
||||
bool myAvatarComputed = false;
|
||||
MyAvatar* avatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
glm::quat myAvatarRotation;
|
||||
glm::vec3 myAvatarPosition(0.0f);
|
||||
float angle = 0.0f;
|
||||
glm::vec3 axis(0.0f, 1.0f, 0.0f);
|
||||
float myAvatarScale = 1.0f;
|
||||
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
|
||||
foreach(Overlay* thisOverlay, _overlaysWorld) {
|
||||
Base3DOverlay* overlay3D = static_cast<Base3DOverlay*>(thisOverlay);
|
||||
if (overlay3D->getDrawInFront() != drawFront) {
|
||||
continue;
|
||||
}
|
||||
glPushMatrix();
|
||||
switch (thisOverlay->getAnchor()) {
|
||||
case Overlay::MY_AVATAR:
|
||||
if (!myAvatarComputed) {
|
||||
myAvatarRotation = avatar->getOrientation();
|
||||
myAvatarPosition = avatar->getPosition();
|
||||
angle = glm::degrees(glm::angle(myAvatarRotation));
|
||||
axis = glm::axis(myAvatarRotation);
|
||||
myAvatarScale = avatar->getScale();
|
||||
|
||||
myAvatarComputed = true;
|
||||
}
|
||||
|
||||
glTranslatef(myAvatarPosition.x, myAvatarPosition.y, myAvatarPosition.z);
|
||||
glRotatef(angle, axis.x, axis.y, axis.z);
|
||||
glScalef(myAvatarScale, myAvatarScale, myAvatarScale);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
thisOverlay->render(renderArgs);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& properties) {
|
||||
unsigned int thisID = 0;
|
||||
Overlay* thisOverlay = NULL;
|
||||
|
@ -189,6 +202,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 +211,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::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 +250,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 +260,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 +285,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 +309,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 +322,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 +342,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 +389,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 +496,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 +508,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,6 @@ public:
|
|||
~Overlays();
|
||||
void init();
|
||||
void update(float deltatime);
|
||||
void renderWorld(RenderArgs* renderArgs, bool drawFront);
|
||||
void renderHUD(RenderArgs* renderArgs);
|
||||
|
||||
public slots:
|
||||
|
@ -90,9 +89,10 @@ 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;
|
||||
void cleanupOverlaysToDelete();
|
||||
QMap<unsigned int, Overlay::Pointer> _overlaysHUD;
|
||||
QMap<unsigned int, Overlay::Pointer> _overlaysWorld;
|
||||
QList<Overlay::Pointer> _overlaysToDelete;
|
||||
unsigned int _nextOverlayID;
|
||||
QReadWriteLock _lock;
|
||||
QReadWriteLock _deleteLock;
|
||||
|
|
|
@ -32,15 +32,16 @@ class Context;
|
|||
class ItemKey {
|
||||
public:
|
||||
enum FlagBit {
|
||||
TYPE_SHAPE = 0, // Item is a Shape
|
||||
TYPE_LIGHT, // Item is a Light
|
||||
TRANSLUCENT, // Transparent and not opaque, for some odd reason TRANSPARENCY doesn't work...
|
||||
VIEW_SPACE, // Transformed in view space, and not in world space
|
||||
DYNAMIC, // Dynamic and bound will change unlike static item
|
||||
DEFORMED, // Deformed within bound, not solid
|
||||
INVISIBLE, // Visible or not? could be just here to cast shadow
|
||||
SHADOW_CASTER, // Item cast shadows
|
||||
PICKABLE, // Item can be picked/selected
|
||||
TYPE_SHAPE = 0, // Item is a Shape
|
||||
TYPE_LIGHT, // Item is a Light
|
||||
TRANSLUCENT, // Transparent and not opaque, for some odd reason TRANSPARENCY doesn't work...
|
||||
VIEW_SPACE, // Transformed in view space, and not in world space
|
||||
DYNAMIC, // Dynamic and bound will change unlike static item
|
||||
DEFORMED, // Deformed within bound, not solid
|
||||
INVISIBLE, // Visible or not? could be just here to cast shadow
|
||||
SHADOW_CASTER, // Item cast shadows
|
||||
PICKABLE, // Item can be picked/selected
|
||||
NO_DEPTH_SORT, // Item should not be depth sorted
|
||||
|
||||
NUM_FLAGS, // Not a valid flag
|
||||
};
|
||||
|
@ -68,6 +69,7 @@ public:
|
|||
Builder& withInvisible() { _flags.set(INVISIBLE); return (*this); }
|
||||
Builder& withShadowCaster() { _flags.set(SHADOW_CASTER); return (*this); }
|
||||
Builder& withPickable() { _flags.set(PICKABLE); return (*this); }
|
||||
Builder& withNoDepthSort() { _flags.set(NO_DEPTH_SORT); return (*this); }
|
||||
|
||||
// Convenient standard keys that we will keep on using all over the place
|
||||
static ItemKey opaqueShape() { return Builder().withTypeShape().build(); }
|
||||
|
@ -80,7 +82,7 @@ public:
|
|||
|
||||
bool isWorldSpace() const { return !_flags[VIEW_SPACE]; }
|
||||
bool isViewSpace() const { return _flags[VIEW_SPACE]; }
|
||||
|
||||
|
||||
bool isStatic() const { return !_flags[DYNAMIC]; }
|
||||
bool isDynamic() const { return _flags[DYNAMIC]; }
|
||||
|
||||
|
@ -88,11 +90,14 @@ public:
|
|||
bool isDeformed() const { return _flags[DEFORMED]; }
|
||||
|
||||
bool isVisible() const { return !_flags[INVISIBLE]; }
|
||||
bool isUnvisible() const { return _flags[INVISIBLE]; }
|
||||
bool isInvisible() const { return _flags[INVISIBLE]; }
|
||||
|
||||
bool isShadowCaster() const { return _flags[SHADOW_CASTER]; }
|
||||
|
||||
bool isPickable() const { return _flags[PICKABLE]; }
|
||||
|
||||
bool isDepthSort() const { return !_flags[NO_DEPTH_SORT]; }
|
||||
bool isNoDepthSort() const { return _flags[NO_DEPTH_SORT]; }
|
||||
};
|
||||
|
||||
inline QDebug operator<<(QDebug debug, const ItemKey& itemKey) {
|
||||
|
@ -142,6 +147,9 @@ public:
|
|||
|
||||
Builder& withPickable() { _value.set(ItemKey::PICKABLE); _mask.set(ItemKey::PICKABLE); return (*this); }
|
||||
|
||||
Builder& withDepthSort() { _value.reset(ItemKey::NO_DEPTH_SORT); _mask.set(ItemKey::NO_DEPTH_SORT); return (*this); }
|
||||
Builder& withNotDepthSort() { _value.set(ItemKey::NO_DEPTH_SORT); _mask.set(ItemKey::NO_DEPTH_SORT); return (*this); }
|
||||
|
||||
// Convenient standard keys that we will keep on using all over the place
|
||||
static ItemFilter opaqueShape() { return Builder().withTypeShape().withOpaque().withWorldSpace().build(); }
|
||||
static ItemFilter transparentShape() { return Builder().withTypeShape().withTransparent().withWorldSpace().build(); }
|
||||
|
@ -174,6 +182,8 @@ public:
|
|||
typedef std::vector<Item> Vector;
|
||||
typedef unsigned int ID;
|
||||
|
||||
static const ID INVALID_ITEM_ID = 0;
|
||||
|
||||
// Bound is the AABBox fully containing this item
|
||||
typedef AABox Bound;
|
||||
|
||||
|
|
Loading…
Reference in a new issue