From f2305fd9690d1a41684c704cfb7e31577bf63d9e Mon Sep 17 00:00:00 2001 From: atlante45 Date: Fri, 9 Aug 2013 23:11:04 -0700 Subject: [PATCH 01/20] Added VoxelImporter class --- interface/src/Application.cpp | 3 +- interface/src/Application.h | 6 ++- interface/src/VoxelImporter.cpp | 76 +++++++++++++++++++++++++++++++++ interface/src/VoxelImporter.h | 37 ++++++++++++++++ 4 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 interface/src/VoxelImporter.cpp create mode 100644 interface/src/VoxelImporter.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 772908abe5..5d6b2d0bd5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -181,6 +181,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _justStarted(true), _particleSystemInitialized(false), _coolDemoParticleEmitter(-1), + _voxelImporter(_window), _wantToKillLocalVoxels(false), _frustumDrawingMode(FRUSTUM_DRAW_MODE_ALL), _viewFrustumOffsetYaw(-135.0), @@ -2033,7 +2034,7 @@ void Application::initMenu() { (_destructiveAddVoxel = voxelMenu->addAction("Create Voxel is Destructive"))->setCheckable(true); voxelMenu->addAction("Export Voxels", this, SLOT(exportVoxels()), Qt::CTRL | Qt::Key_E); - voxelMenu->addAction("Import Voxels", this, SLOT(importVoxels()), Qt::CTRL | Qt::Key_I); + voxelMenu->addAction("Import Voxels", &_voxelImporter, SLOT(exec()), Qt::CTRL | Qt::Key_I); voxelMenu->addAction("Import Voxels to Clipboard", this, SLOT(importVoxelsToClipboard()), Qt::SHIFT | Qt::CTRL | Qt::Key_I); voxelMenu->addAction("Cut Voxels", this, SLOT(cutVoxels()), Qt::CTRL | Qt::Key_X); voxelMenu->addAction("Copy Voxels", this, SLOT(copyVoxels()), Qt::CTRL | Qt::Key_C); diff --git a/interface/src/Application.h b/interface/src/Application.h index cb851c1dfc..ce5e1c6a8a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -38,6 +38,7 @@ #include "ToolsPalette.h" #include "ViewFrustum.h" #include "VoxelSystem.h" +#include "VoxelImporter.h" #include "Webcam.h" #include "PieMenu.h" #include "avatar/Avatar.h" @@ -326,8 +327,9 @@ private: Stars _stars; - VoxelSystem _voxels; - VoxelTree _clipboardTree; // if I copy/paste + VoxelSystem _voxels; + VoxelTree _clipboardTree; // if I copy/paste + VoxelImporter _voxelImporter; QByteArray _voxelsFilename; bool _wantToKillLocalVoxels; diff --git a/interface/src/VoxelImporter.cpp b/interface/src/VoxelImporter.cpp new file mode 100644 index 0000000000..4c389540d2 --- /dev/null +++ b/interface/src/VoxelImporter.cpp @@ -0,0 +1,76 @@ +// +// VoxelImporter.cpp +// hifi +// +// Created by Clement Brisset on 8/9/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#include "VoxelImporter.h" + +#include +#include +#include + +const QString WINDOW_NAME = QObject::tr("Import Voxels"); +const QString PREVIEW_CHECKBOX_STRING = QObject::tr("Load preview"); +const QString IMPORT_BUTTON_NAME = QObject::tr("Import"); +const QString IMPORT_TO_CLIPBOARD_BUTTON_NAME = QObject::tr("Import into clipboard"); +const QString IMPORT_FILE_TYPES = QObject::tr("Sparse Voxel Octree Files, " + "Square PNG, " + "Schematic Files " + "(*.svo *.png *.schematic)"); + +const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); + +VoxelImporter::VoxelImporter(QWidget* parent) + : QFileDialog(parent, WINDOW_NAME, DESKTOP_LOCATION, IMPORT_FILE_TYPES), + _importButton (IMPORT_BUTTON_NAME , this), + _clipboardImportButton(IMPORT_TO_CLIPBOARD_BUTTON_NAME, this), + _previewBox (PREVIEW_CHECKBOX_STRING , this), + _previewBar (this), + _glPreview (this) { + + setOption(QFileDialog::DontUseNativeDialog, true); + setFileMode(QFileDialog::ExistingFile); + setViewMode(QFileDialog::Detail); + _previewBar.setVisible(false); + _glPreview.setVisible(false); + + QGridLayout* gridLayout = (QGridLayout*) layout(); + gridLayout->addWidget(&_importButton , 2, 2); + gridLayout->addWidget(&_clipboardImportButton, 2, 3); + gridLayout->addWidget(&_previewBox , 3, 3); + gridLayout->addWidget(&_previewBar , 0, 3); + gridLayout->addWidget(&_glPreview , 1, 3); + + + connect(&_importButton , SIGNAL(pressed()), this, SLOT(importVoxels())); + connect(&_clipboardImportButton, SIGNAL(pressed()), this, SLOT(importVoxelsToClipboard())); + connect(&_previewBox, SIGNAL(toggled(bool)), &_previewBar, SLOT(setVisible(bool))); + connect(&_previewBox, SIGNAL(toggled(bool)), &_glPreview , SLOT(setVisible(bool))); +} + +int VoxelImporter::exec() { + _previewBox.setChecked(false); + _previewBar.setVisible(false); + _glPreview.setVisible(false); + + return exec(); +} + + +void VoxelImporter::importVoxels() { + accept(); + qDebug("Congratulation, you imported a file.\n"); +} + +void VoxelImporter::importVoxelsToClipboard() { + accept(); + qDebug("Congratulation, you imported a file to the clipboard.\n"); + +} + +void VoxelImporter::preview(bool) { + +} diff --git a/interface/src/VoxelImporter.h b/interface/src/VoxelImporter.h new file mode 100644 index 0000000000..a664788a82 --- /dev/null +++ b/interface/src/VoxelImporter.h @@ -0,0 +1,37 @@ +// +// VoxelImporter.h +// hifi +// +// Created by Clement Brisset on 8/9/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#ifndef __hifi__VoxelImporter__ +#define __hifi__VoxelImporter__ + +#include +#include +#include +#include +#include + +class VoxelImporter : public QFileDialog { + Q_OBJECT +public: + VoxelImporter(QWidget* parent = NULL); + +public slots: + int exec(); + void importVoxels(); + void importVoxelsToClipboard(); + void preview(bool); + +private: + QPushButton _importButton; + QPushButton _clipboardImportButton; + QCheckBox _previewBox; + QProgressBar _previewBar; + QGLWidget _glPreview; +}; + +#endif /* defined(__hifi__VoxelImporter__) */ From 68a1c56ad6e567c6983131e46efaa7fca203c680 Mon Sep 17 00:00:00 2001 From: atlante45 Date: Thu, 15 Aug 2013 17:21:23 -0700 Subject: [PATCH 02/20] More work on import interface --- interface/src/Application.cpp | 20 +-- interface/src/VoxelImporter.cpp | 120 ++++++++++-------- interface/src/VoxelImporter.h | 46 ++++--- interface/src/VoxelSystem.cpp | 16 +++ interface/src/VoxelSystem.h | 6 +- libraries/voxels/src/Tags.cpp | 160 ++++++++++++++++++++++- libraries/voxels/src/Tags.h | 5 +- libraries/voxels/src/VoxelTree.cpp | 196 ++++++----------------------- libraries/voxels/src/VoxelTree.h | 16 ++- 9 files changed, 336 insertions(+), 249 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 63578c78a7..2d15e7fc58 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1623,20 +1623,7 @@ void Application::importVoxelsToClipboard() { _clipboardTree.eraseAllVoxels(); if (fileNameString.endsWith(".png", Qt::CaseInsensitive)) { - QImage pngImage = QImage(fileName); - if (pngImage.height() != pngImage.width()) { - qDebug("ERROR: Bad PNG size: height != width.\n"); - return; - } - - const uint32_t* pixels; - if (pngImage.format() == QImage::Format_ARGB32) { - pixels = reinterpret_cast(pngImage.constBits()); - } else { - QImage tmp = pngImage.convertToFormat(QImage::Format_ARGB32); - pixels = reinterpret_cast(tmp.constBits()); - } - _clipboardTree.readFromSquareARGB32Pixels(pixels, pngImage.height()); + _clipboardTree.readFromSquareARGB32Pixels(fileName); } else if (fileNameString.endsWith(".svo", Qt::CaseInsensitive)) { _clipboardTree.readFromSVOFile(fileName); } else if (fileNameString.endsWith(".schematic", Qt::CaseInsensitive)) { @@ -1696,7 +1683,7 @@ void Application::importVoxels() { pixels = reinterpret_cast(tmp.constBits()); } - importVoxels.readFromSquareARGB32Pixels(pixels, pngImage.height()); + importVoxels.readFromSquareARGB32Pixels(fileName); } else if (fileNameString.endsWith(".svo", Qt::CaseInsensitive)) { extension = QString(".svo"); importVoxels.readFromSVOFile(fileName); @@ -1963,8 +1950,7 @@ void Application::initMenu() { (_destructiveAddVoxel = voxelMenu->addAction("Create Voxel is Destructive"))->setCheckable(true); voxelMenu->addAction("Export Voxels", this, SLOT(exportVoxels()), Qt::CTRL | Qt::Key_E); - voxelMenu->addAction("Import Voxels", &_voxelImporter, SLOT(exec()), Qt::CTRL | Qt::Key_I); - voxelMenu->addAction("Import Voxels to Clipboard", this, SLOT(importVoxelsToClipboard()), Qt::SHIFT | Qt::CTRL | Qt::Key_I); + voxelMenu->addAction("Import Voxels", &_voxelImporter, SLOT(import()), Qt::CTRL | Qt::Key_I); voxelMenu->addAction("Cut Voxels", this, SLOT(cutVoxels()), Qt::CTRL | Qt::Key_X); voxelMenu->addAction("Copy Voxels", this, SLOT(copyVoxels()), Qt::CTRL | Qt::Key_C); voxelMenu->addAction("Paste Voxels", this, SLOT(pasteVoxels()), Qt::CTRL | Qt::Key_V); diff --git a/interface/src/VoxelImporter.cpp b/interface/src/VoxelImporter.cpp index 4c389540d2..488dd4b907 100644 --- a/interface/src/VoxelImporter.cpp +++ b/interface/src/VoxelImporter.cpp @@ -6,71 +6,85 @@ // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // -#include "VoxelImporter.h" +#include -#include -#include -#include +#include +#include -const QString WINDOW_NAME = QObject::tr("Import Voxels"); -const QString PREVIEW_CHECKBOX_STRING = QObject::tr("Load preview"); -const QString IMPORT_BUTTON_NAME = QObject::tr("Import"); -const QString IMPORT_TO_CLIPBOARD_BUTTON_NAME = QObject::tr("Import into clipboard"); -const QString IMPORT_FILE_TYPES = QObject::tr("Sparse Voxel Octree Files, " - "Square PNG, " - "Schematic Files " - "(*.svo *.png *.schematic)"); +class LocalVoxelSystem : public VoxelSystem { +public: + LocalVoxelSystem() : VoxelSystem(1) {}; -const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); + virtual void removeOutOfView() {}; +}; VoxelImporter::VoxelImporter(QWidget* parent) - : QFileDialog(parent, WINDOW_NAME, DESKTOP_LOCATION, IMPORT_FILE_TYPES), - _importButton (IMPORT_BUTTON_NAME , this), - _clipboardImportButton(IMPORT_TO_CLIPBOARD_BUTTON_NAME, this), - _previewBox (PREVIEW_CHECKBOX_STRING , this), - _previewBar (this), - _glPreview (this) { + : QObject(parent), + _voxelSystem(new LocalVoxelSystem()), + _importDialog(parent, _voxelSystem), + _currentTask(NULL), + _nextTask(NULL) { - setOption(QFileDialog::DontUseNativeDialog, true); - setFileMode(QFileDialog::ExistingFile); - setViewMode(QFileDialog::Detail); - _previewBar.setVisible(false); - _glPreview.setVisible(false); - - QGridLayout* gridLayout = (QGridLayout*) layout(); - gridLayout->addWidget(&_importButton , 2, 2); - gridLayout->addWidget(&_clipboardImportButton, 2, 3); - gridLayout->addWidget(&_previewBox , 3, 3); - gridLayout->addWidget(&_previewBar , 0, 3); - gridLayout->addWidget(&_glPreview , 1, 3); - - - connect(&_importButton , SIGNAL(pressed()), this, SLOT(importVoxels())); - connect(&_clipboardImportButton, SIGNAL(pressed()), this, SLOT(importVoxelsToClipboard())); - connect(&_previewBox, SIGNAL(toggled(bool)), &_previewBar, SLOT(setVisible(bool))); - connect(&_previewBox, SIGNAL(toggled(bool)), &_glPreview , SLOT(setVisible(bool))); + connect(&_importDialog, SIGNAL(previewActivated(QString)), SLOT(preImport(QString))); + connect(&_importDialog, SIGNAL(currentChanged(QString)) , SLOT(preImport(QString))); } -int VoxelImporter::exec() { - _previewBox.setChecked(false); - _previewBar.setVisible(false); - _glPreview.setVisible(false); +void VoxelImporter::import(const QString &filename) { + _importDialog.reset(); + _filename = filename; + _currentTask = NULL; + _nextTask = NULL; - return exec(); -} + if (_filename == "") { + _importDialog.exec(); + } -void VoxelImporter::importVoxels() { - accept(); - qDebug("Congratulation, you imported a file.\n"); -} - -void VoxelImporter::importVoxelsToClipboard() { - accept(); - qDebug("Congratulation, you imported a file to the clipboard.\n"); - } -void VoxelImporter::preview(bool) { +void VoxelImporter::preImport(const QString &filename) { + if (_importDialog.getWantPreview() && QFileInfo(filename).isFile()) { + _filename = filename; + + _nextTask = new ImportTask(_voxelSystem, _filename); + connect(_nextTask, SIGNAL(destroyed()), SLOT(launchTask())); + + _importDialog.reset(); + + if (_currentTask != NULL) { + _voxelSystem->getVoxelTree()->cancelImport(); + } else { + launchTask(); + } + } +} + +void VoxelImporter::launchTask() { + if (_nextTask != NULL) { + _voxelSystem->killLocalVoxels(); + _currentTask = _nextTask; + _nextTask = NULL; + QThreadPool::globalInstance()->start(_currentTask); + } else { + _currentTask = NULL; + } +} + +ImportTask::ImportTask(VoxelSystem* voxelSystem, const QString &filename) + : _voxelSystem(voxelSystem), + _filename(filename) { } + +void ImportTask::run() { + if (_filename.endsWith(".png", Qt::CaseInsensitive)) { + _voxelSystem->readFromSquareARGB32Pixels(_filename.toLocal8Bit().data()); + } else if (_filename.endsWith(".svo", Qt::CaseInsensitive)) { + _voxelSystem->readFromSVOFile(_filename.toLocal8Bit().data()); + } else if (_filename.endsWith(".schematic", Qt::CaseInsensitive)) { + qDebug("[DEBUG] %d.\n", + _voxelSystem->readFromSchematicFile(_filename.toLocal8Bit().data())); + } else { + qDebug("[ERROR] Invalid file extension.\n"); + } +} diff --git a/interface/src/VoxelImporter.h b/interface/src/VoxelImporter.h index a664788a82..1e8f1a14ae 100644 --- a/interface/src/VoxelImporter.h +++ b/interface/src/VoxelImporter.h @@ -9,29 +9,45 @@ #ifndef __hifi__VoxelImporter__ #define __hifi__VoxelImporter__ -#include -#include -#include -#include -#include +#include +#include -class VoxelImporter : public QFileDialog { +#include +#include + +class ImportTask : public QObject, public QRunnable { + Q_OBJECT +public: + ImportTask(VoxelSystem* voxelSystem, const QString &filename); + void run(); + +private: + VoxelSystem* _voxelSystem; + QString _filename; +}; + +class VoxelImporter : public QObject { Q_OBJECT public: VoxelImporter(QWidget* parent = NULL); + void init(); + public slots: - int exec(); - void importVoxels(); - void importVoxelsToClipboard(); - void preview(bool); + void import(const QString &filename = ""); + void preImport(const QString &filename); + +private slots: + void launchTask(); private: - QPushButton _importButton; - QPushButton _clipboardImportButton; - QCheckBox _previewBox; - QProgressBar _previewBar; - QGLWidget _glPreview; + VoxelSystem* _voxelSystem; + ImportDialog _importDialog; + + QString _filename; + + ImportTask* _currentTask; + ImportTask* _nextTask; }; #endif /* defined(__hifi__VoxelImporter__) */ diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index becf9f868f..5509ca3a72 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -139,6 +139,22 @@ bool VoxelSystem::readFromSVOFile(const char* filename) { return result; } +bool VoxelSystem::readFromSquareARGB32Pixels(const char *filename) { + bool result = _tree->readFromSquareARGB32Pixels(filename); + if (result) { + setupNewVoxelsForDrawing(); + } + return result; +} + +bool VoxelSystem::readFromSchematicFile(const char* filename) { + bool result = _tree->readFromSchematicFile(filename); + if (result) { + setupNewVoxelsForDrawing(); + } + return result; +} + long int VoxelSystem::getVoxelsCreated() { return _tree->voxelsCreated; } diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 94e2d42e5e..56c22dc02c 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -42,12 +42,16 @@ public: void simulate(float deltaTime) { }; void render(bool texture); - unsigned long getVoxelsUpdated() const {return _voxelsUpdated;}; + + VoxelTree* getVoxelTree () const {return _tree;} + unsigned long getVoxelsUpdated () const {return _voxelsUpdated;}; unsigned long getVoxelsRendered() const {return _voxelsInReadArrays;}; void loadVoxelsFile(const char* fileName,bool wantColorRandomizer); void writeToSVOFile(const char* filename, VoxelNode* node) const; bool readFromSVOFile(const char* filename); + bool readFromSquareARGB32Pixels(const char* filename); + bool readFromSchematicFile(const char* filename); long int getVoxelsCreated(); long int getVoxelsColored(); diff --git a/libraries/voxels/src/Tags.cpp b/libraries/voxels/src/Tags.cpp index 7df6f227ad..914606ce07 100644 --- a/libraries/voxels/src/Tags.cpp +++ b/libraries/voxels/src/Tags.cpp @@ -159,14 +159,19 @@ int retrieveData(std::string filename, std::stringstream &ss) { int type = file.peek(); if (type == 0x0A) { + std::cerr << "[DEBUG] Unzipped\n"; ss.flush(); ss << file; return 0; } + if (type == 0x1F) { - return ungzip(file, ss); + std::cerr << "[DEBUG] Zipped\n"; + int ret = ungzip(file, ss); + return ret; } + std::cerr << "[DEBUG] Neither\n"; return 1; } @@ -242,3 +247,156 @@ int ungzip(std::ifstream &file, std::stringstream &ss) { } +void computeBlockColor(int id, int data, int& red, int& green, int& blue, int& create) { + + switch (id) { + case 1: + case 14: + case 15: + case 16: + case 21: + case 56: + case 73: + case 74: + case 97: + case 129: red = 128; green = 128; blue = 128; break; + case 2: red = 77; green = 117; blue = 66; break; + case 3: + case 60: red = 116; green = 83; blue = 56; break; + case 4: red = 71; green = 71; blue = 71; break; + case 5: + case 125: red = 133; green = 94; blue = 62; break; + case 7: red = 35; green = 35; blue = 35; break; + case 8: + case 9: red = 100; green = 109; blue = 185; break; + case 10: + case 11: red = 192; green = 64; blue = 8; break; + case 12: red = 209; green = 199; blue = 155; break; + case 13: red = 96; green = 94; blue = 93; break; + case 17: red = 71; green = 56; blue = 35; break; + case 18: red = 76; green = 104; blue = 64; break; + case 19: red = 119; green = 119; blue = 37; break; + case 22: red = 22; green = 44; blue = 86; break; + case 23: + case 29: + case 33: + case 61: + case 62: + case 158: red = 61; green = 61; blue = 61; break; + case 24: red = 209; green = 202; blue = 156; break; + case 25: + case 58: + case 84: + case 137: red = 57; green = 38; blue = 25; break; + case 35: + switch (data) { + case 0: red = 234; green = 234; blue = 234; break; + case 1: red = 224; green = 140; blue = 84; break; + case 2: red = 185; green = 90; blue = 194; break; + case 3: red = 124; green = 152; blue = 208; break; + case 4: red = 165; green = 154; blue = 35; break; + case 5: red = 70; green = 187; blue = 61; break; + case 6: red = 206; green = 124; blue = 145; break; + case 7: red = 66; green = 66; blue = 66; break; + case 8: red = 170; green = 176; blue = 176; break; + case 9: red = 45; green = 108; blue = 35; break; + case 10: red = 130; green = 62; blue = 8; break; + case 11: red = 43; green = 51; blue = 29; break; + case 12: red = 73; green = 47; blue = 29; break; + case 13: red = 57; green = 76; blue = 36; break; + case 14: red = 165; green = 58; blue = 53; break; + case 15: red = 24; green = 24; blue = 24; break; + default: + create = 0; + break; + } + break; + case 41: red = 239; green = 238; blue = 105; break; + case 42: red = 146; green = 146; blue = 146; break; + case 43: + case 98: red = 161; green = 161; blue = 161; break; + case 44: + create = 3; + + switch (data) { + case 0: red = 161; green = 161; blue = 161; break; + case 1: red = 209; green = 202; blue = 156; break; + case 2: red = 133; green = 94; blue = 62; break; + case 3: red = 71; green = 71; blue = 71; break; + case 4: red = 121; green = 67; blue = 53; break; + case 5: red = 161; green = 161; blue = 161; break; + case 6: red = 45; green = 22; blue = 26; break; + case 7: red = 195; green = 192; blue = 185; break; + default: + create = 0; + break; + } + break; + case 45: red = 121; green = 67; blue = 53; break; + case 46: red = 118; green = 36; blue = 13; break; + case 47: red = 155; green = 127; blue = 76; break; + case 48: red = 61; green = 79; blue = 61; break; + case 49: red = 52; green = 41; blue = 74; break; + case 52: red = 12; green = 66; blue = 71; break; + case 53: + case 67: + case 108: + case 109: + case 114: + case 128: + case 134: + case 135: + case 136: + case 156: + create = 2; + + switch (id) { + case 53: + case 134: + case 135: + case 136: red = 133; green = 94; blue = 62; break; + case 67: red = 71; green = 71; blue = 71; break; + case 108: red = 121; green = 67; blue = 53; break; + case 109: red = 161; green = 161; blue = 161; break; + case 114: red = 45; green = 22; blue = 26; break; + case 128: red = 209; green = 202; blue = 156; break; + case 156: red = 195; green = 192; blue = 185; break; + default: + create = 0; + break; + } + break; + case 54: + case 95: + case 146: red = 155; green = 105; blue = 32; break; + case 57: red = 145; green = 219; blue = 215; break; + case 79: red = 142; green = 162; blue = 195; break; + case 80: red = 255; green = 255; blue = 255; break; + case 81: red = 8; green = 64; blue = 15; break; + case 82: red = 150; green = 155; blue = 166; break; + case 86: + case 91: red = 179; green = 108; blue = 17; break; + case 87: + case 153: red = 91; green = 31; blue = 30; break; + case 88: red = 68; green = 49; blue = 38; break; + case 89: red = 180; green = 134; blue = 65; break; + case 103: red = 141; green = 143; blue = 36; break; + case 110: red = 103; green = 92; blue = 95; break; + case 112: red = 45; green = 22; blue = 26; break; + case 121: red = 183; green = 178; blue = 129; break; + case 123: red = 101; green = 59; blue = 31; break; + case 124: red = 213; green = 178; blue = 123; break; + case 130: red = 38; green = 54; blue = 56; break; + case 133: red = 53; green = 84; blue = 85; break; + case 152: red = 131; green = 22; blue = 7; break; + case 155: red = 195; green = 192; blue = 185; break; + case 159: red = 195; green = 165; blue = 150; break; + case 170: red = 168; green = 139; blue = 15; break; + case 172: red = 140; green = 86; blue = 61; break; + case 173: red = 9; green = 9; blue = 9; break; + default: + create = 0; + break; + } +} + diff --git a/libraries/voxels/src/Tags.h b/libraries/voxels/src/Tags.h index a005095142..9888190b14 100644 --- a/libraries/voxels/src/Tags.h +++ b/libraries/voxels/src/Tags.h @@ -29,8 +29,9 @@ #define TAG_Compound 10 #define TAG_Int_Array 11 -int retrieveData(std::string filename, std::stringstream &ss); -int ungzip(std::ifstream &file, std::stringstream &ss); +int retrieveData(std::string filename, std::stringstream &ss); +int ungzip(std::ifstream &file, std::stringstream &ss); +void computeBlockColor(int id, int data, int& r, int& g, int& b, int& create); class Tag { public: diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index c0fcee02dd..146e013cf6 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -18,6 +18,7 @@ #include #include +#include #include "CoverageMap.h" #include "GeometryUtil.h" @@ -48,7 +49,8 @@ VoxelTree::VoxelTree(bool shouldReaverage) : voxelsColoredStats(100), voxelsBytesReadStats(100), _isDirty(true), - _shouldReaverage(shouldReaverage) { + _shouldReaverage(shouldReaverage), + _stopImport(false) { rootNode = new VoxelNode(); } @@ -1576,15 +1578,29 @@ bool VoxelTree::readFromSVOFile(const char* fileName) { return false; } -bool VoxelTree::readFromSquareARGB32Pixels(const uint32_t* pixels, int dimension) { - SquarePixelMap pixelMap = SquarePixelMap(pixels, dimension); +bool VoxelTree::readFromSquareARGB32Pixels(const char* filename) { + QImage pngImage = QImage(filename); + if (pngImage.height() != pngImage.width()) { + qDebug("ERROR: Bad PNG size: height != width.\n"); + return false; + } + + const uint32_t* pixels; + if (pngImage.format() == QImage::Format_ARGB32) { + pixels = reinterpret_cast(pngImage.constBits()); + } else { + QImage tmp = pngImage.convertToFormat(QImage::Format_ARGB32); + pixels = reinterpret_cast(tmp.constBits()); + } + + SquarePixelMap pixelMap = SquarePixelMap(pixels, pngImage.height()); pixelMap.addVoxelsToVoxelTree(this); return true; } bool VoxelTree::readFromSchematicFile(const char *fileName) { std::stringstream ss; - int err = retrieveData(fileName, ss); + int err = retrieveData(std::string(fileName), ss); if (err && ss.get() != TAG_Compound) { qDebug("[ERROR] Invalid schematic file.\n"); return false; @@ -1593,10 +1609,12 @@ bool VoxelTree::readFromSchematicFile(const char *fileName) { ss.get(); TagCompound schematics(ss); if (!schematics.getBlocksId() || !schematics.getBlocksData()) { - qDebug("[ERROR] Invalid schematic file.\n"); + qDebug("[ERROR] Invalid schematic data.\n"); return false; } + _stopImport = false; + int max = (schematics.getWidth() > schematics.getLength()) ? schematics.getWidth() : schematics.getLength(); max = (max > schematics.getHeight()) ? max : schematics.getHeight(); @@ -1608,9 +1626,21 @@ bool VoxelTree::readFromSchematicFile(const char *fileName) { int red = 128, green = 128, blue = 128; int count = 0; + emit importSize(size * schematics.getWidth(), + size * schematics.getHeight(), + size * schematics.getLength()); + for (int y = 0; y < schematics.getHeight(); ++y) { for (int z = 0; z < schematics.getLength(); ++z) { + emit importProgress((int) 100 * (y * schematics.getLength() + z) / (schematics.getHeight() * schematics.getLength())); + for (int x = 0; x < schematics.getWidth(); ++x) { + if (_stopImport) { + qDebug("[DEBUG] Canceled import at %d voxels.\n", count); + _stopImport = false; + return true; + } + int pos = ((y * schematics.getLength()) + z) * schematics.getWidth() + x; int id = schematics.getBlocksId()[pos]; int data = schematics.getBlocksData()[pos]; @@ -1656,6 +1686,7 @@ bool VoxelTree::readFromSchematicFile(const char *fileName) { } } + emit importProgress(100); qDebug("Created %d voxels from minecraft import.\n", count); return true; @@ -1747,155 +1778,6 @@ void VoxelTree::copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* destin } } -void VoxelTree::computeBlockColor(int id, int data, int& red, int& green, int& blue, int& create) { - - switch (id) { - case 1: - case 14: - case 15: - case 16: - case 21: - case 56: - case 73: - case 74: - case 97: - case 129: red = 128; green = 128; blue = 128; break; - case 2: red = 77; green = 117; blue = 66; break; - case 3: - case 60: red = 116; green = 83; blue = 56; break; - case 4: red = 71; green = 71; blue = 71; break; - case 5: - case 125: red = 133; green = 94; blue = 62; break; - case 7: red = 35; green = 35; blue = 35; break; - case 8: - case 9: red = 100; green = 109; blue = 185; break; - case 10: - case 11: red = 192; green = 64; blue = 8; break; - case 12: red = 209; green = 199; blue = 155; break; - case 13: red = 96; green = 94; blue = 93; break; - case 17: red = 71; green = 56; blue = 35; break; - case 18: red = 76; green = 104; blue = 64; break; - case 19: red = 119; green = 119; blue = 37; break; - case 22: red = 22; green = 44; blue = 86; break; - case 23: - case 29: - case 33: - case 61: - case 62: - case 158: red = 61; green = 61; blue = 61; break; - case 24: red = 209; green = 202; blue = 156; break; - case 25: - case 58: - case 84: - case 137: red = 57; green = 38; blue = 25; break; - case 35: - switch (data) { - case 0: red = 234; green = 234; blue = 234; break; - case 1: red = 224; green = 140; blue = 84; break; - case 2: red = 185; green = 90; blue = 194; break; - case 3: red = 124; green = 152; blue = 208; break; - case 4: red = 165; green = 154; blue = 35; break; - case 5: red = 70; green = 187; blue = 61; break; - case 6: red = 206; green = 124; blue = 145; break; - case 7: red = 66; green = 66; blue = 66; break; - case 8: red = 170; green = 176; blue = 176; break; - case 9: red = 45; green = 108; blue = 35; break; - case 10: red = 130; green = 62; blue = 8; break; - case 11: red = 43; green = 51; blue = 29; break; - case 12: red = 73; green = 47; blue = 29; break; - case 13: red = 57; green = 76; blue = 36; break; - case 14: red = 165; green = 58; blue = 53; break; - case 15: red = 24; green = 24; blue = 24; break; - default: - create = 0; - break; - } - break; - case 41: red = 239; green = 238; blue = 105; break; - case 42: red = 146; green = 146; blue = 146; break; - case 43: - case 98: red = 161; green = 161; blue = 161; break; - case 44: - create = 3; - - switch (data) { - case 0: red = 161; green = 161; blue = 161; break; - case 1: red = 209; green = 202; blue = 156; break; - case 2: red = 133; green = 94; blue = 62; break; - case 3: red = 71; green = 71; blue = 71; break; - case 4: red = 121; green = 67; blue = 53; break; - case 5: red = 161; green = 161; blue = 161; break; - case 6: red = 45; green = 22; blue = 26; break; - case 7: red = 195; green = 192; blue = 185; break; - default: - create = 0; - break; - } - break; - case 45: red = 121; green = 67; blue = 53; break; - case 46: red = 118; green = 36; blue = 13; break; - case 47: red = 155; green = 127; blue = 76; break; - case 48: red = 61; green = 79; blue = 61; break; - case 49: red = 52; green = 41; blue = 74; break; - case 52: red = 12; green = 66; blue = 71; break; - case 53: - case 67: - case 108: - case 109: - case 114: - case 128: - case 134: - case 135: - case 136: - case 156: - create = 2; - - switch (id) { - case 53: - case 134: - case 135: - case 136: red = 133; green = 94; blue = 62; break; - case 67: red = 71; green = 71; blue = 71; break; - case 108: red = 121; green = 67; blue = 53; break; - case 109: red = 161; green = 161; blue = 161; break; - case 114: red = 45; green = 22; blue = 26; break; - case 128: red = 209; green = 202; blue = 156; break; - case 156: red = 195; green = 192; blue = 185; break; - default: - create = 0; - break; - } - break; - case 54: - case 95: - case 146: red = 155; green = 105; blue = 32; break; - case 57: red = 145; green = 219; blue = 215; break; - case 79: red = 142; green = 162; blue = 195; break; - case 80: red = 255; green = 255; blue = 255; break; - case 81: red = 8; green = 64; blue = 15; break; - case 82: red = 150; green = 155; blue = 166; break; - case 86: - case 91: red = 179; green = 108; blue = 17; break; - case 87: - case 153: red = 91; green = 31; blue = 30; break; - case 88: red = 68; green = 49; blue = 38; break; - case 89: red = 180; green = 134; blue = 65; break; - case 103: red = 141; green = 143; blue = 36; break; - case 110: red = 103; green = 92; blue = 95; break; - case 112: red = 45; green = 22; blue = 26; break; - case 121: red = 183; green = 178; blue = 129; break; - case 123: red = 101; green = 59; blue = 31; break; - case 124: red = 213; green = 178; blue = 123; break; - case 130: red = 38; green = 54; blue = 56; break; - case 133: red = 53; green = 84; blue = 85; break; - case 152: red = 131; green = 22; blue = 7; break; - case 155: red = 195; green = 192; blue = 185; break; - case 159: red = 195; green = 165; blue = 150; break; - case 170: red = 168; green = 139; blue = 15; break; - case 172: red = 140; green = 86; blue = 61; break; - case 173: red = 9; green = 9; blue = 9; break; - default: - create = 0; - break; - } -} \ No newline at end of file +void VoxelTree::cancelImport() { + _stopImport = true; +} diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index f27543caa8..7bdfcc68af 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -19,6 +19,8 @@ #include "VoxelNodeBag.h" #include "VoxelSceneStats.h" +#include + // Callback function, for recuseTreeWithOperation typedef bool (*RecurseVoxelTreeOperation)(VoxelNode* node, void* extraData); typedef enum {GRADIENT, RANDOM, NATURAL} creationMode; @@ -112,7 +114,8 @@ public: {} }; -class VoxelTree { +class VoxelTree : public QObject { + Q_OBJECT public: // when a voxel is created in the tree (object new'd) long voxelsCreated; @@ -172,9 +175,8 @@ public: void writeToSVOFile(const char* filename, VoxelNode* node = NULL) const; bool readFromSVOFile(const char* filename); // reads voxels from square image with alpha as a Y-axis - bool readFromSquareARGB32Pixels(const uint32_t* pixels, int dimension); + bool readFromSquareARGB32Pixels(const char *filename); bool readFromSchematicFile(const char* filename); - void computeBlockColor(int id, int data, int& r, int& g, int& b, int& create); unsigned long getVoxelCount(); @@ -192,6 +194,13 @@ public: RecurseVoxelTreeOperation operation, const glm::vec3& point, void* extraData); +signals: + void importSize(float x, float y, float z); + void importProgress(int progress); // emit an int between 0 and 100 reflecting the progress of the import + +public slots: + void cancelImport(); + private: void deleteVoxelCodeFromTreeRecursion(VoxelNode* node, void* extraData); @@ -209,6 +218,7 @@ private: bool _isDirty; unsigned long int _nodesChangedFromBitstream; bool _shouldReaverage; + bool _stopImport; }; float boundaryDistanceForRenderLevel(unsigned int renderLevel); From 2eb29ee56bd43af5fff52e79a4ca0f65095a5add Mon Sep 17 00:00:00 2001 From: atlante45 Date: Fri, 16 Aug 2013 10:21:12 -0700 Subject: [PATCH 03/20] Added ImportDialog.* --- interface/src/ImportDialog.cpp | 192 +++++++++++++++++++++++++++++++++ interface/src/ImportDialog.h | 50 +++++++++ 2 files changed, 242 insertions(+) create mode 100644 interface/src/ImportDialog.cpp create mode 100644 interface/src/ImportDialog.h diff --git a/interface/src/ImportDialog.cpp b/interface/src/ImportDialog.cpp new file mode 100644 index 0000000000..49bdef0b81 --- /dev/null +++ b/interface/src/ImportDialog.cpp @@ -0,0 +1,192 @@ +// +// ImportDialog.cpp +// hifi +// +// Created by Clement Brisset on 8/12/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// +#include "ImportDialog.h" + +#include +#include + +const QString WINDOW_NAME = QObject::tr("Import Voxels"); +const QString IMPORT_TO_CLIPBOARD_CHECKBOX_STRING = QObject::tr("Import into clipboard"); +const QString PREVIEW_CHECKBOX_STRING = QObject::tr("Load preview"); +const QString IMPORT_FILE_TYPES = QObject::tr("Sparse Voxel Octree Files, " + "Square PNG, " + "Schematic Files " + "(*.svo *.png *.schematic)"); + +const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); + +const glm::vec3 UP = glm::vec3(0, 1, 0); +const float ANGULAR_RATE = 0.02f; + +class GLWidget : public QGLWidget { +public: + GLWidget(QWidget* parent = NULL, VoxelSystem* voxelSystem = NULL); + void setDraw(bool draw) {_draw = draw;} + void setTargetCenter(glm::vec3 targetCenter) {_targetCenter = targetCenter;} + +protected: + virtual void initializeGL(); + virtual void resizeGL(int w, int h); + virtual void paintGL(); + +private: + VoxelSystem* _voxelSystem; + + bool _draw; + + float _a; + float _h; + glm::vec3 _targetCenter; +}; + +GLWidget::GLWidget(QWidget *parent, VoxelSystem *voxelSystem) + : QGLWidget(parent), + _voxelSystem(voxelSystem), + _draw(false), + _a(0.0f), + _h(0.0f), + _targetCenter(0.5f, 0.5f, 0.5f) { +} + +void GLWidget::initializeGL() { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glShadeModel (GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + + if(_voxelSystem) { + _voxelSystem->init(); + } + +} + +void GLWidget::resizeGL(int w, int h) { + glViewport(0, 0, w, h); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60, (float) w / h, 0.25f, 500); +} + +void GLWidget::paintGL() { + glEnable(GL_LINE_SMOOTH); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + _a += ANGULAR_RATE; + gluLookAt(_targetCenter.x + (glm::length(_targetCenter) + 0.5f) * cos((double) _a), + _targetCenter.y * 1.25f, + _targetCenter.z + (glm::length(_targetCenter) + 0.5f) * sin((double) _a), + _targetCenter.x, _targetCenter.y, _targetCenter.z, + UP.x, UP.y, UP.z); + + + if (_draw && _voxelSystem) { + glBegin(GL_LINES); + glColor3d(1, 1 ,1); + glVertex3d(0, 0, 0); + glVertex3d(1, 0, 0); + + glVertex3d(0, 0, 0); + glVertex3d(0, 1, 0); + + glVertex3d(0, 0, 0); + glVertex3d(0, 0, 1); + + + glColor3d(0.4f, 0.4f ,0.4f); + glVertex3d(2 * _targetCenter.x, 2 * _targetCenter.y,2 * _targetCenter.z); + glVertex3d(0 , 2 * _targetCenter.y, 2 * _targetCenter.z); + + glVertex3d(2 * _targetCenter.x, 2 * _targetCenter.y, 2 * _targetCenter.z); + glVertex3d(2 * _targetCenter.x, 0 , 2 * _targetCenter.z); + + glVertex3d(2 * _targetCenter.x, 2 * _targetCenter.y, 2 * _targetCenter.z); + glVertex3d(2 * _targetCenter.x, 2 * _targetCenter.y, 0 ); + glEnd(); + + _voxelSystem->render(false); + } +} + +ImportDialog::ImportDialog(QWidget *parent, VoxelSystem* voxelSystem) + : QFileDialog(parent, WINDOW_NAME, DESKTOP_LOCATION, IMPORT_FILE_TYPES), + _clipboardImportBox (IMPORT_TO_CLIPBOARD_CHECKBOX_STRING, this), + _previewBox (PREVIEW_CHECKBOX_STRING, this), + _previewBar (this), + _glPreview (new GLWidget(this, voxelSystem)) { + + setOption(QFileDialog::DontUseNativeDialog, true); + setFileMode(QFileDialog::ExistingFile); + setViewMode(QFileDialog::Detail); + + QGridLayout* gridLayout = (QGridLayout*) layout(); + gridLayout->addWidget(&_clipboardImportBox, 2, 3); + gridLayout->addWidget(&_previewBox , 3, 3); + gridLayout->addWidget(&_previewBar , 0, 3); + gridLayout->addWidget(_glPreview , 1, 3); + gridLayout->setColumnStretch(3, 1); + + _previewBar.setVisible(false); + _previewBar.setRange(0, 100); + _previewBar.setValue(0); + + connect(&_previewBox, SIGNAL(toggled(bool)), SLOT(preview(bool))); + connect(this, SIGNAL(currentChanged(QString)), SLOT(saveCurrentFile(QString))); + connect(&_glTimer, SIGNAL(timeout()), SLOT(timer())); + + connect(voxelSystem->getVoxelTree(), SIGNAL(importSize(float,float,float)), SLOT(setGLCamera(float, float, float))); + connect(voxelSystem->getVoxelTree(), SIGNAL(importProgress(int)), &_previewBar, SLOT(setValue(int))); +} + +int ImportDialog::exec() { + _previewBox.setChecked(false); + _previewBar.setVisible(false); + + int ret = QFileDialog::exec(); + + + ((GLWidget*) _glPreview)->setDraw(false); + _glTimer.stop(); + _glPreview->updateGL(); + + return ret; +} + +void ImportDialog::setGLCamera(float x, float y, float z) { + ((GLWidget*) _glPreview)->setTargetCenter(glm::vec3(x, y, z) / 2.0f); +} + +void ImportDialog::reset() { + _previewBar.setValue(0); +} + +void ImportDialog::preview(bool wantPreview) { + _previewBar.setValue(0); + _previewBar.setVisible(wantPreview); + ((GLWidget*) _glPreview)->setDraw(wantPreview); + + if (wantPreview) { + emit previewActivated(_currentFile); + _glTimer.start(); + } else { + _glTimer.stop(); + _glPreview->updateGL(); + } +} + +void ImportDialog::saveCurrentFile(QString filename) { + _currentFile = filename; +} + +void ImportDialog::timer() { + _glPreview->updateGL(); + _glTimer.start(16); +} diff --git a/interface/src/ImportDialog.h b/interface/src/ImportDialog.h new file mode 100644 index 0000000000..013a291af3 --- /dev/null +++ b/interface/src/ImportDialog.h @@ -0,0 +1,50 @@ +// +// ImportDialog.h +// hifi +// +// Created by Clement Brisset on 8/12/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#ifndef __hifi__ImportDialog__ +#define __hifi__ImportDialog__ + +#include + +#include +#include +#include +#include +#include +#include + +class ImportDialog : public QFileDialog { + Q_OBJECT +public: + ImportDialog(QWidget* parent = NULL, VoxelSystem* voxelSystem = NULL); + + bool getWantPreview() const { return _previewBox.isChecked(); } + void reset(); + +signals: + void previewActivated(QString); + +public slots: + int exec(); + void setGLCamera(float x, float y, float z); + +private slots: + void preview(bool preview); + void saveCurrentFile(QString); + void timer(); + +private: + QString _currentFile; + QCheckBox _clipboardImportBox; + QCheckBox _previewBox; + QProgressBar _previewBar; + QGLWidget* _glPreview; + QTimer _glTimer; +}; + +#endif /* defined(__hifi__ImportDialog__) */ From 24531fdd107a720236fa6b74cf3f53bb85f4cc0b Mon Sep 17 00:00:00 2001 From: atlante45 Date: Mon, 19 Aug 2013 15:54:51 -0700 Subject: [PATCH 04/20] Dialogbox for import fully functionnal --- interface/src/Application.cpp | 24 +++-- interface/src/Application.h | 2 +- interface/src/ImportDialog.cpp | 136 ++++++++++++++++++++++------- interface/src/ImportDialog.h | 15 +++- interface/src/Menu.cpp | 7 +- interface/src/VoxelImporter.cpp | 119 ++++++++++++++++++++----- interface/src/VoxelImporter.h | 23 +++-- interface/src/VoxelSystem.cpp | 7 ++ interface/src/VoxelSystem.h | 8 +- libraries/voxels/src/Tags.cpp | 4 +- libraries/voxels/src/VoxelTree.cpp | 14 +++ libraries/voxels/src/VoxelTree.h | 2 +- 12 files changed, 275 insertions(+), 86 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a9364a68d2..4d5e548f17 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1199,13 +1199,13 @@ void Application::importVoxelsToClipboard() { QByteArray fileNameAscii = fileNameString.toLocal8Bit(); const char* fileName = fileNameAscii.data(); - _clipboardTree.eraseAllVoxels(); + _clipboard.killLocalVoxels(); if (fileNameString.endsWith(".png", Qt::CaseInsensitive)) { - _clipboardTree.readFromSquareARGB32Pixels(fileName); + _clipboard.readFromSquareARGB32Pixels(fileName); } else if (fileNameString.endsWith(".svo", Qt::CaseInsensitive)) { - _clipboardTree.readFromSVOFile(fileName); + _clipboard.readFromSVOFile(fileName); } else if (fileNameString.endsWith(".schematic", Qt::CaseInsensitive)) { - _clipboardTree.readFromSchematicFile(fileName); + _clipboard.readFromSchematicFile(fileName); } // restore the main window's active state @@ -1213,6 +1213,16 @@ void Application::importVoxelsToClipboard() { } void Application::importVoxels() { + if (_voxelImporter.exec()) { + qDebug("[DEBUG] Import succedded.\n"); + + + } else { + qDebug("[DEBUG] Import failed.\n"); + } + + return; + QString desktopLocation = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); QStringList fileNameStringList = QFileDialog::getOpenFileNames(_glWidget, tr("Import Voxels"), desktopLocation, @@ -1369,10 +1379,10 @@ void Application::copyVoxels() { VoxelNode* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); if (selectedNode) { // clear the clipboard first... - _clipboardTree.eraseAllVoxels(); + _clipboard.killLocalVoxels(); // then copy onto it - _voxels.copySubTreeIntoNewTree(selectedNode, &_clipboardTree, true); + //_voxels.copySubTreeIntoNewTree(selectedNode, _clipboard, true); } } @@ -1393,7 +1403,7 @@ void Application::pasteVoxels() { args.newBaseOctCode = calculatedOctCode = pointToVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); } - _clipboardTree.recurseTreeWithOperation(sendVoxelsOperation, &args); + //_clipboard.recurseTreeWithOperation(sendVoxelsOperation, &args); _voxelEditSender.flushQueue(); if (calculatedOctCode) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 26dcb67733..748642a428 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -239,7 +239,7 @@ private: Stars _stars; VoxelSystem _voxels; - VoxelTree _clipboardTree; // if I copy/paste + VoxelSystem _clipboard; // if I copy/paste VoxelImporter _voxelImporter; QByteArray _voxelsFilename; diff --git a/interface/src/ImportDialog.cpp b/interface/src/ImportDialog.cpp index 49bdef0b81..57b37ca443 100644 --- a/interface/src/ImportDialog.cpp +++ b/interface/src/ImportDialog.cpp @@ -9,8 +9,10 @@ #include #include +#include const QString WINDOW_NAME = QObject::tr("Import Voxels"); +const QString IMPORT_BUTTON_NAME = QObject::tr("Import"); const QString IMPORT_TO_CLIPBOARD_CHECKBOX_STRING = QObject::tr("Import into clipboard"); const QString PREVIEW_CHECKBOX_STRING = QObject::tr("Load preview"); const QString IMPORT_FILE_TYPES = QObject::tr("Sparse Voxel Octree Files, " @@ -20,8 +22,14 @@ const QString IMPORT_FILE_TYPES = QObject::tr("Sparse Voxel Oc const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); + const glm::vec3 UP = glm::vec3(0, 1, 0); const float ANGULAR_RATE = 0.02f; +const float VERTICAL_ANGLE = M_PI_4 / 2.0f; +const float RETURN_RATE = 0.02f; +const float NEAR_CLIP = 0.5f; +const float FAR_CLIP = 10.0f; +const float FIELD_OF_VIEW = 60.0f; class GLWidget : public QGLWidget { public: @@ -31,17 +39,25 @@ public: protected: virtual void initializeGL(); - virtual void resizeGL(int w, int h); + virtual void resizeGL(int width, int height); virtual void paintGL(); + void mousePressEvent(QMouseEvent* event); + void mouseMoveEvent(QMouseEvent* event); + void mouseReleaseEvent(QMouseEvent* event); + private: VoxelSystem* _voxelSystem; bool _draw; - float _a; - float _h; + double _a; // horizontal angle of the camera to the center of the object + double _h; // vertical angle of the camera to the center of the object glm::vec3 _targetCenter; + + bool _pressed; + int _mouseX; + int _mouseY; }; GLWidget::GLWidget(QWidget *parent, VoxelSystem *voxelSystem) @@ -49,8 +65,11 @@ GLWidget::GLWidget(QWidget *parent, VoxelSystem *voxelSystem) _voxelSystem(voxelSystem), _draw(false), _a(0.0f), - _h(0.0f), - _targetCenter(0.5f, 0.5f, 0.5f) { + _h(VERTICAL_ANGLE), + _targetCenter(0.5f, 0.5f, 0.5f), + _pressed(false), + _mouseX(0), + _mouseY(0) { } void GLWidget::initializeGL() { @@ -65,12 +84,15 @@ void GLWidget::initializeGL() { } -void GLWidget::resizeGL(int w, int h) { - glViewport(0, 0, w, h); +void GLWidget::resizeGL(int width, int height) { + glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); - gluPerspective(60, (float) w / h, 0.25f, 500); + gluPerspective(FIELD_OF_VIEW, + (float) width / height, + NEAR_CLIP, + FAR_CLIP); } void GLWidget::paintGL() { @@ -80,10 +102,14 @@ void GLWidget::paintGL() { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - _a += ANGULAR_RATE; - gluLookAt(_targetCenter.x + (glm::length(_targetCenter) + 0.5f) * cos((double) _a), - _targetCenter.y * 1.25f, - _targetCenter.z + (glm::length(_targetCenter) + 0.5f) * sin((double) _a), + if (!_pressed) { + _a += ANGULAR_RATE; + _h = (1.0f - RETURN_RATE) * _h + RETURN_RATE * VERTICAL_ANGLE; + } + + gluLookAt(_targetCenter.x + (glm::length(_targetCenter) + NEAR_CLIP) * cos(_a), + _targetCenter.y + (glm::length(_targetCenter) + NEAR_CLIP) * sin(_h), + _targetCenter.z + (glm::length(_targetCenter) + NEAR_CLIP) * sin(_a), _targetCenter.x, _targetCenter.y, _targetCenter.z, UP.x, UP.y, UP.z); @@ -102,7 +128,7 @@ void GLWidget::paintGL() { glColor3d(0.4f, 0.4f ,0.4f); - glVertex3d(2 * _targetCenter.x, 2 * _targetCenter.y,2 * _targetCenter.z); + glVertex3d(2 * _targetCenter.x, 2 * _targetCenter.y, 2 * _targetCenter.z); glVertex3d(0 , 2 * _targetCenter.y, 2 * _targetCenter.z); glVertex3d(2 * _targetCenter.x, 2 * _targetCenter.y, 2 * _targetCenter.z); @@ -116,18 +142,40 @@ void GLWidget::paintGL() { } } + +void GLWidget::mousePressEvent(QMouseEvent* event) { + _pressed = true; + _mouseX = event->globalX(); + _mouseY = event->globalY(); +} + +void GLWidget::mouseMoveEvent(QMouseEvent* event) { + _a += (M_PI * (event->globalX() - _mouseX)) / height(); + _h += (M_PI * (event->globalY() - _mouseY)) / height(); + _h = glm::clamp(_h, -M_PI_4, M_PI_4); + + _mouseX = event->globalX(); + _mouseY = event->globalY(); +} + +void GLWidget::mouseReleaseEvent(QMouseEvent* event) { + _pressed = false; +} + ImportDialog::ImportDialog(QWidget *parent, VoxelSystem* voxelSystem) : QFileDialog(parent, WINDOW_NAME, DESKTOP_LOCATION, IMPORT_FILE_TYPES), - _clipboardImportBox (IMPORT_TO_CLIPBOARD_CHECKBOX_STRING, this), - _previewBox (PREVIEW_CHECKBOX_STRING, this), - _previewBar (this), - _glPreview (new GLWidget(this, voxelSystem)) { + _importButton (IMPORT_BUTTON_NAME, this), + _clipboardImportBox(IMPORT_TO_CLIPBOARD_CHECKBOX_STRING, this), + _previewBox (PREVIEW_CHECKBOX_STRING, this), + _previewBar (this), + _glPreview (new GLWidget(this, voxelSystem)) { setOption(QFileDialog::DontUseNativeDialog, true); setFileMode(QFileDialog::ExistingFile); setViewMode(QFileDialog::Detail); QGridLayout* gridLayout = (QGridLayout*) layout(); + gridLayout->addWidget(&_importButton , 2, 2); gridLayout->addWidget(&_clipboardImportBox, 2, 3); gridLayout->addWidget(&_previewBox , 3, 3); gridLayout->addWidget(&_previewBar , 0, 3); @@ -138,43 +186,71 @@ ImportDialog::ImportDialog(QWidget *parent, VoxelSystem* voxelSystem) _previewBar.setRange(0, 100); _previewBar.setValue(0); + connect(&_importButton, SIGNAL(pressed()), SLOT(import())); + connect(&_previewBox, SIGNAL(toggled(bool)), SIGNAL(previewToggled(bool))); connect(&_previewBox, SIGNAL(toggled(bool)), SLOT(preview(bool))); + connect(this, SIGNAL(currentChanged(QString)), SLOT(saveCurrentFile(QString))); connect(&_glTimer, SIGNAL(timeout()), SLOT(timer())); - connect(voxelSystem->getVoxelTree(), SIGNAL(importSize(float,float,float)), SLOT(setGLCamera(float, float, float))); - connect(voxelSystem->getVoxelTree(), SIGNAL(importProgress(int)), &_previewBar, SLOT(setValue(int))); + connect(voxelSystem, SIGNAL(importSize(float,float,float)), SLOT(setGLCamera(float, float, float))); + connect(voxelSystem, SIGNAL(importProgress(int)), &_previewBar, SLOT(setValue(int))); +} + +ImportDialog::~ImportDialog() { + delete _glPreview; +} + +void ImportDialog::import() { + _importButton.setDisabled(true); + _clipboardImportBox.setDisabled(true); + _previewBox.setDisabled(true); + + _previewBar.setValue(0); + _previewBar.setVisible(true); + + emit accepted(); +} + +void ImportDialog::accept() { + QFileDialog::accept(); +} + +void ImportDialog::reject() { + QFileDialog::reject(); } int ImportDialog::exec() { - _previewBox.setChecked(false); - _previewBar.setVisible(false); - + reset(); int ret = QFileDialog::exec(); - - - ((GLWidget*) _glPreview)->setDraw(false); - _glTimer.stop(); - _glPreview->updateGL(); + preview(false); return ret; } void ImportDialog::setGLCamera(float x, float y, float z) { - ((GLWidget*) _glPreview)->setTargetCenter(glm::vec3(x, y, z) / 2.0f); + _glPreview->setTargetCenter(glm::vec3(x, y, z) / 2.0f); } void ImportDialog::reset() { + _previewBox.setChecked(false); + _previewBar.setVisible(false); _previewBar.setValue(0); + _importButton.setEnabled(true); + _clipboardImportBox.setEnabled(true); + _previewBox.setEnabled(true); + + _glTimer.stop(); + _glPreview->setDraw(false); + _glPreview->updateGL(); } void ImportDialog::preview(bool wantPreview) { _previewBar.setValue(0); _previewBar.setVisible(wantPreview); - ((GLWidget*) _glPreview)->setDraw(wantPreview); + _glPreview->setDraw(wantPreview); if (wantPreview) { - emit previewActivated(_currentFile); _glTimer.start(); } else { _glTimer.stop(); diff --git a/interface/src/ImportDialog.h b/interface/src/ImportDialog.h index 013a291af3..f3c1934760 100644 --- a/interface/src/ImportDialog.h +++ b/interface/src/ImportDialog.h @@ -18,20 +18,30 @@ #include #include +class GLWidget; + class ImportDialog : public QFileDialog { Q_OBJECT public: ImportDialog(QWidget* parent = NULL, VoxelSystem* voxelSystem = NULL); + ~ImportDialog(); bool getWantPreview() const { return _previewBox.isChecked(); } + QString getCurrentFile() const { return _currentFile; } + bool getImportIntoClipboard() const { return _clipboardImportBox.isChecked(); } + void reset(); signals: - void previewActivated(QString); + void previewToggled(bool); + void accepted(); public slots: int exec(); void setGLCamera(float x, float y, float z); + void import(); + void accept(); + void reject(); private slots: void preview(bool preview); @@ -40,10 +50,11 @@ private slots: private: QString _currentFile; + QPushButton _importButton; QCheckBox _clipboardImportBox; QCheckBox _previewBox; QProgressBar _previewBar; - QGLWidget* _glPreview; + GLWidget* _glPreview; QTimer _glTimer; }; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index ee4cd36b16..181b109bfd 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -233,11 +233,6 @@ Menu::Menu() : addActionToQMenuAndActionHash(voxelMenu, MenuOption::ExportVoxels, Qt::CTRL | Qt::Key_E, appInstance, SLOT(exportVoxels())); addActionToQMenuAndActionHash(voxelMenu, MenuOption::ImportVoxels, Qt::CTRL | Qt::Key_I, appInstance, SLOT(importVoxels())); - addActionToQMenuAndActionHash(voxelMenu, - MenuOption::ImportVoxelsClipboard, - Qt::SHIFT | Qt::CTRL | Qt::Key_I, - appInstance, - SLOT(importVoxelsToClipboard())); addActionToQMenuAndActionHash(voxelMenu, MenuOption::CutVoxels, Qt::CTRL | Qt::Key_X, appInstance, SLOT(cutVoxels())); addActionToQMenuAndActionHash(voxelMenu, MenuOption::CopyVoxels, Qt::CTRL | Qt::Key_C, appInstance, SLOT(copyVoxels())); addActionToQMenuAndActionHash(voxelMenu, MenuOption::PasteVoxels, Qt::CTRL | Qt::Key_V, appInstance, SLOT(pasteVoxels())); @@ -776,4 +771,4 @@ void Menu::updateFrustumRenderModeAction() { frustumRenderModeAction->setText("Render Mode - Keyhole"); break; } -} \ No newline at end of file +} diff --git a/interface/src/VoxelImporter.cpp b/interface/src/VoxelImporter.cpp index 488dd4b907..4dbabe129f 100644 --- a/interface/src/VoxelImporter.cpp +++ b/interface/src/VoxelImporter.cpp @@ -11,11 +11,21 @@ #include #include +class ImportTask : public QObject, public QRunnable { +public: + ImportTask(VoxelSystem* voxelSystem, const QString &filename); + void run(); + +private: + VoxelSystem* _voxelSystem; + QString _filename; +}; + class LocalVoxelSystem : public VoxelSystem { public: - LocalVoxelSystem() : VoxelSystem(1) {}; + LocalVoxelSystem() : VoxelSystem(1, 2000000) {} - virtual void removeOutOfView() {}; + virtual void removeOutOfView() {} }; VoxelImporter::VoxelImporter(QWidget* parent) @@ -25,38 +35,107 @@ VoxelImporter::VoxelImporter(QWidget* parent) _currentTask(NULL), _nextTask(NULL) { - connect(&_importDialog, SIGNAL(previewActivated(QString)), SLOT(preImport(QString))); - connect(&_importDialog, SIGNAL(currentChanged(QString)) , SLOT(preImport(QString))); + connect(&_importDialog, SIGNAL(previewToggled(bool)), SLOT(preImport())); + connect(&_importDialog, SIGNAL(currentChanged(QString)), SLOT(preImport())); + connect(&_importDialog, SIGNAL(accepted()), SLOT(import())); } -void VoxelImporter::import(const QString &filename) { - _importDialog.reset(); - _filename = filename; - _currentTask = NULL; - _nextTask = NULL; - - if (_filename == "") { - _importDialog.exec(); +VoxelImporter::~VoxelImporter() { + if (_nextTask) { + delete _nextTask; + _nextTask = NULL; } - + if (_currentTask) { + disconnect(_currentTask, 0, 0, 0); + connect(_currentTask, SIGNAL(destroyed()), _voxelSystem, SLOT(deleteLater())); + _voxelSystem->cancelImport(); + _currentTask = NULL; + } else { + delete _voxelSystem; + } } -void VoxelImporter::preImport(const QString &filename) { - if (_importDialog.getWantPreview() && QFileInfo(filename).isFile()) { +void VoxelImporter::reset() { + _voxelSystem->killLocalVoxels(); + _importDialog.reset(); + _filename = ""; + _currentTask = NULL; + _nextTask = NULL; +} + +int VoxelImporter::exec() { + reset(); + + int ret = _importDialog.exec(); + + if (!ret) { + if (_nextTask) { + delete _nextTask; + _nextTask = NULL; + } + + if (_currentTask) { + _voxelSystem->cancelImport(); + } + } + + return ret; +} + +int VoxelImporter::preImport() { + QString filename = _importDialog.getCurrentFile(); + + if (!QFileInfo(filename).isFile()) { + return 0; + } + + if (_importDialog.getWantPreview()) { _filename = filename; _nextTask = new ImportTask(_voxelSystem, _filename); connect(_nextTask, SIGNAL(destroyed()), SLOT(launchTask())); - _importDialog.reset(); - if (_currentTask != NULL) { - _voxelSystem->getVoxelTree()->cancelImport(); + _voxelSystem->cancelImport(); } else { launchTask(); } } + + return 1; +} + +int VoxelImporter::import() { + QString filename = _importDialog.getCurrentFile(); + + if (!QFileInfo(filename).isFile()) { + _importDialog.reject(); + return 0; + } + + if (_filename == filename) { + if (_currentTask) { + connect(_currentTask, SIGNAL(destroyed()), &_importDialog, SLOT(accept())); + } else { + _importDialog.accept(); + } + return 1; + } + + _filename = filename; + + _nextTask = new ImportTask(_voxelSystem, _filename); + connect(_nextTask, SIGNAL(destroyed()), SLOT(launchTask())); + connect(_nextTask, SIGNAL(destroyed()), &_importDialog, SLOT(accept())); + + if (_currentTask != NULL) { + _voxelSystem->cancelImport(); + } else { + launchTask(); + } + + return 1; } void VoxelImporter::launchTask() { @@ -73,7 +152,6 @@ void VoxelImporter::launchTask() { ImportTask::ImportTask(VoxelSystem* voxelSystem, const QString &filename) : _voxelSystem(voxelSystem), _filename(filename) { - } void ImportTask::run() { @@ -82,8 +160,7 @@ void ImportTask::run() { } else if (_filename.endsWith(".svo", Qt::CaseInsensitive)) { _voxelSystem->readFromSVOFile(_filename.toLocal8Bit().data()); } else if (_filename.endsWith(".schematic", Qt::CaseInsensitive)) { - qDebug("[DEBUG] %d.\n", - _voxelSystem->readFromSchematicFile(_filename.toLocal8Bit().data())); + _voxelSystem->readFromSchematicFile(_filename.toLocal8Bit().data()); } else { qDebug("[ERROR] Invalid file extension.\n"); } diff --git a/interface/src/VoxelImporter.h b/interface/src/VoxelImporter.h index 1e8f1a14ae..be39123367 100644 --- a/interface/src/VoxelImporter.h +++ b/interface/src/VoxelImporter.h @@ -15,33 +15,30 @@ #include #include -class ImportTask : public QObject, public QRunnable { - Q_OBJECT -public: - ImportTask(VoxelSystem* voxelSystem, const QString &filename); - void run(); - -private: - VoxelSystem* _voxelSystem; - QString _filename; -}; +class ImportTask; +class LocalVoxelSystem; class VoxelImporter : public QObject { Q_OBJECT public: VoxelImporter(QWidget* parent = NULL); + ~VoxelImporter(); + void reset(); - void init(); + VoxelSystem* getVoxelSystem() const { return _voxelSystem; } + bool getimportIntoClipboard() const { return _importDialog.getImportIntoClipboard(); } public slots: - void import(const QString &filename = ""); - void preImport(const QString &filename); + int exec(); + int preImport(); + int import(); private slots: void launchTask(); private: VoxelSystem* _voxelSystem; + ImportDialog _importDialog; QString _filename; diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 843d02790a..c1e7f3f06e 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -65,6 +65,9 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) : _falseColorizeBySource = false; _dataSourceID = UNKNOWN_NODE_ID; _voxelServerCount = 0; + + connect(_tree, SIGNAL(importSize(float,float,float)), SIGNAL(importSize(float,float,float))); + connect(_tree, SIGNAL(importProgress(int)), SIGNAL(importProgress(int))); } void VoxelSystem::nodeDeleted(VoxelNode* node) { @@ -994,6 +997,10 @@ public: { } }; +void VoxelSystem::cancelImport() { + _tree->cancelImport(); +} + // "Remove" voxels from the tree that are not in view. We don't actually delete them, // we remove them from the tree and place them into a holding area for later deletion bool VoxelSystem::removeOutOfViewOperation(VoxelNode* node, void* extraData) { diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index f45398a96b..aef1bedd6a 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -43,8 +43,6 @@ public: void simulate(float deltaTime) { }; void render(bool texture); - - VoxelTree* getVoxelTree () const {return _tree;} unsigned long getVoxelsUpdated () const {return _voxelsUpdated;}; unsigned long getVoxelsRendered() const {return _voxelsInReadArrays;}; @@ -91,6 +89,10 @@ public: virtual void nodeAdded(Node* node); virtual void nodeKilled(Node* node); +signals: + void importSize(float x, float y, float z); + void importProgress(int progress); + public slots: void collectStatsForTreesAndVBOs(); @@ -104,6 +106,8 @@ public slots: void falseColorizeOccluded(); void falseColorizeOccludedV2(); void falseColorizeBySource(); + + void cancelImport(); protected: float _treeScale; diff --git a/libraries/voxels/src/Tags.cpp b/libraries/voxels/src/Tags.cpp index 914606ce07..32d717cc6b 100644 --- a/libraries/voxels/src/Tags.cpp +++ b/libraries/voxels/src/Tags.cpp @@ -159,19 +159,17 @@ int retrieveData(std::string filename, std::stringstream &ss) { int type = file.peek(); if (type == 0x0A) { - std::cerr << "[DEBUG] Unzipped\n"; ss.flush(); ss << file; return 0; } if (type == 0x1F) { - std::cerr << "[DEBUG] Zipped\n"; int ret = ungzip(file, ss); return ret; } - std::cerr << "[DEBUG] Neither\n"; + std::cerr << "[DEBUG] Schematic compression type not recognize : " << type << std::endl; return 1; } diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 146e013cf6..31b7e30b87 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -361,6 +361,8 @@ void VoxelTree::readBitstreamToTree(unsigned char * bitstream, unsigned long int // skip bitstream to new startPoint bitstreamAt += theseBytesRead; bytesRead += theseBytesRead; + + emit importProgress((100 * (bitstreamAt - bitstream)) / bufferSizeBytes); } this->voxelsBytesRead += bufferSizeBytes; @@ -1559,6 +1561,10 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp bool VoxelTree::readFromSVOFile(const char* fileName) { std::ifstream file(fileName, std::ios::in|std::ios::binary|std::ios::ate); if(file.is_open()) { + + emit importSize(1.0f, 1.0f, 1.0f); + emit importProgress(0); + qDebug("loading file %s...\n", fileName); // get file length.... @@ -1572,6 +1578,8 @@ bool VoxelTree::readFromSVOFile(const char* fileName) { readBitstreamToTree(entireFile, fileLength, args); delete[] entireFile; + emit importProgress(100); + file.close(); return true; } @@ -1585,6 +1593,9 @@ bool VoxelTree::readFromSquareARGB32Pixels(const char* filename) { return false; } + emit importSize(1.0f, 1.0f, 1.0f); + emit importProgress(0); + const uint32_t* pixels; if (pngImage.format() == QImage::Format_ARGB32) { pixels = reinterpret_cast(pngImage.constBits()); @@ -1595,6 +1606,8 @@ bool VoxelTree::readFromSquareARGB32Pixels(const char* filename) { SquarePixelMap pixelMap = SquarePixelMap(pixels, pngImage.height()); pixelMap.addVoxelsToVoxelTree(this); + + emit importProgress(100); return true; } @@ -1629,6 +1642,7 @@ bool VoxelTree::readFromSchematicFile(const char *fileName) { emit importSize(size * schematics.getWidth(), size * schematics.getHeight(), size * schematics.getLength()); + emit importProgress(0); for (int y = 0; y < schematics.getHeight(); ++y) { for (int z = 0; z < schematics.getLength(); ++z) { diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 7bdfcc68af..e988b3f3e0 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -196,7 +196,7 @@ public: signals: void importSize(float x, float y, float z); - void importProgress(int progress); // emit an int between 0 and 100 reflecting the progress of the import + void importProgress(int progress); public slots: void cancelImport(); From 7f4557fe1a32f132c8d93076fa1f51cc7b75393d Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 20 Aug 2013 10:50:25 -0700 Subject: [PATCH 05/20] Add blur scale uniform. --- .../src/renderer/AmbientOcclusionEffect.cpp | 20 ++++++++++--------- .../src/renderer/AmbientOcclusionEffect.h | 1 + 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/interface/src/renderer/AmbientOcclusionEffect.cpp b/interface/src/renderer/AmbientOcclusionEffect.cpp index ff86615b26..f4931c5f71 100644 --- a/interface/src/renderer/AmbientOcclusionEffect.cpp +++ b/interface/src/renderer/AmbientOcclusionEffect.cpp @@ -32,15 +32,6 @@ void AmbientOcclusionEffect::init() { _occlusionProgram->addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/ambient_occlusion.frag"); _occlusionProgram->link(); - _blurProgram = new ProgramObject(); - _blurProgram->addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/ambient_occlusion.vert"); - _blurProgram->addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/occlusion_blur.frag"); - _blurProgram->link(); - - _blurProgram->bind(); - _blurProgram->setUniformValue("originalTexture", 0); - _blurProgram->release(); - // create the sample kernel: an array of spherically distributed offset vectors const int SAMPLE_KERNEL_SIZE = 16; QVector3D sampleKernel[SAMPLE_KERNEL_SIZE]; @@ -83,6 +74,17 @@ void AmbientOcclusionEffect::init() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glBindTexture(GL_TEXTURE_2D, 0); + + _blurProgram = new ProgramObject(); + _blurProgram->addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/ambient_occlusion.vert"); + _blurProgram->addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/occlusion_blur.frag"); + _blurProgram->link(); + + _blurProgram->bind(); + _blurProgram->setUniformValue("originalTexture", 0); + _blurProgram->release(); + + _blurScaleLocation = _blurProgram->uniformLocation("blurScale"); } void AmbientOcclusionEffect::render() { diff --git a/interface/src/renderer/AmbientOcclusionEffect.h b/interface/src/renderer/AmbientOcclusionEffect.h index d41bb65381..416d97c236 100644 --- a/interface/src/renderer/AmbientOcclusionEffect.h +++ b/interface/src/renderer/AmbientOcclusionEffect.h @@ -32,6 +32,7 @@ private: int _noiseScaleLocation; ProgramObject* _blurProgram; + int _blurScaleLocation; GLuint _rotationTextureID; }; From 22598ceb4f702ad04b6d45ce18a90cd381884200 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 20 Aug 2013 11:52:43 -0700 Subject: [PATCH 06/20] Optimizations for occlusion blur (the main one being that we only need to sample the texture four, not sixteen, times if we turn on linear filtering and sample between the texels). --- .../resources/shaders/occlusion_blur.frag | 19 +++++++------- .../src/renderer/AmbientOcclusionEffect.cpp | 5 ++-- interface/src/renderer/TextureCache.cpp | 25 +++++++++++++------ interface/src/renderer/TextureCache.h | 2 ++ 4 files changed, 31 insertions(+), 20 deletions(-) diff --git a/interface/resources/shaders/occlusion_blur.frag b/interface/resources/shaders/occlusion_blur.frag index 2ee5eaf2cb..5b86aec68d 100644 --- a/interface/resources/shaders/occlusion_blur.frag +++ b/interface/resources/shaders/occlusion_blur.frag @@ -11,15 +11,14 @@ // the original texture uniform sampler2D originalTexture; +// the scale for the blur kernel +uniform vec2 blurScale; + void main(void) { - float ds = dFdx(gl_TexCoord[0].s); - float dt = dFdy(gl_TexCoord[0].t); - vec4 sum = vec4(0.0, 0.0, 0.0, 0.0); - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - sum += texture2D(originalTexture, gl_TexCoord[0].st + - vec2(ds, dt) * vec2(-2.0 + float(i), -2.0 + float(j))); - } - } - gl_FragColor = sum / 16.0; + vec2 minExtents = gl_TexCoord[0].st + blurScale * vec2(-0.5, -0.5); + vec2 maxExtents = gl_TexCoord[0].st + blurScale * vec2(1.5, 1.5); + gl_FragColor = (texture2D(originalTexture, minExtents) + + texture2D(originalTexture, vec2(maxExtents.s, minExtents.t)) + + texture2D(originalTexture, vec2(minExtents.s, maxExtents.t)) + + texture2D(originalTexture, maxExtents)) * 0.25; } diff --git a/interface/src/renderer/AmbientOcclusionEffect.cpp b/interface/src/renderer/AmbientOcclusionEffect.cpp index f4931c5f71..184298fd06 100644 --- a/interface/src/renderer/AmbientOcclusionEffect.cpp +++ b/interface/src/renderer/AmbientOcclusionEffect.cpp @@ -112,8 +112,8 @@ void AmbientOcclusionEffect::render() { _occlusionProgram->setUniformValue(_leftBottomLocation, left, bottom); _occlusionProgram->setUniformValue(_rightTopLocation, right, top); QSize size = Application::getInstance()->getGLWidget()->size(); - _occlusionProgram->setUniformValue(_noiseScaleLocation, size.width() / (float)ROTATION_WIDTH, - size.height() / (float)ROTATION_HEIGHT); + QVector2D noiseScale(size.width() / (float)ROTATION_WIDTH, size.height() / (float)ROTATION_HEIGHT); + _occlusionProgram->setUniformValue(_noiseScaleLocation, noiseScale); renderFullscreenQuad(); @@ -133,6 +133,7 @@ void AmbientOcclusionEffect::render() { glBindTexture(GL_TEXTURE_2D, secondaryFBO->texture()); _blurProgram->bind(); + _blurProgram->setUniformValue(_blurScaleLocation, 1.0f / size.width(), 1.0f / size.height()); renderFullscreenQuad(); diff --git a/interface/src/renderer/TextureCache.cpp b/interface/src/renderer/TextureCache.cpp index 5696475487..603ff2ccf0 100644 --- a/interface/src/renderer/TextureCache.cpp +++ b/interface/src/renderer/TextureCache.cpp @@ -64,12 +64,11 @@ GLuint TextureCache::getPermutationNormalTextureID() { QOpenGLFramebufferObject* TextureCache::getPrimaryFramebufferObject() { if (_primaryFramebufferObject == NULL) { - QSize size = Application::getInstance()->getGLWidget()->size(); - _primaryFramebufferObject = new QOpenGLFramebufferObject(size); - Application::getInstance()->getGLWidget()->installEventFilter(this); - + _primaryFramebufferObject = createFramebufferObject(); + glGenTextures(1, &_primaryDepthTextureID); glBindTexture(GL_TEXTURE_2D, _primaryDepthTextureID); + QSize size = Application::getInstance()->getGLWidget()->size(); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, size.width(), size.height(), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -91,16 +90,14 @@ GLuint TextureCache::getPrimaryDepthTextureID() { QOpenGLFramebufferObject* TextureCache::getSecondaryFramebufferObject() { if (_secondaryFramebufferObject == NULL) { - _secondaryFramebufferObject = new QOpenGLFramebufferObject(Application::getInstance()->getGLWidget()->size()); - Application::getInstance()->getGLWidget()->installEventFilter(this); + _secondaryFramebufferObject = createFramebufferObject(); } return _secondaryFramebufferObject; } QOpenGLFramebufferObject* TextureCache::getTertiaryFramebufferObject() { if (_tertiaryFramebufferObject == NULL) { - _tertiaryFramebufferObject = new QOpenGLFramebufferObject(Application::getInstance()->getGLWidget()->size()); - Application::getInstance()->getGLWidget()->installEventFilter(this); + _tertiaryFramebufferObject = createFramebufferObject(); } return _tertiaryFramebufferObject; } @@ -124,3 +121,15 @@ bool TextureCache::eventFilter(QObject* watched, QEvent* event) { } return false; } + +QOpenGLFramebufferObject* TextureCache::createFramebufferObject() { + QOpenGLFramebufferObject* fbo = new QOpenGLFramebufferObject(Application::getInstance()->getGLWidget()->size()); + Application::getInstance()->getGLWidget()->installEventFilter(this); + + glBindTexture(GL_TEXTURE_2D, fbo->texture()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glBindTexture(GL_TEXTURE_2D, 0); + + return fbo; +} diff --git a/interface/src/renderer/TextureCache.h b/interface/src/renderer/TextureCache.h index 1f2fc96ac5..9be048f398 100644 --- a/interface/src/renderer/TextureCache.h +++ b/interface/src/renderer/TextureCache.h @@ -46,6 +46,8 @@ public: private: + QOpenGLFramebufferObject* createFramebufferObject(); + GLuint _permutationNormalTextureID; QOpenGLFramebufferObject* _primaryFramebufferObject; From 11be8c752baa685e1481ebf8819d919881985ec9 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 20 Aug 2013 13:40:45 -0700 Subject: [PATCH 07/20] Cleanup. --- interface/src/renderer/AmbientOcclusionEffect.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/interface/src/renderer/AmbientOcclusionEffect.cpp b/interface/src/renderer/AmbientOcclusionEffect.cpp index 184298fd06..368546a566 100644 --- a/interface/src/renderer/AmbientOcclusionEffect.cpp +++ b/interface/src/renderer/AmbientOcclusionEffect.cpp @@ -112,8 +112,8 @@ void AmbientOcclusionEffect::render() { _occlusionProgram->setUniformValue(_leftBottomLocation, left, bottom); _occlusionProgram->setUniformValue(_rightTopLocation, right, top); QSize size = Application::getInstance()->getGLWidget()->size(); - QVector2D noiseScale(size.width() / (float)ROTATION_WIDTH, size.height() / (float)ROTATION_HEIGHT); - _occlusionProgram->setUniformValue(_noiseScaleLocation, noiseScale); + _occlusionProgram->setUniformValue(_noiseScaleLocation, size.width() / (float)ROTATION_WIDTH, + size.height() / (float)ROTATION_HEIGHT); renderFullscreenQuad(); @@ -141,7 +141,6 @@ void AmbientOcclusionEffect::render() { glBindTexture(GL_TEXTURE_2D, 0); - //glEnable(GL_BLEND); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); From 5b923bc6f27d63ae3ffc141a253e4362dacff29b Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 20 Aug 2013 13:46:13 -0700 Subject: [PATCH 08/20] More cleanup. --- interface/resources/shaders/ambient_occlusion.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/shaders/ambient_occlusion.frag b/interface/resources/shaders/ambient_occlusion.frag index b59c87d797..a62d1d3a71 100644 --- a/interface/resources/shaders/ambient_occlusion.frag +++ b/interface/resources/shaders/ambient_occlusion.frag @@ -59,7 +59,7 @@ void main(void) { vec3 offset = center + rotation * (radius * sampleKernel[i]); vec4 projected = gl_ProjectionMatrix * vec4(offset, 1.0); float depth = texCoordToViewSpaceZ(projected.xy * 0.5 / projected.w + vec2(0.5, 0.5)); - occlusion += 1.0 - step(offset.z, depth); // * step(abs(center.z - depth), radius); + occlusion += 1.0 - step(offset.z, depth); } gl_FragColor = vec4(occlusion, occlusion, occlusion, 0.0) / 16.0; From 7e1b682663a552d772209c80a6b057e126f50838 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 20 Aug 2013 14:55:29 -0700 Subject: [PATCH 09/20] switch OS X base SDK to 10.7 --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 77ae85589d..7a664c4ce4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,9 @@ project(hifi) set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} $ENV{QT_CMAKE_PREFIX_PATH}) +# set our Base SDK to 10.7 +set(CMAKE_OSX_SYSROOT /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk) + # Find includes in corresponding build directories set(CMAKE_INCLUDE_CURRENT_DIR ON) # Instruct CMake to run moc automatically when needed. From d5c66f6b6736d7c6f90cdb2b26b0a3914a3316f0 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 20 Aug 2013 16:07:12 -0700 Subject: [PATCH 10/20] Default to diffuse/add mode, fix for interacting with ambient occlusion. Unfortunately, I managed to break the diffusion somehow. --- .../src/renderer/AmbientOcclusionEffect.cpp | 10 +++---- interface/src/renderer/GlowEffect.cpp | 29 +++++++++++++++++-- interface/src/renderer/GlowEffect.h | 6 ++++ 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/interface/src/renderer/AmbientOcclusionEffect.cpp b/interface/src/renderer/AmbientOcclusionEffect.cpp index ff86615b26..36b4dc2b3b 100644 --- a/interface/src/renderer/AmbientOcclusionEffect.cpp +++ b/interface/src/renderer/AmbientOcclusionEffect.cpp @@ -95,9 +95,9 @@ void AmbientOcclusionEffect::render() { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, _rotationTextureID); - // render with the occlusion shader to the secondary buffer - QOpenGLFramebufferObject* secondaryFBO = Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject(); - secondaryFBO->bind(); + // render with the occlusion shader to the secondary/tertiary buffer + QOpenGLFramebufferObject* freeFBO = Application::getInstance()->getGlowEffect()->getFreeFramebufferObject(); + freeFBO->bind(); float left, right, bottom, top, nearVal, farVal; glm::vec4 nearClipPlane, farClipPlane; @@ -117,7 +117,7 @@ void AmbientOcclusionEffect::render() { _occlusionProgram->release(); - secondaryFBO->release(); + freeFBO->release(); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); @@ -128,7 +128,7 @@ void AmbientOcclusionEffect::render() { glEnable(GL_BLEND); glBlendFuncSeparate(GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE); - glBindTexture(GL_TEXTURE_2D, secondaryFBO->texture()); + glBindTexture(GL_TEXTURE_2D, freeFBO->texture()); _blurProgram->bind(); diff --git a/interface/src/renderer/GlowEffect.cpp b/interface/src/renderer/GlowEffect.cpp index 85c4eb27b2..762ecd1271 100644 --- a/interface/src/renderer/GlowEffect.cpp +++ b/interface/src/renderer/GlowEffect.cpp @@ -15,7 +15,13 @@ #include "ProgramObject.h" #include "RenderUtil.h" -GlowEffect::GlowEffect() : _renderMode(BLUR_ADD_MODE) { +GlowEffect::GlowEffect() : _renderMode(DIFFUSE_ADD_MODE) { +} + +QOpenGLFramebufferObject* GlowEffect::getFreeFramebufferObject() const { + return (_renderMode == DIFFUSE_ADD_MODE && _isOddFrame) ? + Application::getInstance()->getTextureCache()->getTertiaryFramebufferObject() : + Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject(); } static ProgramObject* createProgram(const QString& name) { @@ -58,6 +64,7 @@ void GlowEffect::prepare() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); _isEmpty = true; + _isOddFrame = !_isOddFrame; } void GlowEffect::begin(float intensity) { @@ -109,7 +116,7 @@ void GlowEffect::render() { Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject(); QOpenGLFramebufferObject* newDiffusedFBO = Application::getInstance()->getTextureCache()->getTertiaryFramebufferObject(); - if ((_isOddFrame = !_isOddFrame)) { + if (_isOddFrame) { qSwap(oldDiffusedFBO, newDiffusedFBO); } newDiffusedFBO->bind(); @@ -204,5 +211,21 @@ void GlowEffect::render() { } void GlowEffect::cycleRenderMode() { - _renderMode = (RenderMode)((_renderMode + 1) % RENDER_MODE_COUNT); + switch(_renderMode = (RenderMode)((_renderMode + 1) % RENDER_MODE_COUNT)) { + case ADD_MODE: + qDebug() << "Glow mode: Add\n"; + break; + + case BLUR_ADD_MODE: + qDebug() << "Glow mode: Blur/add\n"; + break; + + case BLUR_PERSIST_ADD_MODE: + qDebug() << "Glow mode: Blur/persist/add\n"; + break; + + case DIFFUSE_ADD_MODE: + qDebug() << "Glow mode: Diffuse/add\n"; + break; + } } diff --git a/interface/src/renderer/GlowEffect.h b/interface/src/renderer/GlowEffect.h index 0d6e83a7a6..73ed9ed881 100644 --- a/interface/src/renderer/GlowEffect.h +++ b/interface/src/renderer/GlowEffect.h @@ -11,6 +11,8 @@ #include +class QOpenGLFramebufferObject; + class ProgramObject; /// A generic full screen glow effect. @@ -21,6 +23,10 @@ public: GlowEffect(); + /// Returns a pointer to the framebuffer object that the glow effect is *not* using for persistent state + /// (either the secondary or the tertiary). + QOpenGLFramebufferObject* getFreeFramebufferObject() const; + void init(); /// Prepares the glow effect for rendering the current frame. To be called before rendering the scene. From 49da612a4e5d7bdf2f5a550ec07296bd18ca72bc Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 20 Aug 2013 16:37:23 -0700 Subject: [PATCH 11/20] Turns out we do have to initialize the "odd frame" field. --- interface/src/Application.cpp | 2 ++ interface/src/renderer/GlowEffect.cpp | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index adc5bb1b71..4c169463a4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2360,8 +2360,10 @@ void Application::displaySide(Camera& whichCamera) { if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { _myAvatar.getHead().setLookAtPosition(_myCamera.getPosition()); } + _glowEffect.begin(); _myAvatar.render(Menu::getInstance()->isOptionChecked(MenuOption::Mirror), Menu::getInstance()->isOptionChecked(MenuOption::AvatarAsBalls)); + _glowEffect.end(); _myAvatar.setDisplayingLookatVectors(Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors)); if (Menu::getInstance()->isOptionChecked(MenuOption::LookAtIndicator) && _isLookingAtOtherAvatar) { diff --git a/interface/src/renderer/GlowEffect.cpp b/interface/src/renderer/GlowEffect.cpp index 762ecd1271..77bb136b6d 100644 --- a/interface/src/renderer/GlowEffect.cpp +++ b/interface/src/renderer/GlowEffect.cpp @@ -15,11 +15,11 @@ #include "ProgramObject.h" #include "RenderUtil.h" -GlowEffect::GlowEffect() : _renderMode(DIFFUSE_ADD_MODE) { +GlowEffect::GlowEffect() : _renderMode(DIFFUSE_ADD_MODE), _isOddFrame(false) { } QOpenGLFramebufferObject* GlowEffect::getFreeFramebufferObject() const { - return (_renderMode == DIFFUSE_ADD_MODE && _isOddFrame) ? + return (_renderMode == DIFFUSE_ADD_MODE && !_isOddFrame) ? Application::getInstance()->getTextureCache()->getTertiaryFramebufferObject() : Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject(); } From 590672d03554587c42224bdfbc387ba51d5b2d19 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 20 Aug 2013 17:02:35 -0700 Subject: [PATCH 12/20] Fewer texture lookups when diffusing. --- interface/resources/shaders/diffuse.frag | 19 +++++++++---------- interface/src/renderer/GlowEffect.cpp | 6 ++++++ interface/src/renderer/GlowEffect.h | 1 + 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/interface/resources/shaders/diffuse.frag b/interface/resources/shaders/diffuse.frag index f8be7075db..6ad77c860e 100644 --- a/interface/resources/shaders/diffuse.frag +++ b/interface/resources/shaders/diffuse.frag @@ -14,15 +14,14 @@ uniform sampler2D originalTexture; // the texture containing the diffused color uniform sampler2D diffusedTexture; +// the scale of diffusion +uniform vec2 diffusionScale; + void main(void) { - float ds = dFdx(gl_TexCoord[0].s); - float dt = dFdy(gl_TexCoord[0].t); - gl_FragColor = (texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(-ds, -dt)) + - texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(0.0, -dt)) + - texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(ds, -dt)) + - texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(ds, 0.0)) + - texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(ds, dt)) + - texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(0.0, dt)) + - texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(-ds, dt)) + - texture2D(diffusedTexture, gl_TexCoord[0].st + vec2(-ds, 0.0))) / 8.5 + texture2D(originalTexture, gl_TexCoord[0].st) * 0.1; + vec2 minExtents = gl_TexCoord[0].st + diffusionScale * vec2(-1.5, -1.5); + vec2 maxExtents = gl_TexCoord[0].st + diffusionScale * vec2(1.5, 1.5); + gl_FragColor = (texture2D(diffusedTexture, minExtents) + + texture2D(diffusedTexture, vec2(maxExtents.s, minExtents.t)) + + texture2D(diffusedTexture, vec2(minExtents.s, maxExtents.t)) + + texture2D(diffusedTexture, maxExtents)) / 4.25 + texture2D(originalTexture, gl_TexCoord[0].st) * 0.1; } diff --git a/interface/src/renderer/GlowEffect.cpp b/interface/src/renderer/GlowEffect.cpp index 77bb136b6d..b08d0680d5 100644 --- a/interface/src/renderer/GlowEffect.cpp +++ b/interface/src/renderer/GlowEffect.cpp @@ -57,6 +57,8 @@ void GlowEffect::init() { _diffuseProgram->bind(); _diffuseProgram->setUniformValue("diffusedTexture", 1); _diffuseProgram->release(); + + _diffusionScaleLocation = _diffuseProgram->uniformLocation("diffusionScale"); } void GlowEffect::prepare() { @@ -125,7 +127,11 @@ void GlowEffect::render() { glBindTexture(GL_TEXTURE_2D, oldDiffusedFBO->texture()); _diffuseProgram->bind(); + QSize size = Application::getInstance()->getGLWidget()->size(); + _diffuseProgram->setUniformValue(_diffusionScaleLocation, 1.0f / size.width(), 1.0f / size.height()); + renderFullscreenQuad(); + _diffuseProgram->release(); newDiffusedFBO->release(); diff --git a/interface/src/renderer/GlowEffect.h b/interface/src/renderer/GlowEffect.h index 73ed9ed881..73119365e8 100644 --- a/interface/src/renderer/GlowEffect.h +++ b/interface/src/renderer/GlowEffect.h @@ -57,6 +57,7 @@ private: ProgramObject* _verticalBlurProgram; ProgramObject* _addSeparateProgram; ProgramObject* _diffuseProgram; + int _diffusionScaleLocation; bool _isEmpty; ///< set when nothing in the scene is currently glowing bool _isOddFrame; ///< controls the alternation between texture targets in diffuse add mode From f3a32a7934bc98818042eb2b0b48f6f4385ffd63 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 20 Aug 2013 17:04:29 -0700 Subject: [PATCH 13/20] Might as well convert the divide to a multiply. --- interface/resources/shaders/diffuse.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/shaders/diffuse.frag b/interface/resources/shaders/diffuse.frag index 6ad77c860e..ebf11dace2 100644 --- a/interface/resources/shaders/diffuse.frag +++ b/interface/resources/shaders/diffuse.frag @@ -23,5 +23,5 @@ void main(void) { gl_FragColor = (texture2D(diffusedTexture, minExtents) + texture2D(diffusedTexture, vec2(maxExtents.s, minExtents.t)) + texture2D(diffusedTexture, vec2(minExtents.s, maxExtents.t)) + - texture2D(diffusedTexture, maxExtents)) / 4.25 + texture2D(originalTexture, gl_TexCoord[0].st) * 0.1; + texture2D(diffusedTexture, maxExtents)) * 0.235 + texture2D(originalTexture, gl_TexCoord[0].st) * 0.1; } From 571131d42e4230f58353e1eecb49882317f11a5b Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 20 Aug 2013 17:25:54 -0700 Subject: [PATCH 14/20] No glow effect on the avatar, fixed OS X warning. --- interface/src/Application.cpp | 2 -- interface/src/renderer/GlowEffect.cpp | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4c169463a4..adc5bb1b71 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2360,10 +2360,8 @@ void Application::displaySide(Camera& whichCamera) { if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { _myAvatar.getHead().setLookAtPosition(_myCamera.getPosition()); } - _glowEffect.begin(); _myAvatar.render(Menu::getInstance()->isOptionChecked(MenuOption::Mirror), Menu::getInstance()->isOptionChecked(MenuOption::AvatarAsBalls)); - _glowEffect.end(); _myAvatar.setDisplayingLookatVectors(Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors)); if (Menu::getInstance()->isOptionChecked(MenuOption::LookAtIndicator) && _isLookingAtOtherAvatar) { diff --git a/interface/src/renderer/GlowEffect.cpp b/interface/src/renderer/GlowEffect.cpp index b08d0680d5..936364f8c0 100644 --- a/interface/src/renderer/GlowEffect.cpp +++ b/interface/src/renderer/GlowEffect.cpp @@ -229,7 +229,8 @@ void GlowEffect::cycleRenderMode() { case BLUR_PERSIST_ADD_MODE: qDebug() << "Glow mode: Blur/persist/add\n"; break; - + + default: case DIFFUSE_ADD_MODE: qDebug() << "Glow mode: Diffuse/add\n"; break; From 27b03382944ca0fc067eb61020adb7542a4c9c45 Mon Sep 17 00:00:00 2001 From: atlante45 Date: Wed, 21 Aug 2013 10:31:56 -0700 Subject: [PATCH 15/20] Fixed clipboard not being previewed --- interface/src/VoxelImporter.cpp | 5 +++-- interface/src/VoxelSystem.cpp | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/interface/src/VoxelImporter.cpp b/interface/src/VoxelImporter.cpp index 095110eb35..d292766fc1 100644 --- a/interface/src/VoxelImporter.cpp +++ b/interface/src/VoxelImporter.cpp @@ -70,7 +70,9 @@ void VoxelImporter::reset() { } int VoxelImporter::exec() { - if (!_initialized) { + reset(); + + if (_initialized) { _voxelSystem->init(); _importViewFrustum.setKeyholeRadius(100000.0f); _importViewFrustum.calculate(); @@ -78,7 +80,6 @@ int VoxelImporter::exec() { _initialized = true; } - reset(); int ret = _importDialog.exec(); if (!ret) { diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 37f7a49c6b..729bc65745 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -1314,6 +1314,7 @@ void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bo void VoxelSystem::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelSystem* destinationTree, bool rebaseToRoot) { _tree->copySubTreeIntoNewTree(startNode, destinationTree->_tree, rebaseToRoot); + destinationTree->setupNewVoxelsForDrawing(); } void VoxelSystem::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destinationTree, bool rebaseToRoot) { From 867303e673857d27c1a33cb5f8602a514b53cad2 Mon Sep 17 00:00:00 2001 From: atlante45 Date: Wed, 21 Aug 2013 11:33:10 -0700 Subject: [PATCH 16/20] Code cleanup --- interface/src/Application.cpp | 180 ++--------------------------- interface/src/Application.h | 1 - interface/src/ImportDialog.cpp | 2 +- interface/src/VoxelImporter.cpp | 7 +- libraries/voxels/src/VoxelTree.cpp | 2 - 5 files changed, 16 insertions(+), 176 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7080463466..c3137e2d9b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1194,183 +1194,27 @@ void Application::exportVoxels() { _window->activateWindow(); } -const char* IMPORT_FILE_TYPES = "Sparse Voxel Octree Files, Square PNG, Schematic Files (*.svo *.png *.schematic)"; -void Application::importVoxelsToClipboard() { - QString desktopLocation = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); - QString fileNameString = QFileDialog::getOpenFileName(_glWidget, tr("Import Voxels to Clipboard"), desktopLocation, - tr(IMPORT_FILE_TYPES)); - - QByteArray fileNameAscii = fileNameString.toLocal8Bit(); - const char* fileName = fileNameAscii.data(); - - _clipboard.killLocalVoxels(); - if (fileNameString.endsWith(".png", Qt::CaseInsensitive)) { - _clipboard.readFromSquareARGB32Pixels(fileName); - } else if (fileNameString.endsWith(".svo", Qt::CaseInsensitive)) { - _clipboard.readFromSVOFile(fileName); - } else if (fileNameString.endsWith(".schematic", Qt::CaseInsensitive)) { - _clipboard.readFromSchematicFile(fileName); - } - - // restore the main window's active state - _window->activateWindow(); -} - void Application::importVoxels() { _pasteMode = false; if (_voxelImporter.exec()) { qDebug("[DEBUG] Import succedded.\n"); - _pasteMode = true; + + if (_voxelImporter.getimportIntoClipboard()) { + _clipboard.killLocalVoxels(); + _voxelImporter.getVoxelSystem()->copySubTreeIntoNewTree( + _voxelImporter.getVoxelSystem()->getVoxelAt(0, 0, 0, 1), + &_clipboard, + true); + } else { + _pasteMode = true; + } + + } else { qDebug("[DEBUG] Import failed.\n"); } - return; - - QString desktopLocation = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); - - QStringList fileNameStringList = QFileDialog::getOpenFileNames(_glWidget, tr("Import Voxels"), desktopLocation, - tr(IMPORT_FILE_TYPES)); - - - // remember the "selected" voxel point before we do any importing... - float originalX = _mouseVoxel.x; - float originalZ = _mouseVoxel.z; - - const int PNG_TYPE_NAME_LENGTH = 4; - const int SVO_TYPE_NAME_LENGTH = 4; - const int SCH_TYPE_NAME_LENGTH = 10; - - // assume this is where we'll place it if filename doesn't have tiling - int unspecifiedColumnNum = 1; - int unspecifiedRowNum = 1; - - // if they select multiple files, but they don't specify the tiling, we - // will tile them to this size - int unspecifiedSquare = (sqrt(fileNameStringList.size()) + 0.5); - qDebug("unspecifiedSquare: %d\n", unspecifiedSquare); - - for (int i = 0; i < fileNameStringList.size(); i++) { - QString fileNameString = fileNameStringList.at(i); - QString extension; - QByteArray fileNameAscii = fileNameString.toLocal8Bit(); - const char* fileName = fileNameAscii.data(); - - int fileTypeNameLength = 0; - VoxelTree importVoxels; - if (fileNameString.endsWith(".png", Qt::CaseInsensitive)) { - extension = QString(".png"); - QImage pngImage = QImage(fileName); - fileTypeNameLength = PNG_TYPE_NAME_LENGTH; - if (pngImage.height() != pngImage.width()) { - qDebug("ERROR: Bad PNG size: height != width.\n"); - return; - } - - const uint32_t* pixels; - if (pngImage.format() == QImage::Format_ARGB32) { - pixels = reinterpret_cast(pngImage.constBits()); - } else { - QImage tmp = pngImage.convertToFormat(QImage::Format_ARGB32); - pixels = reinterpret_cast(tmp.constBits()); - } - - importVoxels.readFromSquareARGB32Pixels(fileName); - } else if (fileNameString.endsWith(".svo", Qt::CaseInsensitive)) { - extension = QString(".svo"); - importVoxels.readFromSVOFile(fileName); - fileTypeNameLength = SVO_TYPE_NAME_LENGTH; - } else if (fileNameString.endsWith(".schematic", Qt::CaseInsensitive)) { - extension = QString(".schematic"); - importVoxels.readFromSchematicFile(fileName); - fileTypeNameLength = SCH_TYPE_NAME_LENGTH; - } - - // Where we plan to place this - int columnNum = 1; - int rowNum = 1; - bool isTileLocationUnspecified = false; - - // If we're in multi-file mode, then look for tiling specification in the file name - if (fileNameStringList.size() > 1) { - int indexOfFirstPeriod = fileNameString.indexOf('.'); - - //qDebug("indexOfFirstPeriod: %d\n", indexOfFirstPeriod); - - // If the first period, is the extension, then this is not a grid name; - if (fileNameString.mid(indexOfFirstPeriod, fileNameString.length() - indexOfFirstPeriod) == extension) { - qDebug("not a valid grid name... treat like tile Location Unspecified\n"); - isTileLocationUnspecified = true; - } else { - QString fileCoord = fileNameString.mid(indexOfFirstPeriod + 1, - fileNameString.length() - indexOfFirstPeriod - fileTypeNameLength - 1); - - //qDebug() << "fileCoord: " << fileCoord << "\n"; - indexOfFirstPeriod = fileCoord.indexOf('.'); - - //qDebug("indexOfFirstPeriod: %d\n", indexOfFirstPeriod); - - QString columnNumString = fileCoord.right(fileCoord.length() - indexOfFirstPeriod - 1); - QString rowNumString = fileCoord.left(indexOfFirstPeriod); - - //qDebug() << "columnNumString: " << columnNumString << "\n"; - //qDebug() << "rowNumString: " << rowNumString << "\n"; - - columnNum = columnNumString.toFloat(); - rowNum = rowNumString.toFloat(); - - // If there are no "grid sections" in the filename, then we're going to get - if (columnNum < 1 || rowNum < 1) { - qDebug("not a valid grid name... treat like tile Location Unspecified\n"); - isTileLocationUnspecified = true; - } - } - } - - if (isTileLocationUnspecified) { - qDebug("tile Location is Unspecified... \n"); - columnNum = unspecifiedColumnNum; - rowNum = unspecifiedRowNum; - - unspecifiedColumnNum++; - if (unspecifiedColumnNum > unspecifiedSquare) { - unspecifiedColumnNum = 1; - unspecifiedRowNum++; - } - } - qDebug("columnNum: %d\t rowNum: %d\n", columnNum, rowNum); - - _mouseVoxel.x = originalX + (columnNum - 1) * _mouseVoxel.s; - _mouseVoxel.z = originalZ + (rowNum - 1) * _mouseVoxel.s; - - VoxelNode* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); - - // Recurse the Import Voxels tree, where everything is root relative, and send all the colored voxels to - // the server as an set voxel message, this will also rebase the voxels to the new location - unsigned char* calculatedOctCode = NULL; - SendVoxelsOperationArgs args; - - // we only need the selected voxel to get the newBaseOctCode, which we can actually calculate from the - // voxel size/position details. - if (selectedNode) { - args.newBaseOctCode = selectedNode->getOctalCode(); - } else { - args.newBaseOctCode = calculatedOctCode = pointToVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); - } - - qDebug("column:%d, row:%d, voxel:%f,%f,%f,%f\n", columnNum, rowNum, _mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s ); - - // send the insert/paste of these voxels - importVoxels.recurseTreeWithOperation(sendVoxelsOperation, &args); - _voxelEditSender.flushQueue(); - - if (calculatedOctCode) { - delete[] calculatedOctCode; - } - - } - // restore the main window's active state _window->activateWindow(); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 01d5c22fa4..a4ae01b730 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -139,7 +139,6 @@ public slots: void sendAvatarFaceVideoMessage(int frameCount, const QByteArray& data); void exportVoxels(); void importVoxels(); - void importVoxelsToClipboard(); void cutVoxels(); void copyVoxels(); void togglePasteMode(); diff --git a/interface/src/ImportDialog.cpp b/interface/src/ImportDialog.cpp index 7308a44347..9c6653cc8a 100644 --- a/interface/src/ImportDialog.cpp +++ b/interface/src/ImportDialog.cpp @@ -134,7 +134,7 @@ void GLWidget::paintGL() { glVertex3d(2 * _targetCenter.x, 2 * _targetCenter.y, 0 ); glEnd(); - _voxelSystem->render(true); + _voxelSystem->render(false); } } diff --git a/interface/src/VoxelImporter.cpp b/interface/src/VoxelImporter.cpp index d292766fc1..7aa7dcb02a 100644 --- a/interface/src/VoxelImporter.cpp +++ b/interface/src/VoxelImporter.cpp @@ -48,7 +48,7 @@ VoxelImporter::~VoxelImporter() { connect(_currentTask, SIGNAL(destroyed()), _voxelSystem, SLOT(deleteLater())); _voxelSystem->cancelImport(); _currentTask = NULL; - } else { + } else if (_initialized) { delete _voxelSystem; } } @@ -70,15 +70,14 @@ void VoxelImporter::reset() { } int VoxelImporter::exec() { - reset(); - - if (_initialized) { + if (!_initialized) { _voxelSystem->init(); _importViewFrustum.setKeyholeRadius(100000.0f); _importViewFrustum.calculate(); _voxelSystem->setViewFrustum(&_importViewFrustum); _initialized = true; } + reset(); int ret = _importDialog.exec(); diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 41ccc2f2c8..124d2f7fa6 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -1629,8 +1629,6 @@ bool VoxelTree::readFromSchematicFile(const char *fileName) { return false; } - _stopImport = false; - int max = (schematics.getWidth() > schematics.getLength()) ? schematics.getWidth() : schematics.getLength(); max = (max > schematics.getHeight()) ? max : schematics.getHeight(); From 9003a7d40b3fa39938e546a68b51901b430e327d Mon Sep 17 00:00:00 2001 From: atlante45 Date: Wed, 21 Aug 2013 12:06:47 -0700 Subject: [PATCH 17/20] PR comments --- interface/src/Application.cpp | 4 +++- interface/src/VoxelImporter.cpp | 29 +++++++++++++---------------- interface/src/VoxelImporter.h | 4 ++-- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c3137e2d9b..dbb2170150 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -81,6 +81,8 @@ const int STARTUP_JITTER_SAMPLES = PACKET_LENGTH_SAMPLES_PER_CHANNEL / 2; // Startup optimistically with small jitter buffer that // will start playback on the second received audio packet. +static const float CLIPBOARD_TREE_SCALE = 1.0f; + void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message) { fprintf(stdout, "%s", message.toLocal8Bit().constData()); LogDisplay::instance.addMessage(message.toLocal8Bit().constData()); @@ -94,7 +96,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _frameCount(0), _fps(120.0f), _justStarted(true), - _clipboard(1), + _clipboard(CLIPBOARD_TREE_SCALE), _voxelImporter(_window), _wantToKillLocalVoxels(false), _audioScope(256, 200, true), diff --git a/interface/src/VoxelImporter.cpp b/interface/src/VoxelImporter.cpp index 7aa7dcb02a..ef4eeafc4b 100644 --- a/interface/src/VoxelImporter.cpp +++ b/interface/src/VoxelImporter.cpp @@ -11,6 +11,7 @@ #include #include +static const int IMPORT_SYSTEM_SCALE = 1.0f; static const int MAX_VOXELS_PER_IMPORT = 2000000; class ImportTask : public QObject, public QRunnable { @@ -25,10 +26,10 @@ private: VoxelImporter::VoxelImporter(QWidget* parent) : QObject(parent), - _voxelSystem(new VoxelSystem(1, MAX_VOXELS_PER_IMPORT)), + _voxelSystem(IMPORT_SYSTEM_SCALE, MAX_VOXELS_PER_IMPORT), _initialized(false), _importWaiting(false), - _importDialog(parent, _voxelSystem), + _importDialog(parent, &_voxelSystem), _currentTask(NULL), _nextTask(NULL) { @@ -45,16 +46,13 @@ VoxelImporter::~VoxelImporter() { if (_currentTask) { disconnect(_currentTask, 0, 0, 0); - connect(_currentTask, SIGNAL(destroyed()), _voxelSystem, SLOT(deleteLater())); - _voxelSystem->cancelImport(); + _voxelSystem.cancelImport(); _currentTask = NULL; - } else if (_initialized) { - delete _voxelSystem; } } void VoxelImporter::reset() { - _voxelSystem->killLocalVoxels(); + _voxelSystem.killLocalVoxels(); _importDialog.reset(); _filename = ""; _importWaiting = false; @@ -65,16 +63,15 @@ void VoxelImporter::reset() { } if (_currentTask) { - _voxelSystem->cancelImport(); + _voxelSystem.cancelImport(); } } int VoxelImporter::exec() { if (!_initialized) { - _voxelSystem->init(); - _importViewFrustum.setKeyholeRadius(100000.0f); + _voxelSystem.init(); _importViewFrustum.calculate(); - _voxelSystem->setViewFrustum(&_importViewFrustum); + _voxelSystem.setViewFrustum(&_importViewFrustum); _initialized = true; } reset(); @@ -105,11 +102,11 @@ int VoxelImporter::preImport() { delete _nextTask; } - _nextTask = new ImportTask(_voxelSystem, _filename); + _nextTask = new ImportTask(&_voxelSystem, _filename); connect(_nextTask, SIGNAL(destroyed()), SLOT(launchTask())); if (_currentTask != NULL) { - _voxelSystem->cancelImport(); + _voxelSystem.cancelImport(); } else { launchTask(); } @@ -141,12 +138,12 @@ int VoxelImporter::import() { delete _nextTask; } - _nextTask = new ImportTask(_voxelSystem, _filename); + _nextTask = new ImportTask(&_voxelSystem, _filename); connect(_nextTask, SIGNAL(destroyed()), SLOT(launchTask())); connect(_nextTask, SIGNAL(destroyed()), &_importDialog, SLOT(accept())); if (_currentTask != NULL) { - _voxelSystem->cancelImport(); + _voxelSystem.cancelImport(); } else { launchTask(); } @@ -156,7 +153,7 @@ int VoxelImporter::import() { void VoxelImporter::launchTask() { if (_nextTask != NULL) { - _voxelSystem->killLocalVoxels(); + _voxelSystem.killLocalVoxels(); _currentTask = _nextTask; _nextTask = NULL; QThreadPool::globalInstance()->start(_currentTask); diff --git a/interface/src/VoxelImporter.h b/interface/src/VoxelImporter.h index b5624ed07f..4ab230d6fb 100644 --- a/interface/src/VoxelImporter.h +++ b/interface/src/VoxelImporter.h @@ -25,7 +25,7 @@ public: void reset(); bool getImportWaiting() const { return _importWaiting; } - VoxelSystem* getVoxelSystem() const { return _voxelSystem; } + VoxelSystem* getVoxelSystem() { return &_voxelSystem; } bool getimportIntoClipboard() const { return _importDialog.getImportIntoClipboard(); } public slots: @@ -37,7 +37,7 @@ private slots: void launchTask(); private: - VoxelSystem* _voxelSystem; + VoxelSystem _voxelSystem; ViewFrustum _importViewFrustum; bool _initialized; bool _importWaiting; From bda6e03117944fb67514fb882fb95d92dc3b63cd Mon Sep 17 00:00:00 2001 From: atlante45 Date: Wed, 21 Aug 2013 12:11:34 -0700 Subject: [PATCH 18/20] Changed name of copySubTreeIntoNewTree destinationTree argument --- interface/src/VoxelSystem.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 729bc65745..b0cbcf02c3 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -1312,13 +1312,13 @@ void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bo setupNewVoxelsForDrawing(); }; -void VoxelSystem::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelSystem* destinationTree, bool rebaseToRoot) { - _tree->copySubTreeIntoNewTree(startNode, destinationTree->_tree, rebaseToRoot); - destinationTree->setupNewVoxelsForDrawing(); +void VoxelSystem::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelSystem* destination, bool rebaseToRoot) { + _tree->copySubTreeIntoNewTree(startNode, destination->_tree, rebaseToRoot); + destination->setupNewVoxelsForDrawing(); } -void VoxelSystem::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destinationTree, bool rebaseToRoot) { - _tree->copySubTreeIntoNewTree(startNode, destinationTree, rebaseToRoot); +void VoxelSystem::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destination, bool rebaseToRoot) { + _tree->copySubTreeIntoNewTree(startNode, destination, rebaseToRoot); } void VoxelSystem::copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* destinationNode) { From 4fd23a0cd91af19ed3c1731255f3034b07c2e0f8 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 21 Aug 2013 13:09:51 -0700 Subject: [PATCH 19/20] CR feedback --- animation-server/src/main.cpp | 12 ++++++------ libraries/voxels/src/JurisdictionMap.cpp | 1 - libraries/voxels/src/JurisdictionSender.cpp | 6 +----- libraries/voxels/src/VoxelSceneStats.h | 3 ++- voxel-server/src/main.cpp | 5 ++--- 5 files changed, 11 insertions(+), 16 deletions(-) diff --git a/animation-server/src/main.cpp b/animation-server/src/main.cpp index 9b43378eb2..eb1e3546dd 100644 --- a/animation-server/src/main.cpp +++ b/animation-server/src/main.cpp @@ -651,27 +651,27 @@ int main(int argc, const char * argv[]) // Handle Local Domain testing with the --local command line const char* NO_BILLBOARD = "--NoBillboard"; ::includeBillboard = !cmdOptionExists(argc, argv, NO_BILLBOARD); - printf("includeBillboard=%s\n",debug::valueOf(::includeBillboard)); + printf("includeBillboard=%s\n", debug::valueOf(::includeBillboard)); const char* NO_BORDER_TRACER = "--NoBorderTracer"; ::includeBorderTracer = !cmdOptionExists(argc, argv, NO_BORDER_TRACER); - printf("includeBorderTracer=%s\n",debug::valueOf(::includeBorderTracer)); + printf("includeBorderTracer=%s\n", debug::valueOf(::includeBorderTracer)); const char* NO_MOVING_BUG = "--NoMovingBug"; ::includeMovingBug = !cmdOptionExists(argc, argv, NO_MOVING_BUG); - printf("includeMovingBug=%s\n",debug::valueOf(::includeMovingBug)); + printf("includeMovingBug=%s\n", debug::valueOf(::includeMovingBug)); const char* INCLUDE_BLINKING_VOXEL = "--includeBlinkingVoxel"; ::includeBlinkingVoxel = cmdOptionExists(argc, argv, INCLUDE_BLINKING_VOXEL); - printf("includeBlinkingVoxel=%s\n",debug::valueOf(::includeBlinkingVoxel)); + printf("includeBlinkingVoxel=%s\n", debug::valueOf(::includeBlinkingVoxel)); const char* NO_DANCE_FLOOR = "--NoDanceFloor"; ::includeDanceFloor = !cmdOptionExists(argc, argv, NO_DANCE_FLOOR); - printf("includeDanceFloor=%s\n",debug::valueOf(::includeDanceFloor)); + printf("includeDanceFloor=%s\n", debug::valueOf(::includeDanceFloor)); const char* BUILD_STREET = "--BuildStreet"; ::buildStreet = cmdOptionExists(argc, argv, BUILD_STREET); - printf("buildStreet=%s\n",debug::valueOf(::buildStreet)); + printf("buildStreet=%s\n", debug::valueOf(::buildStreet)); // Handle Local Domain testing with the --local command line const char* showPPS = "--showPPS"; diff --git a/libraries/voxels/src/JurisdictionMap.cpp b/libraries/voxels/src/JurisdictionMap.cpp index 3b05e2980a..94e589c801 100644 --- a/libraries/voxels/src/JurisdictionMap.cpp +++ b/libraries/voxels/src/JurisdictionMap.cpp @@ -235,7 +235,6 @@ int JurisdictionMap::packIntoMessage(unsigned char* destinationBuffer, int avail // add the root jurisdiction if (_rootOctalCode) { - // copy the int bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(_rootOctalCode)); memcpy(destinationBuffer, &bytes, sizeof(bytes)); destinationBuffer += sizeof(bytes); diff --git a/libraries/voxels/src/JurisdictionSender.cpp b/libraries/voxels/src/JurisdictionSender.cpp index e699951527..df48c27c47 100644 --- a/libraries/voxels/src/JurisdictionSender.cpp +++ b/libraries/voxels/src/JurisdictionSender.cpp @@ -39,11 +39,7 @@ bool JurisdictionSender::process() { bool continueProcessing = isStillRunning(); // call our ReceivedPacketProcessor base class process so we'll get any pending packets - if (continueProcessing) { - continueProcessing = ReceivedPacketProcessor::process(); - } - - if (continueProcessing) { + if (continueProcessing && (continueProcessing = ReceivedPacketProcessor::process())) { // add our packet to our own queue, then let the PacketSender class do the rest of the work. static unsigned char buffer[MAX_PACKET_SIZE]; unsigned char* bufferOut = &buffer[0]; diff --git a/libraries/voxels/src/VoxelSceneStats.h b/libraries/voxels/src/VoxelSceneStats.h index 2d7f7cd068..0883de45e1 100644 --- a/libraries/voxels/src/VoxelSceneStats.h +++ b/libraries/voxels/src/VoxelSceneStats.h @@ -119,10 +119,11 @@ public: }; /// Returns details about items tracked by VoxelSceneStats - /// \param + /// \param Item item The item from the stats you're interested in. ItemInfo& getItemInfo(Item item) { return _ITEMS[item]; }; /// Returns a UI formatted value of an item tracked by VoxelSceneStats + /// \param Item item The item from the stats you're interested in. char* getItemValue(Item item); /// Returns OctCode for root node of the jurisdiction of this particular voxel server diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 2579c54751..3446ebe9c1 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -510,9 +510,8 @@ int main(int argc, const char * argv[]) { NodeList* nodeList = NodeList::createInstance(NODE_TYPE_VOXEL_SERVER, listenPort); setvbuf(stdout, NULL, _IOLBF, 0); - const int numNodeTypes = 2; - const NODE_TYPE nodeTypes[numNodeTypes] = { NODE_TYPE_AGENT, NODE_TYPE_ANIMATION_SERVER }; - NodeList::getInstance()->setNodeTypesOfInterest(&nodeTypes[0], numNodeTypes); + const NODE_TYPE nodeTypes[] = { NODE_TYPE_AGENT, NODE_TYPE_ANIMATION_SERVER }; + NodeList::getInstance()->setNodeTypesOfInterest(&nodeTypes[0], sizeof(nodeTypes)); // Handle Local Domain testing with the --local command line const char* local = "--local"; From bae0f7fa1b1fdea7890f61e16a51628e89b4b70d Mon Sep 17 00:00:00 2001 From: atlante45 Date: Wed, 21 Aug 2013 13:21:15 -0700 Subject: [PATCH 20/20] New paste behaviour --- interface/src/Application.cpp | 23 ++++++++++------------- interface/src/Application.h | 1 - interface/src/Menu.cpp | 2 +- interface/src/VoxelImporter.h | 2 +- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index dbb2170150..847ceda135 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -492,6 +492,11 @@ void Application::keyPressEvent(QKeyEvent* event) { bool isShifted = event->modifiers().testFlag(Qt::ShiftModifier); switch (event->key()) { + case Qt::Key_Shift: + if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelSelectMode)) { + _pasteMode = true; + } + break; case Qt::Key_BracketLeft: case Qt::Key_BracketRight: case Qt::Key_BraceLeft: @@ -723,6 +728,9 @@ void Application::keyReleaseEvent(QKeyEvent* event) { } switch (event->key()) { + case Qt::Key_Shift: + _pasteMode = false; + break; case Qt::Key_E: _myAvatar.setDriveKeys(UP, 0); break; @@ -1197,22 +1205,17 @@ void Application::exportVoxels() { } void Application::importVoxels() { - _pasteMode = false; - if (_voxelImporter.exec()) { qDebug("[DEBUG] Import succedded.\n"); - if (_voxelImporter.getimportIntoClipboard()) { + if (_voxelImporter.getImportIntoClipboard()) { _clipboard.killLocalVoxels(); _voxelImporter.getVoxelSystem()->copySubTreeIntoNewTree( _voxelImporter.getVoxelSystem()->getVoxelAt(0, 0, 0, 1), &_clipboard, true); - } else { - _pasteMode = true; + _voxelImporter.reset(); } - - } else { qDebug("[DEBUG] Import failed.\n"); } @@ -1235,12 +1238,6 @@ void Application::copyVoxels() { // then copy onto it _voxels.copySubTreeIntoNewTree(selectedNode, &_clipboard, true); } - - _pasteMode = false; -} - -void Application::togglePasteMode() { - _pasteMode = !_pasteMode; } void Application::pasteVoxels() { diff --git a/interface/src/Application.h b/interface/src/Application.h index a4ae01b730..49419dc2e5 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -141,7 +141,6 @@ public slots: void importVoxels(); void cutVoxels(); void copyVoxels(); - void togglePasteMode(); void pasteVoxels(); void setRenderVoxels(bool renderVoxels); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 434ecbdf58..0e5f8bb5b9 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -248,7 +248,7 @@ Menu::Menu() : addActionToQMenuAndActionHash(voxelMenu, MenuOption::ImportVoxels, Qt::CTRL | Qt::Key_I, appInstance, SLOT(importVoxels())); addActionToQMenuAndActionHash(voxelMenu, MenuOption::CutVoxels, Qt::CTRL | Qt::Key_X, appInstance, SLOT(cutVoxels())); addActionToQMenuAndActionHash(voxelMenu, MenuOption::CopyVoxels, Qt::CTRL | Qt::Key_C, appInstance, SLOT(copyVoxels())); - addActionToQMenuAndActionHash(voxelMenu, MenuOption::PasteVoxels, Qt::CTRL | Qt::Key_V, appInstance, SLOT(togglePasteMode())); + addActionToQMenuAndActionHash(voxelMenu, MenuOption::PasteVoxels, Qt::CTRL | Qt::Key_V, appInstance, SLOT(pasteVoxels())); QMenu* debugMenu = addMenu("Debug"); diff --git a/interface/src/VoxelImporter.h b/interface/src/VoxelImporter.h index 4ab230d6fb..9b25adcee0 100644 --- a/interface/src/VoxelImporter.h +++ b/interface/src/VoxelImporter.h @@ -26,7 +26,7 @@ public: bool getImportWaiting() const { return _importWaiting; } VoxelSystem* getVoxelSystem() { return &_voxelSystem; } - bool getimportIntoClipboard() const { return _importDialog.getImportIntoClipboard(); } + bool getImportIntoClipboard() const { return _importDialog.getImportIntoClipboard(); } public slots: int exec();