Merge pull request #2182 from Atlante45/local_voxels

Local voxels
This commit is contained in:
ZappoMan 2014-03-04 11:48:10 -08:00
commit f7a0d878dd
18 changed files with 613 additions and 91 deletions

View file

@ -0,0 +1,54 @@
var TREE_SCALE = 16384;
var tree = LocalVoxels("tree");
tree.setVoxel(0, 0, 0,
0.5 * TREE_SCALE,
255, 0, 0);
tree.setVoxel(0.5 * TREE_SCALE,
0.5 * TREE_SCALE,
0.5 * TREE_SCALE,
0.5 * TREE_SCALE,
0, 255, 0);
var copy = LocalVoxels("copy");
tree.pasteFrom(0, 0, 0, TREE_SCALE, "copy");
tree.pasteFrom(0, 0, 0, TREE_SCALE, "clipboard");
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: "copy"
});
var clipboard = Overlays.addOverlay("localvoxels", {
position: {x: 1, y: 5, z: 1},
size: 1,
name: "clipboard"
});
// 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);
Overlays.deleteOverlay(clipboard);
}
Script.scriptEnding.connect(scriptEnding);

View file

@ -61,6 +61,7 @@
#include <ResourceCache.h>
#include <UUID.h>
#include <VoxelSceneStats.h>
#include <LocalVoxelsList.h>
#include "Application.h"
#include "ClipboardScriptingInterface.h"
@ -311,7 +312,10 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
checkVersion();
_overlays.init(_glWidget); // do this before scripts load
LocalVoxelsList::getInstance()->addPersistantTree(DOMAIN_TREE_NAME, _voxels.getTree());
LocalVoxelsList::getInstance()->addPersistantTree(CLIPBOARD_TREE_NAME, &_clipboard);
// do this as late as possible so that all required subsystems are inialized
loadScripts();
}
@ -1424,6 +1428,7 @@ void Application::pasteVoxelsToOctalCode(const unsigned char* octalCodeDestinati
args.newBaseOctCode = octalCodeDestination;
_sharedVoxelSystem.getTree()->recurseTreeWithOperation(sendVoxelsOperation, &args);
// Switch back to clipboard if it was an import
if (_sharedVoxelSystem.getTree() != &_clipboard) {
_sharedVoxelSystem.killLocalVoxels();
_sharedVoxelSystem.changeTree(&_clipboard);
@ -1885,6 +1890,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

@ -90,5 +90,4 @@ void ClipboardScriptingInterface::nudgeVoxel(float x, float y, float z, float s,
s / (float)TREE_SCALE };
Application::getInstance()->nudgeVoxelsByVector(sourceVoxel, nudgeVecInTreeSpace);
}
}

View file

@ -8,6 +8,7 @@
#include <VoxelImporter.h>
#include <Application.h>
#include <LocalVoxelsList.h>
#include <QFileInfo>
#include <QThreadPool>
@ -31,6 +32,8 @@ VoxelImporter::VoxelImporter(QWidget* parent) :
_task(NULL),
_didImport(false)
{
LocalVoxelsList::getInstance()->addPersistantTree(IMPORT_TREE_NAME, &_voxelTree);
connect(&_voxelTree, SIGNAL(importProgress(int)), &_importDialog, SLOT(setProgressBarValue(int)));
connect(&_importDialog, SIGNAL(canceled()), this, SLOT(cancel()));
connect(&_importDialog, SIGNAL(accepted()), this, SLOT(import()));

View file

@ -53,7 +53,7 @@ GLubyte identityIndicesRight[] = { 1, 2, 6, 1, 6, 5 };
GLubyte identityIndicesFront[] = { 0, 2, 1, 0, 3, 2 };
GLubyte identityIndicesBack[] = { 4, 5, 6, 4, 6, 7 };
VoxelSystem::VoxelSystem(float treeScale, int maxVoxels)
VoxelSystem::VoxelSystem(float treeScale, int maxVoxels, VoxelTree* tree)
: NodeData(),
_treeScale(treeScale),
_maxVoxels(maxVoxels),
@ -69,7 +69,7 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels)
_voxelsInReadArrays = _voxelsInWriteArrays = _voxelsUpdated = 0;
_writeRenderFullVBO = true;
_readRenderFullVBO = true;
_tree = new VoxelTree();
_tree = (tree) ? tree : new VoxelTree();
_tree->getRoot()->setVoxelSystem(this);

View file

@ -44,7 +44,7 @@ class VoxelSystem : public NodeData, public OctreeElementDeleteHook, public Octr
friend class VoxelHideShowThread;
public:
VoxelSystem(float treeScale = TREE_SCALE, int maxVoxels = DEFAULT_MAX_VOXELS_PER_SYSTEM);
VoxelSystem(float treeScale = TREE_SCALE, int maxVoxels = DEFAULT_MAX_VOXELS_PER_SYSTEM, VoxelTree* tree = NULL);
~VoxelSystem();
void setDataSourceUUID(const QUuid& dataSourceUUID) { _dataSourceUUID = dataSourceUUID; }
@ -52,8 +52,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

@ -1,50 +0,0 @@
//
// ClipboardOverlay.cpp
// hifi
//
// Created by Clément Brisset on 2/20/14.
// 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 <SharedUtil.h>
#include "ClipboardOverlay.h"
#include "../Application.h"
static int lastVoxelCount = 0;
ClipboardOverlay::ClipboardOverlay() {
}
ClipboardOverlay::~ClipboardOverlay() {
}
void ClipboardOverlay::render() {
if (!_visible) {
return; // do nothing if we're not visible
}
VoxelSystem* voxelSystem = Application::getInstance()->getSharedVoxelSystem();
VoxelTree* clipboard = Application::getInstance()->getClipboard();
if (voxelSystem->getTree() != clipboard) {
voxelSystem->changeTree(clipboard);
}
glPushMatrix();
glTranslatef(_position.x, _position.y, _position.z);
glScalef(_size, _size, _size);
// We only force the redraw when the clipboard content has changed
if (lastVoxelCount != clipboard->getOctreeElementsCount()) {
voxelSystem->forceRedrawEntireTree();
lastVoxelCount = clipboard->getOctreeElementsCount();
}
voxelSystem->render();
glPopMatrix();
}

View file

@ -1,25 +0,0 @@
//
// ClipboardOverlay.h
// hifi
//
// Created by Clément Brisset on 2/20/14.
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
//
#ifndef __interface__ClipboardOverlay__
#define __interface__ClipboardOverlay__
#include "Volume3DOverlay.h"
class ClipboardOverlay : public Volume3DOverlay {
Q_OBJECT
public:
ClipboardOverlay();
~ClipboardOverlay();
virtual void render();
};
#endif /* defined(__interface__ClipboardOverlay__) */

View file

@ -0,0 +1,84 @@
//
// LocalVoxelsOverlay.cpp
// hifi
//
// Created by Clément Brisset on 2/28/14.
// 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 <VoxelSystem.h>
#include <Application.h>
#include "LocalVoxelsOverlay.h"
QMap<QString, WeakVoxelSystemPointer> LocalVoxelsOverlay::_voxelSystemMap;
LocalVoxelsOverlay::LocalVoxelsOverlay() :
Volume3DOverlay(),
_voxelCount(0)
{
}
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() {
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);
}
}
}

View file

@ -0,0 +1,50 @@
//
// LocalVoxelsOverlay.h
// hifi
//
// Created by Clément Brisset on 2/28/14.
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
//
// Scriptable interface for LocalVoxels
//
#ifndef __hifi__LocalVoxelsOverlay__
#define __hifi__LocalVoxelsOverlay__
// include this before QGLWidget, which includes an earlier version of OpenGL
#include "InterfaceConfig.h"
#include <QGLWidget>
#include <QScriptValue>
#include <QMap>
#include <QSharedPointer>
#include <QWeakPointer>
#include <LocalVoxelsList.h>
#include "Volume3DOverlay.h"
typedef QSharedPointer<VoxelSystem> StrongVoxelSystemPointer;
typedef QWeakPointer<VoxelSystem> WeakVoxelSystemPointer;
class LocalVoxelsOverlay : public Volume3DOverlay {
Q_OBJECT
public:
LocalVoxelsOverlay();
~LocalVoxelsOverlay();
virtual void update(float deltatime);
virtual void render();
virtual void setProperties(const QScriptValue& properties);
private:
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

@ -28,6 +28,7 @@ public:
Overlay();
~Overlay();
void init(QGLWidget* parent);
virtual void update(float deltatime) {}
virtual void render() = 0;
// getters

View file

@ -12,20 +12,41 @@
#include "Overlays.h"
#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();
@ -73,8 +94,8 @@ unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& prope
thisOverlay->setProperties(properties);
created = true;
is3D = true;
} else if (type == "clipboard") {
thisOverlay = new ClipboardOverlay();
} else if (type == "localvoxels") {
thisOverlay = new LocalVoxelsOverlay();
thisOverlay->init(_parent);
thisOverlay->setProperties(properties);
created = true;
@ -111,11 +132,16 @@ 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;
}
_overlaysToDelete.push_back(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

@ -0,0 +1,153 @@
//
// LocalVoxels.cpp
// hifi
//
// Created by Clément Brisset on 2/24/14.
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
//
#include "LocalVoxels.h"
LocalVoxels::LocalVoxels(QString name) :
QObject(NULL),
_name(name),
_tree(new VoxelTree(true))
{
LocalVoxelsList::getInstance()->insert(_name, _tree);
}
LocalVoxels::~LocalVoxels() {
_tree.clear();
LocalVoxelsList::getInstance()->remove(_name);
}
VoxelDetail LocalVoxels::getVoxelAt(float x, float y, float z, float scale) {
// setup a VoxelDetail struct with the data
VoxelDetail result = {0,0,0,0,0,0,0};
if (_tree) {
_tree->lockForRead();
VoxelTreeElement* voxel = static_cast<VoxelTreeElement*>(_tree->getOctreeElementAt(x / (float)TREE_SCALE,
y / (float)TREE_SCALE,
z / (float)TREE_SCALE,
scale / (float)TREE_SCALE));
_tree->unlock();
if (voxel) {
// Note: these need to be in voxel space because the VoxelDetail -> js converter will upscale
result.x = voxel->getCorner().x;
result.y = voxel->getCorner().y;
result.z = voxel->getCorner().z;
result.s = voxel->getScale();
result.red = voxel->getColor()[RED_INDEX];
result.green = voxel->getColor()[GREEN_INDEX];
result.blue = voxel->getColor()[BLUE_INDEX];
}
}
return result;
}
void LocalVoxels::setVoxelNonDestructive(float x, float y, float z, float scale,
uchar red, uchar green, uchar blue) {
if (_name == DOMAIN_TREE_NAME) {
qDebug() << "LocalVoxels::setVoxelNonDestructive(): Please use the \"Voxels\" interface to modify the domain tree.";
return;
}
if (_tree ) {
_tree->createVoxel(x / (float)TREE_SCALE,
y / (float)TREE_SCALE,
z / (float)TREE_SCALE,
scale / (float)TREE_SCALE,
red, green, blue, false);
}
}
void LocalVoxels::setVoxel(float x, float y, float z, float scale,
uchar red, uchar green, uchar blue) {
if (_name == DOMAIN_TREE_NAME) {
qDebug() << "LocalVoxels::setVoxel(): Please use the \"Voxels\" interface to modify the domain tree.";
return;
}
if (_tree ) {
_tree->createVoxel(x / (float)TREE_SCALE,
y / (float)TREE_SCALE,
z / (float)TREE_SCALE,
scale / (float)TREE_SCALE,
red, green, blue, true);
}
}
void LocalVoxels::eraseVoxel(float x, float y, float z, float scale) {
if (_name == DOMAIN_TREE_NAME) {
qDebug() << "LocalVoxels::eraseVoxel(): Please use the \"Voxels\" interface to modify the domain tree.";
return;
}
if (_tree ) {
_tree->deleteVoxelAt(x / (float)TREE_SCALE,
y / (float)TREE_SCALE,
z / (float)TREE_SCALE,
scale / (float)TREE_SCALE);
}
}
void LocalVoxels::copyTo(float x, float y, float z, float scale, const QString destination) {
if (destination == DOMAIN_TREE_NAME) {
qDebug() << "LocalVoxels::copyTo(): Please use the \"Voxels\" interface to modify the domain tree.";
return;
}
StrongVoxelTreePointer destinationTree = LocalVoxelsList::getInstance()->getTree(destination);
VoxelTreeElement* destinationNode = destinationTree->getVoxelAt(x / (float)TREE_SCALE,
y / (float)TREE_SCALE,
z / (float)TREE_SCALE,
scale / (float)TREE_SCALE);
destinationTree->copyFromTreeIntoSubTree(_tree.data(), destinationNode);
}
void LocalVoxels::pasteFrom(float x, float y, float z, float scale, const QString source) {
if (_name == DOMAIN_TREE_NAME) {
qDebug() << "LocalVoxels::pasteFrom(): Please use the \"Voxels\" interface to modify the domain tree.";
return;
}
StrongVoxelTreePointer sourceTree = LocalVoxelsList::getInstance()->getTree(source);
VoxelTreeElement* sourceNode = _tree->getVoxelAt(x / (float)TREE_SCALE,
y / (float)TREE_SCALE,
z / (float)TREE_SCALE,
scale / (float)TREE_SCALE);
_tree->copySubTreeIntoNewTree(sourceNode, sourceTree.data(), true);
}
RayToVoxelIntersectionResult LocalVoxels::findRayIntersection(const PickRay& ray) {
RayToVoxelIntersectionResult result;
if (_tree) {
OctreeElement* element;
result.intersects = _tree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face);
if (result.intersects) {
VoxelTreeElement* voxel = (VoxelTreeElement*)element;
result.voxel.x = voxel->getCorner().x;
result.voxel.y = voxel->getCorner().y;
result.voxel.z = voxel->getCorner().z;
result.voxel.s = voxel->getScale();
result.voxel.red = voxel->getColor()[0];
result.voxel.green = voxel->getColor()[1];
result.voxel.blue = voxel->getColor()[2];
result.intersection = ray.origin + (ray.direction * result.distance);
}
}
return result;
}
glm::vec3 LocalVoxels::getFaceVector(const QString& face) {
if (face == "MIN_X_FACE") {
return glm::vec3(-1, 0, 0);
} else if (face == "MAX_X_FACE") {
return glm::vec3(1, 0, 0);
} else if (face == "MIN_Y_FACE") {
return glm::vec3(0, -1, 0);
} else if (face == "MAX_Y_FACE") {
return glm::vec3(0, 1, 0);
} else if (face == "MIN_Z_FACE") {
return glm::vec3(0, 0, -1);
} else if (face == "MAX_Z_FACE") {
return glm::vec3(0, 0, 1);
}
return glm::vec3(0, 0, 0); //error case
}

View file

@ -0,0 +1,90 @@
//
// LocalVoxels.h
// hifi
//
// Created by Clément Brisset on 2/24/14.
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
//
#ifndef __hifi__LocalVoxels__
#define __hifi__LocalVoxels__
#include <QObject>
#include <RegisteredMetaTypes.h>
#include <LocalVoxelsList.h>
/// object allowing JS scripters to use their own local trees
class LocalVoxels : public QObject {
Q_OBJECT
public:
LocalVoxels(QString name);
~LocalVoxels();
/// checks the local voxel tree for a voxel at the specified location and scale
/// \param x the x-coordinate of the voxel (in meter units)
/// \param y the y-coordinate of the voxel (in meter units)
/// \param z the z-coordinate of the voxel (in meter units)
/// \param scale the scale of the voxel (in meter units)
Q_INVOKABLE VoxelDetail getVoxelAt(float x, float y, float z, float scale);
/// creates a non destructive voxel in the local tree
/// \param x the x-coordinate of the voxel (in meter units)
/// \param y the y-coordinate of the voxel (in meter units)
/// \param z the z-coordinate of the voxel (in meter units)
/// \param scale the scale of the voxel (in meter units)
/// \param red the R value for RGB color of voxel
/// \param green the G value for RGB color of voxel
/// \param blue the B value for RGB color of voxel
Q_INVOKABLE void setVoxelNonDestructive(float x, float y, float z, float scale, uchar red, uchar green, uchar blue);
/// creates a voxel in the local tree
/// \param x the x-coordinate of the voxel (in meter units)
/// \param y the y-coordinate of the voxel (in meter units)
/// \param z the z-coordinate of the voxel (in meter units)
/// \param scale the scale of the voxel (in meter units)
/// \param red the R value for RGB color of voxel
/// \param green the G value for RGB color of voxel
/// \param blue the B value for RGB color of voxel
Q_INVOKABLE void setVoxel(float x, float y, float z, float scale, uchar red, uchar green, uchar blue);
/// erase the voxel and its children at the given coordinate
/// \param x the x-coordinate of the voxel (in meter units)
/// \param y the y-coordinate of the voxel (in meter units)
/// \param z the z-coordinate of the voxel (in meter units)
/// \param scale the scale of the voxel (in meter units)
Q_INVOKABLE void eraseVoxel(float x, float y, float z, float scale);
/// copy the given subtree onto destination's root node
/// \param x the x-coordinate of the subtree (in meter units)
/// \param y the y-coordinate of the subtree (in meter units)
/// \param z the z-coordinate of the subtree (in meter units)
/// \param scale the scale of the subtree (in meter units)
/// \param destination LocalVoxels' destination tree
Q_INVOKABLE void copyTo(float x, float y, float z, float scale, const QString destination);
///copy source in the given subtree
/// \param x the x-coordinate of the subtree (in meter units)
/// \param y the y-coordinate of the subtree (in meter units)
/// \param z the z-coordinate of the subtree (in meter units)
/// \param scale the scale of the subtree (in meter units)
/// \param source LocalVoxels' source tree
Q_INVOKABLE void pasteFrom(float x, float y, float z, float scale, const QString source);
/// If the scripting context has visible voxels, this will determine a ray intersection
Q_INVOKABLE RayToVoxelIntersectionResult findRayIntersection(const PickRay& ray);
/// returns a voxel space axis aligned vector for the face, useful in doing voxel math
Q_INVOKABLE glm::vec3 getFaceVector(const QString& face);
private:
QString _name;
StrongVoxelTreePointer _tree;
};
#endif /* defined(__hifi__LocalVoxels__) */

View file

@ -25,6 +25,7 @@
#include <Sound.h>
#include "MenuItemProperties.h"
#include "LocalVoxels.h"
#include "ScriptEngine.h"
const unsigned int VISUAL_DATA_CALLBACK_USECS = (1.0 / 60.0) * 1000 * 1000;
@ -118,6 +119,7 @@ bool ScriptEngine::setScriptContents(const QString& scriptContents) {
}
Q_SCRIPT_DECLARE_QMETAOBJECT(AudioInjectorOptions, QObject*)
Q_SCRIPT_DECLARE_QMETAOBJECT(LocalVoxels, QString)
void ScriptEngine::init() {
if (_isInitialized) {
@ -146,6 +148,9 @@ void ScriptEngine::init() {
QScriptValue injectionOptionValue = _engine.scriptValueFromQMetaObject<AudioInjectorOptions>();
_engine.globalObject().setProperty("AudioInjectionOptions", injectionOptionValue);
QScriptValue localVoxelsValue = _engine.scriptValueFromQMetaObject<LocalVoxels>();
_engine.globalObject().setProperty("LocalVoxels", localVoxelsValue);
registerGlobalObject("Script", this);
registerGlobalObject("Audio", &_audioScriptingInterface);

View file

@ -0,0 +1,64 @@
//
// LocalVoxelsList.cpp
// hifi
//
// Created by Clément Brisset on 2/24/14.
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
//
#include "LocalVoxelsList.h"
static void doNothing(VoxelTree* t) {
// do nothing
}
LocalVoxelsList* LocalVoxelsList::_instance = NULL;
LocalVoxelsList* LocalVoxelsList::getInstance() {
if (!_instance) {
_instance = new LocalVoxelsList();
}
return _instance;
}
LocalVoxelsList::LocalVoxelsList() {
}
LocalVoxelsList::~LocalVoxelsList() {
_instance = NULL;
}
StrongVoxelTreePointer LocalVoxelsList::getTree(QString treeName) {
return _trees.value(treeName);
}
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 << ")";
}
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 << ")";
} 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 << ")";
}
}
void LocalVoxelsList::remove(QString treeName) {
// if the tree is not used anymore (no strong pointer)
if (!_trees.value(treeName)) {
// then remove it from the list
qDebug() << "[DEBUG] LocalVoxelsList : removed unused tree (" << treeName << ")";
_trees.remove(treeName);
} else {
qDebug() << "[DEBUG] LocalVoxelsList : tree still in use (" << treeName << ")";
}
}

View file

@ -0,0 +1,59 @@
//
// LocalVoxelsList.h
// hifi
//
// Created by Clément Brisset on 2/24/14.
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
//
#ifndef __hifi__LocalVoxelsList__
#define __hifi__LocalVoxelsList__
#include <QHash>
#include <QString>
#include <QSharedPointer>
#include <QWeakPointer>
#include "VoxelTree.h"
typedef QSharedPointer<VoxelTree> StrongVoxelTreePointer;
typedef QWeakPointer<VoxelTree> WeakVoxelTreePointer;
static const QString DOMAIN_TREE_NAME = "domain";
static const QString CLIPBOARD_TREE_NAME = "clipboard";
static const QString IMPORT_TREE_NAME = "import";
/// Handles the the storage and cleanup of local named trees used by JS
class LocalVoxelsList {
public:
static LocalVoxelsList* getInstance();
~LocalVoxelsList();
/// Lookup up a tree in the QHash and return a strong pointer to it.
/// \param treeName name of the tree to look up
StrongVoxelTreePointer getTree(QString treeName);
/// Add a that will stay in the list until destruction of the instance and won't be destroyed then either.
/// \param treeName name to give to the tree in the list
/// \param tree standard pointer to the tree
void addPersistantTree(QString treeName, VoxelTree* tree);
/// insert a local tree in the list
/// \param treeName name to give to the tree in the list
/// \param tree strong pointer to the tree
void insert(QString treeName, StrongVoxelTreePointer& tree);
/// remove a tree from the list if it's not being used anymore
/// \param treeName name of the tree to remove
void remove(QString treeName);
private:
static LocalVoxelsList* _instance;
LocalVoxelsList();
QHash<QString, WeakVoxelTreePointer> _trees;
QList<StrongVoxelTreePointer> _persistantTrees;
};
#endif /* defined(__hifi__LocalVoxelsList__) */