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");
tree.setVoxel(0, 0, 0, 1, 128, 128, 128);
var tree = LocalVoxels("tree");
tree.setVoxel(0, 0, 0, 0.5, 255, 0, 0);
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);
}
test();
Script.scriptEnding.connect(scriptEnding);

View file

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

View file

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

View file

@ -6,106 +6,80 @@
// 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 <Application.h>
#include "LocalVoxelsOverlay.h"
struct OverlayElement {
QString treeName;
StrongVoxelTreePointer tree; // so that the tree doesn't get freed
glm::vec3 position;
float scale;
bool wantDisplay;
StrongVoxelSystemPointer voxelSystem;
};
QMap<QString, WeakVoxelSystemPointer> LocalVoxelsOverlay::_voxelSystemMap;
LocalVoxelsOverlay::LocalVoxelsOverlay() {
LocalVoxelsOverlay::LocalVoxelsOverlay() :
Volume3DOverlay(),
_voxelCount(0)
{
_wantDeleteOnRenderThread = true;
}
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() {
QMap<QString, OverlayElement>::iterator i;
for (i = _overlayMap.begin(); i != _overlayMap.end(); ++i) {
if (i->wantDisplay && i->scale > 0) {
glPushMatrix();
glTranslatef(i->position.x, i->position.y, i->position.z);
glScalef(i->scale, i->scale, i->scale);
i->voxelSystem->render();
glPopMatrix();
if (_visible && _size > 0 && _voxelSystem && _voxelSystem->isInitialized()) {
glPushMatrix(); {
glTranslatef(_position.x, _position.y, _position.z);
glScalef(_size, _size, _size);
_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__
#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 <QSharedPointer>
#include <QWeakPointer>
struct OverlayElement;
#include <LocalVoxelsList.h>
#include "Volume3DOverlay.h"
typedef QSharedPointer<VoxelSystem> StrongVoxelSystemPointer;
typedef QWeakPointer<VoxelSystem> WeakVoxelSystemPointer;
@ -27,19 +33,18 @@ public:
LocalVoxelsOverlay();
~LocalVoxelsOverlay();
virtual void update(float deltatime);
virtual void render();
void addOverlay(QString overlayName, QString treeName);
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);
virtual void setProperties(const QScriptValue& properties);
private:
QMap<QString, OverlayElement> _overlayMap; // overlayName/overlayElement
QMap<QString, WeakVoxelSystemPointer> _voxelSystemMap; // treeName/voxelSystem
static 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__) */

View file

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

View file

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

View file

@ -13,19 +13,41 @@
#include "Sphere3DOverlay.h"
#include "TextOverlay.h"
#include "ClipboardOverlay.h"
#include "LocalVoxelsOverlay.h"
unsigned int Overlays::_nextOverlayID = 1;
Overlays::Overlays() {
Overlays::Overlays() : _nextOverlayID(1) {
}
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) {
_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() {
foreach(Overlay* thisOverlay, _overlays2D) {
thisOverlay->render();
@ -79,6 +101,12 @@ unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& prope
thisOverlay->setProperties(properties);
created = true;
is3D = true;
} else if (type == "localvoxels") {
thisOverlay = new LocalVoxelsOverlay();
thisOverlay->init(_parent);
thisOverlay->setProperties(properties);
created = true;
is3D = true;
}
if (created) {
@ -111,11 +139,21 @@ bool Overlays::editOverlay(unsigned int id, const QScriptValue& properties) {
// TODO: make multi-threaded safe
void Overlays::deleteOverlay(unsigned int id) {
Overlay* overlayToDelete;
if (_overlays2D.contains(id)) {
_overlays2D.erase(_overlays2D.find(id));
overlayToDelete = _overlays2D.take(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) {

View file

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

View file

@ -37,28 +37,28 @@ void LocalVoxelsList::addPersistantTree(QString treeName, VoxelTree* tree) {
StrongVoxelTreePointer treePtr(tree, doNothing);
_persistantTrees.push_back(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) {
// If the key don't already exist or the value is null
if (!_trees.contains(treeName) || !_trees.value(treeName)) {
_trees.insert(treeName, tree);
qDebug() << "[DEBUG] LocalVoxelsList : added local tree (" << treeName << ")" << endl;
qDebug() << "[DEBUG] LocalVoxelsList : added local tree (" << treeName << ")";
} else {
// if not we replace the tree created by the user with the existing one
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) {
// 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
qDebug() << "[DEBUG] LocalVoxelsList : removed unused tree (" << treeName << ")" << endl;
qDebug() << "[DEBUG] LocalVoxelsList : removed unused tree (" << treeName << ")";
_trees.remove(treeName);
} else {
qDebug() << "[DEBUG] LocalVoxelsList : tree still in use (" << treeName << ")" << endl;
qDebug() << "[DEBUG] LocalVoxelsList : tree still in use (" << treeName << ")";
}
}