mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-15 20:10:20 +02:00
Merge branch 'master' of https://github.com/worklist/hifi into animation_server_jurisdictions
This commit is contained in:
commit
4bdaf7589f
23 changed files with 995 additions and 399 deletions
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)) * 0.235 + texture2D(originalTexture, gl_TexCoord[0].st) * 0.1;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,6 +96,8 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
|||
_frameCount(0),
|
||||
_fps(120.0f),
|
||||
_justStarted(true),
|
||||
_clipboard(CLIPBOARD_TREE_SCALE),
|
||||
_voxelImporter(_window),
|
||||
_wantToKillLocalVoxels(false),
|
||||
_audioScope(256, 200, true),
|
||||
_mouseX(0),
|
||||
|
@ -125,7 +129,8 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
|||
_packetsPerSecond(0),
|
||||
_bytesPerSecond(0),
|
||||
_bytesCount(0),
|
||||
_swatch(NULL)
|
||||
_swatch(NULL),
|
||||
_pasteMode(false)
|
||||
{
|
||||
_applicationStartupTime = startup_time;
|
||||
_window->setWindowTitle("Interface");
|
||||
|
@ -813,6 +818,10 @@ void Application::mousePressEvent(QMouseEvent* event) {
|
|||
_pieMenu.mousePressEvent(_mouseX, _mouseY);
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelSelectMode) && _pasteMode) {
|
||||
pasteVoxels();
|
||||
}
|
||||
|
||||
if (MAKE_SOUND_ON_VOXEL_CLICK && _isHoverVoxel && !_isHoverVoxelSounding) {
|
||||
_hoverVoxelOriginalColor[0] = _hoverVoxel.red;
|
||||
_hoverVoxelOriginalColor[1] = _hoverVoxel.green;
|
||||
|
@ -1191,185 +1200,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();
|
||||
|
||||
_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<const uint32_t*>(pngImage.constBits());
|
||||
} else {
|
||||
QImage tmp = pngImage.convertToFormat(QImage::Format_ARGB32);
|
||||
pixels = reinterpret_cast<const uint32_t*>(tmp.constBits());
|
||||
}
|
||||
_clipboardTree.readFromSquareARGB32Pixels(pixels, pngImage.height());
|
||||
} else if (fileNameString.endsWith(".svo", Qt::CaseInsensitive)) {
|
||||
_clipboardTree.readFromSVOFile(fileName);
|
||||
} else if (fileNameString.endsWith(".schematic", Qt::CaseInsensitive)) {
|
||||
_clipboardTree.readFromSchematicFile(fileName);
|
||||
}
|
||||
|
||||
// restore the main window's active state
|
||||
_window->activateWindow();
|
||||
}
|
||||
|
||||
void Application::importVoxels() {
|
||||
QString desktopLocation = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
|
||||
_pasteMode = false;
|
||||
|
||||
QStringList fileNameStringList = QFileDialog::getOpenFileNames(_glWidget, tr("Import Voxels"), desktopLocation,
|
||||
tr(IMPORT_FILE_TYPES));
|
||||
if (_voxelImporter.exec()) {
|
||||
qDebug("[DEBUG] Import succedded.\n");
|
||||
|
||||
|
||||
// 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<const uint32_t*>(pngImage.constBits());
|
||||
} else {
|
||||
QImage tmp = pngImage.convertToFormat(QImage::Format_ARGB32);
|
||||
pixels = reinterpret_cast<const uint32_t*>(tmp.constBits());
|
||||
}
|
||||
|
||||
importVoxels.readFromSquareARGB32Pixels(pixels, pngImage.height());
|
||||
} 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();
|
||||
if (_voxelImporter.getimportIntoClipboard()) {
|
||||
_clipboard.killLocalVoxels();
|
||||
_voxelImporter.getVoxelSystem()->copySubTreeIntoNewTree(
|
||||
_voxelImporter.getVoxelSystem()->getVoxelAt(0, 0, 0, 1),
|
||||
&_clipboard,
|
||||
true);
|
||||
} 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;
|
||||
_pasteMode = true;
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
qDebug("[DEBUG] Import failed.\n");
|
||||
}
|
||||
|
||||
|
||||
// restore the main window's active state
|
||||
_window->activateWindow();
|
||||
}
|
||||
|
@ -1383,11 +1234,17 @@ 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);
|
||||
}
|
||||
|
||||
_pasteMode = false;
|
||||
}
|
||||
|
||||
void Application::togglePasteMode() {
|
||||
_pasteMode = !_pasteMode;
|
||||
}
|
||||
|
||||
void Application::pasteVoxels() {
|
||||
|
@ -1407,7 +1264,12 @@ void Application::pasteVoxels() {
|
|||
args.newBaseOctCode = calculatedOctCode = pointToVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
|
||||
}
|
||||
|
||||
_clipboardTree.recurseTreeWithOperation(sendVoxelsOperation, &args);
|
||||
if (_voxelImporter.getImportWaiting()) {
|
||||
_voxelImporter.getVoxelSystem()->recurseTreeWithOperation(sendVoxelsOperation, &args);
|
||||
_voxelImporter.reset();
|
||||
} else {
|
||||
_clipboard.recurseTreeWithOperation(sendVoxelsOperation, &args);
|
||||
}
|
||||
_voxelEditSender.flushQueue();
|
||||
|
||||
if (calculatedOctCode) {
|
||||
|
@ -1449,6 +1311,10 @@ void Application::initDisplay() {
|
|||
|
||||
void Application::init() {
|
||||
_voxels.init();
|
||||
_clipboard.init();
|
||||
_clipboardViewFrustum.setKeyholeRadius(1000.0f);
|
||||
_clipboardViewFrustum.calculate();
|
||||
_clipboard.setViewFrustum(&_clipboardViewFrustum);
|
||||
|
||||
_environment.init();
|
||||
|
||||
|
@ -2335,6 +2201,23 @@ void Application::displaySide(Camera& whichCamera) {
|
|||
glEnable(GL_LIGHTING);
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelSelectMode) && _pasteMode) {
|
||||
glPushMatrix();
|
||||
glTranslatef(_mouseVoxel.x * TREE_SCALE,
|
||||
_mouseVoxel.y * TREE_SCALE,
|
||||
_mouseVoxel.z * TREE_SCALE);
|
||||
glScalef(_mouseVoxel.s * TREE_SCALE,
|
||||
_mouseVoxel.s * TREE_SCALE,
|
||||
_mouseVoxel.s * TREE_SCALE);
|
||||
|
||||
if (_voxelImporter.getImportWaiting()) {
|
||||
_voxelImporter.getVoxelSystem()->render(true);
|
||||
} else {
|
||||
_clipboard.render(true);
|
||||
}
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
_myAvatar.renderScreenTint(SCREEN_TINT_BEFORE_AVATARS, whichCamera);
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
|
||||
|
@ -2403,7 +2286,7 @@ void Application::displaySide(Camera& whichCamera) {
|
|||
}
|
||||
|
||||
renderFollowIndicator();
|
||||
|
||||
|
||||
// render the glow effect
|
||||
_glowEffect.render();
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "VoxelEditPacketSender.h"
|
||||
#include "VoxelPacketProcessor.h"
|
||||
#include "VoxelSystem.h"
|
||||
#include "VoxelImporter.h"
|
||||
#include "Webcam.h"
|
||||
#include "avatar/Avatar.h"
|
||||
#include "avatar/HandControl.h"
|
||||
|
@ -137,9 +138,9 @@ public slots:
|
|||
void sendAvatarFaceVideoMessage(int frameCount, const QByteArray& data);
|
||||
void exportVoxels();
|
||||
void importVoxels();
|
||||
void importVoxelsToClipboard();
|
||||
void cutVoxels();
|
||||
void copyVoxels();
|
||||
void togglePasteMode();
|
||||
void pasteVoxels();
|
||||
|
||||
void setRenderVoxels(bool renderVoxels);
|
||||
|
@ -237,8 +238,10 @@ private:
|
|||
|
||||
Stars _stars;
|
||||
|
||||
VoxelSystem _voxels;
|
||||
VoxelTree _clipboardTree; // if I copy/paste
|
||||
VoxelSystem _voxels;
|
||||
VoxelSystem _clipboard; // if I copy/paste
|
||||
ViewFrustum _clipboardViewFrustum;
|
||||
VoxelImporter _voxelImporter;
|
||||
|
||||
QByteArray _voxelsFilename;
|
||||
bool _wantToKillLocalVoxels;
|
||||
|
@ -340,6 +343,8 @@ private:
|
|||
ToolsPalette _palette;
|
||||
Swatch _swatch;
|
||||
|
||||
bool _pasteMode;
|
||||
|
||||
PieMenu _pieMenu;
|
||||
|
||||
VoxelSceneStats _voxelSceneStats;
|
||||
|
|
260
interface/src/ImportDialog.cpp
Normal file
260
interface/src/ImportDialog.cpp
Normal file
|
@ -0,0 +1,260 @@
|
|||
//
|
||||
// ImportDialog.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Clement Brisset on 8/12/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
#include "ImportDialog.h"
|
||||
#include "Application.h"
|
||||
|
||||
#include <QStandardPaths>
|
||||
#include <QGridLayout>
|
||||
#include <QMouseEvent>
|
||||
|
||||
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, "
|
||||
"Square PNG, "
|
||||
"Schematic Files "
|
||||
"(*.svo *.png *.schematic)");
|
||||
|
||||
const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
|
||||
|
||||
|
||||
const glm::vec3 UP_VECT = 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:
|
||||
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 width, int height);
|
||||
virtual void paintGL();
|
||||
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
void mouseReleaseEvent(QMouseEvent* event);
|
||||
|
||||
private:
|
||||
VoxelSystem* _voxelSystem;
|
||||
|
||||
bool _draw;
|
||||
|
||||
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)
|
||||
: QGLWidget(parent, Application::getInstance()->getGLWidget()),
|
||||
_voxelSystem(voxelSystem),
|
||||
_draw(false),
|
||||
_a(0.0f),
|
||||
_h(VERTICAL_ANGLE),
|
||||
_targetCenter(0.5f, 0.5f, 0.5f),
|
||||
_pressed(false),
|
||||
_mouseX(0),
|
||||
_mouseY(0) {
|
||||
}
|
||||
|
||||
void GLWidget::initializeGL() {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glShadeModel (GL_SMOOTH);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
void GLWidget::resizeGL(int width, int height) {
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(FIELD_OF_VIEW,
|
||||
(float) width / height,
|
||||
NEAR_CLIP,
|
||||
FAR_CLIP);
|
||||
}
|
||||
|
||||
void GLWidget::paintGL() {
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
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_VECT.x, UP_VECT.y, UP_VECT.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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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),
|
||||
_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);
|
||||
gridLayout->addWidget(_glPreview , 1, 3);
|
||||
gridLayout->setColumnStretch(3, 1);
|
||||
|
||||
_previewBar.setVisible(false);
|
||||
_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, 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() {
|
||||
return QFileDialog::exec();
|
||||
}
|
||||
|
||||
void ImportDialog::setGLCamera(float x, float y, float z) {
|
||||
_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);
|
||||
_glPreview->setDraw(wantPreview);
|
||||
|
||||
if (wantPreview) {
|
||||
_glTimer.start();
|
||||
} else {
|
||||
_glTimer.stop();
|
||||
_glPreview->updateGL();
|
||||
}
|
||||
}
|
||||
|
||||
void ImportDialog::saveCurrentFile(QString filename) {
|
||||
_currentFile = filename;
|
||||
}
|
||||
|
||||
void ImportDialog::timer() {
|
||||
_glPreview->updateGL();
|
||||
_glTimer.start(16);
|
||||
}
|
61
interface/src/ImportDialog.h
Normal file
61
interface/src/ImportDialog.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
//
|
||||
// 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 <VoxelSystem.h>
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QPushButton>
|
||||
#include <QCheckBox>
|
||||
#include <QProgressBar>
|
||||
#include <QGLWidget>
|
||||
#include <QTimer>
|
||||
|
||||
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 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);
|
||||
void saveCurrentFile(QString);
|
||||
void timer();
|
||||
|
||||
private:
|
||||
QString _currentFile;
|
||||
QPushButton _importButton;
|
||||
QCheckBox _clipboardImportBox;
|
||||
QCheckBox _previewBox;
|
||||
QProgressBar _previewBar;
|
||||
GLWidget* _glPreview;
|
||||
QTimer _glTimer;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__ImportDialog__) */
|
|
@ -246,14 +246,9 @@ 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()));
|
||||
addActionToQMenuAndActionHash(voxelMenu, MenuOption::PasteVoxels, Qt::CTRL | Qt::Key_V, appInstance, SLOT(togglePasteMode()));
|
||||
|
||||
QMenu* debugMenu = addMenu("Debug");
|
||||
|
||||
|
|
180
interface/src/VoxelImporter.cpp
Normal file
180
interface/src/VoxelImporter.cpp
Normal file
|
@ -0,0 +1,180 @@
|
|||
//
|
||||
// VoxelImporter.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Clement Brisset on 8/9/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <VoxelImporter.h>
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QThreadPool>
|
||||
|
||||
static const int IMPORT_SYSTEM_SCALE = 1.0f;
|
||||
static const int MAX_VOXELS_PER_IMPORT = 2000000;
|
||||
|
||||
class ImportTask : public QObject, public QRunnable {
|
||||
public:
|
||||
ImportTask(VoxelSystem* voxelSystem, const QString &filename);
|
||||
void run();
|
||||
|
||||
private:
|
||||
VoxelSystem* _voxelSystem;
|
||||
QString _filename;
|
||||
};
|
||||
|
||||
VoxelImporter::VoxelImporter(QWidget* parent)
|
||||
: QObject(parent),
|
||||
_voxelSystem(IMPORT_SYSTEM_SCALE, MAX_VOXELS_PER_IMPORT),
|
||||
_initialized(false),
|
||||
_importWaiting(false),
|
||||
_importDialog(parent, &_voxelSystem),
|
||||
_currentTask(NULL),
|
||||
_nextTask(NULL) {
|
||||
|
||||
connect(&_importDialog, SIGNAL(previewToggled(bool)), SLOT(preImport()));
|
||||
connect(&_importDialog, SIGNAL(currentChanged(QString)), SLOT(preImport()));
|
||||
connect(&_importDialog, SIGNAL(accepted()), SLOT(import()));
|
||||
}
|
||||
|
||||
VoxelImporter::~VoxelImporter() {
|
||||
if (_nextTask) {
|
||||
delete _nextTask;
|
||||
_nextTask = NULL;
|
||||
}
|
||||
|
||||
if (_currentTask) {
|
||||
disconnect(_currentTask, 0, 0, 0);
|
||||
_voxelSystem.cancelImport();
|
||||
_currentTask = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelImporter::reset() {
|
||||
_voxelSystem.killLocalVoxels();
|
||||
_importDialog.reset();
|
||||
_filename = "";
|
||||
_importWaiting = false;
|
||||
|
||||
if (_nextTask) {
|
||||
delete _nextTask;
|
||||
_nextTask = NULL;
|
||||
}
|
||||
|
||||
if (_currentTask) {
|
||||
_voxelSystem.cancelImport();
|
||||
}
|
||||
}
|
||||
|
||||
int VoxelImporter::exec() {
|
||||
if (!_initialized) {
|
||||
_voxelSystem.init();
|
||||
_importViewFrustum.calculate();
|
||||
_voxelSystem.setViewFrustum(&_importViewFrustum);
|
||||
_initialized = true;
|
||||
}
|
||||
reset();
|
||||
|
||||
int ret = _importDialog.exec();
|
||||
|
||||
if (!ret) {
|
||||
reset();
|
||||
} else {
|
||||
_importDialog.reset();
|
||||
_importWaiting = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int VoxelImporter::preImport() {
|
||||
QString filename = _importDialog.getCurrentFile();
|
||||
|
||||
if (!QFileInfo(filename).isFile()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_importDialog.getWantPreview()) {
|
||||
_filename = filename;
|
||||
|
||||
if (_nextTask) {
|
||||
delete _nextTask;
|
||||
}
|
||||
|
||||
_nextTask = new ImportTask(&_voxelSystem, _filename);
|
||||
connect(_nextTask, SIGNAL(destroyed()), SLOT(launchTask()));
|
||||
|
||||
if (_currentTask != NULL) {
|
||||
_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;
|
||||
|
||||
if (_nextTask) {
|
||||
delete _nextTask;
|
||||
}
|
||||
|
||||
_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() {
|
||||
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)) {
|
||||
_voxelSystem->readFromSchematicFile(_filename.toLocal8Bit().data());
|
||||
} else {
|
||||
qDebug("[ERROR] Invalid file extension.\n");
|
||||
}
|
||||
}
|
53
interface/src/VoxelImporter.h
Normal file
53
interface/src/VoxelImporter.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
//
|
||||
// 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 <VoxelSystem.h>
|
||||
#include <ImportDialog.h>
|
||||
|
||||
#include <QThread>
|
||||
#include <QRunnable>
|
||||
|
||||
class ImportTask;
|
||||
|
||||
class VoxelImporter : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
VoxelImporter(QWidget* parent = NULL);
|
||||
~VoxelImporter();
|
||||
void reset();
|
||||
|
||||
bool getImportWaiting() const { return _importWaiting; }
|
||||
VoxelSystem* getVoxelSystem() { return &_voxelSystem; }
|
||||
bool getimportIntoClipboard() const { return _importDialog.getImportIntoClipboard(); }
|
||||
|
||||
public slots:
|
||||
int exec();
|
||||
int preImport();
|
||||
int import();
|
||||
|
||||
private slots:
|
||||
void launchTask();
|
||||
|
||||
private:
|
||||
VoxelSystem _voxelSystem;
|
||||
ViewFrustum _importViewFrustum;
|
||||
bool _initialized;
|
||||
bool _importWaiting;
|
||||
|
||||
ImportDialog _importDialog;
|
||||
|
||||
QString _filename;
|
||||
|
||||
ImportTask* _currentTask;
|
||||
ImportTask* _nextTask;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__VoxelImporter__) */
|
|
@ -67,6 +67,9 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) :
|
|||
_voxelServerCount = 0;
|
||||
|
||||
_viewFrustum = Application::getInstance()->getViewFrustum();
|
||||
|
||||
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) {
|
||||
|
@ -142,6 +145,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;
|
||||
}
|
||||
|
@ -638,7 +657,7 @@ void VoxelSystem::updatePartialVBOs() {
|
|||
}
|
||||
|
||||
// if we got to the end of the array, and we're in an active dirty segment...
|
||||
if (inSegment) {
|
||||
if (inSegment) {
|
||||
updateVBOSegment(segmentStart, _voxelsInReadArrays - 1);
|
||||
inSegment = false;
|
||||
}
|
||||
|
@ -978,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) {
|
||||
|
@ -1289,14 +1312,23 @@ void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bo
|
|||
setupNewVoxelsForDrawing();
|
||||
};
|
||||
|
||||
void VoxelSystem::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destinationTree, bool rebaseToRoot) {
|
||||
_tree->copySubTreeIntoNewTree(startNode, destinationTree, rebaseToRoot);
|
||||
void VoxelSystem::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelSystem* destination, bool rebaseToRoot) {
|
||||
_tree->copySubTreeIntoNewTree(startNode, destination->_tree, rebaseToRoot);
|
||||
destination->setupNewVoxelsForDrawing();
|
||||
}
|
||||
|
||||
void VoxelSystem::copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destination, bool rebaseToRoot) {
|
||||
_tree->copySubTreeIntoNewTree(startNode, destination, rebaseToRoot);
|
||||
}
|
||||
|
||||
void VoxelSystem::copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* destinationNode) {
|
||||
_tree->copyFromTreeIntoSubTree(sourceTree, destinationNode);
|
||||
}
|
||||
|
||||
void VoxelSystem::recurseTreeWithOperation(RecurseVoxelTreeOperation operation, void* extraData) {
|
||||
_tree->recurseTreeWithOperation(operation, extraData);
|
||||
}
|
||||
|
||||
struct FalseColorizeOccludedArgs {
|
||||
ViewFrustum* viewFrustum;
|
||||
CoverageMap* map;
|
||||
|
|
|
@ -51,6 +51,8 @@ public:
|
|||
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();
|
||||
|
@ -79,9 +81,12 @@ public:
|
|||
void createSphere(float r,float xc, float yc, float zc, float s, bool solid,
|
||||
creationMode mode, bool destructive = false, bool debug = false);
|
||||
|
||||
void copySubTreeIntoNewTree(VoxelNode* startNode, VoxelSystem* destinationTree, bool rebaseToRoot);
|
||||
void copySubTreeIntoNewTree(VoxelNode* startNode, VoxelTree* destinationTree, bool rebaseToRoot);
|
||||
void copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelNode* destinationNode);
|
||||
|
||||
void recurseTreeWithOperation(RecurseVoxelTreeOperation operation, void* extraData=NULL);
|
||||
|
||||
CoverageMapV2 myCoverageMapV2;
|
||||
CoverageMap myCoverageMap;
|
||||
|
||||
|
@ -89,6 +94,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();
|
||||
|
||||
|
@ -102,6 +111,8 @@ public slots:
|
|||
void falseColorizeOccluded();
|
||||
void falseColorizeOccludedV2();
|
||||
void falseColorizeBySource();
|
||||
|
||||
void cancelImport();
|
||||
|
||||
protected:
|
||||
float _treeScale;
|
||||
|
|
|
@ -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() {
|
||||
|
@ -95,9 +97,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 +119,7 @@ void AmbientOcclusionEffect::render() {
|
|||
|
||||
_occlusionProgram->release();
|
||||
|
||||
secondaryFBO->release();
|
||||
freeFBO->release();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
@ -128,9 +130,10 @@ 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();
|
||||
_blurProgram->setUniformValue(_blurScaleLocation, 1.0f / size.width(), 1.0f / size.height());
|
||||
|
||||
renderFullscreenQuad();
|
||||
|
||||
|
@ -138,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);
|
||||
|
|
|
@ -32,6 +32,7 @@ private:
|
|||
int _noiseScaleLocation;
|
||||
|
||||
ProgramObject* _blurProgram;
|
||||
int _blurScaleLocation;
|
||||
|
||||
GLuint _rotationTextureID;
|
||||
};
|
||||
|
|
|
@ -15,7 +15,13 @@
|
|||
#include "ProgramObject.h"
|
||||
#include "RenderUtil.h"
|
||||
|
||||
GlowEffect::GlowEffect() : _renderMode(BLUR_ADD_MODE) {
|
||||
GlowEffect::GlowEffect() : _renderMode(DIFFUSE_ADD_MODE), _isOddFrame(false) {
|
||||
}
|
||||
|
||||
QOpenGLFramebufferObject* GlowEffect::getFreeFramebufferObject() const {
|
||||
return (_renderMode == DIFFUSE_ADD_MODE && !_isOddFrame) ?
|
||||
Application::getInstance()->getTextureCache()->getTertiaryFramebufferObject() :
|
||||
Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject();
|
||||
}
|
||||
|
||||
static ProgramObject* createProgram(const QString& name) {
|
||||
|
@ -51,6 +57,8 @@ void GlowEffect::init() {
|
|||
_diffuseProgram->bind();
|
||||
_diffuseProgram->setUniformValue("diffusedTexture", 1);
|
||||
_diffuseProgram->release();
|
||||
|
||||
_diffusionScaleLocation = _diffuseProgram->uniformLocation("diffusionScale");
|
||||
}
|
||||
|
||||
void GlowEffect::prepare() {
|
||||
|
@ -58,6 +66,7 @@ void GlowEffect::prepare() {
|
|||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
_isEmpty = true;
|
||||
_isOddFrame = !_isOddFrame;
|
||||
}
|
||||
|
||||
void GlowEffect::begin(float intensity) {
|
||||
|
@ -109,7 +118,7 @@ void GlowEffect::render() {
|
|||
Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject();
|
||||
QOpenGLFramebufferObject* newDiffusedFBO =
|
||||
Application::getInstance()->getTextureCache()->getTertiaryFramebufferObject();
|
||||
if ((_isOddFrame = !_isOddFrame)) {
|
||||
if (_isOddFrame) {
|
||||
qSwap(oldDiffusedFBO, newDiffusedFBO);
|
||||
}
|
||||
newDiffusedFBO->bind();
|
||||
|
@ -118,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();
|
||||
|
@ -204,5 +217,22 @@ 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;
|
||||
|
||||
default:
|
||||
case DIFFUSE_ADD_MODE:
|
||||
qDebug() << "Glow mode: Diffuse/add\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
#include <QObject>
|
||||
|
||||
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.
|
||||
|
@ -51,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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
QOpenGLFramebufferObject* createFramebufferObject();
|
||||
|
||||
GLuint _permutationNormalTextureID;
|
||||
|
||||
QOpenGLFramebufferObject* _primaryFramebufferObject;
|
||||
|
|
|
@ -163,10 +163,13 @@ int retrieveData(std::string filename, std::stringstream &ss) {
|
|||
ss << file;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (type == 0x1F) {
|
||||
return ungzip(file, ss);
|
||||
int ret = ungzip(file, ss);
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::cerr << "[DEBUG] Schematic compression type not recognize : " << type << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -242,3 +245,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <glm/gtc/noise.hpp>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QImage>
|
||||
|
||||
#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();
|
||||
}
|
||||
|
||||
|
@ -359,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;
|
||||
|
@ -1557,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....
|
||||
|
@ -1570,21 +1578,45 @@ bool VoxelTree::readFromSVOFile(const char* fileName) {
|
|||
readBitstreamToTree(entireFile, fileLength, args);
|
||||
delete[] entireFile;
|
||||
|
||||
emit importProgress(100);
|
||||
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
emit importSize(1.0f, 1.0f, 1.0f);
|
||||
emit importProgress(0);
|
||||
|
||||
const uint32_t* pixels;
|
||||
if (pngImage.format() == QImage::Format_ARGB32) {
|
||||
pixels = reinterpret_cast<const uint32_t*>(pngImage.constBits());
|
||||
} else {
|
||||
QImage tmp = pngImage.convertToFormat(QImage::Format_ARGB32);
|
||||
pixels = reinterpret_cast<const uint32_t*>(tmp.constBits());
|
||||
}
|
||||
|
||||
SquarePixelMap pixelMap = SquarePixelMap(pixels, pngImage.height());
|
||||
pixelMap.addVoxelsToVoxelTree(this);
|
||||
|
||||
emit importProgress(100);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VoxelTree::readFromSchematicFile(const char *fileName) {
|
||||
_stopImport = false;
|
||||
emit importProgress(0);
|
||||
|
||||
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,7 +1625,7 @@ 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;
|
||||
}
|
||||
|
||||
|
@ -1608,9 +1640,22 @@ 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());
|
||||
emit importProgress(0);
|
||||
|
||||
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 +1701,7 @@ bool VoxelTree::readFromSchematicFile(const char *fileName) {
|
|||
}
|
||||
}
|
||||
|
||||
emit importProgress(100);
|
||||
qDebug("Created %d voxels from minecraft import.\n", count);
|
||||
|
||||
return true;
|
||||
|
@ -1747,155 +1793,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;
|
||||
}
|
||||
}
|
||||
void VoxelTree::cancelImport() {
|
||||
_stopImport = true;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include "VoxelNodeBag.h"
|
||||
#include "VoxelSceneStats.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
// 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);
|
||||
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue