int OctreeElement::getMyChildContaining(const AABox& box) const { float ourScale = getScale(); float boxLargestScale = box.getLargestDimension(); // TODO: consider changing this to assert() if(boxLargestScale > ourScale) { qCDebug(octree, "UNEXPECTED -- OctreeElement::getMyChildContaining() " "boxLargestScale=[%f] > ourScale=[%f] ", (double)boxLargestScale, (double)ourScale); } // Determine which of our children the minimum and maximum corners of the cube live in... glm::vec3 cubeCornerMinimum = box.getCorner(); glm::vec3 cubeCornerMaximum = box.calcTopFarLeft(); if (_cube.contains(cubeCornerMinimum) && _cube.contains(cubeCornerMaximum)) { int childIndexCubeMinimum = getMyChildContainingPoint(cubeCornerMinimum); int childIndexCubeMaximum = getMyChildContainingPoint(cubeCornerMaximum); // If the minimum and maximum corners of the cube are in two different children's cubes, // then we are the containing element if (childIndexCubeMinimum != childIndexCubeMaximum) { return CHILD_UNKNOWN; } return childIndexCubeMinimum; // either would do, they are the same } return CHILD_UNKNOWN; // since box is not contained in our element, it can't be in one of our children }
int OctreeElement::getMyChildContaining(const AACube& cube) const { float ourScale = getScale(); float cubeScale = cube.getScale(); // TODO: consider changing this to assert() if (cubeScale > ourScale) { qCDebug(octree) << "UNEXPECTED -- OctreeElement::getMyChildContaining() -- (cubeScale > ourScale)"; qCDebug(octree) << " cube=" << cube; qCDebug(octree) << " elements AACube=" << _cube; qCDebug(octree) << " cubeScale=" << cubeScale; qCDebug(octree) << " ourScale=" << ourScale; assert(false); } // Determine which of our children the minimum and maximum corners of the cube live in... glm::vec3 cubeCornerMinimum = glm::clamp(cube.getCorner(), (float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE); glm::vec3 cubeCornerMaximum = glm::clamp(cube.calcTopFarLeft(), (float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE); if (_cube.contains(cubeCornerMinimum) && _cube.contains(cubeCornerMaximum)) { int childIndexCubeMinimum = getMyChildContainingPoint(cubeCornerMinimum); int childIndexCubeMaximum = getMyChildContainingPoint(cubeCornerMaximum); // If the minimum and maximum corners of the cube are in two different children's cubes, then we are the containing element if (childIndexCubeMinimum != childIndexCubeMaximum) { return CHILD_UNKNOWN; } return childIndexCubeMinimum; // either would do, they are the same } return CHILD_UNKNOWN; // since cube is not contained in our element, it can't be in one of our children }
bool ModelTreeElement::bestFitModelBounds(const ModelItem& model) const { if (_box.contains(model.getMinimumPoint()) && _box.contains(model.getMaximumPoint())) { int childForMinimumPoint = getMyChildContainingPoint(model.getMinimumPoint()); int childForMaximumPoint = getMyChildContainingPoint(model.getMaximumPoint()); // If I contain both the minimum and maximum point, but two different children of mine // contain those points, then I am the best fit for that model if (childForMinimumPoint != childForMaximumPoint) { return true; } } return false; }
// 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); }
bool ModelTreeElement::bestFitModelBounds(const ModelItem& model) const { glm::vec3 clampedMin = glm::clamp(model.getMinimumPoint(), 0.0f, 1.0f); glm::vec3 clampedMax = glm::clamp(model.getMaximumPoint(), 0.0f, 1.0f); if (_box.contains(clampedMin) && _box.contains(clampedMax)) { int childForMinimumPoint = getMyChildContainingPoint(clampedMin); int childForMaximumPoint = getMyChildContainingPoint(clampedMax); // if this is a really small box, then it's close enough! if (_box.getScale() <= SMALLEST_REASONABLE_OCTREE_ELEMENT_SCALE) { return true; } // If I contain both the minimum and maximum point, but two different children of mine // contain those points, then I am the best fit for that model if (childForMinimumPoint != childForMaximumPoint) { return true; } } return false; }