void OctreeTests::elementAddChildTests() { EntityTreePointer tree = std::make_shared<EntityTree>(); auto elem = tree->createNewElement(); QCOMPARE((bool)elem->getChildAtIndex(0), false); elem->addChildAtIndex(0); QCOMPARE((bool)elem->getChildAtIndex(0), true); const int MAX_CHILD_INDEX = 8; for (int i = 0; i < MAX_CHILD_INDEX; i++) { for (int j = 0; j < MAX_CHILD_INDEX; j++) { auto e = tree->createNewElement(); // add a single child. auto firstChild = e->addChildAtIndex(i); QCOMPARE(e->getChildAtIndex(i), firstChild); if (i != j) { // add a second child. auto secondChild = e->addChildAtIndex(j); QCOMPARE(e->getChildAtIndex(i), firstChild); QCOMPARE(e->getChildAtIndex(j), secondChild); // remove scecond child. e->removeChildAtIndex(j); QCOMPARE((bool)e->getChildAtIndex(j), false); } QCOMPARE(e->getChildAtIndex(i), firstChild); } } }
void HorizontalLayout::addOrMergeChildAtIndex(ExpressionLayout * eL, int index, bool removeEmptyChildren) { if (eL->isHorizontal()) { mergeChildrenAtIndex(static_cast<HorizontalLayout *>(eL), index, removeEmptyChildren); } else { addChildAtIndex(eL, index); } }
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); }
void VoxelTreeElement::splitChildren() { if (requiresSplit()) { const nodeColor& ourColor = getColor(); // for colored leaves, we must add *all* the children for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { addChildAtIndex(i)->setColor(ourColor); } nodeColor noColor = { 0, 0, 0, 0}; setColor(noColor); // set our own color to noColor so we are a pure non-leaf } }
void HorizontalLayout::privateRemoveChildAtIndex(int index, bool deleteAfterRemoval, bool forceRemove) { /* Remove the child before potentially adding an EmptyLayout. Indeed, adding * a new child would remove any EmptyLayout surrounding the new child and in * the case the child to be removed was an Empty layout, it would result in * removing it twice if we remove it afterwards. */ DynamicLayoutHierarchy::removeChildAtIndex(index, deleteAfterRemoval); /* If the child to remove is at index 0 and its right sibling must have a left * sibling (e.g. it is a VerticalOffsetLayout), replace the child with an * EmptyLayout instead of removing it. */ if (!forceRemove && index == 0 && numberOfChildren() > 0 && child(0)->mustHaveLeftSibling()) { addChildAtIndex(new EmptyLayout(), 0); } }
// 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); }