From 62b29d26d28e468a27714012e5f693b1b77fdd6e Mon Sep 17 00:00:00 2001 From: LionTurtle Date: Thu, 29 Aug 2013 18:17:06 -0700 Subject: [PATCH] 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);