Put initialization and deletion of localVoxelSystems on render thread

This commit is contained in:
Atlante45 2014-03-03 16:46:25 -08:00
parent af691e1f75
commit ef9ff0fa74
10 changed files with 170 additions and 116 deletions

View file

@ -1,7 +1,35 @@
function test() { var tree = LocalVoxels("tree");
var tree = LocalVoxels("tree"); tree.setVoxel(0, 0, 0, 0.5, 255, 0, 0);
tree.setVoxel(0, 0, 0, 1, 128, 128, 128); tree.setVoxel(0.5, 0.5, 0.5, 0.5, 0, 255, 0);
var overlay1 = Overlays.addOverlay("localvoxels", {
position: {x: 1, y: 1, z: 1},
size: 1,
name: "tree"
});
var overlay2 = Overlays.addOverlay("localvoxels", {
position: {x: 1, y: 2, z: 1},
size: 1,
name: "tree"
});
var overlay3 = Overlays.addOverlay("localvoxels", {
position: {x: 1, y: 3, z: 1},
size: 1,
name: "tree"
});
var overlay4 = Overlays.addOverlay("localvoxels", {
position: {x: 1, y: 4, z: 1},
size: 1,
name: "tree"
});
// When our script shuts down, we should clean up all of our overlays
function scriptEnding() {
Overlays.deleteOverlay(overlay1);
Overlays.deleteOverlay(overlay2);
Overlays.deleteOverlay(overlay3);
Overlays.deleteOverlay(overlay4);
} }
Script.scriptEnding.connect(scriptEnding);
test();

View file

@ -1920,6 +1920,8 @@ void Application::update(float deltaTime) {
_particles.update(); // update the particles... _particles.update(); // update the particles...
_particleCollisionSystem.update(); // collide the particles... _particleCollisionSystem.update(); // collide the particles...
_overlays.update(deltaTime);
// let external parties know we're updating // let external parties know we're updating
emit simulating(deltaTime); emit simulating(deltaTime);
} }

View file

@ -53,8 +53,8 @@ public:
int parseData(const QByteArray& packet); int parseData(const QByteArray& packet);
bool isInitialized() { return _initialized; }
virtual void init(); virtual void init();
void simulate(float deltaTime) { }
void render(); void render();
void changeTree(VoxelTree* newTree); void changeTree(VoxelTree* newTree);

View file

@ -6,106 +6,80 @@
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. // Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
// //
// //
// include this before QGLWidget, which includes an earlier version of OpenGL
#include "InterfaceConfig.h"
#include <QGLWidget>
#include <QScriptValue>
#include <LocalVoxelsList.h>
#include <VoxelSystem.h> #include <VoxelSystem.h>
#include <Application.h>
#include "LocalVoxelsOverlay.h" #include "LocalVoxelsOverlay.h"
struct OverlayElement { QMap<QString, WeakVoxelSystemPointer> LocalVoxelsOverlay::_voxelSystemMap;
QString treeName;
StrongVoxelTreePointer tree; // so that the tree doesn't get freed
glm::vec3 position;
float scale;
bool wantDisplay;
StrongVoxelSystemPointer voxelSystem;
};
LocalVoxelsOverlay::LocalVoxelsOverlay() :
LocalVoxelsOverlay::LocalVoxelsOverlay() { Volume3DOverlay(),
_voxelCount(0)
{
_wantDeleteOnRenderThread = true;
} }
LocalVoxelsOverlay::~LocalVoxelsOverlay() { LocalVoxelsOverlay::~LocalVoxelsOverlay() {
_voxelSystem->changeTree(new VoxelTree());
_voxelSystem.clear();
if (_voxelSystemMap.value(_treeName).isNull()) {
_voxelSystemMap.remove(_treeName);
}
_tree.clear();
LocalVoxelsList::getInstance()->remove(_treeName);
}
void LocalVoxelsOverlay::update(float deltatime) {
if (!_voxelSystem->isInitialized()) {
_voxelSystem->init();
}
if (_voxelCount != _tree->getOctreeElementsCount()) {
_voxelCount = _tree->getOctreeElementsCount();
_voxelSystem->forceRedrawEntireTree();
}
} }
void LocalVoxelsOverlay::render() { void LocalVoxelsOverlay::render() {
QMap<QString, OverlayElement>::iterator i; if (_visible && _size > 0 && _voxelSystem && _voxelSystem->isInitialized()) {
for (i = _overlayMap.begin(); i != _overlayMap.end(); ++i) { glPushMatrix(); {
if (i->wantDisplay && i->scale > 0) { glTranslatef(_position.x, _position.y, _position.z);
glPushMatrix(); glScalef(_size, _size, _size);
glTranslatef(i->position.x, i->position.y, i->position.z); _voxelSystem->render();
glScalef(i->scale, i->scale, i->scale); } glPopMatrix();
i->voxelSystem->render(); }
glPopMatrix(); }
void LocalVoxelsOverlay::setProperties(const QScriptValue &properties) {
Volume3DOverlay::setProperties(properties);
QScriptValue treeName = properties.property("name");
// if "end" property was not there, check to see if they included aliases: endPoint, or p2
if (treeName.isValid()) {
if ((_treeName = treeName.toString()) == DOMAIN_TREE_NAME) {
qDebug() << "addOverlay(): Can't create overlay from domain tree";
return;
}
_tree = LocalVoxelsList::getInstance()->getTree(_treeName);
if (_tree.isNull()) {
qDebug() << "addOverlay(): Invalid tree name";
return;
}
_voxelSystem = _voxelSystemMap[_treeName];
if (_voxelSystem.isNull()) {
_voxelSystem = StrongVoxelSystemPointer(new VoxelSystem(1,
DEFAULT_MAX_VOXELS_PER_SYSTEM,
_tree.data()));
_voxelSystemMap.insert(_treeName, _voxelSystem);
} }
} }
} }
void LocalVoxelsOverlay::addOverlay(QString overlayName, QString treeName) {
if (treeName == DOMAIN_TREE_NAME) {
qDebug() << "addOverlay(): Can't create overlay from domain tree";
return;
}
if (_overlayMap.contains(overlayName)) {
qDebug() << "addOverlay(): Overlay name elready in use";
return;
}
StrongVoxelTreePointer tree = LocalVoxelsList::getInstance()->getTree(treeName);
if (tree.isNull()) {
qDebug() << "addOverlay(): Invalid tree name";
return;
}
StrongVoxelSystemPointer voxelSystem = _voxelSystemMap[treeName];
if (voxelSystem.isNull()) {
voxelSystem = StrongVoxelSystemPointer(new VoxelSystem(TREE_SCALE,
DEFAULT_MAX_VOXELS_PER_SYSTEM,
tree.data()));
_voxelSystemMap.insert(treeName, voxelSystem);
}
OverlayElement element = {
treeName,
tree,
glm::vec3(0, 0, 0),
0,
false,
voxelSystem
};
_overlayMap.insert(overlayName, element);
}
void LocalVoxelsOverlay::setPosition(QString overlayName, float x, float y, float z) {
if (_overlayMap.contains(overlayName)) {
_overlayMap[overlayName].position = glm::vec3(x, y, z);
}
}
void LocalVoxelsOverlay::setScale(QString overlayName, float scale) {
if (_overlayMap.contains(overlayName)) {
_overlayMap[overlayName].scale = scale;
}
}
void LocalVoxelsOverlay::display(QString overlayName, bool wantDisplay) {
if (_overlayMap.contains(overlayName)) {
_overlayMap[overlayName].wantDisplay = wantDisplay;
}
}
void LocalVoxelsOverlay::removeOverlay(QString overlayName) {
if (_overlayMap.contains(overlayName)) {
QString treeName = _overlayMap.take(overlayName).treeName;
if (_voxelSystemMap.value(treeName).isNull()) {
_voxelSystemMap.remove(treeName);
}
}
}

View file

@ -11,13 +11,19 @@
#ifndef __hifi__LocalVoxelsOverlay__ #ifndef __hifi__LocalVoxelsOverlay__
#define __hifi__LocalVoxelsOverlay__ #define __hifi__LocalVoxelsOverlay__
#include "Volume3DOverlay.h" // include this before QGLWidget, which includes an earlier version of OpenGL
#include "InterfaceConfig.h"
#include <QGLWidget>
#include <QScriptValue>
#include <QMap> #include <QMap>
#include <QSharedPointer> #include <QSharedPointer>
#include <QWeakPointer> #include <QWeakPointer>
struct OverlayElement; #include <LocalVoxelsList.h>
#include "Volume3DOverlay.h"
typedef QSharedPointer<VoxelSystem> StrongVoxelSystemPointer; typedef QSharedPointer<VoxelSystem> StrongVoxelSystemPointer;
typedef QWeakPointer<VoxelSystem> WeakVoxelSystemPointer; typedef QWeakPointer<VoxelSystem> WeakVoxelSystemPointer;
@ -27,19 +33,18 @@ public:
LocalVoxelsOverlay(); LocalVoxelsOverlay();
~LocalVoxelsOverlay(); ~LocalVoxelsOverlay();
virtual void update(float deltatime);
virtual void render(); virtual void render();
void addOverlay(QString overlayName, QString treeName); virtual void setProperties(const QScriptValue& properties);
void setPosition(QString overlayName, float x, float y, float z);
void setScale(QString overlayName, float scale);
void update(QString overlayName);
void display(QString overlayName, bool wantDisplay);
void removeOverlay(QString overlayName);
private: private:
QMap<QString, OverlayElement> _overlayMap; // overlayName/overlayElement static QMap<QString, WeakVoxelSystemPointer> _voxelSystemMap; // treeName/voxelSystem
QMap<QString, WeakVoxelSystemPointer> _voxelSystemMap; // treeName/voxelSystem
QString _treeName;
StrongVoxelTreePointer _tree; // so that the tree doesn't get freed
int _voxelCount;
StrongVoxelSystemPointer _voxelSystem;
}; };
#endif /* defined(__hifi__LocalVoxelsOverlay__) */ #endif /* defined(__hifi__LocalVoxelsOverlay__) */

View file

@ -18,6 +18,7 @@
Overlay::Overlay() : Overlay::Overlay() :
_parent(NULL), _parent(NULL),
_wantDeleteOnRenderThread(false),
_alpha(DEFAULT_ALPHA), _alpha(DEFAULT_ALPHA),
_color(DEFAULT_BACKGROUND_COLOR), _color(DEFAULT_BACKGROUND_COLOR),
_visible(true) _visible(true)

View file

@ -28,9 +28,11 @@ public:
Overlay(); Overlay();
~Overlay(); ~Overlay();
void init(QGLWidget* parent); void init(QGLWidget* parent);
virtual void update(float deltatime) {}
virtual void render() = 0; virtual void render() = 0;
// getters // getters
bool deleteOnRenderThread() { return _wantDeleteOnRenderThread; }
bool getVisible() const { return _visible; } bool getVisible() const { return _visible; }
const xColor& getColor() const { return _color; } const xColor& getColor() const { return _color; }
float getAlpha() const { return _alpha; } float getAlpha() const { return _alpha; }
@ -44,6 +46,8 @@ public:
protected: protected:
QGLWidget* _parent; QGLWidget* _parent;
bool _wantDeleteOnRenderThread;
float _alpha; float _alpha;
xColor _color; xColor _color;
bool _visible; // should the overlay be drawn at all bool _visible; // should the overlay be drawn at all

View file

@ -13,19 +13,41 @@
#include "Sphere3DOverlay.h" #include "Sphere3DOverlay.h"
#include "TextOverlay.h" #include "TextOverlay.h"
#include "ClipboardOverlay.h" #include "ClipboardOverlay.h"
#include "LocalVoxelsOverlay.h"
unsigned int Overlays::_nextOverlayID = 1; Overlays::Overlays() : _nextOverlayID(1) {
Overlays::Overlays() {
} }
Overlays::~Overlays() { Overlays::~Overlays() {
QMap<unsigned int, Overlay*>::iterator it;
for (it = _overlays2D.begin(); it != _overlays2D.end(); ++it) {
delete _overlays2D.take(it.key());
}
for (it = _overlays3D.begin(); it != _overlays3D.end(); ++it) {
delete _overlays3D.take(it.key());
}
while (!_overlaysToDelete.isEmpty()) {
delete _overlaysToDelete.takeLast();
}
} }
void Overlays::init(QGLWidget* parent) { void Overlays::init(QGLWidget* parent) {
_parent = parent; _parent = parent;
} }
void Overlays::update(float deltatime) {
foreach (Overlay* thisOverlay, _overlays2D) {
thisOverlay->update(deltatime);
}
foreach (Overlay* thisOverlay, _overlays3D) {
thisOverlay->update(deltatime);
}
while (!_overlaysToDelete.isEmpty()) {
delete _overlaysToDelete.takeLast();
}
}
void Overlays::render2D() { void Overlays::render2D() {
foreach(Overlay* thisOverlay, _overlays2D) { foreach(Overlay* thisOverlay, _overlays2D) {
thisOverlay->render(); thisOverlay->render();
@ -79,6 +101,12 @@ unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& prope
thisOverlay->setProperties(properties); thisOverlay->setProperties(properties);
created = true; created = true;
is3D = true; is3D = true;
} else if (type == "localvoxels") {
thisOverlay = new LocalVoxelsOverlay();
thisOverlay->init(_parent);
thisOverlay->setProperties(properties);
created = true;
is3D = true;
} }
if (created) { if (created) {
@ -111,11 +139,21 @@ bool Overlays::editOverlay(unsigned int id, const QScriptValue& properties) {
// TODO: make multi-threaded safe // TODO: make multi-threaded safe
void Overlays::deleteOverlay(unsigned int id) { void Overlays::deleteOverlay(unsigned int id) {
Overlay* overlayToDelete;
if (_overlays2D.contains(id)) { if (_overlays2D.contains(id)) {
_overlays2D.erase(_overlays2D.find(id)); overlayToDelete = _overlays2D.take(id);
} else if (_overlays3D.contains(id)) { } else if (_overlays3D.contains(id)) {
_overlays3D.erase(_overlays3D.find(id)); overlayToDelete = _overlays3D.take(id);
} else {
return;
} }
if (overlayToDelete->deleteOnRenderThread()) {
_overlaysToDelete.push_back(overlayToDelete);
} else {
delete overlayToDelete;
}
} }
unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) { unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) {

View file

@ -18,6 +18,7 @@ public:
Overlays(); Overlays();
~Overlays(); ~Overlays();
void init(QGLWidget* parent); void init(QGLWidget* parent);
void update(float deltatime);
void render3D(); void render3D();
void render2D(); void render2D();
@ -38,7 +39,8 @@ public slots:
private: private:
QMap<unsigned int, Overlay*> _overlays2D; QMap<unsigned int, Overlay*> _overlays2D;
QMap<unsigned int, Overlay*> _overlays3D; QMap<unsigned int, Overlay*> _overlays3D;
static unsigned int _nextOverlayID; QList<Overlay*> _overlaysToDelete;
unsigned int _nextOverlayID;
QGLWidget* _parent; QGLWidget* _parent;
}; };

View file

@ -37,28 +37,28 @@ void LocalVoxelsList::addPersistantTree(QString treeName, VoxelTree* tree) {
StrongVoxelTreePointer treePtr(tree, doNothing); StrongVoxelTreePointer treePtr(tree, doNothing);
_persistantTrees.push_back(treePtr); _persistantTrees.push_back(treePtr);
_trees.insert(treeName, treePtr); _trees.insert(treeName, treePtr);
qDebug() << "[DEBUG] LocalVoxelsList : added persistant tree (" << treeName << ")" << endl; qDebug() << "[DEBUG] LocalVoxelsList : added persistant tree (" << treeName << ")";
} }
void LocalVoxelsList::insert(QString treeName, StrongVoxelTreePointer& tree) { void LocalVoxelsList::insert(QString treeName, StrongVoxelTreePointer& tree) {
// If the key don't already exist or the value is null // If the key don't already exist or the value is null
if (!_trees.contains(treeName) || !_trees.value(treeName)) { if (!_trees.contains(treeName) || !_trees.value(treeName)) {
_trees.insert(treeName, tree); _trees.insert(treeName, tree);
qDebug() << "[DEBUG] LocalVoxelsList : added local tree (" << treeName << ")" << endl; qDebug() << "[DEBUG] LocalVoxelsList : added local tree (" << treeName << ")";
} else { } else {
// if not we replace the tree created by the user with the existing one // if not we replace the tree created by the user with the existing one
tree = _trees.value(treeName); tree = _trees.value(treeName);
qDebug() << "[DEBUG] LocalVoxelsList : local tree already exist (" << treeName << ")"<< endl; qDebug() << "[DEBUG] LocalVoxelsList : local tree already exist (" << treeName << ")";
} }
} }
void LocalVoxelsList::remove(QString treeName) { void LocalVoxelsList::remove(QString treeName) {
// if the tree is not used anymore (no strong pointer) // if the tree is not used anymore (no strong pointer)
if (!_trees.value(treeName, StrongVoxelTreePointer(NULL))) { if (!_trees.value(treeName)) {
// then remove it from the list // then remove it from the list
qDebug() << "[DEBUG] LocalVoxelsList : removed unused tree (" << treeName << ")" << endl; qDebug() << "[DEBUG] LocalVoxelsList : removed unused tree (" << treeName << ")";
_trees.remove(treeName); _trees.remove(treeName);
} else { } else {
qDebug() << "[DEBUG] LocalVoxelsList : tree still in use (" << treeName << ")" << endl; qDebug() << "[DEBUG] LocalVoxelsList : tree still in use (" << treeName << ")";
} }
} }