From dd02bae5b32bb6de15f6b7c92a8abf11ebabce00 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 15 Apr 2014 16:11:00 -0700 Subject: [PATCH 1/5] First cut at improved undo --- libraries/voxels/src/VoxelTreeCommands.cpp | 84 +++++++++++++++++----- libraries/voxels/src/VoxelTreeCommands.h | 4 ++ 2 files changed, 70 insertions(+), 18 deletions(-) diff --git a/libraries/voxels/src/VoxelTreeCommands.cpp b/libraries/voxels/src/VoxelTreeCommands.cpp index f0f092fd04..75b38667ec 100644 --- a/libraries/voxels/src/VoxelTreeCommands.cpp +++ b/libraries/voxels/src/VoxelTreeCommands.cpp @@ -17,8 +17,37 @@ AddVoxelCommand::AddVoxelCommand(VoxelTree* tree, VoxelDetail& voxel, VoxelEditP QUndoCommand("Add Voxel", parent), _tree(tree), _packetSender(packetSender), - _voxel(voxel) + _voxel(voxel), + _oldTree(NULL) { + VoxelTreeElement* element = _tree->getVoxelAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s); + if (element) { + if (element->hasContent() && element->isLeaf()) { + // Do nothing, everything is in order + } else { + _oldTree = new VoxelTree(); + _tree->copySubTreeIntoNewTree(element, _oldTree, true); + } + } else { + glm::vec3 point(_voxel.x + _voxel.s / 2.0f, + _voxel.y + _voxel.s / 2.0f, + _voxel.z + _voxel.s / 2.0f); + OctreeElement* element = _tree->getElementEnclosingPoint(point, Octree::Lock); + if (element) { + VoxelTreeElement* node = static_cast(element); + _voxel.x = node->getCorner().x; + _voxel.y = node->getCorner().y; + _voxel.z = node->getCorner().z; + _voxel.s = node->getScale(); + _voxel.red = node->getColor()[0]; + _voxel.green = node->getColor()[1]; + _voxel.blue = node->getColor()[2]; + } + } +} + +AddVoxelCommand::~AddVoxelCommand() { + delete _oldTree; } void AddVoxelCommand::redo() { @@ -31,11 +60,17 @@ void AddVoxelCommand::redo() { } void AddVoxelCommand::undo() { - if (_tree) { - _tree->deleteVoxelAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s); - } - if (_packetSender) { - _packetSender->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &_voxel); + if (_oldTree) { + OctreeElement* element = _tree->getOrCreateChildElementAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s); + qDebug() << _voxel.x << " " << _voxel.y << " " << _voxel.z << " " << _voxel.s; + _tree->copyFromTreeIntoSubTree(_oldTree, element); + } else { + if (_tree) { + _tree->deleteVoxelAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s); + } + if (_packetSender) { + _packetSender->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &_voxel); + } } } @@ -43,24 +78,37 @@ DeleteVoxelCommand::DeleteVoxelCommand(VoxelTree* tree, VoxelDetail& voxel, Voxe QUndoCommand("Delete Voxel", parent), _tree(tree), _packetSender(packetSender), - _voxel(voxel) + _voxel(voxel), + _oldTree(NULL) { } +DeleteVoxelCommand::~DeleteVoxelCommand() { + delete _oldTree; +} + void DeleteVoxelCommand::redo() { - if (_tree) { - _tree->deleteVoxelAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s); - } - if (_packetSender) { - _packetSender->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &_voxel); + if (_oldTree) { + + } else { + if (_tree) { + _tree->deleteVoxelAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s); + } + if (_packetSender) { + _packetSender->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &_voxel); + } } } void DeleteVoxelCommand::undo() { - if (_tree) { - _tree->createVoxel(_voxel.x, _voxel.y, _voxel.z, _voxel.s, _voxel.red, _voxel.green, _voxel.blue); + if (_oldTree) { + + } else { + if (_tree) { + _tree->createVoxel(_voxel.x, _voxel.y, _voxel.z, _voxel.s, _voxel.red, _voxel.green, _voxel.blue); + } + if (_packetSender) { + _packetSender->queueVoxelEditMessages(PacketTypeVoxelSet, 1, &_voxel); + } } - if (_packetSender) { - _packetSender->queueVoxelEditMessages(PacketTypeVoxelSet, 1, &_voxel); - } -} +} \ No newline at end of file diff --git a/libraries/voxels/src/VoxelTreeCommands.h b/libraries/voxels/src/VoxelTreeCommands.h index 4f2610577e..c3b23e7201 100644 --- a/libraries/voxels/src/VoxelTreeCommands.h +++ b/libraries/voxels/src/VoxelTreeCommands.h @@ -23,6 +23,7 @@ class VoxelTree; class AddVoxelCommand : public QUndoCommand { public: AddVoxelCommand(VoxelTree* tree, VoxelDetail& voxel, VoxelEditPacketSender* packetSender = NULL, QUndoCommand* parent = NULL); + ~AddVoxelCommand(); virtual void redo(); virtual void undo(); @@ -31,11 +32,13 @@ private: VoxelTree* _tree; VoxelEditPacketSender* _packetSender; VoxelDetail _voxel; + VoxelTree* _oldTree; }; class DeleteVoxelCommand : public QUndoCommand { public: DeleteVoxelCommand(VoxelTree* tree, VoxelDetail& voxel, VoxelEditPacketSender* packetSender = NULL, QUndoCommand* parent = NULL); + ~DeleteVoxelCommand(); virtual void redo(); virtual void undo(); @@ -44,6 +47,7 @@ private: VoxelTree* _tree; VoxelEditPacketSender* _packetSender; VoxelDetail _voxel; + VoxelTree* _oldTree; }; #endif // hifi_VoxelTreeCommands_h From 378afdf117fb2617232b636311b34dcd27a3e2d9 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 23 Apr 2014 10:35:24 -0700 Subject: [PATCH 2/5] More undo work --- libraries/voxels/src/VoxelTree.cpp | 2 +- libraries/voxels/src/VoxelTreeCommands.cpp | 26 ++++------------------ 2 files changed, 5 insertions(+), 23 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index bb9de72e9d..3a77382a84 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -42,7 +42,7 @@ void VoxelTree::deleteVoxelAt(float x, float y, float z, float s) { } VoxelTreeElement* VoxelTree::getVoxelAt(float x, float y, float z, float s) const { - return (VoxelTreeElement*)getOctreeElementAt(x, y, z, s); + return static_cast(getOctreeElementAt(x, y, z, s)); } void VoxelTree::createVoxel(float x, float y, float z, float s, diff --git a/libraries/voxels/src/VoxelTreeCommands.cpp b/libraries/voxels/src/VoxelTreeCommands.cpp index 75b38667ec..46837aa23e 100644 --- a/libraries/voxels/src/VoxelTreeCommands.cpp +++ b/libraries/voxels/src/VoxelTreeCommands.cpp @@ -22,27 +22,8 @@ AddVoxelCommand::AddVoxelCommand(VoxelTree* tree, VoxelDetail& voxel, VoxelEditP { VoxelTreeElement* element = _tree->getVoxelAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s); if (element) { - if (element->hasContent() && element->isLeaf()) { - // Do nothing, everything is in order - } else { - _oldTree = new VoxelTree(); - _tree->copySubTreeIntoNewTree(element, _oldTree, true); - } - } else { - glm::vec3 point(_voxel.x + _voxel.s / 2.0f, - _voxel.y + _voxel.s / 2.0f, - _voxel.z + _voxel.s / 2.0f); - OctreeElement* element = _tree->getElementEnclosingPoint(point, Octree::Lock); - if (element) { - VoxelTreeElement* node = static_cast(element); - _voxel.x = node->getCorner().x; - _voxel.y = node->getCorner().y; - _voxel.z = node->getCorner().z; - _voxel.s = node->getScale(); - _voxel.red = node->getColor()[0]; - _voxel.green = node->getColor()[1]; - _voxel.blue = node->getColor()[2]; - } + _oldTree = new VoxelTree(); + _tree->copySubTreeIntoNewTree(element, _oldTree, true); } } @@ -62,8 +43,9 @@ void AddVoxelCommand::redo() { void AddVoxelCommand::undo() { if (_oldTree) { OctreeElement* element = _tree->getOrCreateChildElementAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s); - qDebug() << _voxel.x << " " << _voxel.y << " " << _voxel.z << " " << _voxel.s; + qDebug() << "undo(): " << _voxel.x << " " << _voxel.y << " " << _voxel.z << " " << _voxel.s; _tree->copyFromTreeIntoSubTree(_oldTree, element); + qDebug() << "done"; } else { if (_tree) { _tree->deleteVoxelAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s); From 9bdcfe6d041fcf192b1e20597e118f6f130a5c79 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Apr 2014 11:01:12 -0700 Subject: [PATCH 3/5] Undo now fully support local subtrees --- examples/editVoxels.js | 2 - libraries/voxels/src/VoxelTree.cpp | 7 + libraries/voxels/src/VoxelTree.h | 1 + libraries/voxels/src/VoxelTreeCommands.cpp | 130 +++++++++++++----- libraries/voxels/src/VoxelTreeCommands.h | 2 - .../voxels/src/VoxelsScriptingInterface.cpp | 36 ++--- 6 files changed, 115 insertions(+), 63 deletions(-) diff --git a/examples/editVoxels.js b/examples/editVoxels.js index 12c571b09c..453ac28649 100644 --- a/examples/editVoxels.js +++ b/examples/editVoxels.js @@ -1088,7 +1088,6 @@ function keyPressEvent(event) { red: colors[whichColor].red, green: colors[whichColor].green, blue: colors[whichColor].blue }; - Voxels.eraseVoxel(newVoxel.x, newVoxel.y, newVoxel.z, newVoxel.s); Voxels.setVoxel(newVoxel.x, newVoxel.y, newVoxel.z, newVoxel.s, newVoxel.red, newVoxel.green, newVoxel.blue); setAudioPosition(); initialVoxelSound.playRandom(); @@ -1394,7 +1393,6 @@ function checkControllers() { if (Vec3.length(Vec3.subtract(fingerTipPosition,lastFingerAddVoxel)) > (FINGERTIP_VOXEL_SIZE / 2)) { newColor = { red: colors[whichColor].red, green: colors[whichColor].green, blue: colors[whichColor].blue }; - Voxels.eraseVoxel(fingerTipPosition.x, fingerTipPosition.y, fingerTipPosition.z, FINGERTIP_VOXEL_SIZE); Voxels.setVoxel(fingerTipPosition.x, fingerTipPosition.y, fingerTipPosition.z, FINGERTIP_VOXEL_SIZE, newColor.red, newColor.green, newColor.blue); diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 3a77382a84..aeb877ef78 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -45,6 +45,13 @@ VoxelTreeElement* VoxelTree::getVoxelAt(float x, float y, float z, float s) cons return static_cast(getOctreeElementAt(x, y, z, s)); } +VoxelTreeElement* VoxelTree::getEnclosingVoxelAt(float x, float y, float z, float s) const { + unsigned char* octalCode = pointToOctalCode(x,y,z,s); + OctreeElement* node = nodeForOctalCode(_rootNode, octalCode, NULL); + + return static_cast(node); +} + void VoxelTree::createVoxel(float x, float y, float z, float s, unsigned char red, unsigned char green, unsigned char blue, bool destructive) { diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index e0bc1d9a47..2992815787 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -30,6 +30,7 @@ public: void deleteVoxelAt(float x, float y, float z, float s); VoxelTreeElement* getVoxelAt(float x, float y, float z, float s) const; + VoxelTreeElement* getEnclosingVoxelAt(float x, float y, float z, float s) const; void createVoxel(float x, float y, float z, float s, unsigned char red, unsigned char green, unsigned char blue, bool destructive = false); diff --git a/libraries/voxels/src/VoxelTreeCommands.cpp b/libraries/voxels/src/VoxelTreeCommands.cpp index 46837aa23e..d1dc0f3560 100644 --- a/libraries/voxels/src/VoxelTreeCommands.cpp +++ b/libraries/voxels/src/VoxelTreeCommands.cpp @@ -13,22 +13,56 @@ #include "VoxelTreeCommands.h" + + +struct SendVoxelsOperationArgs { + const unsigned char* newBaseOctCode; + VoxelEditPacketSender* packetSender; +}; + +bool sendVoxelsOperation(OctreeElement* element, void* extraData) { + VoxelTreeElement* voxel = (VoxelTreeElement*)element; + SendVoxelsOperationArgs* args = (SendVoxelsOperationArgs*)extraData; + if (voxel->isColored()) { + const unsigned char* nodeOctalCode = voxel->getOctalCode(); + unsigned char* codeColorBuffer = NULL; + int codeLength = 0; + int bytesInCode = 0; + int codeAndColorLength; + + // If the newBase is NULL, then don't rebase + if (args->newBaseOctCode) { + codeColorBuffer = rebaseOctalCode(nodeOctalCode, args->newBaseOctCode, true); + codeLength = numberOfThreeBitSectionsInCode(codeColorBuffer); + bytesInCode = bytesRequiredForCodeLength(codeLength); + codeAndColorLength = bytesInCode + SIZE_OF_COLOR_DATA; + } else { + codeLength = numberOfThreeBitSectionsInCode(nodeOctalCode); + bytesInCode = bytesRequiredForCodeLength(codeLength); + codeAndColorLength = bytesInCode + SIZE_OF_COLOR_DATA; + codeColorBuffer = new unsigned char[codeAndColorLength]; + memcpy(codeColorBuffer, nodeOctalCode, bytesInCode); + } + + // copy the colors over + codeColorBuffer[bytesInCode + RED_INDEX] = voxel->getColor()[RED_INDEX]; + codeColorBuffer[bytesInCode + GREEN_INDEX] = voxel->getColor()[GREEN_INDEX]; + codeColorBuffer[bytesInCode + BLUE_INDEX] = voxel->getColor()[BLUE_INDEX]; + args->packetSender->queueVoxelEditMessage(PacketTypeVoxelSetDestructive, + codeColorBuffer, codeAndColorLength); + + delete[] codeColorBuffer; + } + return true; // keep going +} + + AddVoxelCommand::AddVoxelCommand(VoxelTree* tree, VoxelDetail& voxel, VoxelEditPacketSender* packetSender, QUndoCommand* parent) : QUndoCommand("Add Voxel", parent), _tree(tree), _packetSender(packetSender), - _voxel(voxel), - _oldTree(NULL) + _voxel(voxel) { - VoxelTreeElement* element = _tree->getVoxelAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s); - if (element) { - _oldTree = new VoxelTree(); - _tree->copySubTreeIntoNewTree(element, _oldTree, true); - } -} - -AddVoxelCommand::~AddVoxelCommand() { - delete _oldTree; } void AddVoxelCommand::redo() { @@ -41,18 +75,11 @@ void AddVoxelCommand::redo() { } void AddVoxelCommand::undo() { - if (_oldTree) { - OctreeElement* element = _tree->getOrCreateChildElementAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s); - qDebug() << "undo(): " << _voxel.x << " " << _voxel.y << " " << _voxel.z << " " << _voxel.s; - _tree->copyFromTreeIntoSubTree(_oldTree, element); - qDebug() << "done"; - } else { - if (_tree) { - _tree->deleteVoxelAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s); - } - if (_packetSender) { - _packetSender->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &_voxel); - } + if (_tree) { + _tree->deleteVoxelAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s); + } + if (_packetSender) { + _packetSender->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &_voxel); } } @@ -63,6 +90,26 @@ DeleteVoxelCommand::DeleteVoxelCommand(VoxelTree* tree, VoxelDetail& voxel, Voxe _voxel(voxel), _oldTree(NULL) { + _tree->lockForRead(); + VoxelTreeElement* element = _tree->getEnclosingVoxelAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s); + if (element->getScale() == _voxel.s) { + if (!element->hasContent() && !element->isLeaf()) { + _oldTree = new VoxelTree(); + _tree->copySubTreeIntoNewTree(element, _oldTree, false); + } else { + _voxel.red = element->getColor()[0]; + _voxel.green = element->getColor()[1]; + _voxel.blue = element->getColor()[2]; + } + } else if (element->hasContent() && element->isLeaf()) { + _voxel.red = element->getColor()[0]; + _voxel.green = element->getColor()[1]; + _voxel.blue = element->getColor()[2]; + } else { + _voxel.s = 0.0f; + qDebug() << "No element for delete."; + } + _tree->unlock(); } DeleteVoxelCommand::~DeleteVoxelCommand() { @@ -70,21 +117,38 @@ DeleteVoxelCommand::~DeleteVoxelCommand() { } void DeleteVoxelCommand::redo() { - if (_oldTree) { - - } else { - if (_tree) { - _tree->deleteVoxelAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s); - } - if (_packetSender) { - _packetSender->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &_voxel); - } + if (_voxel.s == 0) { + return; + } + + if (_tree) { + _tree->deleteVoxelAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s); } + if (_packetSender) { + _packetSender->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &_voxel); } } void DeleteVoxelCommand::undo() { + if (_voxel.s == 0) { + return; + } + if (_oldTree) { - + VoxelTreeElement* element = _oldTree->getVoxelAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s); + if (element) { + if (_tree) { + _tree->lockForWrite(); + _oldTree->copySubTreeIntoNewTree(element, _tree, false); + _tree->unlock(); + } + if (_packetSender) { + SendVoxelsOperationArgs args; + args.newBaseOctCode = NULL; + args.packetSender = _packetSender; + _oldTree->recurseTreeWithOperation(sendVoxelsOperation, &args); + _packetSender->releaseQueuedMessages(); + } + } } else { if (_tree) { _tree->createVoxel(_voxel.x, _voxel.y, _voxel.z, _voxel.s, _voxel.red, _voxel.green, _voxel.blue); diff --git a/libraries/voxels/src/VoxelTreeCommands.h b/libraries/voxels/src/VoxelTreeCommands.h index c3b23e7201..8df1f0dc14 100644 --- a/libraries/voxels/src/VoxelTreeCommands.h +++ b/libraries/voxels/src/VoxelTreeCommands.h @@ -23,7 +23,6 @@ class VoxelTree; class AddVoxelCommand : public QUndoCommand { public: AddVoxelCommand(VoxelTree* tree, VoxelDetail& voxel, VoxelEditPacketSender* packetSender = NULL, QUndoCommand* parent = NULL); - ~AddVoxelCommand(); virtual void redo(); virtual void undo(); @@ -32,7 +31,6 @@ private: VoxelTree* _tree; VoxelEditPacketSender* _packetSender; VoxelDetail _voxel; - VoxelTree* _oldTree; }; class DeleteVoxelCommand : public QUndoCommand { diff --git a/libraries/voxels/src/VoxelsScriptingInterface.cpp b/libraries/voxels/src/VoxelsScriptingInterface.cpp index 08dcfd3f47..15503db454 100644 --- a/libraries/voxels/src/VoxelsScriptingInterface.cpp +++ b/libraries/voxels/src/VoxelsScriptingInterface.cpp @@ -76,32 +76,16 @@ void VoxelsScriptingInterface::setVoxel(float x, float y, float z, float scale, if (_tree) { if (_undoStack) { AddVoxelCommand* addCommand = new AddVoxelCommand(_tree, - addVoxelDetail, - getVoxelPacketSender()); - - VoxelTreeElement* deleteVoxelElement = _tree->getVoxelAt(addVoxelDetail.x, addVoxelDetail.y, addVoxelDetail.z, addVoxelDetail.s); - if (deleteVoxelElement) { - nodeColor color; - memcpy(&color, &deleteVoxelElement->getColor(), sizeof(nodeColor)); - VoxelDetail deleteVoxelDetail = {addVoxelDetail.x, - addVoxelDetail.y, - addVoxelDetail.z, - addVoxelDetail.s, - color[0], - color[1], - color[2]}; - DeleteVoxelCommand* delCommand = new DeleteVoxelCommand(_tree, - deleteVoxelDetail, - getVoxelPacketSender()); - _undoStack->beginMacro(addCommand->text()); - // As QUndoStack automatically executes redo() on push, we don't need to execute the command ourselves. - _undoStack->push(delCommand); - _undoStack->push(addCommand); - _undoStack->endMacro(); - } else { - // As QUndoStack automatically executes redo() on push, we don't need to execute the command ourselves. - _undoStack->push(addCommand); - } + addVoxelDetail, + getVoxelPacketSender()); + DeleteVoxelCommand* deleteCommand = new DeleteVoxelCommand(_tree, + addVoxelDetail, + getVoxelPacketSender()); + _undoStack->beginMacro(addCommand->text()); + // As QUndoStack automatically executes redo() on push, we don't need to execute the command ourselves. + _undoStack->push(deleteCommand); + _undoStack->push(addCommand); + _undoStack->endMacro(); } else { // queue the destructive add queueVoxelAdd(PacketTypeVoxelSetDestructive, addVoxelDetail); From 1844eb2c9e7302ba8835fd2ae091617894ab6f7a Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Apr 2014 11:12:01 -0700 Subject: [PATCH 4/5] Pre CR tweaks --- libraries/voxels/src/VoxelTreeCommands.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libraries/voxels/src/VoxelTreeCommands.cpp b/libraries/voxels/src/VoxelTreeCommands.cpp index d1dc0f3560..a35096b5c7 100644 --- a/libraries/voxels/src/VoxelTreeCommands.cpp +++ b/libraries/voxels/src/VoxelTreeCommands.cpp @@ -21,7 +21,7 @@ struct SendVoxelsOperationArgs { }; bool sendVoxelsOperation(OctreeElement* element, void* extraData) { - VoxelTreeElement* voxel = (VoxelTreeElement*)element; + VoxelTreeElement* voxel = static_cast(element); SendVoxelsOperationArgs* args = (SendVoxelsOperationArgs*)extraData; if (voxel->isColored()) { const unsigned char* nodeOctalCode = voxel->getOctalCode(); @@ -117,19 +117,20 @@ DeleteVoxelCommand::~DeleteVoxelCommand() { } void DeleteVoxelCommand::redo() { - if (_voxel.s == 0) { + if (_voxel.s == 0.0f) { return; } if (_tree) { - _tree->deleteVoxelAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s); } + _tree->deleteVoxelAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s); + } if (_packetSender) { _packetSender->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &_voxel); } } void DeleteVoxelCommand::undo() { - if (_voxel.s == 0) { + if (_voxel.s == 0.0f) { return; } @@ -157,4 +158,4 @@ void DeleteVoxelCommand::undo() { _packetSender->queueVoxelEditMessages(PacketTypeVoxelSet, 1, &_voxel); } } -} \ No newline at end of file +} From 3143e10bd85029d0adc0136b7251c5fcb8fe09b6 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 25 Apr 2014 13:33:59 -0700 Subject: [PATCH 5/5] CR --- libraries/octree/src/Octree.cpp | 13 +++++++++++++ libraries/octree/src/Octree.h | 8 ++++++++ libraries/voxels/src/VoxelTree.cpp | 5 +---- libraries/voxels/src/VoxelTree.h | 7 +++++++ libraries/voxels/src/VoxelTreeCommands.cpp | 2 +- 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index ebfb954bd8..5e812c06c3 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -542,6 +542,19 @@ OctreeElement* Octree::getOctreeElementAt(float x, float y, float z, float s) co return node; } +OctreeElement* Octree::getOctreeEnclosingElementAt(float x, float y, float z, float s) const { + unsigned char* octalCode = pointToOctalCode(x,y,z,s); + OctreeElement* node = nodeForOctalCode(_rootNode, octalCode, NULL); + + delete[] octalCode; // cleanup memory +#ifdef HAS_AUDIT_CHILDREN + if (node) { + node->auditChildren("Octree::getOctreeElementAt()"); + } +#endif // def HAS_AUDIT_CHILDREN + return node; +} + OctreeElement* Octree::getOrCreateChildElementAt(float x, float y, float z, float s) { return getRoot()->getOrCreateChildElementAt(x, y, z, s); diff --git a/libraries/octree/src/Octree.h b/libraries/octree/src/Octree.h index 0b9f1657ee..a11e73ab04 100644 --- a/libraries/octree/src/Octree.h +++ b/libraries/octree/src/Octree.h @@ -210,7 +210,15 @@ public: void reaverageOctreeElements(OctreeElement* startNode = NULL); void deleteOctreeElementAt(float x, float y, float z, float s); + + /// Find the voxel at position x,y,z,s + /// \return pointer to the OctreeElement or NULL if none at x,y,z,s. OctreeElement* getOctreeElementAt(float x, float y, float z, float s) const; + + /// Find the voxel at position x,y,z,s + /// \return pointer to the OctreeElement or to the smallest enclosing parent if none at x,y,z,s. + OctreeElement* getOctreeEnclosingElementAt(float x, float y, float z, float s) const; + OctreeElement* getOrCreateChildElementAt(float x, float y, float z, float s); void recurseTreeWithOperation(RecurseOctreeOperation operation, void* extraData = NULL); diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index aeb877ef78..b1ddf2e5b0 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -46,10 +46,7 @@ VoxelTreeElement* VoxelTree::getVoxelAt(float x, float y, float z, float s) cons } VoxelTreeElement* VoxelTree::getEnclosingVoxelAt(float x, float y, float z, float s) const { - unsigned char* octalCode = pointToOctalCode(x,y,z,s); - OctreeElement* node = nodeForOctalCode(_rootNode, octalCode, NULL); - - return static_cast(node); + return static_cast(getOctreeEnclosingElementAt(x, y, z, s)); } void VoxelTree::createVoxel(float x, float y, float z, float s, diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 2992815787..eb24c182b2 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -29,8 +29,15 @@ public: VoxelTreeElement* getRoot() { return (VoxelTreeElement*)_rootNode; } void deleteVoxelAt(float x, float y, float z, float s); + + /// Find the voxel at position x,y,z,s + /// \return pointer to the VoxelTreeElement or NULL if none at x,y,z,s. VoxelTreeElement* getVoxelAt(float x, float y, float z, float s) const; + + /// Find the voxel at position x,y,z,s + /// \return pointer to the VoxelTreeElement or to the smallest enclosing parent if none at x,y,z,s. VoxelTreeElement* getEnclosingVoxelAt(float x, float y, float z, float s) const; + void createVoxel(float x, float y, float z, float s, unsigned char red, unsigned char green, unsigned char blue, bool destructive = false); diff --git a/libraries/voxels/src/VoxelTreeCommands.cpp b/libraries/voxels/src/VoxelTreeCommands.cpp index a35096b5c7..39e08d3bc2 100644 --- a/libraries/voxels/src/VoxelTreeCommands.cpp +++ b/libraries/voxels/src/VoxelTreeCommands.cpp @@ -22,7 +22,7 @@ struct SendVoxelsOperationArgs { bool sendVoxelsOperation(OctreeElement* element, void* extraData) { VoxelTreeElement* voxel = static_cast(element); - SendVoxelsOperationArgs* args = (SendVoxelsOperationArgs*)extraData; + SendVoxelsOperationArgs* args = static_cast(extraData); if (voxel->isColored()) { const unsigned char* nodeOctalCode = voxel->getOctalCode(); unsigned char* codeColorBuffer = NULL;