From 62b29d26d28e468a27714012e5f693b1b77fdd6e Mon Sep 17 00:00:00 2001 From: LionTurtle Date: Thu, 29 Aug 2013 18:17:06 -0700 Subject: [PATCH 1/8] Nudge function added. Testing nudge. --- interface/src/Application.cpp | 3 + interface/src/VoxelSystem.h | 1 + libraries/voxels/src/VoxelNode.cpp | 2 +- libraries/voxels/src/VoxelTree.cpp | 93 +++++++++++++++++++++++++++++- libraries/voxels/src/VoxelTree.h | 7 +++ 5 files changed, 102 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d69770678c..e22f1c0ccb 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1543,6 +1543,9 @@ void Application::update(float deltaTime) { hoveredNode->setColor(_hoverVoxelOriginalColor); _isHoverVoxelSounding = false; } + glm::vec3 nudgeVec(1, 1, 1); + _voxels.getVoxelTree()->nudgeSubTree(hoveredNode, nudgeVec); + // qDebug("nudge called!\n"); } else { // Voxel is not found, clear all _isHoverVoxelSounding = false; diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 7b6c001e8a..c51df3ce70 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -60,6 +60,7 @@ public: float getVoxelsCreatedPerSecondAverage(); float getVoxelsColoredPerSecondAverage(); float getVoxelsBytesReadPerSecondAverage(); + VoxelTree* getVoxelTree() {return _tree;} void killLocalVoxels(); diff --git a/libraries/voxels/src/VoxelNode.cpp b/libraries/voxels/src/VoxelNode.cpp index 7355e91243..72fb72d466 100644 --- a/libraries/voxels/src/VoxelNode.cpp +++ b/libraries/voxels/src/VoxelNode.cpp @@ -422,4 +422,4 @@ void VoxelNode::notifyDeleteHooks() { for (int i = 0; i < _hooks.size(); i++) { _hooks[i]->nodeDeleted(this); } -} +} \ No newline at end of file diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index b17200448b..b06562fa7b 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -206,7 +206,7 @@ VoxelNode* VoxelTree::nodeForOctalCode(VoxelNode* ancestorNode, return childNode; } else { // we need to go deeper - return nodeForOctalCode(childNode, needleCode,parentOfFoundNode); + return nodeForOctalCode(childNode, needleCode, parentOfFoundNode); } } } @@ -452,10 +452,10 @@ void VoxelTree::deleteVoxelCodeFromTreeRecursion(VoxelNode* node, void* extraDat } } } - int lengthOfancestorNode = numberOfThreeBitSectionsInCode(ancestorNode->getOctalCode()); + int lengthOfAncestorNode = numberOfThreeBitSectionsInCode(ancestorNode->getOctalCode()); // If we've reached the parent of the target, then stop breaking up children - if (lengthOfancestorNode == (args->lengthOfCode - 1)) { + if (lengthOfAncestorNode == (args->lengthOfCode - 1)) { break; } ancestorNode->addChildAtIndex(index); @@ -1911,3 +1911,90 @@ void VoxelTree::emptyDeleteQueue() { void VoxelTree::cancelImport() { _stopImport = true; } + +class NodeChunkArgs { +public: + VoxelTree* thisVoxelTree; + float newSize; + glm::vec3 nudgeVec; +}; + +bool VoxelTree::nudgeCheck(VoxelNode* node, void* extraData) { + if (node->isLeaf()) { + // we have reached the deepest level of nodes/voxels + // now there are two scenarios + // 1) this node's size is <= the minNudgeAmount + // in which case we will simply call nudgeLeaf on this leaf + // 2) this node's size is still not <= the minNudgeAmount + // in which case we need to break this leaf down until the leaf sizes are <= minNudgeAmount + + NodeChunkArgs* args = (NodeChunkArgs*)extraData; + + // get octal code of this node + unsigned char* octalCode = node->getOctalCode(); + + // get voxel position/size + VoxelPositionSize unNudgedDetails; + voxelDetailsForCode(octalCode, unNudgedDetails); + + // check to see if this unNudged node can be nudged + if (unNudgedDetails.s <= args->newSize) { + args->thisVoxelTree->nudgeLeaf(node, extraData); + return false; + } else { + // break the current leaf into smaller chunks + args->thisVoxelTree->chunkifyLeaf(node); + } + } + return true; +} + +void VoxelTree::chunkifyLeaf(VoxelNode* node) { + // because this function will continue being called recursively + // we only need to worry about breaking this specific leaf down + for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { + node->addChildAtIndex(i); + if (node->isColored()) { + node->getChildAtIndex(i)->setColor(node->getColor()); + } + } +} + +// This function is called to nudge the leaves of a tree, given that the +// nudge amount is >= to the leaf scale. +void VoxelTree::nudgeLeaf(VoxelNode* node, void* extraData) { + NodeChunkArgs* args = (NodeChunkArgs*)extraData; + + // get octal code of this node + unsigned char* octalCode = node->getOctalCode(); + + // get voxel position/size + VoxelPositionSize unNudgedDetails; + voxelDetailsForCode(octalCode, unNudgedDetails); + + // delete the old node + deleteVoxelAt(unNudgedDetails.x, unNudgedDetails.y, unNudgedDetails.z, unNudgedDetails.s); + qDebug("unNudged voxel deleted!\n"); + + // create a new voxel in its stead + glm::vec3 nudge = args->nudgeVec; + qDebug("nudged by %f, %f, %f\n", nudge.x, nudge.y, nudge.z); + // createVoxel(unNudgedDetails.x + nudge.x, unNudgedDetails.y + nudge.y, unNudgedDetails.z + nudge.z, unNudgedDetails.s, + // node->getColor()[0], node->getColor()[1], node->getColor()[2], true); + createVoxel(unNudgedDetails.x + nudge.x, unNudgedDetails.y + nudge.y, unNudgedDetails.z + nudge.z, unNudgedDetails.s, + 0, 0, 0, true); + qDebug("nudged voxel created!\n"); +} + +void VoxelTree::nudgeSubTree(VoxelNode* nodeToNudge, const glm::vec3& nudgeAmount) { + // calculate minNudgeAmount to check if breaking the tree into smaller chunks is necessary + float minNudgeAmount = fmin(nudgeAmount.x, nudgeAmount.y); + minNudgeAmount = fmin(minNudgeAmount, nudgeAmount.z); + + NodeChunkArgs args; + args.thisVoxelTree = this; + args.newSize = minNudgeAmount; + args.nudgeVec = nudgeAmount; + + recurseNodeWithOperation(nodeToNudge, nudgeCheck, &args); +} diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 4128ba6cbd..396edcc542 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -195,6 +195,8 @@ public: RecurseVoxelTreeOperation operation, const glm::vec3& point, void* extraData); + void nudgeSubTree(VoxelNode* nodeToNudge, const glm::vec3& nudgeAmount); + signals: void importSize(float x, float y, float z); void importProgress(int progress); @@ -254,6 +256,11 @@ private: void queueForLaterDelete(unsigned char* codeBuffer); /// flushes out any Octal Codes that had to be queued void emptyDeleteQueue(); + + // helper functions for nudgeSubTree + static bool nudgeCheck(VoxelNode* node, void* extraData); + void nudgeLeaf(VoxelNode* node, void* extraData); + void chunkifyLeaf(VoxelNode* node); }; float boundaryDistanceForRenderLevel(unsigned int renderLevel); From 6e37bc3644c728b044317538bc2e6408b1ef2875 Mon Sep 17 00:00:00 2001 From: LionTurtle Date: Thu, 5 Sep 2013 11:06:12 -0700 Subject: [PATCH 2/8] Nudge code working for nudge that is greater than or equal to leaf size. --- interface/src/Application.cpp | 57 ++++++++++++++++-- interface/src/Application.h | 3 + interface/src/Menu.cpp | 1 + interface/src/Menu.h | 1 + libraries/voxels/src/VoxelEditPacketSender.h | 1 + libraries/voxels/src/VoxelTree.cpp | 61 +++++++++++++++++--- libraries/voxels/src/VoxelTree.h | 5 +- 7 files changed, 113 insertions(+), 16 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e22f1c0ccb..b90b8cbe0a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -130,7 +130,8 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _bytesPerSecond(0), _bytesCount(0), _swatch(NULL), - _pasteMode(false) + _pasteMode(false), + _nudgeCount(0) { _applicationStartupTime = startup_time; _window->setWindowTitle("Interface"); @@ -1272,6 +1273,50 @@ void Application::pasteVoxels() { } } +void Application::nudgeVoxels() { + VoxelNode* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); + + if (selectedNode) { + qDebug("UnNudged xyz: %f, %f, %f\n", _mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z); + // // clear the clipboard first... + // _clipboard.killLocalVoxels(); + + // nudge the node + glm::vec3 nudgeVec(0.5 * _mouseVoxel.s, 0.5 * _mouseVoxel.s, 0.5 * _mouseVoxel.s); + // glm::vec3 nudgeVec(_mouseVoxel.s, _mouseVoxel.s, _mouseVoxel.s); + // _voxelEditSender.sendVoxelEditMessage(PACKET_TYPE_ERASE_VOXEL, _mouseVoxel); + _voxels.getVoxelTree()->nudgeSubTree(selectedNode, nudgeVec, _voxelEditSender); + + // if (!selectedNode) { + // qDebug("new node is null\n"); + // } else { + // // get octal code of this node + // unsigned char* octalCode = selectedNode->getOctalCode(); + + // // get voxel position/size + // VoxelPositionSize nudgedDetails; + // voxelDetailsForCode(octalCode, nudgedDetails); + // qDebug("Nudged xyz: %f, %f, %f\n", nudgedDetails.x, nudgedDetails.y, nudgedDetails.z); + // } + + // // then copy onto it + // _voxels.copySubTreeIntoNewTree(selectedNode, &_clipboard, true); + // // deleteVoxelUnderCursor(); + + // // Recurse the clipboard 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 + // SendVoxelsOperationArgs args; + + // // we only need the selected voxel to get the newBaseOctCode, which we can actually calculate from the + // // voxel size/position details. If we don't have an actual selectedNode then use the mouseVoxel to create a + // // target octalCode for where the user is pointing. + // args.newBaseOctCode = selectedNode->getOctalCode(); + + // _clipboard.recurseTreeWithOperation(sendVoxelsOperation, &args); + // _voxelEditSender.flushQueue(); + } +} + void Application::setListenModeNormal() { _audio.setListenMode(AudioRingBuffer::NORMAL); } @@ -1543,9 +1588,11 @@ void Application::update(float deltaTime) { hoveredNode->setColor(_hoverVoxelOriginalColor); _isHoverVoxelSounding = false; } - glm::vec3 nudgeVec(1, 1, 1); - _voxels.getVoxelTree()->nudgeSubTree(hoveredNode, nudgeVec); - // qDebug("nudge called!\n"); + // if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelSelectMode)) { + // nudgeVoxels(); + // _nudgeCount++; + // qDebug("nudgeCount = %d\n", _nudgeCount); + // } } else { // Voxel is not found, clear all _isHoverVoxelSounding = false; @@ -1637,7 +1684,7 @@ void Application::update(float deltaTime) { _mouseVoxel.red = 255; _mouseVoxel.green = _mouseVoxel.blue = 0; } else if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelSelectMode)) { - // yellow indicates deletion + // yellow indicates selection _mouseVoxel.red = _mouseVoxel.green = 255; _mouseVoxel.blue = 0; } else { // _addVoxelMode->isChecked() || _colorVoxelMode->isChecked() diff --git a/interface/src/Application.h b/interface/src/Application.h index a88ea3269f..f1c1d53a66 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -142,6 +142,7 @@ public slots: void cutVoxels(); void copyVoxels(); void pasteVoxels(); + void nudgeVoxels(); void setRenderVoxels(bool renderVoxels); void doKillLocalVoxels(); @@ -352,6 +353,8 @@ private: NodeToJurisdictionMap _voxelServerJurisdictions; std::vector _voxelFades; + + int _nudgeCount; }; #endif /* defined(__interface__Application__) */ diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 119f21df60..937ef5b74c 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -249,6 +249,7 @@ Menu::Menu() : 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::NudgeVoxels, Qt::CTRL | Qt::Key_N, appInstance, SLOT(nudgeVoxels())); QMenu* debugMenu = addMenu("Debug"); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 252c9a8707..6934f09d8f 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -158,6 +158,7 @@ namespace MenuOption { const QString LookAtVectors = "Look-at Vectors"; const QString LowRes = "Lower Resolution While Moving"; const QString Mirror = "Mirror"; + const QString NudgeVoxels = "Nudge Voxels"; const QString OcclusionCulling = "Occlusion Culling"; const QString Oscilloscope = "Audio Oscilloscope"; const QString Pair = "Pair"; diff --git a/libraries/voxels/src/VoxelEditPacketSender.h b/libraries/voxels/src/VoxelEditPacketSender.h index e07bd11baa..bda2c8006d 100644 --- a/libraries/voxels/src/VoxelEditPacketSender.h +++ b/libraries/voxels/src/VoxelEditPacketSender.h @@ -12,6 +12,7 @@ #define __shared__VoxelEditPacketSender__ #include +#include #include // for VoxelDetail #include "JurisdictionMap.h" diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index b06562fa7b..6f125e0d6b 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -31,6 +31,7 @@ #include "VoxelConstants.h" #include "VoxelNodeBag.h" #include "VoxelTree.h" +#include float boundaryDistanceForRenderLevel(unsigned int renderLevel) { return ::VOXEL_SIZE_SCALE / powf(2, renderLevel); @@ -1912,11 +1913,20 @@ void VoxelTree::cancelImport() { _stopImport = true; } +typedef unsigned char nodeColor[4]; + +const nodeColor red = {255, 0, 0, 0}; +const nodeColor green = {0, 255, 0, 0}; +const nodeColor blue = {0, 0, 255, 0}; + class NodeChunkArgs { public: VoxelTree* thisVoxelTree; float newSize; glm::vec3 nudgeVec; + VoxelEditPacketSender* voxelEditSenderPtr; + + int colorIndex; }; bool VoxelTree::nudgeCheck(VoxelNode* node, void* extraData) { @@ -1943,20 +1953,31 @@ bool VoxelTree::nudgeCheck(VoxelNode* node, void* extraData) { return false; } else { // break the current leaf into smaller chunks - args->thisVoxelTree->chunkifyLeaf(node); + args->thisVoxelTree->chunkifyLeaf(node, extraData); } } return true; } -void VoxelTree::chunkifyLeaf(VoxelNode* node) { +void VoxelTree::chunkifyLeaf(VoxelNode* node, void* extraData) { // because this function will continue being called recursively // we only need to worry about breaking this specific leaf down + if (!node->isColored()) { + return; + } + NodeChunkArgs* args = (NodeChunkArgs*)extraData; for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { node->addChildAtIndex(i); - if (node->isColored()) { - node->getChildAtIndex(i)->setColor(node->getColor()); + if (args->colorIndex == 0) { + node->getChildAtIndex(i)->setColor(red); + } else if (args->colorIndex == 1) { + node->getChildAtIndex(i)->setColor(green); + } else if (args->colorIndex == 2) { + node->getChildAtIndex(i)->setColor(blue); } + args->colorIndex++; + args->colorIndex = args->colorIndex % 3; + // node->getChildAtIndex(i)->setColor(node->getColor()); } } @@ -1971,9 +1992,21 @@ void VoxelTree::nudgeLeaf(VoxelNode* node, void* extraData) { // get voxel position/size VoxelPositionSize unNudgedDetails; voxelDetailsForCode(octalCode, unNudgedDetails); + VoxelDetail voxelDetails; + voxelDetails.x = unNudgedDetails.x; + voxelDetails.y = unNudgedDetails.y; + voxelDetails.z = unNudgedDetails.z; + voxelDetails.s = unNudgedDetails.s; + voxelDetails.red = node->getColor()[0]; + qDebug("rgb: %u, %u, %u\n", node->getColor()[0], node->getColor()[1], node->getColor()[2]); + voxelDetails.green = node->getColor()[1]; + voxelDetails.blue = node->getColor()[2]; + + qDebug("UnNudged xyz: %f, %f, %f\n", unNudgedDetails.x, unNudgedDetails.y, unNudgedDetails.z); // delete the old node - deleteVoxelAt(unNudgedDetails.x, unNudgedDetails.y, unNudgedDetails.z, unNudgedDetails.s); + args->voxelEditSenderPtr->sendVoxelEditMessage(PACKET_TYPE_ERASE_VOXEL, voxelDetails); + // deleteVoxelAt(unNudgedDetails.x, unNudgedDetails.y, unNudgedDetails.z, unNudgedDetails.s); qDebug("unNudged voxel deleted!\n"); // create a new voxel in its stead @@ -1981,12 +2014,20 @@ void VoxelTree::nudgeLeaf(VoxelNode* node, void* extraData) { qDebug("nudged by %f, %f, %f\n", nudge.x, nudge.y, nudge.z); // createVoxel(unNudgedDetails.x + nudge.x, unNudgedDetails.y + nudge.y, unNudgedDetails.z + nudge.z, unNudgedDetails.s, // node->getColor()[0], node->getColor()[1], node->getColor()[2], true); - createVoxel(unNudgedDetails.x + nudge.x, unNudgedDetails.y + nudge.y, unNudgedDetails.z + nudge.z, unNudgedDetails.s, - 0, 0, 0, true); - qDebug("nudged voxel created!\n"); + voxelDetails.x = unNudgedDetails.x + nudge.x; + voxelDetails.y = unNudgedDetails.y + nudge.y; + voxelDetails.z = unNudgedDetails.z + nudge.z; + qDebug("Nudged xyz: %f, %f, %f\n", voxelDetails.x, voxelDetails.y, voxelDetails.z); + args->voxelEditSenderPtr->sendVoxelEditMessage(PACKET_TYPE_SET_VOXEL, voxelDetails); + // unsigned char* newOctalCode = pointToVoxel(unNudgedDetails.x + nudge.x, unNudgedDetails.y + nudge.y, unNudgedDetails.z + nudge.z, + // unNudgedDetails.s, node->getColor()[0], node->getColor()[1], node->getColor()[2]); + + // // node = new VoxelNode(newOctalCode); + // node = NULL; + qDebug("nudged node created!\n"); } -void VoxelTree::nudgeSubTree(VoxelNode* nodeToNudge, const glm::vec3& nudgeAmount) { +void VoxelTree::nudgeSubTree(VoxelNode* nodeToNudge, const glm::vec3& nudgeAmount, VoxelEditPacketSender& voxelEditSender) { // calculate minNudgeAmount to check if breaking the tree into smaller chunks is necessary float minNudgeAmount = fmin(nudgeAmount.x, nudgeAmount.y); minNudgeAmount = fmin(minNudgeAmount, nudgeAmount.z); @@ -1995,6 +2036,8 @@ void VoxelTree::nudgeSubTree(VoxelNode* nodeToNudge, const glm::vec3& nudgeAmoun args.thisVoxelTree = this; args.newSize = minNudgeAmount; args.nudgeVec = nudgeAmount; + args.voxelEditSenderPtr = &voxelEditSender; + args.colorIndex = 0; recurseNodeWithOperation(nodeToNudge, nudgeCheck, &args); } diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 396edcc542..b684c96923 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -19,6 +19,7 @@ #include "VoxelNode.h" #include "VoxelNodeBag.h" #include "VoxelSceneStats.h" +#include "VoxelEditPacketSender.h" #include @@ -195,7 +196,7 @@ public: RecurseVoxelTreeOperation operation, const glm::vec3& point, void* extraData); - void nudgeSubTree(VoxelNode* nodeToNudge, const glm::vec3& nudgeAmount); + void nudgeSubTree(VoxelNode* nodeToNudge, const glm::vec3& nudgeAmount, VoxelEditPacketSender& voxelEditSender); signals: void importSize(float x, float y, float z); @@ -260,7 +261,7 @@ private: // helper functions for nudgeSubTree static bool nudgeCheck(VoxelNode* node, void* extraData); void nudgeLeaf(VoxelNode* node, void* extraData); - void chunkifyLeaf(VoxelNode* node); + void chunkifyLeaf(VoxelNode* node, void* extraData); }; float boundaryDistanceForRenderLevel(unsigned int renderLevel); From 647bd5b704922d79b973a7d16c1673f6265aa46a Mon Sep 17 00:00:00 2001 From: LionTurtle Date: Thu, 5 Sep 2013 11:30:23 -0700 Subject: [PATCH 3/8] Got rid of delete in nudge. Create is already destructive. --- interface/src/Application.cpp | 2 ++ libraries/voxels/src/VoxelTree.cpp | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b90b8cbe0a..2d963f939d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1314,6 +1314,8 @@ void Application::nudgeVoxels() { // _clipboard.recurseTreeWithOperation(sendVoxelsOperation, &args); // _voxelEditSender.flushQueue(); + } else { + qDebug("selectedNode is NULL\n"); } } diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 6f125e0d6b..bb20dd1d4a 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -2005,9 +2005,10 @@ void VoxelTree::nudgeLeaf(VoxelNode* node, void* extraData) { qDebug("UnNudged xyz: %f, %f, %f\n", unNudgedDetails.x, unNudgedDetails.y, unNudgedDetails.z); // delete the old node - args->voxelEditSenderPtr->sendVoxelEditMessage(PACKET_TYPE_ERASE_VOXEL, voxelDetails); + // creating a voxel is inherently destructive + // args->voxelEditSenderPtr->sendVoxelEditMessage(PACKET_TYPE_ERASE_VOXEL, voxelDetails); // deleteVoxelAt(unNudgedDetails.x, unNudgedDetails.y, unNudgedDetails.z, unNudgedDetails.s); - qDebug("unNudged voxel deleted!\n"); + // qDebug("unNudged voxel deleted!\n"); // create a new voxel in its stead glm::vec3 nudge = args->nudgeVec; From 868ef8bec67922f4488be9f7341e29d762aa5778 Mon Sep 17 00:00:00 2001 From: LionTurtle Date: Thu, 5 Sep 2013 17:42:25 -0700 Subject: [PATCH 4/8] Add VoxelNudgeMode and preliminary UI grid for nudging. --- interface/src/Application.cpp | 80 ++++++++++++------------------ interface/src/Application.h | 4 +- interface/src/Menu.cpp | 3 ++ interface/src/Menu.h | 1 + interface/src/Util.cpp | 26 ++++++++++ interface/src/Util.h | 2 + libraries/voxels/src/VoxelTree.cpp | 55 ++++++++++---------- libraries/voxels/src/VoxelTree.h | 2 +- 8 files changed, 92 insertions(+), 81 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2d963f939d..9f8453449c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -130,8 +130,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _bytesPerSecond(0), _bytesCount(0), _swatch(NULL), - _pasteMode(false), - _nudgeCount(0) + _pasteMode(false) { _applicationStartupTime = startup_time; _window->setWindowTitle("Interface"); @@ -689,6 +688,9 @@ void Application::keyPressEvent(QKeyEvent* event) { case Qt::Key_O: Menu::getInstance()->triggerOption(MenuOption::VoxelSelectMode); break; + case Qt::Key_N: + Menu::getInstance()->triggerOption(MenuOption::VoxelNudgeMode); + break; case Qt::Key_Slash: Menu::getInstance()->triggerOption(MenuOption::Stats); break; @@ -830,6 +832,9 @@ void Application::mousePressEvent(QMouseEvent* event) { } if (MAKE_SOUND_ON_VOXEL_CLICK && _isHoverVoxel && !_isHoverVoxelSounding) { + if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelNudgeMode)) { + _nudgeVoxel = _hoverVoxel; + } _hoverVoxelOriginalColor[0] = _hoverVoxel.red; _hoverVoxelOriginalColor[1] = _hoverVoxel.green; _hoverVoxelOriginalColor[2] = _hoverVoxel.blue; @@ -1274,48 +1279,22 @@ void Application::pasteVoxels() { } void Application::nudgeVoxels() { - VoxelNode* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); + if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelNudgeMode)) { + VoxelNode* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); - if (selectedNode) { - qDebug("UnNudged xyz: %f, %f, %f\n", _mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z); - // // clear the clipboard first... - // _clipboard.killLocalVoxels(); + if (selectedNode) { + // glPushMatrix(); + // glScalef(TREE_SCALE, TREE_SCALE, TREE_SCALE); + // renderNudgeGrid(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); + // glPopMatrix(); + qDebug("UnNudged xyz: %f, %f, %f\n", _mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z); - // nudge the node - glm::vec3 nudgeVec(0.5 * _mouseVoxel.s, 0.5 * _mouseVoxel.s, 0.5 * _mouseVoxel.s); - // glm::vec3 nudgeVec(_mouseVoxel.s, _mouseVoxel.s, _mouseVoxel.s); - // _voxelEditSender.sendVoxelEditMessage(PACKET_TYPE_ERASE_VOXEL, _mouseVoxel); - _voxels.getVoxelTree()->nudgeSubTree(selectedNode, nudgeVec, _voxelEditSender); - - // if (!selectedNode) { - // qDebug("new node is null\n"); - // } else { - // // get octal code of this node - // unsigned char* octalCode = selectedNode->getOctalCode(); - - // // get voxel position/size - // VoxelPositionSize nudgedDetails; - // voxelDetailsForCode(octalCode, nudgedDetails); - // qDebug("Nudged xyz: %f, %f, %f\n", nudgedDetails.x, nudgedDetails.y, nudgedDetails.z); - // } - - // // then copy onto it - // _voxels.copySubTreeIntoNewTree(selectedNode, &_clipboard, true); - // // deleteVoxelUnderCursor(); - - // // Recurse the clipboard 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 - // SendVoxelsOperationArgs args; - - // // we only need the selected voxel to get the newBaseOctCode, which we can actually calculate from the - // // voxel size/position details. If we don't have an actual selectedNode then use the mouseVoxel to create a - // // target octalCode for where the user is pointing. - // args.newBaseOctCode = selectedNode->getOctalCode(); - - // _clipboard.recurseTreeWithOperation(sendVoxelsOperation, &args); - // _voxelEditSender.flushQueue(); - } else { - qDebug("selectedNode is NULL\n"); + // nudge the node + // glm::vec3 nudgeVec(_mouseVoxel.s, _mouseVoxel.s, _mouseVoxel.s); + // glm::vec3 nudgeVec(0.5 * _mouseVoxel.s, 0.5 * _mouseVoxel.s, 0.5 * _mouseVoxel.s); + glm::vec3 nudgeVec(0.25 * _mouseVoxel.s, 0.25 * _mouseVoxel.s, 0.25 * _mouseVoxel.s); + _voxels.getVoxelTree()->nudgeSubTree(selectedNode, nudgeVec, _voxelEditSender); + } } } @@ -1404,6 +1383,7 @@ void Application::init() { _palette.addAction(Menu::getInstance()->getActionForOption(MenuOption::VoxelColorMode), 0, 2); _palette.addAction(Menu::getInstance()->getActionForOption(MenuOption::VoxelGetColorMode), 0, 3); _palette.addAction(Menu::getInstance()->getActionForOption(MenuOption::VoxelSelectMode), 0, 4); + _palette.addAction(Menu::getInstance()->getActionForOption(MenuOption::VoxelNudgeMode), 0, 5); _pieMenu.init("./resources/images/hifi-interface-tools-v2-pie.svg", _glWidget->width(), @@ -1590,11 +1570,6 @@ void Application::update(float deltaTime) { hoveredNode->setColor(_hoverVoxelOriginalColor); _isHoverVoxelSounding = false; } - // if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelSelectMode)) { - // nudgeVoxels(); - // _nudgeCount++; - // qDebug("nudgeCount = %d\n", _nudgeCount); - // } } else { // Voxel is not found, clear all _isHoverVoxelSounding = false; @@ -1689,6 +1664,8 @@ void Application::update(float deltaTime) { // yellow indicates selection _mouseVoxel.red = _mouseVoxel.green = 255; _mouseVoxel.blue = 0; + } else if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelNudgeMode)) { + _mouseVoxel.red = _mouseVoxel.green = _mouseVoxel.blue = 255; } else { // _addVoxelMode->isChecked() || _colorVoxelMode->isChecked() QColor paintColor = Menu::getInstance()->getActionForOption(MenuOption::VoxelPaintColor)->data().value(); _mouseVoxel.red = paintColor.red(); @@ -2221,7 +2198,14 @@ void Application::displaySide(Camera& whichCamera) { glDisable(GL_LIGHTING); glPushMatrix(); glScalef(TREE_SCALE, TREE_SCALE, TREE_SCALE); - renderMouseVoxelGrid(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); + if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelNudgeMode)) { + VoxelNode* selectedNode = _voxels.getVoxelAt(_nudgeVoxel.x, _nudgeVoxel.y, _nudgeVoxel.z, _nudgeVoxel.s); + if (selectedNode) { + renderNudgeGrid(_nudgeVoxel.x, _nudgeVoxel.y, _nudgeVoxel.z, _nudgeVoxel.s); + } + } else { + renderMouseVoxelGrid(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); + } if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelAddMode)) { // use a contrasting color so that we can see what we're doing glColor3ub(_mouseVoxel.red + 128, _mouseVoxel.green + 128, _mouseVoxel.blue + 128); diff --git a/interface/src/Application.h b/interface/src/Application.h index f1c1d53a66..aca11301b2 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -295,6 +295,8 @@ private: glm::vec3 _lastMouseVoxelPos; // the position of the last mouse voxel edit bool _justEditedVoxel; // set when we've just added/deleted/colored a voxel + VoxelDetail _nudgeVoxel; // details of the voxel to be nudged + bool _isLookingAtOtherAvatar; glm::vec3 _lookatOtherPosition; float _lookatIndicatorScale; @@ -353,8 +355,6 @@ private: NodeToJurisdictionMap _voxelServerJurisdictions; std::vector _voxelFades; - - int _nudgeCount; }; #endif /* defined(__interface__Application__) */ diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 937ef5b74c..3cfc804a89 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -206,6 +206,9 @@ Menu::Menu() : QAction* colorVoxelMode = addCheckableActionToQMenuAndActionHash(voxelMenu, MenuOption::VoxelColorMode, Qt::Key_B); _voxelModeActionsGroup->addAction(colorVoxelMode); + + QAction* nudgeVoxelMode = addCheckableActionToQMenuAndActionHash(voxelMenu, MenuOption::VoxelNudgeMode, Qt::Key_N); + _voxelModeActionsGroup->addAction(nudgeVoxelMode); QAction* selectVoxelMode = addCheckableActionToQMenuAndActionHash(voxelMenu, MenuOption::VoxelSelectMode, Qt::Key_O); _voxelModeActionsGroup->addAction(selectVoxelMode); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 6934f09d8f..57840604b5 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -195,6 +195,7 @@ namespace MenuOption { const QString VoxelGetColorMode = "Get Color Mode"; const QString VoxelMode = "Cycle Voxel Mode"; const QString VoxelPaintColor = "Voxel Paint Color"; + const QString VoxelNudgeMode = "Nudge Voxel Mode"; const QString VoxelSelectMode = "Select Voxel Mode"; const QString VoxelStats = "Voxel Stats"; const QString VoxelTextures = "Voxel Textures"; diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 743957128c..6de1bee2c7 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -414,6 +414,32 @@ void renderMouseVoxelGrid(const float& mouseVoxelX, const float& mouseVoxelY, co glEnd(); } +void renderNudgeGrid(const float& mouseVoxelX, const float& mouseVoxelY, const float& mouseVoxelZ, const float& mouseVoxelS) { + glm::vec3 origin = glm::vec3(mouseVoxelX, mouseVoxelY, mouseVoxelZ); + + glLineWidth(1.0); + + const int GRID_DIMENSIONS = 4; + glBegin(GL_LINES); + + for (int i = 0; i <= GRID_DIMENSIONS; i++) { + for (int j = -GRID_DIMENSIONS / 2; j <= GRID_DIMENSIONS / 2; j++) { + glm::vec3 xColor(0.0, 0.6, 0.0); + glColor3fv(&xColor.x); + + glVertex3f(origin.x + GRID_DIMENSIONS * mouseVoxelS, i * mouseVoxelS, origin.z + j * mouseVoxelS); + glVertex3f(origin.x - GRID_DIMENSIONS * mouseVoxelS, i * mouseVoxelS, origin.z + j * mouseVoxelS); + + glm::vec3 zColor(0.0, 0.0, 0.6); + glColor3fv(&zColor.x); + + glVertex3f(origin.x + j * mouseVoxelS, i * mouseVoxelS, origin.z + GRID_DIMENSIONS * mouseVoxelS); + glVertex3f(origin.x + j * mouseVoxelS, i * mouseVoxelS, origin.z - GRID_DIMENSIONS * mouseVoxelS); + } + } + glEnd(); +} + void renderDiskShadow(glm::vec3 position, glm::vec3 upDirection, float radius, float darkness) { glColor4f(0.0f, 0.0f, 0.0f, darkness); diff --git a/interface/src/Util.h b/interface/src/Util.h index c1bb2949fa..dd41b2bab7 100644 --- a/interface/src/Util.h +++ b/interface/src/Util.h @@ -61,6 +61,8 @@ void renderGroundPlaneGrid(float size, float impact); void renderMouseVoxelGrid(const float& mouseVoxelX, const float& mouseVoxelY, const float& mouseVoxelZ, const float& mouseVoxelS); +void renderNudgeGrid(const float& mouseVoxelX, const float& mouseVoxelY, const float& mouseVoxelZ, const float& mouseVoxelS); + void renderCollisionOverlay(int width, int height, float magnitude); void renderDiskShadow(glm::vec3 position, glm::vec3 upDirection, float radius, float darkness); diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index bb20dd1d4a..6a8ba7b28d 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -1922,6 +1922,7 @@ const nodeColor blue = {0, 0, 255, 0}; class NodeChunkArgs { public: VoxelTree* thisVoxelTree; + float ancestorSize; float newSize; glm::vec3 nudgeVec; VoxelEditPacketSender* voxelEditSenderPtr; @@ -1953,31 +1954,21 @@ bool VoxelTree::nudgeCheck(VoxelNode* node, void* extraData) { return false; } else { // break the current leaf into smaller chunks - args->thisVoxelTree->chunkifyLeaf(node, extraData); + args->thisVoxelTree->chunkifyLeaf(node); } } return true; } -void VoxelTree::chunkifyLeaf(VoxelNode* node, void* extraData) { +void VoxelTree::chunkifyLeaf(VoxelNode* node) { // because this function will continue being called recursively // we only need to worry about breaking this specific leaf down if (!node->isColored()) { return; } - NodeChunkArgs* args = (NodeChunkArgs*)extraData; for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { node->addChildAtIndex(i); - if (args->colorIndex == 0) { - node->getChildAtIndex(i)->setColor(red); - } else if (args->colorIndex == 1) { - node->getChildAtIndex(i)->setColor(green); - } else if (args->colorIndex == 2) { - node->getChildAtIndex(i)->setColor(blue); - } - args->colorIndex++; - args->colorIndex = args->colorIndex % 3; - // node->getChildAtIndex(i)->setColor(node->getColor()); + node->getChildAtIndex(i)->setColor(node->getColor()); } } @@ -1992,39 +1983,35 @@ void VoxelTree::nudgeLeaf(VoxelNode* node, void* extraData) { // get voxel position/size VoxelPositionSize unNudgedDetails; voxelDetailsForCode(octalCode, unNudgedDetails); + + qDebug("UnNudged xyz: %f, %f, %f\n", unNudgedDetails.x, unNudgedDetails.y, unNudgedDetails.z); + VoxelDetail voxelDetails; voxelDetails.x = unNudgedDetails.x; voxelDetails.y = unNudgedDetails.y; voxelDetails.z = unNudgedDetails.z; voxelDetails.s = unNudgedDetails.s; voxelDetails.red = node->getColor()[0]; - qDebug("rgb: %u, %u, %u\n", node->getColor()[0], node->getColor()[1], node->getColor()[2]); voxelDetails.green = node->getColor()[1]; voxelDetails.blue = node->getColor()[2]; - - qDebug("UnNudged xyz: %f, %f, %f\n", unNudgedDetails.x, unNudgedDetails.y, unNudgedDetails.z); + glm::vec3 nudge = args->nudgeVec; // delete the old node - // creating a voxel is inherently destructive - // args->voxelEditSenderPtr->sendVoxelEditMessage(PACKET_TYPE_ERASE_VOXEL, voxelDetails); - // deleteVoxelAt(unNudgedDetails.x, unNudgedDetails.y, unNudgedDetails.z, unNudgedDetails.s); - // qDebug("unNudged voxel deleted!\n"); + if (nudge.x >= args->ancestorSize && nudge.y >= args->ancestorSize && nudge.z >= args->ancestorSize) { + args->voxelEditSenderPtr->sendVoxelEditMessage(PACKET_TYPE_ERASE_VOXEL, voxelDetails); + qDebug("unNudged voxel deleted!\n"); + } - // create a new voxel in its stead - glm::vec3 nudge = args->nudgeVec; + // nudge the old node qDebug("nudged by %f, %f, %f\n", nudge.x, nudge.y, nudge.z); - // createVoxel(unNudgedDetails.x + nudge.x, unNudgedDetails.y + nudge.y, unNudgedDetails.z + nudge.z, unNudgedDetails.s, - // node->getColor()[0], node->getColor()[1], node->getColor()[2], true); + voxelDetails.x = unNudgedDetails.x + nudge.x; voxelDetails.y = unNudgedDetails.y + nudge.y; voxelDetails.z = unNudgedDetails.z + nudge.z; - qDebug("Nudged xyz: %f, %f, %f\n", voxelDetails.x, voxelDetails.y, voxelDetails.z); - args->voxelEditSenderPtr->sendVoxelEditMessage(PACKET_TYPE_SET_VOXEL, voxelDetails); - // unsigned char* newOctalCode = pointToVoxel(unNudgedDetails.x + nudge.x, unNudgedDetails.y + nudge.y, unNudgedDetails.z + nudge.z, - // unNudgedDetails.s, node->getColor()[0], node->getColor()[1], node->getColor()[2]); - // // node = new VoxelNode(newOctalCode); - // node = NULL; + // create a new voxel in its stead + args->voxelEditSenderPtr->sendVoxelEditMessage(PACKET_TYPE_SET_VOXEL, voxelDetails); + qDebug("Nudged xyz: %f, %f, %f\n", voxelDetails.x, voxelDetails.y, voxelDetails.z); qDebug("nudged node created!\n"); } @@ -2033,8 +2020,16 @@ void VoxelTree::nudgeSubTree(VoxelNode* nodeToNudge, const glm::vec3& nudgeAmoun float minNudgeAmount = fmin(nudgeAmount.x, nudgeAmount.y); minNudgeAmount = fmin(minNudgeAmount, nudgeAmount.z); + // get octal code of this node + unsigned char* octalCode = nodeToNudge->getOctalCode(); + + // get voxel position/size + VoxelPositionSize ancestorDetails; + voxelDetailsForCode(octalCode, ancestorDetails); + NodeChunkArgs args; args.thisVoxelTree = this; + args.ancestorSize = ancestorDetails.s; args.newSize = minNudgeAmount; args.nudgeVec = nudgeAmount; args.voxelEditSenderPtr = &voxelEditSender; diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index b684c96923..281cef63e8 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -261,7 +261,7 @@ private: // helper functions for nudgeSubTree static bool nudgeCheck(VoxelNode* node, void* extraData); void nudgeLeaf(VoxelNode* node, void* extraData); - void chunkifyLeaf(VoxelNode* node, void* extraData); + void chunkifyLeaf(VoxelNode* node); }; float boundaryDistanceForRenderLevel(unsigned int renderLevel); From d9657898127dc34a4e79b32b67a2363ba7674459 Mon Sep 17 00:00:00 2001 From: LionTurtle Date: Fri, 6 Sep 2013 11:40:35 -0700 Subject: [PATCH 5/8] Switching nudge to cut/paste implementation. Preliminary. --- interface/src/Application.cpp | 60 ++++++++++++++++++++++++-------- interface/src/Menu.cpp | 9 ++--- interface/src/Util.cpp | 24 ++++++------- interface/src/Util.h | 2 +- libraries/voxels/src/VoxelTree.h | 4 --- 5 files changed, 59 insertions(+), 40 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2a69cb55a1..857951a670 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1287,22 +1287,52 @@ void Application::pasteVoxels() { void Application::nudgeVoxels() { if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelNudgeMode)) { + cutVoxels(); + unsigned char* calculatedOctCode = NULL; VoxelNode* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); - if (selectedNode) { - // glPushMatrix(); - // glScalef(TREE_SCALE, TREE_SCALE, TREE_SCALE); - // renderNudgeGrid(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); - // glPopMatrix(); - qDebug("UnNudged xyz: %f, %f, %f\n", _mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z); + // Recurse the clipboard 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 + SendVoxelsOperationArgs args; - // nudge the node - // glm::vec3 nudgeVec(_mouseVoxel.s, _mouseVoxel.s, _mouseVoxel.s); - // glm::vec3 nudgeVec(0.5 * _mouseVoxel.s, 0.5 * _mouseVoxel.s, 0.5 * _mouseVoxel.s); - glm::vec3 nudgeVec(0.25 * _mouseVoxel.s, 0.25 * _mouseVoxel.s, 0.25 * _mouseVoxel.s); - _voxels.getVoxelTree()->nudgeSubTree(selectedNode, nudgeVec, _voxelEditSender); + // we only need the selected voxel to get the newBaseOctCode, which we can actually calculate from the + // voxel size/position details. If we don't have an actual selectedNode then use the mouseVoxel to create a + // target octalCode for where the user is pointing. + if (selectedNode) { + args.newBaseOctCode = selectedNode->getOctalCode(); + } else { + args.newBaseOctCode = calculatedOctCode = pointToVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); + } + + _sharedVoxelSystem.getTree()->recurseTreeWithOperation(sendVoxelsOperation, &args); + glm::vec3 nudgeVec(0.25 * _mouseVoxel.s, 0.25 * _mouseVoxel.s, 0.25 * _mouseVoxel.s); + _voxels.getVoxelTree()->nudgeSubTree(selectedNode, nudgeVec, _voxelEditSender); + + if (_sharedVoxelSystem.getTree() != &_clipboard) { + _sharedVoxelSystem.killLocalVoxels(); + _sharedVoxelSystem.changeTree(&_clipboard); + } + + _voxelEditSender.flushQueue(); + + if (calculatedOctCode) { + delete[] calculatedOctCode; } } + + + + // VoxelNode* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); + + // if (selectedNode) { + // qDebug("UnNudged xyz: %f, %f, %f\n", _mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z); + + // // nudge the node + // // glm::vec3 nudgeVec(_mouseVoxel.s, _mouseVoxel.s, _mouseVoxel.s); + // // glm::vec3 nudgeVec(0.5 * _mouseVoxel.s, 0.5 * _mouseVoxel.s, 0.5 * _mouseVoxel.s); + // glm::vec3 nudgeVec(0.25 * _mouseVoxel.s, 0.25 * _mouseVoxel.s, 0.25 * _mouseVoxel.s); + // _voxels.getVoxelTree()->nudgeSubTree(selectedNode, nudgeVec, _voxelEditSender); + // } } void Application::setListenModeNormal() { @@ -2278,10 +2308,10 @@ void Application::displaySide(Camera& whichCamera) { glPushMatrix(); glScalef(TREE_SCALE, TREE_SCALE, TREE_SCALE); if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelNudgeMode)) { - VoxelNode* selectedNode = _voxels.getVoxelAt(_nudgeVoxel.x, _nudgeVoxel.y, _nudgeVoxel.z, _nudgeVoxel.s); - if (selectedNode) { - renderNudgeGrid(_nudgeVoxel.x, _nudgeVoxel.y, _nudgeVoxel.z, _nudgeVoxel.s); - } + // VoxelNode* selectedNode = _voxels.getVoxelAt(_nudgeVoxel.x, _nudgeVoxel.y, _nudgeVoxel.z, _nudgeVoxel.s); + // if (selectedNode) { + renderNudgeGrid(_nudgeVoxel.x, _nudgeVoxel.y, _nudgeVoxel.z, _nudgeVoxel.s); + // } } else { renderMouseVoxelGrid(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); } diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 3992189c99..1d9e12cc96 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -108,6 +108,7 @@ Menu::Menu() : addActionToQMenuAndActionHash(editMenu, MenuOption::CutVoxels, Qt::CTRL | Qt::Key_X, appInstance, SLOT(cutVoxels())); addActionToQMenuAndActionHash(editMenu, MenuOption::CopyVoxels, Qt::CTRL | Qt::Key_C, appInstance, SLOT(copyVoxels())); addActionToQMenuAndActionHash(editMenu, MenuOption::PasteVoxels, Qt::CTRL | Qt::Key_V, appInstance, SLOT(pasteVoxels())); + addActionToQMenuAndActionHash(editMenu, MenuOption::NudgeVoxels, Qt::CTRL | Qt::Key_N, appInstance, SLOT(nudgeVoxels())); addDisabledActionAndSeparator(editMenu, "Physics"); addCheckableActionToQMenuAndActionHash(editMenu, MenuOption::Gravity, Qt::SHIFT | Qt::Key_G, true); @@ -132,7 +133,7 @@ Menu::Menu() : QAction* colorVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelColorMode, Qt::Key_B); _voxelModeActionsGroup->addAction(colorVoxelMode); - QAction* nudgeVoxelMode = addCheckableActionToQMenuAndActionHash(voxelMenu, MenuOption::VoxelNudgeMode, Qt::Key_N); + QAction* nudgeVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelNudgeMode, Qt::Key_N); _voxelModeActionsGroup->addAction(nudgeVoxelMode); QAction* selectVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelSelectMode, Qt::Key_O); @@ -180,12 +181,6 @@ Menu::Menu() : appInstance, SLOT(setFullscreen(bool))); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson, Qt::Key_P, true); - 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::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::NudgeVoxels, Qt::CTRL | Qt::Key_N, appInstance, SLOT(nudgeVoxels())); addActionToQMenuAndActionHash(viewMenu, MenuOption::IncreaseAvatarSize, diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index b251500cd2..19c49c2418 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -414,28 +414,26 @@ void renderMouseVoxelGrid(const float& mouseVoxelX, const float& mouseVoxelY, co glEnd(); } -void renderNudgeGrid(const float& mouseVoxelX, const float& mouseVoxelY, const float& mouseVoxelZ, const float& mouseVoxelS) { - glm::vec3 origin = glm::vec3(mouseVoxelX, mouseVoxelY, mouseVoxelZ); +void renderNudgeGrid(const float& voxelX, const float& voxelY, const float& voxelZ, const float& voxelS) { + glm::vec3 origin = glm::vec3(voxelX, voxelY, voxelZ); glLineWidth(1.0); const int GRID_DIMENSIONS = 4; glBegin(GL_LINES); - for (int i = 0; i <= GRID_DIMENSIONS; i++) { - for (int j = -GRID_DIMENSIONS / 2; j <= GRID_DIMENSIONS / 2; j++) { - glm::vec3 xColor(0.0, 0.6, 0.0); - glColor3fv(&xColor.x); + for (int xz = - (GRID_DIMENSIONS / 2); xz <= GRID_DIMENSIONS / 2 + 1; xz++) { + glm::vec3 xColor(0.0, 0.6, 0.0); + glColor3fv(&xColor.x); - glVertex3f(origin.x + GRID_DIMENSIONS * mouseVoxelS, i * mouseVoxelS, origin.z + j * mouseVoxelS); - glVertex3f(origin.x - GRID_DIMENSIONS * mouseVoxelS, i * mouseVoxelS, origin.z + j * mouseVoxelS); + glVertex3f(origin.x + GRID_DIMENSIONS * voxelS, 0, origin.z + xz * voxelS); + glVertex3f(origin.x - (GRID_DIMENSIONS - 1) * voxelS, 0, origin.z + xz * voxelS); - glm::vec3 zColor(0.0, 0.0, 0.6); - glColor3fv(&zColor.x); + glm::vec3 zColor(0.0, 0.0, 0.6); + glColor3fv(&zColor.x); - glVertex3f(origin.x + j * mouseVoxelS, i * mouseVoxelS, origin.z + GRID_DIMENSIONS * mouseVoxelS); - glVertex3f(origin.x + j * mouseVoxelS, i * mouseVoxelS, origin.z - GRID_DIMENSIONS * mouseVoxelS); - } + glVertex3f(origin.x + xz * voxelS, 0, origin.z + GRID_DIMENSIONS * voxelS); + glVertex3f(origin.x + xz * voxelS, 0, origin.z - (GRID_DIMENSIONS - 1) * voxelS); } glEnd(); } diff --git a/interface/src/Util.h b/interface/src/Util.h index cad5bc3495..dc61eaca97 100644 --- a/interface/src/Util.h +++ b/interface/src/Util.h @@ -61,7 +61,7 @@ void renderGroundPlaneGrid(float size, float impact); void renderMouseVoxelGrid(const float& mouseVoxelX, const float& mouseVoxelY, const float& mouseVoxelZ, const float& mouseVoxelS); -void renderNudgeGrid(const float& mouseVoxelX, const float& mouseVoxelY, const float& mouseVoxelZ, const float& mouseVoxelS); +void renderNudgeGrid(const float& voxelX, const float& voxelY, const float& voxelZ, const float& voxelS); void renderCollisionOverlay(int width, int height, float magnitude); diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index c793261433..48550956b2 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -190,10 +190,6 @@ public: void recurseNodeWithOperationDistanceSorted(VoxelNode* node, RecurseVoxelTreeOperation operation, const glm::vec3& point, void* extraData); - void recurseTreeWithOperationDistanceSortedTimed(PointerStack* stackOfNodes, long allowedTime, - RecurseVoxelTreeOperation operation, - const glm::vec3& point, void* extraData); - void nudgeSubTree(VoxelNode* nodeToNudge, const glm::vec3& nudgeAmount, VoxelEditPacketSender& voxelEditSender); signals: From ac878c9c63c20f9ffa479967411dcf85483c9ccb Mon Sep 17 00:00:00 2001 From: LionTurtle Date: Mon, 9 Sep 2013 16:53:31 -0700 Subject: [PATCH 6/8] UI for nudge completed! --- interface/src/Application.cpp | 91 +++++++++++++----------------- interface/src/Application.h | 1 + interface/src/Util.cpp | 39 +++++++++++-- interface/src/Util.h | 4 +- libraries/voxels/src/VoxelTree.cpp | 51 ++++++++++------- 5 files changed, 105 insertions(+), 81 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 857951a670..9653226b0e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -128,7 +128,8 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _bytesPerSecond(0), _bytesCount(0), _swatch(NULL), - _pasteMode(false) + _pasteMode(false), + _finishedNudge(true) { _applicationStartupTime = startup_time; _window->setWindowTitle("Interface"); @@ -844,10 +845,15 @@ void Application::mousePressEvent(QMouseEvent* event) { pasteVoxels(); } - if (MAKE_SOUND_ON_VOXEL_CLICK && _isHoverVoxel && !_isHoverVoxelSounding) { - if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelNudgeMode)) { - _nudgeVoxel = _hoverVoxel; + if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelNudgeMode)) { + VoxelNode* clickedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); + if (clickedNode) { + _nudgeVoxel = _mouseVoxel; + _finishedNudge = false; } + } + + if (MAKE_SOUND_ON_VOXEL_CLICK && _isHoverVoxel && !_isHoverVoxelSounding) { _hoverVoxelOriginalColor[0] = _hoverVoxel.red; _hoverVoxelOriginalColor[1] = _hoverVoxel.green; _hoverVoxelOriginalColor[2] = _hoverVoxel.blue; @@ -1287,52 +1293,16 @@ void Application::pasteVoxels() { void Application::nudgeVoxels() { if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelNudgeMode)) { - cutVoxels(); - unsigned char* calculatedOctCode = NULL; - VoxelNode* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); + // calculate nudgeVec + glm::vec3 nudgeVec(_mouseVoxel.x - _nudgeVoxel.x, _mouseVoxel.y - _nudgeVoxel.y, _mouseVoxel.z - _nudgeVoxel.z); - // Recurse the clipboard 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 - SendVoxelsOperationArgs args; + VoxelNode* nodeToNudge = _voxels.getVoxelAt(_nudgeVoxel.x, _nudgeVoxel.y, _nudgeVoxel.z, _nudgeVoxel.s); - // we only need the selected voxel to get the newBaseOctCode, which we can actually calculate from the - // voxel size/position details. If we don't have an actual selectedNode then use the mouseVoxel to create a - // target octalCode for where the user is pointing. - if (selectedNode) { - args.newBaseOctCode = selectedNode->getOctalCode(); - } else { - args.newBaseOctCode = calculatedOctCode = pointToVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); - } - - _sharedVoxelSystem.getTree()->recurseTreeWithOperation(sendVoxelsOperation, &args); - glm::vec3 nudgeVec(0.25 * _mouseVoxel.s, 0.25 * _mouseVoxel.s, 0.25 * _mouseVoxel.s); - _voxels.getVoxelTree()->nudgeSubTree(selectedNode, nudgeVec, _voxelEditSender); - - if (_sharedVoxelSystem.getTree() != &_clipboard) { - _sharedVoxelSystem.killLocalVoxels(); - _sharedVoxelSystem.changeTree(&_clipboard); - } - - _voxelEditSender.flushQueue(); - - if (calculatedOctCode) { - delete[] calculatedOctCode; + if (nodeToNudge) { + _voxels.getVoxelTree()->nudgeSubTree(nodeToNudge, nudgeVec, _voxelEditSender); + _finishedNudge = true; } } - - - - // VoxelNode* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); - - // if (selectedNode) { - // qDebug("UnNudged xyz: %f, %f, %f\n", _mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z); - - // // nudge the node - // // glm::vec3 nudgeVec(_mouseVoxel.s, _mouseVoxel.s, _mouseVoxel.s); - // // glm::vec3 nudgeVec(0.5 * _mouseVoxel.s, 0.5 * _mouseVoxel.s, 0.5 * _mouseVoxel.s); - // glm::vec3 nudgeVec(0.25 * _mouseVoxel.s, 0.25 * _mouseVoxel.s, 0.25 * _mouseVoxel.s); - // _voxels.getVoxelTree()->nudgeSubTree(selectedNode, nudgeVec, _voxelEditSender); - // } } void Application::setListenModeNormal() { @@ -1612,7 +1582,7 @@ void Application::update(float deltaTime) { lookAtSpot = lookAtRayOrigin + lookAtRayDirection * FAR_AWAY_STARE; _myAvatar.getHead().setLookAtPosition(lookAtSpot); } - + // Find the voxel we are hovering over, and respond if clicked float distance; BoxFace face; @@ -1702,11 +1672,13 @@ void Application::update(float deltaTime) { _mouseVoxel.z += faceVector.z * _mouseVoxel.s; } } + _nudgeVoxel.s = _mouseVoxel.s; } else { _mouseVoxel.s = 0.0f; } } else if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelAddMode) - || Menu::getInstance()->isOptionChecked(MenuOption::VoxelSelectMode)) { + || Menu::getInstance()->isOptionChecked(MenuOption::VoxelSelectMode) + || Menu::getInstance()->isOptionChecked(MenuOption::VoxelNudgeMode)) { // place the voxel a fixed distance away float worldMouseVoxelScale = _mouseVoxelScale * TREE_SCALE; glm::vec3 pt = mouseRayOrigin + mouseRayDirection * (2.0f + worldMouseVoxelScale * 0.5f); @@ -2308,13 +2280,22 @@ void Application::displaySide(Camera& whichCamera) { glPushMatrix(); glScalef(TREE_SCALE, TREE_SCALE, TREE_SCALE); if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelNudgeMode)) { - // VoxelNode* selectedNode = _voxels.getVoxelAt(_nudgeVoxel.x, _nudgeVoxel.y, _nudgeVoxel.z, _nudgeVoxel.s); - // if (selectedNode) { - renderNudgeGrid(_nudgeVoxel.x, _nudgeVoxel.y, _nudgeVoxel.z, _nudgeVoxel.s); - // } + if (!_finishedNudge) { + renderNudgeGuide(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _nudgeVoxel.s); + renderNudgeGrid(_nudgeVoxel.x, _nudgeVoxel.y, _nudgeVoxel.z, _nudgeVoxel.s, _mouseVoxel.s); + glPushMatrix(); + glTranslatef(_nudgeVoxel.x + _nudgeVoxel.s * 0.5f, + _nudgeVoxel.y + _nudgeVoxel.s * 0.5f, + _nudgeVoxel.z + _nudgeVoxel.s * 0.5f); + glColor3ub(255, 255, 255); + glLineWidth(4.0f); + glutWireCube(_nudgeVoxel.s); + glPopMatrix(); + } } else { renderMouseVoxelGrid(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); } + if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelAddMode)) { // use a contrasting color so that we can see what we're doing glColor3ub(_mouseVoxel.red + 128, _mouseVoxel.green + 128, _mouseVoxel.blue + 128); @@ -2325,7 +2306,11 @@ void Application::displaySide(Camera& whichCamera) { _mouseVoxel.y + _mouseVoxel.s*0.5f, _mouseVoxel.z + _mouseVoxel.s*0.5f); glLineWidth(4.0f); - glutWireCube(_mouseVoxel.s); + if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelNudgeMode)) { + glutWireCube(_nudgeVoxel.s); + } else { + glutWireCube(_mouseVoxel.s); + } glLineWidth(1.0f); glPopMatrix(); glEnable(GL_LIGHTING); diff --git a/interface/src/Application.h b/interface/src/Application.h index 2fa97aebdc..5965293c1a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -357,6 +357,7 @@ private: Swatch _swatch; bool _pasteMode; + bool _finishedNudge; PieMenu _pieMenu; diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 19c49c2418..c259379e15 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -414,30 +414,57 @@ void renderMouseVoxelGrid(const float& mouseVoxelX, const float& mouseVoxelY, co glEnd(); } -void renderNudgeGrid(const float& voxelX, const float& voxelY, const float& voxelZ, const float& voxelS) { +void renderNudgeGrid(const float& voxelX, const float& voxelY, const float& voxelZ, const float& voxelS, const float& voxelPrecision) { glm::vec3 origin = glm::vec3(voxelX, voxelY, voxelZ); glLineWidth(1.0); const int GRID_DIMENSIONS = 4; + const int GRID_SCALER = voxelS / voxelPrecision; + const int GRID_SEGMENTS = GRID_DIMENSIONS * GRID_SCALER; glBegin(GL_LINES); - for (int xz = - (GRID_DIMENSIONS / 2); xz <= GRID_DIMENSIONS / 2 + 1; xz++) { + for (int xz = - (GRID_SEGMENTS / 2); xz <= GRID_SEGMENTS / 2 + GRID_SCALER; xz++) { glm::vec3 xColor(0.0, 0.6, 0.0); glColor3fv(&xColor.x); - glVertex3f(origin.x + GRID_DIMENSIONS * voxelS, 0, origin.z + xz * voxelS); - glVertex3f(origin.x - (GRID_DIMENSIONS - 1) * voxelS, 0, origin.z + xz * voxelS); + glVertex3f(origin.x + GRID_DIMENSIONS * voxelS, 0, origin.z + xz * voxelPrecision); + glVertex3f(origin.x - (GRID_DIMENSIONS - 1) * voxelS, 0, origin.z + xz * voxelPrecision); glm::vec3 zColor(0.0, 0.0, 0.6); glColor3fv(&zColor.x); - glVertex3f(origin.x + xz * voxelS, 0, origin.z + GRID_DIMENSIONS * voxelS); - glVertex3f(origin.x + xz * voxelS, 0, origin.z - (GRID_DIMENSIONS - 1) * voxelS); + glVertex3f(origin.x + xz * voxelPrecision, 0, origin.z + GRID_DIMENSIONS * voxelS); + glVertex3f(origin.x + xz * voxelPrecision, 0, origin.z - (GRID_DIMENSIONS - 1) * voxelS); } glEnd(); } +void renderNudgeGuide(const float& voxelX, const float& voxelY, const float& voxelZ, const float& voxelS) { + glm::vec3 origin = glm::vec3(voxelX, voxelY, voxelZ); + + glLineWidth(3.0); + + glBegin(GL_LINES); + + glm::vec3 guideColor(1.0, 1.0, 1.0); + glColor3fv(&guideColor.x); + + glVertex3f(origin.x + voxelS, 0, origin.z); + glVertex3f(origin.x, 0, origin.z); + + glVertex3f(origin.x, 0, origin.z); + glVertex3f(origin.x, 0, origin.z + voxelS); + + glVertex3f(origin.x + voxelS, 0, origin.z); + glVertex3f(origin.x + voxelS, 0, origin.z + voxelS); + + glVertex3f(origin.x, 0, origin.z + voxelS); + glVertex3f(origin.x + voxelS, 0, origin.z + voxelS); + + glEnd(); +} + void renderDiskShadow(glm::vec3 position, glm::vec3 upDirection, float radius, float darkness) { glColor4f(0.0f, 0.0f, 0.0f, darkness); diff --git a/interface/src/Util.h b/interface/src/Util.h index dc61eaca97..9401ca2e9a 100644 --- a/interface/src/Util.h +++ b/interface/src/Util.h @@ -61,7 +61,9 @@ void renderGroundPlaneGrid(float size, float impact); void renderMouseVoxelGrid(const float& mouseVoxelX, const float& mouseVoxelY, const float& mouseVoxelZ, const float& mouseVoxelS); -void renderNudgeGrid(const float& voxelX, const float& voxelY, const float& voxelZ, const float& voxelS); +void renderNudgeGrid(const float& voxelX, const float& voxelY, const float& voxelZ, const float& voxelS, const float& voxelPrecision); + +void renderNudgeGuide(const float& voxelX, const float& voxelY, const float& voxelZ, const float& voxelS); void renderCollisionOverlay(int width, int height, float magnitude); diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 0e9409a795..cec46998e7 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -1858,23 +1858,35 @@ void VoxelTree::cancelImport() { _stopImport = true; } -typedef unsigned char nodeColor[4]; - -const nodeColor red = {255, 0, 0, 0}; -const nodeColor green = {0, 255, 0, 0}; -const nodeColor blue = {0, 0, 255, 0}; - class NodeChunkArgs { public: VoxelTree* thisVoxelTree; float ancestorSize; - float newSize; glm::vec3 nudgeVec; VoxelEditPacketSender* voxelEditSenderPtr; int colorIndex; }; +float findNewLeafSize(const glm::vec3& nudgeAmount, float leafSize) { + // we want the smallest non-zero and non-negative new leafSize + float newLeafSizeX = fabs(fmod(nudgeAmount.x, leafSize)); + float newLeafSizeY = fabs(fmod(nudgeAmount.y, leafSize)); + float newLeafSizeZ = fabs(fmod(nudgeAmount.z, leafSize)); + + float newLeafSize = leafSize; + if (newLeafSizeX) { + newLeafSize = fmin(newLeafSize, newLeafSizeX); + } + if (newLeafSizeY) { + newLeafSize = fmin(newLeafSize, newLeafSizeY); + } + if (newLeafSizeZ) { + newLeafSize = fmin(newLeafSize, newLeafSizeZ); + } + return newLeafSize; +} + bool VoxelTree::nudgeCheck(VoxelNode* node, void* extraData) { if (node->isLeaf()) { // we have reached the deepest level of nodes/voxels @@ -1893,8 +1905,12 @@ bool VoxelTree::nudgeCheck(VoxelNode* node, void* extraData) { VoxelPositionSize unNudgedDetails; voxelDetailsForCode(octalCode, unNudgedDetails); + // find necessary leaf size + float newLeafSize = findNewLeafSize(args->nudgeVec, unNudgedDetails.s); + args->ancestorSize = unNudgedDetails.s; + // check to see if this unNudged node can be nudged - if (unNudgedDetails.s <= args->newSize) { + if (unNudgedDetails.s <= newLeafSize) { args->thisVoxelTree->nudgeLeaf(node, extraData); return false; } else { @@ -1928,8 +1944,6 @@ void VoxelTree::nudgeLeaf(VoxelNode* node, void* extraData) { // get voxel position/size VoxelPositionSize unNudgedDetails; voxelDetailsForCode(octalCode, unNudgedDetails); - - qDebug("UnNudged xyz: %f, %f, %f\n", unNudgedDetails.x, unNudgedDetails.y, unNudgedDetails.z); VoxelDetail voxelDetails; voxelDetails.x = unNudgedDetails.x; @@ -1942,28 +1956,24 @@ void VoxelTree::nudgeLeaf(VoxelNode* node, void* extraData) { glm::vec3 nudge = args->nudgeVec; // delete the old node - if (nudge.x >= args->ancestorSize && nudge.y >= args->ancestorSize && nudge.z >= args->ancestorSize) { + // if the nudge replaces the node in an area outside of the ancestor node + if (fabs(nudge.x) >= args->ancestorSize || fabs(nudge.y) >= args->ancestorSize || fabs(nudge.z) >= args->ancestorSize) { args->voxelEditSenderPtr->sendVoxelEditMessage(PACKET_TYPE_ERASE_VOXEL, voxelDetails); - qDebug("unNudged voxel deleted!\n"); } // nudge the old node - qDebug("nudged by %f, %f, %f\n", nudge.x, nudge.y, nudge.z); - voxelDetails.x = unNudgedDetails.x + nudge.x; voxelDetails.y = unNudgedDetails.y + nudge.y; voxelDetails.z = unNudgedDetails.z + nudge.z; // create a new voxel in its stead - args->voxelEditSenderPtr->sendVoxelEditMessage(PACKET_TYPE_SET_VOXEL, voxelDetails); - qDebug("Nudged xyz: %f, %f, %f\n", voxelDetails.x, voxelDetails.y, voxelDetails.z); - qDebug("nudged node created!\n"); + args->voxelEditSenderPtr->sendVoxelEditMessage(PACKET_TYPE_SET_VOXEL_DESTRUCTIVE, voxelDetails); } void VoxelTree::nudgeSubTree(VoxelNode* nodeToNudge, const glm::vec3& nudgeAmount, VoxelEditPacketSender& voxelEditSender) { - // calculate minNudgeAmount to check if breaking the tree into smaller chunks is necessary - float minNudgeAmount = fmin(nudgeAmount.x, nudgeAmount.y); - minNudgeAmount = fmin(minNudgeAmount, nudgeAmount.z); + if (nudgeAmount == glm::vec3(0, 0, 0)) { + return; + } // get octal code of this node unsigned char* octalCode = nodeToNudge->getOctalCode(); @@ -1975,7 +1985,6 @@ void VoxelTree::nudgeSubTree(VoxelNode* nodeToNudge, const glm::vec3& nudgeAmoun NodeChunkArgs args; args.thisVoxelTree = this; args.ancestorSize = ancestorDetails.s; - args.newSize = minNudgeAmount; args.nudgeVec = nudgeAmount; args.voxelEditSenderPtr = &voxelEditSender; args.colorIndex = 0; From f41533fee6580a052f9169c7b978c716a3afc38d Mon Sep 17 00:00:00 2001 From: LionTurtle Date: Mon, 9 Sep 2013 18:23:37 -0700 Subject: [PATCH 7/8] Add nudgeVoxel shading in grid. Fix erase bug. --- interface/src/Application.cpp | 7 +++++-- interface/src/Util.cpp | 9 +++++++++ libraries/voxels/src/VoxelTree.cpp | 3 +-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e2d857e94e..e14bfa7714 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1672,7 +1672,6 @@ void Application::update(float deltaTime) { _mouseVoxel.z += faceVector.z * _mouseVoxel.s; } } - _nudgeVoxel.s = _mouseVoxel.s; } else { _mouseVoxel.s = 0.0f; } @@ -2322,7 +2321,11 @@ void Application::displaySide(Camera& whichCamera) { _mouseVoxel.z + _mouseVoxel.s*0.5f); glLineWidth(4.0f); if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelNudgeMode)) { - glutWireCube(_nudgeVoxel.s); + if (_nudgeVoxel.s) { + glutWireCube(_nudgeVoxel.s); + } else { + glutWireCube(_mouseVoxel.s); + } } else { glutWireCube(_mouseVoxel.s); } diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index c259379e15..05a68cc5a5 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -438,6 +438,15 @@ void renderNudgeGrid(const float& voxelX, const float& voxelY, const float& voxe glVertex3f(origin.x + xz * voxelPrecision, 0, origin.z - (GRID_DIMENSIONS - 1) * voxelS); } glEnd(); + + glColor3f(1.0f,1.0f,1.0f); + + glBegin(GL_POLYGON);//begin drawing of square + glVertex3f(voxelX, 0.0f, voxelZ);//first vertex + glVertex3f(voxelX + voxelS, 0.0f, voxelZ);//second vertex + glVertex3f(voxelX + voxelS, 0.0f, voxelZ + voxelS);//third vertex + glVertex3f(voxelX, 0.0f, voxelZ + voxelS);//fourth vertex + glEnd();//end drawing of polygon } void renderNudgeGuide(const float& voxelX, const float& voxelY, const float& voxelZ, const float& voxelS) { diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index cec46998e7..3ca3ff90e6 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -1907,7 +1907,6 @@ bool VoxelTree::nudgeCheck(VoxelNode* node, void* extraData) { // find necessary leaf size float newLeafSize = findNewLeafSize(args->nudgeVec, unNudgedDetails.s); - args->ancestorSize = unNudgedDetails.s; // check to see if this unNudged node can be nudged if (unNudgedDetails.s <= newLeafSize) { @@ -1957,7 +1956,7 @@ void VoxelTree::nudgeLeaf(VoxelNode* node, void* extraData) { // delete the old node // if the nudge replaces the node in an area outside of the ancestor node - if (fabs(nudge.x) >= args->ancestorSize || fabs(nudge.y) >= args->ancestorSize || fabs(nudge.z) >= args->ancestorSize) { + if ((fabs(nudge.x) >= args->ancestorSize || fabs(nudge.y) >= args->ancestorSize || fabs(nudge.z) >= args->ancestorSize)) { args->voxelEditSenderPtr->sendVoxelEditMessage(PACKET_TYPE_ERASE_VOXEL, voxelDetails); } From 3b464094d9113bff5a3f2a1ff866f34c02063098 Mon Sep 17 00:00:00 2001 From: LionTurtle Date: Tue, 10 Sep 2013 11:09:50 -0700 Subject: [PATCH 8/8] Remove magic numbers, fix spacing, and other code clean up in nudge code. --- interface/src/Application.cpp | 2 +- interface/src/Util.cpp | 6 +++--- interface/src/Util.h | 4 ++-- interface/src/VoxelSystem.h | 1 - libraries/voxels/src/VoxelTree.cpp | 11 ++++------- 5 files changed, 10 insertions(+), 14 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e14bfa7714..20889ab117 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1299,7 +1299,7 @@ void Application::nudgeVoxels() { VoxelNode* nodeToNudge = _voxels.getVoxelAt(_nudgeVoxel.x, _nudgeVoxel.y, _nudgeVoxel.z, _nudgeVoxel.s); if (nodeToNudge) { - _voxels.getVoxelTree()->nudgeSubTree(nodeToNudge, nudgeVec, _voxelEditSender); + _voxels.getTree()->nudgeSubTree(nodeToNudge, nudgeVec, _voxelEditSender); _finishedNudge = true; } } diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 05a68cc5a5..8898ab9eab 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -414,7 +414,7 @@ void renderMouseVoxelGrid(const float& mouseVoxelX, const float& mouseVoxelY, co glEnd(); } -void renderNudgeGrid(const float& voxelX, const float& voxelY, const float& voxelZ, const float& voxelS, const float& voxelPrecision) { +void renderNudgeGrid(float voxelX, float voxelY, float voxelZ, float voxelS, float voxelPrecision) { glm::vec3 origin = glm::vec3(voxelX, voxelY, voxelZ); glLineWidth(1.0); @@ -438,7 +438,7 @@ void renderNudgeGrid(const float& voxelX, const float& voxelY, const float& voxe glVertex3f(origin.x + xz * voxelPrecision, 0, origin.z - (GRID_DIMENSIONS - 1) * voxelS); } glEnd(); - + glColor3f(1.0f,1.0f,1.0f); glBegin(GL_POLYGON);//begin drawing of square @@ -449,7 +449,7 @@ void renderNudgeGrid(const float& voxelX, const float& voxelY, const float& voxe glEnd();//end drawing of polygon } -void renderNudgeGuide(const float& voxelX, const float& voxelY, const float& voxelZ, const float& voxelS) { +void renderNudgeGuide(float voxelX, float voxelY, float voxelZ, float voxelS) { glm::vec3 origin = glm::vec3(voxelX, voxelY, voxelZ); glLineWidth(3.0); diff --git a/interface/src/Util.h b/interface/src/Util.h index 9401ca2e9a..3039ab1a31 100644 --- a/interface/src/Util.h +++ b/interface/src/Util.h @@ -61,9 +61,9 @@ void renderGroundPlaneGrid(float size, float impact); void renderMouseVoxelGrid(const float& mouseVoxelX, const float& mouseVoxelY, const float& mouseVoxelZ, const float& mouseVoxelS); -void renderNudgeGrid(const float& voxelX, const float& voxelY, const float& voxelZ, const float& voxelS, const float& voxelPrecision); +void renderNudgeGrid(float voxelX, float voxelY, float voxelZ, float voxelS, float voxelPrecision); -void renderNudgeGuide(const float& voxelX, const float& voxelY, const float& voxelZ, const float& voxelS); +void renderNudgeGuide(float voxelX, float voxelY, float voxelZ, float voxelS); void renderCollisionOverlay(int width, int height, float magnitude); diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 45c0a5fee7..5ac5310b76 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -62,7 +62,6 @@ public: float getVoxelsCreatedPerSecondAverage(); float getVoxelsColoredPerSecondAverage(); float getVoxelsBytesReadPerSecondAverage(); - VoxelTree* getVoxelTree() {return _tree;} void killLocalVoxels(); diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 3ca3ff90e6..2e4fbdf26e 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -1864,8 +1864,6 @@ public: float ancestorSize; glm::vec3 nudgeVec; VoxelEditPacketSender* voxelEditSenderPtr; - - int colorIndex; }; float findNewLeafSize(const glm::vec3& nudgeAmount, float leafSize) { @@ -1949,14 +1947,14 @@ void VoxelTree::nudgeLeaf(VoxelNode* node, void* extraData) { voxelDetails.y = unNudgedDetails.y; voxelDetails.z = unNudgedDetails.z; voxelDetails.s = unNudgedDetails.s; - voxelDetails.red = node->getColor()[0]; - voxelDetails.green = node->getColor()[1]; - voxelDetails.blue = node->getColor()[2]; + voxelDetails.red = node->getColor()[RED_INDEX]; + voxelDetails.green = node->getColor()[GREEN_INDEX]; + voxelDetails.blue = node->getColor()[BLUE_INDEX]; glm::vec3 nudge = args->nudgeVec; // delete the old node // if the nudge replaces the node in an area outside of the ancestor node - if ((fabs(nudge.x) >= args->ancestorSize || fabs(nudge.y) >= args->ancestorSize || fabs(nudge.z) >= args->ancestorSize)) { + if (fabs(nudge.x) >= args->ancestorSize || fabs(nudge.y) >= args->ancestorSize || fabs(nudge.z) >= args->ancestorSize) { args->voxelEditSenderPtr->sendVoxelEditMessage(PACKET_TYPE_ERASE_VOXEL, voxelDetails); } @@ -1986,7 +1984,6 @@ void VoxelTree::nudgeSubTree(VoxelNode* nodeToNudge, const glm::vec3& nudgeAmoun args.ancestorSize = ancestorDetails.s; args.nudgeVec = nudgeAmount; args.voxelEditSenderPtr = &voxelEditSender; - args.colorIndex = 0; recurseNodeWithOperation(nodeToNudge, nudgeCheck, &args); }