mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-13 21:27:21 +02:00
commit
f7a0d878dd
18 changed files with 613 additions and 91 deletions
54
examples/localVoxelsExample.js
Normal file
54
examples/localVoxelsExample.js
Normal 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);
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -90,5 +90,4 @@ void ClipboardScriptingInterface::nudgeVoxel(float x, float y, float z, float s,
|
|||
s / (float)TREE_SCALE };
|
||||
|
||||
Application::getInstance()->nudgeVoxelsByVector(sourceVoxel, nudgeVecInTreeSpace);
|
||||
}
|
||||
|
||||
}
|
|
@ -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()));
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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__) */
|
84
interface/src/ui/LocalVoxelsOverlay.cpp
Normal file
84
interface/src/ui/LocalVoxelsOverlay.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
50
interface/src/ui/LocalVoxelsOverlay.h
Normal file
50
interface/src/ui/LocalVoxelsOverlay.h
Normal 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__) */
|
|
@ -28,6 +28,7 @@ public:
|
|||
Overlay();
|
||||
~Overlay();
|
||||
void init(QGLWidget* parent);
|
||||
virtual void update(float deltatime) {}
|
||||
virtual void render() = 0;
|
||||
|
||||
// getters
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
153
libraries/script-engine/src/LocalVoxels.cpp
Normal file
153
libraries/script-engine/src/LocalVoxels.cpp
Normal 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
|
||||
}
|
90
libraries/script-engine/src/LocalVoxels.h
Normal file
90
libraries/script-engine/src/LocalVoxels.h
Normal 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__) */
|
|
@ -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);
|
||||
|
|
64
libraries/voxels/src/LocalVoxelsList.cpp
Normal file
64
libraries/voxels/src/LocalVoxelsList.cpp
Normal 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 << ")";
|
||||
}
|
||||
}
|
59
libraries/voxels/src/LocalVoxelsList.h
Normal file
59
libraries/voxels/src/LocalVoxelsList.h
Normal 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__) */
|
Loading…
Reference in a new issue