From 775fd5bd2ebb2a77b649239213a54cf15f4987d4 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 14 May 2013 14:53:29 -0700 Subject: [PATCH 1/6] Use the sun location in the environment to set the light position. --- interface/src/Application.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2cf67b6b8c..ed91a4fcd3 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -374,7 +374,8 @@ void Application::paintGL() { glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); - GLfloat light_position0[] = { 1.0, 1.0, 0.0, 0.0 }; + glm::vec3 relativeSunLoc = glm::normalize(_environment.getSunLocation() - whichCamera.getPosition()); + GLfloat light_position0[] = { relativeSunLoc.x, relativeSunLoc.y, relativeSunLoc.z, 0.0 }; glLightfv(GL_LIGHT0, GL_POSITION, light_position0); GLfloat ambient_color[] = { 0.7, 0.7, 0.8 }; glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_color); From 45e1d341fac1da79fb8e86f95b6212f39b973399 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 14 May 2013 16:02:50 -0700 Subject: [PATCH 2/6] When we add voxels, add them with the selected color. --- interface/src/Application.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ed91a4fcd3..696e3d30ce 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -851,16 +851,16 @@ void Application::idle() { } } - if (_mouseMode == COLOR_VOXEL_MODE) { + if (_mouseMode == DELETE_VOXEL_MODE) { + // red indicates deletion + _mouseVoxel.red = 255; + _mouseVoxel.green = _mouseVoxel.blue = 0; + + } else { // _mouseMode == ADD_VOXEL_MODE || _mouseMode == COLOR_VOXEL_MODE QColor paintColor = _voxelPaintColor->data().value(); _mouseVoxel.red = paintColor.red(); _mouseVoxel.green = paintColor.green(); _mouseVoxel.blue = paintColor.blue(); - - } else if (_mouseMode == DELETE_VOXEL_MODE) { - // red indicates deletion - _mouseVoxel.red = 255; - _mouseVoxel.green = _mouseVoxel.blue = 0; } } From b05140ee511f3e63e84fd6ca28ebaa4e762bdb28 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 15 May 2013 10:40:41 -0700 Subject: [PATCH 3/6] Turned the voxel edit commands into menu options for better visibility. --- interface/src/Application.cpp | 144 ++++++++++++++++++---------------- interface/src/Application.h | 15 ++-- 2 files changed, 87 insertions(+), 72 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 790d044f1b..64f68693f2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -18,6 +18,7 @@ #include #endif +#include #include #include #include @@ -143,7 +144,6 @@ Application::Application(int& argc, char** argv) : _mouseX(0), _mouseY(0), _mousePressed(false), - _mouseMode(NO_EDIT_MODE), _mouseVoxelScale(1.0f / 1024.0f), _paintOn(false), _dominantColor(0), @@ -547,30 +547,6 @@ void Application::keyPressEvent(QKeyEvent* event) { case Qt::Key_Percent: sendVoxelServerAddScene(); break; - - case Qt::Key_1: - _mouseMode = (_mouseMode == ADD_VOXEL_MODE) ? NO_EDIT_MODE : ADD_VOXEL_MODE; - break; - - case Qt::Key_2: - _mouseMode = (_mouseMode == DELETE_VOXEL_MODE) ? NO_EDIT_MODE : DELETE_VOXEL_MODE; - break; - - case Qt::Key_3: - _mouseMode = (_mouseMode == COLOR_VOXEL_MODE) ? NO_EDIT_MODE : COLOR_VOXEL_MODE; - break; - - case Qt::Key_4: - addVoxelInFrontOfAvatar(); - break; - - case Qt::Key_5: - _mouseVoxelScale /= 2; - break; - - case Qt::Key_6: - _mouseVoxelScale *= 2; - break; case Qt::Key_L: _displayLevels = !_displayLevels; @@ -702,13 +678,13 @@ void Application::mousePressEvent(QMouseEvent* event) { _mouseY = event->y(); _mousePressed = true; - if (_mouseMode == ADD_VOXEL_MODE || _mouseMode == COLOR_VOXEL_MODE) { + if (_addVoxelMode->isChecked() || _colorVoxelMode->isChecked()) { addVoxelUnderCursor(); - } else if (_mouseMode == DELETE_VOXEL_MODE) { + } else if (_deleteVoxelMode->isChecked()) { deleteVoxelUnderCursor(); } - } else if (event->button() == Qt::RightButton && _mouseMode != NO_EDIT_MODE) { + } else if (event->button() == Qt::RightButton && _voxelModeActions->checkedAction() != 0) { deleteVoxelUnderCursor(); } } @@ -722,14 +698,14 @@ void Application::mouseReleaseEvent(QMouseEvent* event) { } void Application::wheelEvent(QWheelEvent* event) { - if (_mouseMode == NO_EDIT_MODE) { + if (_voxelModeActions->checkedAction() == 0) { event->ignore(); return; } if (event->delta() > 0) { - _mouseVoxelScale *= 2; + increaseVoxelSize(); } else { - _mouseVoxelScale /= 2; + decreaseVoxelSize(); } } @@ -822,7 +798,7 @@ void Application::idle() { float distance; BoxFace face; _mouseVoxel.s = 0.0f; - if (_mouseMode != NO_EDIT_MODE && _voxels.findRayIntersection( + if (_voxelModeActions->checkedAction() != 0 && _voxels.findRayIntersection( mouseRayOrigin, mouseRayDirection, _mouseVoxel, distance, face)) { // find the nearest voxel with the desired scale if (_mouseVoxelScale > _mouseVoxel.s) { @@ -843,7 +819,7 @@ void Application::idle() { _mouseVoxel.z = _mouseVoxelScale * floorf(pt.z / _mouseVoxelScale); _mouseVoxel.s = _mouseVoxelScale; } - if (_mouseMode == ADD_VOXEL_MODE) { + if (_addVoxelMode->isChecked()) { // use the face to determine the side on which to create a neighbor _mouseVoxel.x += faceVector.x * _mouseVoxel.s; _mouseVoxel.y += faceVector.y * _mouseVoxel.s; @@ -851,12 +827,12 @@ void Application::idle() { } } - if (_mouseMode == DELETE_VOXEL_MODE) { + if (_deleteVoxelMode->isChecked()) { // red indicates deletion _mouseVoxel.red = 255; _mouseVoxel.green = _mouseVoxel.blue = 0; - } else { // _mouseMode == ADD_VOXEL_MODE || _mouseMode == COLOR_VOXEL_MODE + } else { // _addVoxelMode->isChecked() || _colorVoxelMode->isChecked() QColor paintColor = _voxelPaintColor->data().value(); _mouseVoxel.red = paintColor.red(); _mouseVoxel.green = paintColor.green(); @@ -1050,6 +1026,54 @@ void Application::setWantsDelta(bool wantsDelta) { _myAvatar.setWantDelta(wantsDelta); } +void Application::updateVoxelModeActions() { + // only the sender can be checked + foreach (QAction* action, _voxelModeActions->actions()) { + if (action->isChecked() && action != sender()) { + action->setChecked(false); + } + } +} + +static void sendVoxelEditMessage(PACKET_HEADER header, VoxelDetail& detail) { + unsigned char* bufferOut; + int sizeOut; + + if (createVoxelEditMessage(header, 0, 1, &detail, bufferOut, sizeOut)){ + AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1); + delete bufferOut; + } +} + +void Application::addVoxelInFrontOfAvatar() { + VoxelDetail detail; + + glm::vec3 position = (_myAvatar.getPosition() + _myAvatar.getCameraDirection()) * (1.0f / TREE_SCALE); + detail.s = _mouseVoxelScale; + + detail.x = detail.s * floor(position.x / detail.s); + detail.y = detail.s * floor(position.y / detail.s); + detail.z = detail.s * floor(position.z / detail.s); + QColor paintColor = _voxelPaintColor->data().value(); + detail.red = paintColor.red(); + detail.green = paintColor.green(); + detail.blue = paintColor.blue(); + + PACKET_HEADER message = (_destructiveAddVoxel ? PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL); + sendVoxelEditMessage(message, detail); + + // create the voxel locally so it appears immediately + _voxels.createVoxel(detail.x, detail.y, detail.z, detail.s, detail.red, detail.green, detail.blue, _destructiveAddVoxel); +} + +void Application::decreaseVoxelSize() { + _mouseVoxelScale /= 2; +} + +void Application::increaseVoxelSize() { + _mouseVoxelScale *= 2; +} + static QIcon createSwatchIcon(const QColor& color) { QPixmap map(16, 16); map.fill(color); @@ -1102,6 +1126,23 @@ void Application::initMenu() { _renderStatsOn->setShortcut(Qt::Key_Slash); (_logOn = toolsMenu->addAction("Log"))->setCheckable(true); _logOn->setChecked(true); + + _voxelModeActions = new QActionGroup(this); + _voxelModeActions->setExclusive(false); // exclusivity implies one is always checked + (_addVoxelMode = toolsMenu->addAction( + "Add Voxel Mode", this, SLOT(updateVoxelModeActions()), Qt::Key_1))->setCheckable(true); + _voxelModeActions->addAction(_addVoxelMode); + (_deleteVoxelMode = toolsMenu->addAction( + "Delete Voxel Mode", this, SLOT(updateVoxelModeActions()), Qt::Key_2))->setCheckable(true); + _voxelModeActions->addAction(_deleteVoxelMode); + (_colorVoxelMode = toolsMenu->addAction( + "Color Voxel Mode", this, SLOT(updateVoxelModeActions()), Qt::Key_3))->setCheckable(true); + _voxelModeActions->addAction(_colorVoxelMode); + + toolsMenu->addAction("Place Voxel", this, SLOT(addVoxelInFrontOfAvatar()), Qt::Key_4); + toolsMenu->addAction("Decrease Voxel Size", this, SLOT(decreaseVoxelSize()), Qt::Key_5); + toolsMenu->addAction("Increase Voxel Size", this, SLOT(increaseVoxelSize()), Qt::Key_6); + _voxelPaintColor = toolsMenu->addAction("Voxel Paint Color", this, SLOT(chooseVoxelPaintColor()), Qt::Key_7); QColor paintColor(128, 128, 128); _voxelPaintColor->setData(paintColor); @@ -1193,16 +1234,6 @@ void Application::init() { gettimeofday(&_lastTimeIdle, NULL); } -static void sendVoxelEditMessage(PACKET_HEADER header, VoxelDetail& detail) { - unsigned char* bufferOut; - int sizeOut; - - if (createVoxelEditMessage(header, 0, 1, &detail, bufferOut, sizeOut)){ - AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1); - delete bufferOut; - } -} - void Application::updateAvatar(float deltaTime) { // Update my avatar's head position from gyros _myAvatar.updateHeadFromGyros(deltaTime, &_serialPort, &_gravity); @@ -1578,7 +1609,7 @@ void Application::displaySide(Camera& whichCamera) { // indicate what we'll be adding/removing in mouse mode, if anything if (_mouseVoxel.s != 0) { glPushMatrix(); - if (_mouseMode == ADD_VOXEL_MODE) { + if (_addVoxelMode->isChecked()) { // use a contrasting color so that we can see what we're doing glColor3ub(_mouseVoxel.red + 128, _mouseVoxel.green + 128, _mouseVoxel.blue + 128); } else { @@ -1896,27 +1927,6 @@ void Application::shiftPaintingColor() { _paintingVoxel.blue = (_dominantColor == 2) ? randIntInRange(200, 255) : randIntInRange(40, 100); } -void Application::addVoxelInFrontOfAvatar() { - VoxelDetail detail; - - glm::vec3 position = (_myAvatar.getPosition() + _myAvatar.getCameraDirection()) * (1.0f / TREE_SCALE); - detail.s = _mouseVoxelScale; - - detail.x = detail.s * floor(position.x / detail.s); - detail.y = detail.s * floor(position.y / detail.s); - detail.z = detail.s * floor(position.z / detail.s); - QColor paintColor = _voxelPaintColor->data().value(); - detail.red = paintColor.red(); - detail.green = paintColor.green(); - detail.blue = paintColor.blue(); - - PACKET_HEADER message = (_destructiveAddVoxel ? PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL); - sendVoxelEditMessage(message, detail); - - // create the voxel locally so it appears immediately - _voxels.createVoxel(detail.x, detail.y, detail.z, detail.s, detail.red, detail.green, detail.blue, _destructiveAddVoxel); -} - void Application::addVoxelUnderCursor() { if (_mouseVoxel.s != 0) { PACKET_HEADER message = (_destructiveAddVoxel ? PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL); diff --git a/interface/src/Application.h b/interface/src/Application.h index 5418d0740e..9690816172 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -30,6 +30,7 @@ #include "ui/ChatEntry.h" class QAction; +class QActionGroup; class QGLWidget; class QKeyEvent; class QMainWindow; @@ -89,6 +90,10 @@ private slots: void setWantsMonochrome(bool wantsMonochrome); void setWantsResIn(bool wantsResIn); void setWantsDelta(bool wantsDelta); + void updateVoxelModeActions(); + void addVoxelInFrontOfAvatar(); + void decreaseVoxelSize(); + void increaseVoxelSize(); void chooseVoxelPaintColor(); private: @@ -110,7 +115,6 @@ private: void setupPaintingVoxel(); void shiftPaintingColor(); - void addVoxelInFrontOfAvatar(); void addVoxelUnderCursor(); void deleteVoxelUnderCursor(); @@ -135,7 +139,11 @@ private: QAction* _renderAvatarsOn; // Whether to render avatars QAction* _oculusOn; // Whether to configure the display for the Oculus Rift QAction* _renderStatsOn; // Whether to show onscreen text overlay with stats - QAction* _logOn; // Whether to show on-screen log + QAction* _logOn; // Whether to show on-screen log + QActionGroup* _voxelModeActions; // The group of voxel edit mode actions + QAction* _addVoxelMode; // Whether add voxel mode is enabled + QAction* _deleteVoxelMode; // Whether delete voxel mode is enabled + QAction* _colorVoxelMode; // Whether color voxel mode is enabled QAction* _voxelPaintColor; // The color with which to paint voxels QAction* _frustumOn; // Whether or not to display the debug view frustum QAction* _viewFrustumFromOffset; // Whether or not to offset the view of the frustum @@ -192,9 +200,6 @@ private: int _mouseY; bool _mousePressed; // true if mouse has been pressed (clear when finished) - // The current mode for mouse interaction - enum MouseMode { NO_EDIT_MODE, ADD_VOXEL_MODE, DELETE_VOXEL_MODE, COLOR_VOXEL_MODE }; - MouseMode _mouseMode; VoxelDetail _mouseVoxel; // details of the voxel under the mouse cursor float _mouseVoxelScale; // the scale for adding/removing voxels From 63174042491f03c96074fe0e4fb65c72a277bb1d Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 15 May 2013 11:21:34 -0700 Subject: [PATCH 4/6] When in add mode and there's no voxel under the cursor, place the mouse voxel a fixed distance away. --- interface/src/Application.cpp | 84 ++++++++++++++++++++++------------- interface/src/Application.h | 2 + 2 files changed, 56 insertions(+), 30 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 64f68693f2..0545644be0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -684,7 +684,7 @@ void Application::mousePressEvent(QMouseEvent* event) { } else if (_deleteVoxelMode->isChecked()) { deleteVoxelUnderCursor(); } - } else if (event->button() == Qt::RightButton && _voxelModeActions->checkedAction() != 0) { + } else if (event->button() == Qt::RightButton && checkedVoxelModeAction() != 0) { deleteVoxelUnderCursor(); } } @@ -698,7 +698,7 @@ void Application::mouseReleaseEvent(QMouseEvent* event) { } void Application::wheelEvent(QWheelEvent* event) { - if (_voxelModeActions->checkedAction() == 0) { + if (checkedVoxelModeAction() == 0) { event->ignore(); return; } @@ -795,38 +795,49 @@ void Application::idle() { // tell my avatar the posiion and direction of the ray projected ino the world based on the mouse position _myAvatar.setMouseRay(mouseRayOrigin, mouseRayDirection); - float distance; - BoxFace face; _mouseVoxel.s = 0.0f; - if (_voxelModeActions->checkedAction() != 0 && _voxels.findRayIntersection( - mouseRayOrigin, mouseRayDirection, _mouseVoxel, distance, face)) { - // find the nearest voxel with the desired scale - if (_mouseVoxelScale > _mouseVoxel.s) { - // choose the larger voxel that encompasses the one selected - _mouseVoxel.x = _mouseVoxelScale * floorf(_mouseVoxel.x / _mouseVoxelScale); - _mouseVoxel.y = _mouseVoxelScale * floorf(_mouseVoxel.y / _mouseVoxelScale); - _mouseVoxel.z = _mouseVoxelScale * floorf(_mouseVoxel.z / _mouseVoxelScale); - _mouseVoxel.s = _mouseVoxelScale; + if (checkedVoxelModeAction() != 0) { + glm::vec3 oldMouseVoxelPos(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z); - } else { - glm::vec3 faceVector = getFaceVector(face); - if (_mouseVoxelScale < _mouseVoxel.s) { - // find the closest contained voxel - glm::vec3 pt = (mouseRayOrigin + mouseRayDirection * distance) / (float)TREE_SCALE - - faceVector * (_mouseVoxelScale * 0.5f); - _mouseVoxel.x = _mouseVoxelScale * floorf(pt.x / _mouseVoxelScale); - _mouseVoxel.y = _mouseVoxelScale * floorf(pt.y / _mouseVoxelScale); - _mouseVoxel.z = _mouseVoxelScale * floorf(pt.z / _mouseVoxelScale); + float distance; + BoxFace face; + if (_voxels.findRayIntersection(mouseRayOrigin, mouseRayDirection, _mouseVoxel, distance, face)) { + // find the nearest voxel with the desired scale + if (_mouseVoxelScale > _mouseVoxel.s) { + // choose the larger voxel that encompasses the one selected + _mouseVoxel.x = _mouseVoxelScale * floorf(_mouseVoxel.x / _mouseVoxelScale); + _mouseVoxel.y = _mouseVoxelScale * floorf(_mouseVoxel.y / _mouseVoxelScale); + _mouseVoxel.z = _mouseVoxelScale * floorf(_mouseVoxel.z / _mouseVoxelScale); _mouseVoxel.s = _mouseVoxelScale; - } - if (_addVoxelMode->isChecked()) { - // use the face to determine the side on which to create a neighbor - _mouseVoxel.x += faceVector.x * _mouseVoxel.s; - _mouseVoxel.y += faceVector.y * _mouseVoxel.s; - _mouseVoxel.z += faceVector.z * _mouseVoxel.s; - } - } + } else { + glm::vec3 faceVector = getFaceVector(face); + if (_mouseVoxelScale < _mouseVoxel.s) { + // find the closest contained voxel + glm::vec3 pt = (mouseRayOrigin + mouseRayDirection * distance) / (float)TREE_SCALE - + faceVector * (_mouseVoxelScale * 0.5f); + _mouseVoxel.x = _mouseVoxelScale * floorf(pt.x / _mouseVoxelScale); + _mouseVoxel.y = _mouseVoxelScale * floorf(pt.y / _mouseVoxelScale); + _mouseVoxel.z = _mouseVoxelScale * floorf(pt.z / _mouseVoxelScale); + _mouseVoxel.s = _mouseVoxelScale; + } + if (_addVoxelMode->isChecked()) { + // use the face to determine the side on which to create a neighbor + _mouseVoxel.x += faceVector.x * _mouseVoxel.s; + _mouseVoxel.y += faceVector.y * _mouseVoxel.s; + _mouseVoxel.z += faceVector.z * _mouseVoxel.s; + } + } + } else if (_addVoxelMode->isChecked()) { + // place the voxel a fixed distance away + float worldMouseVoxelScale = _mouseVoxelScale * TREE_SCALE; + glm::vec3 pt = mouseRayOrigin + mouseRayDirection * (2.0f + worldMouseVoxelScale * 0.5f); + _mouseVoxel.x = _mouseVoxelScale * floorf(pt.x / worldMouseVoxelScale); + _mouseVoxel.y = _mouseVoxelScale * floorf(pt.y / worldMouseVoxelScale); + _mouseVoxel.z = _mouseVoxelScale * floorf(pt.z / worldMouseVoxelScale); + _mouseVoxel.s = _mouseVoxelScale; + } + if (_deleteVoxelMode->isChecked()) { // red indicates deletion _mouseVoxel.red = 255; @@ -1608,6 +1619,7 @@ void Application::displaySide(Camera& whichCamera) { // indicate what we'll be adding/removing in mouse mode, if anything if (_mouseVoxel.s != 0) { + glDisable(GL_LIGHTING); glPushMatrix(); if (_addVoxelMode->isChecked()) { // use a contrasting color so that we can see what we're doing @@ -1623,6 +1635,7 @@ void Application::displaySide(Camera& whichCamera) { glutWireCube(_mouseVoxel.s); glLineWidth(1.0f); glPopMatrix(); + glEnable(GL_LIGHTING); } if (_renderAvatarsOn->isChecked()) { @@ -1977,6 +1990,17 @@ void Application::setMenuShortcutsEnabled(bool enabled) { setShortcutsEnabled(_window->menuBar(), enabled); } +// when QActionGroup is set to non-exclusive, it doesn't return anything as checked; +// hence, we must check ourselves +QAction* Application::checkedVoxelModeAction() const { + foreach (QAction* action, _voxelModeActions->actions()) { + if (action->isChecked()) { + return action; + } + } + return 0; +} + void Application::attachNewHeadToAgent(Agent *newAgent) { if (newAgent->getLinkedData() == NULL) { newAgent->setLinkedData(new Avatar(false)); diff --git a/interface/src/Application.h b/interface/src/Application.h index 9690816172..7960eeb51a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -122,6 +122,8 @@ private: void setMenuShortcutsEnabled(bool enabled); + QAction* checkedVoxelModeAction() const; + static void attachNewHeadToAgent(Agent *newAgent); #ifndef _WIN32 static void audioMixerUpdate(in_addr_t newMixerAddress, in_port_t newMixerPort); From 0ce9e420855cc3e063cc6d6edc840f3cb6ac84a8 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 15 May 2013 11:48:23 -0700 Subject: [PATCH 5/6] Support dragging when in coloring mode. I tried it in add/delete mode, too, but it felt messy. --- interface/src/Application.cpp | 14 ++++++++++++-- interface/src/Application.h | 5 +++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0545644be0..f954c0a41f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -670,6 +670,12 @@ void Application::keyReleaseEvent(QKeyEvent* event) { void Application::mouseMoveEvent(QMouseEvent* event) { _mouseX = event->x(); _mouseY = event->y(); + + // detect drag + glm::vec3 mouseVoxelPos(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z); + if (_colorVoxelMode->isChecked() && event->buttons().testFlag(Qt::LeftButton) && mouseVoxelPos != _lastMouseVoxelPos) { + addVoxelUnderCursor(); + } } void Application::mousePressEvent(QMouseEvent* event) { @@ -797,8 +803,6 @@ void Application::idle() { _mouseVoxel.s = 0.0f; if (checkedVoxelModeAction() != 0) { - glm::vec3 oldMouseVoxelPos(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z); - float distance; BoxFace face; if (_voxels.findRayIntersection(mouseRayOrigin, mouseRayDirection, _mouseVoxel, distance, face)) { @@ -1948,6 +1952,9 @@ void Application::addVoxelUnderCursor() { // create the voxel locally so it appears immediately _voxels.createVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s, _mouseVoxel.red, _mouseVoxel.green, _mouseVoxel.blue, _destructiveAddVoxel); + + // remember the position for drag detection + _lastMouseVoxelPos = glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z); } } @@ -1957,6 +1964,9 @@ void Application::deleteVoxelUnderCursor() { // delete the voxel locally so it disappears immediately _voxels.deleteVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); + + // remember the position for drag detection + _lastMouseVoxelPos = glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z); } } diff --git a/interface/src/Application.h b/interface/src/Application.h index 7960eeb51a..fde63ef88c 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -202,8 +202,9 @@ private: int _mouseY; bool _mousePressed; // true if mouse has been pressed (clear when finished) - VoxelDetail _mouseVoxel; // details of the voxel under the mouse cursor - float _mouseVoxelScale; // the scale for adding/removing voxels + VoxelDetail _mouseVoxel; // details of the voxel under the mouse cursor + float _mouseVoxelScale; // the scale for adding/removing voxels + glm::vec3 _lastMouseVoxelPos; // the position of the last mouse voxel edit bool _paintOn; // Whether to paint voxels as you fly around unsigned char _dominantColor; // The dominant color of the voxel we're painting From 4292cd9ab391ca32bf37fb532db32e50eb59eb15 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 15 May 2013 12:05:32 -0700 Subject: [PATCH 6/6] Moved voxel options into their own menu, switched destructive flag to check Qt action. --- interface/src/Application.cpp | 36 +++++++++++++++++------------------ interface/src/Application.h | 3 +-- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f954c0a41f..84cc7a1b30 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -148,7 +148,6 @@ Application::Application(int& argc, char** argv) : _paintOn(false), _dominantColor(0), _perfStatsOn(false), - _destructiveAddVoxel(false), _chatEntryOn(false), _oculusTextureID(0), _oculusProgram(0), @@ -985,10 +984,6 @@ void Application::cycleFrustumRenderMode() { updateFrustumRenderModeAction(); } -void Application::setDestructivePaint(bool destructive) { - _destructiveAddVoxel = destructive; -} - void Application::setRenderWarnings(bool renderWarnings) { _voxels.setRenderPipelineWarnings(renderWarnings); } @@ -1074,11 +1069,13 @@ void Application::addVoxelInFrontOfAvatar() { detail.green = paintColor.green(); detail.blue = paintColor.blue(); - PACKET_HEADER message = (_destructiveAddVoxel ? PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL); + PACKET_HEADER message = (_destructiveAddVoxel->isChecked() ? + PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL); sendVoxelEditMessage(message, detail); // create the voxel locally so it appears immediately - _voxels.createVoxel(detail.x, detail.y, detail.z, detail.s, detail.red, detail.green, detail.blue, _destructiveAddVoxel); + _voxels.createVoxel(detail.x, detail.y, detail.z, detail.s, + detail.red, detail.green, detail.blue, _destructiveAddVoxel->isChecked()); } void Application::decreaseVoxelSize() { @@ -1142,27 +1139,28 @@ void Application::initMenu() { (_logOn = toolsMenu->addAction("Log"))->setCheckable(true); _logOn->setChecked(true); + QMenu* voxelMenu = menuBar->addMenu("Voxels"); _voxelModeActions = new QActionGroup(this); _voxelModeActions->setExclusive(false); // exclusivity implies one is always checked - (_addVoxelMode = toolsMenu->addAction( + (_addVoxelMode = voxelMenu->addAction( "Add Voxel Mode", this, SLOT(updateVoxelModeActions()), Qt::Key_1))->setCheckable(true); _voxelModeActions->addAction(_addVoxelMode); - (_deleteVoxelMode = toolsMenu->addAction( + (_deleteVoxelMode = voxelMenu->addAction( "Delete Voxel Mode", this, SLOT(updateVoxelModeActions()), Qt::Key_2))->setCheckable(true); _voxelModeActions->addAction(_deleteVoxelMode); - (_colorVoxelMode = toolsMenu->addAction( + (_colorVoxelMode = voxelMenu->addAction( "Color Voxel Mode", this, SLOT(updateVoxelModeActions()), Qt::Key_3))->setCheckable(true); _voxelModeActions->addAction(_colorVoxelMode); - toolsMenu->addAction("Place Voxel", this, SLOT(addVoxelInFrontOfAvatar()), Qt::Key_4); - toolsMenu->addAction("Decrease Voxel Size", this, SLOT(decreaseVoxelSize()), Qt::Key_5); - toolsMenu->addAction("Increase Voxel Size", this, SLOT(increaseVoxelSize()), Qt::Key_6); + voxelMenu->addAction("Place Voxel", this, SLOT(addVoxelInFrontOfAvatar()), Qt::Key_4); + voxelMenu->addAction("Decrease Voxel Size", this, SLOT(decreaseVoxelSize()), Qt::Key_5); + voxelMenu->addAction("Increase Voxel Size", this, SLOT(increaseVoxelSize()), Qt::Key_6); - _voxelPaintColor = toolsMenu->addAction("Voxel Paint Color", this, SLOT(chooseVoxelPaintColor()), Qt::Key_7); + _voxelPaintColor = voxelMenu->addAction("Voxel Paint Color", this, SLOT(chooseVoxelPaintColor()), Qt::Key_7); QColor paintColor(128, 128, 128); _voxelPaintColor->setData(paintColor); _voxelPaintColor->setIcon(createSwatchIcon(paintColor)); - toolsMenu->addAction("Create Voxel is Destructive", this, SLOT(setDestructivePaint(bool)))->setCheckable(true); + (_destructiveAddVoxel = voxelMenu->addAction("Create Voxel is Destructive"))->setCheckable(true); QMenu* frustumMenu = menuBar->addMenu("Frustum"); (_frustumOn = frustumMenu->addAction("Display Frustum"))->setCheckable(true); @@ -1373,7 +1371,8 @@ void Application::updateAvatar(float deltaTime) { _paintingVoxel.y >= 0.0 && _paintingVoxel.y <= 1.0 && _paintingVoxel.z >= 0.0 && _paintingVoxel.z <= 1.0) { - PACKET_HEADER message = (_destructiveAddVoxel ? PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL); + PACKET_HEADER message = (_destructiveAddVoxel->isChecked() ? + PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL); sendVoxelEditMessage(message, _paintingVoxel); } } @@ -1946,12 +1945,13 @@ void Application::shiftPaintingColor() { void Application::addVoxelUnderCursor() { if (_mouseVoxel.s != 0) { - PACKET_HEADER message = (_destructiveAddVoxel ? PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL); + PACKET_HEADER message = (_destructiveAddVoxel->isChecked() ? + PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL); sendVoxelEditMessage(message, _mouseVoxel); // create the voxel locally so it appears immediately _voxels.createVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s, - _mouseVoxel.red, _mouseVoxel.green, _mouseVoxel.blue, _destructiveAddVoxel); + _mouseVoxel.red, _mouseVoxel.green, _mouseVoxel.blue, _destructiveAddVoxel->isChecked()); // remember the position for drag detection _lastMouseVoxelPos = glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z); diff --git a/interface/src/Application.h b/interface/src/Application.h index fde63ef88c..50341c051e 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -77,7 +77,6 @@ private slots: void setFrustumOffset(bool frustumOffset); void cycleFrustumRenderMode(); - void setDestructivePaint(bool destructive); void setRenderWarnings(bool renderWarnings); void doKillLocalVoxels(); void doRandomizeVoxelColors(); @@ -147,6 +146,7 @@ private: QAction* _deleteVoxelMode; // Whether delete voxel mode is enabled QAction* _colorVoxelMode; // Whether color voxel mode is enabled QAction* _voxelPaintColor; // The color with which to paint voxels + QAction* _destructiveAddVoxel; // when doing voxel editing do we want them to be destructive QAction* _frustumOn; // Whether or not to display the debug view frustum QAction* _viewFrustumFromOffset; // Whether or not to offset the view of the frustum QAction* _cameraFrustum; // which frustum to look at @@ -211,7 +211,6 @@ private: VoxelDetail _paintingVoxel; // The voxel we're painting if we're painting bool _perfStatsOn; // Do we want to display perfStats? - bool _destructiveAddVoxel; // when doing voxel editing do we want them to be destructive ChatEntry _chatEntry; // chat entry field bool _chatEntryOn; // Whether to show the chat entry