void OctreeQueryNode::dumpOutOfView() { // if shutting down, return immediately if (_isShuttingDown) { return; } int stillInView = 0; int outOfView = 0; OctreeElementBag tempBag; while (!nodeBag.isEmpty()) { OctreeElement* node = nodeBag.extract(); if (node->isInView(_currentViewFrustum)) { tempBag.insert(node); stillInView++; } else { outOfView++; } } if (stillInView > 0) { while (!tempBag.isEmpty()) { OctreeElement* node = tempBag.extract(); if (node->isInView(_currentViewFrustum)) { nodeBag.insert(node); } } } }
OctreeElement* OctreeElement::getOrCreateChildElementContaining(const AABox& box) { OctreeElement* child = NULL; int childIndex = getMyChildContaining(box); // If getMyChildContaining() returns CHILD_UNKNOWN then it means that our level // is the correct level for this cube if (childIndex == CHILD_UNKNOWN) { return this; } // Now, check if we have a child at that location child = getChildAtIndex(childIndex); if (!child) { child = addChildAtIndex(childIndex); } // if we've made a really small child, then go ahead and use that one. if (child->getScale() <= SMALLEST_REASONABLE_OCTREE_ELEMENT_SCALE) { return child; } // Now that we have the child to recurse down, let it answer the original question... return child->getOrCreateChildElementContaining(box); }
// TODO: consider removing this, or switching to using getOrCreateChildElementContaining(const AACube& box)... OctreeElement* OctreeElement::getOrCreateChildElementAt(float x, float y, float z, float s) { OctreeElement* child = NULL; // If the requested size is less than or equal to our scale, but greater than half our scale, then // we are the Element they are looking for. float ourScale = getScale(); float halfOurScale = ourScale / 2.0f; if(s > ourScale) { qCDebug(octree, "UNEXPECTED -- OctreeElement::getOrCreateChildElementAt() s=[%f] > ourScale=[%f] ", (double)s, (double)ourScale); } if (s > halfOurScale) { return this; } int childIndex = getMyChildContainingPoint(glm::vec3(x, y, z)); // Now, check if we have a child at that location child = getChildAtIndex(childIndex); if (!child) { child = addChildAtIndex(childIndex); } // Now that we have the child to recurse down, let it answer the original question... return child->getOrCreateChildElementAt(x, y, z, s); }
// handles staging or deletion of all deep children bool OctreeElement::safeDeepDeleteChildAtIndex(int childIndex, int recursionCount) { bool deleteApproved = false; if (recursionCount > DANGEROUSLY_DEEP_RECURSION) { static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex( "OctreeElement::safeDeepDeleteChildAtIndex\\(\\) reached DANGEROUSLY_DEEP_RECURSION, bailing!"); qCDebug(octree) << "OctreeElement::safeDeepDeleteChildAtIndex() reached DANGEROUSLY_DEEP_RECURSION, bailing!"; return deleteApproved; } OctreeElement* childToDelete = getChildAtIndex(childIndex); if (childToDelete) { if (childToDelete->deleteApproved()) { // If the child is not a leaf, then call ourselves recursively on all the children if (!childToDelete->isLeaf()) { // delete all it's children for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { if (childToDelete->getChildAtIndex(i)) { deleteApproved = childToDelete->safeDeepDeleteChildAtIndex(i,recursionCount+1); if (!deleteApproved) { break; // no point in continuing... } } } } else { deleteApproved = true; // because we got here after checking that delete was approved } if (deleteApproved) { deleteChildAtIndex(childIndex); _isDirty = true; markWithChangedTime(); } } } return deleteApproved; }
// TODO: consider removing this, or switching to using getOrCreateChildElementContaining(const AACube& box)... OctreeElement* OctreeElement::getOrCreateChildElementAt(float x, float y, float z, float s) { OctreeElement* child = NULL; // If the requested size is less than or equal to our scale, but greater than half our scale, then // we are the Element they are looking for. float ourScale = getScale(); float halfOurScale = ourScale / 2.0f; if(s > ourScale) { qCDebug(octree, "UNEXPECTED -- OctreeElement::getOrCreateChildElementAt() s=[%f] > ourScale=[%f] ", (double)s, (double)ourScale); } if (s > halfOurScale) { return this; } // otherwise, we need to find which of our children we should recurse glm::vec3 ourCenter = _cube.calcCenter(); int childIndex = CHILD_UNKNOWN; // left half if (x > ourCenter.x) { if (y > ourCenter.y) { // top left if (z > ourCenter.z) { // top left far childIndex = CHILD_TOP_LEFT_FAR; } else { // top left near childIndex = CHILD_TOP_LEFT_NEAR; } } else { // bottom left if (z > ourCenter.z) { // bottom left far childIndex = CHILD_BOTTOM_LEFT_FAR; } else { // bottom left near childIndex = CHILD_BOTTOM_LEFT_NEAR; } } } else { // right half if (y > ourCenter.y) { // top right if (z > ourCenter.z) { // top right far childIndex = CHILD_TOP_RIGHT_FAR; } else { // top right near childIndex = CHILD_TOP_RIGHT_NEAR; } } else { // bottom right if (z > ourCenter.z) { // bottom right far childIndex = CHILD_BOTTOM_RIGHT_FAR; } else { // bottom right near childIndex = CHILD_BOTTOM_RIGHT_NEAR; } } } // Now, check if we have a child at that location child = getChildAtIndex(childIndex); if (!child) { child = addChildAtIndex(childIndex); } // Now that we have the child to recurse down, let it answer the original question... return child->getOrCreateChildElementAt(x, y, z, s); }