Commit 44154e1d authored by Numanoglu's avatar Numanoglu
Browse files

Clean up BVH tree API

parent cd89dc71
Pipeline #12397 passed with stage
in 1 minute and 58 seconds
...@@ -146,6 +146,8 @@ final class BoundingVolumeHierarchyBuilder<E> { ...@@ -146,6 +146,8 @@ final class BoundingVolumeHierarchyBuilder<E> {
private boolean shouldStop(List<BvhBuildItem<E>> items, int depth, AABB totalAabb) { private boolean shouldStop(List<BvhBuildItem<E>> items, int depth, AABB totalAabb) {
return items.size() <= config.getMaxLeafSize() return items.size() <= config.getMaxLeafSize()
|| depth >= config.getMaxDepth() || depth >= config.getMaxDepth()
// Very flat bounds are kept as one terminal group to avoid repeated
// ineffective spatial splits on effectively lower-dimensional data.
|| totalAabb.isDegenerate(config.getDegenerateTolerance()); || totalAabb.isDegenerate(config.getDegenerateTolerance());
} }
...@@ -156,6 +158,8 @@ final class BoundingVolumeHierarchyBuilder<E> { ...@@ -156,6 +158,8 @@ final class BoundingVolumeHierarchyBuilder<E> {
} }
Node<E> leafGroup = new Node<>(null, totalAabb); Node<E> leafGroup = new Node<>(null, totalAabb);
// A terminal group keeps its aggregate AABB for pruning, while the children
// remain the actual element leaves returned by queries.
for (BvhBuildItem<E> item : items) { for (BvhBuildItem<E> item : items) {
leafGroup.getChildren().add(new Node<>(item.element, item.aabb)); leafGroup.getChildren().add(new Node<>(item.element, item.aabb));
} }
......
...@@ -6,12 +6,9 @@ import java.util.Objects; ...@@ -6,12 +6,9 @@ import java.util.Objects;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon;
public class BoundingVolumeHierarchyTree<E> { public class BoundingVolumeHierarchyTree<E> {
private Node<E> root; private final Node<E> root;
private final Function<E, AABB> aabbFunction;
static final int DEFAULT_MIN_DEPTH = 4; static final int DEFAULT_MIN_DEPTH = 4;
static final int DEFAULT_MAX_DEPTH = 32; static final int DEFAULT_MAX_DEPTH = 32;
...@@ -21,7 +18,6 @@ public class BoundingVolumeHierarchyTree<E> { ...@@ -21,7 +18,6 @@ public class BoundingVolumeHierarchyTree<E> {
private BoundingVolumeHierarchyTree(Builder<E> builder) { private BoundingVolumeHierarchyTree(Builder<E> builder) {
Objects.requireNonNull(builder, "builder"); Objects.requireNonNull(builder, "builder");
this.aabbFunction = Objects.requireNonNull(builder.getAabbFunction(), "aabbFunction");
this.root = new BoundingVolumeHierarchyBuilder<>(builder).buildRoot(); this.root = new BoundingVolumeHierarchyBuilder<>(builder).buildRoot();
} }
...@@ -110,14 +106,11 @@ public class BoundingVolumeHierarchyTree<E> { ...@@ -110,14 +106,11 @@ public class BoundingVolumeHierarchyTree<E> {
return root; return root;
} }
public void setRoot(Node<E> root) {
this.root = root;
}
/** /**
* Returns all elements whose node AABBs overlap or touch the query AABB. * Returns all elements whose node AABBs overlap or touch the query AABB.
*/ */
public List<E> getAllIntersectingElements(AABB query) { public List<E> getAllIntersectingElements(AABB query) {
Objects.requireNonNull(query, "query");
List<E> result = new ArrayList<>(); List<E> result = new ArrayList<>();
collectMatchingElements( collectMatchingElements(
root, root,
...@@ -133,6 +126,7 @@ public class BoundingVolumeHierarchyTree<E> { ...@@ -133,6 +126,7 @@ public class BoundingVolumeHierarchyTree<E> {
* missed when their parent node AABB extends beyond the container. * missed when their parent node AABB extends beyond the container.
*/ */
public List<E> getAllElementsContainedIn(AABB container) { public List<E> getAllElementsContainedIn(AABB container) {
Objects.requireNonNull(container, "container");
List<E> result = new ArrayList<>(); List<E> result = new ArrayList<>();
collectMatchingElements( collectMatchingElements(
root, root,
...@@ -161,14 +155,13 @@ public class BoundingVolumeHierarchyTree<E> { ...@@ -161,14 +155,13 @@ public class BoundingVolumeHierarchyTree<E> {
} }
} }
public static AABB getAggregateAABB(List<ConcretePolygon> polygons) { public static <E> AABB getAggregateAABB(List<E> elements, Function<E, AABB> aabbFunc) {
if (polygons.size() == 1) { Objects.requireNonNull(elements, "elements");
return AABB.of(polygons.get(0)); Objects.requireNonNull(aabbFunc, "aabbFunc");
if (elements.isEmpty()) {
throw new IllegalArgumentException("elements must not be empty");
} }
return getAggregateAABB(polygons, AABB::of);
}
public static <E> AABB getAggregateAABB(List<E> elements, Function<E, AABB> aabbFunc) {
double minX = Double.POSITIVE_INFINITY; double minX = Double.POSITIVE_INFINITY;
double minY = Double.POSITIVE_INFINITY; double minY = Double.POSITIVE_INFINITY;
double minZ = Double.POSITIVE_INFINITY; double minZ = Double.POSITIVE_INFINITY;
...@@ -177,7 +170,7 @@ public class BoundingVolumeHierarchyTree<E> { ...@@ -177,7 +170,7 @@ public class BoundingVolumeHierarchyTree<E> {
double maxZ = Double.NEGATIVE_INFINITY; double maxZ = Double.NEGATIVE_INFINITY;
for (E e : elements) { for (E e : elements) {
AABB aabb = aabbFunc.apply(e); AABB aabb = Objects.requireNonNull(aabbFunc.apply(e), "aabbFunc returned null");
minX = Math.min(minX, aabb.getMinX()); minX = Math.min(minX, aabb.getMinX());
minY = Math.min(minY, aabb.getMinY()); minY = Math.min(minY, aabb.getMinY());
minZ = Math.min(minZ, aabb.getMinZ()); minZ = Math.min(minZ, aabb.getMinZ());
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment