Bounding Volume Hierarchies
Bounding Volume Hierarchies
By arranging the bounding volumes into a tree hierarchy called a bounding volume hierarchy (BVH), the time complexity can be reduced to logarithmic in the number of tests performed.
A bounding volume hierarchy of five simple objects. Here the bounding volumes used are AABBs.
With a hierarchy in place, during collision testing children do not have to be examined if their parent volume is not intersected.
Hierarchy Design Issues
Serval desired properties for bounding volume hierarchies have been suggested.
- The nodes contained in any given subtree should be near each other.
- Each node in the hierarchy should be of minimal volume.
- The sum of all bounding volumes should be minimal.
- Greater attention should be paid to nodes near the root of the hierarchy.
- The volume of overlap of sibling nodes should be minimal.
- The hierarchy should be balanced with respect to both its node structure and its content.
Cost Functions
The cost function is defined as below:
\[ T = N_VC_V + N_PC_P + N_UC_U + C_O \]
Here,
- \(T\) is the total cost of intersecting the two hierarchies
- \(N_V\) is the number of BV pairs tested for overlap
- \(C_V\) is the cost of testing a pair of BVs for overlap
- \(N_P\) is the number of primitive pairs tested
- \(C_P\) is the cost of testing a primitive pair
- \(N_U\) is the number of nodes that need to be updated
- \(C_U\) is the cost of updating each such node
- \(C_O\) is the cost of a one-time processing (such as a coordinate transformation between objects)
Tree Degree
In terms of size, a d-ary tree of \(n\) leaves has \((n - 1)/(d - 1)\) internal nodes for a total of \((nd - 1)/(d - 1)\) nodes in the tree.
Building Strategies for Hierrachy Construction
There are three primary categories of tree construction methods: top-down, bottom-up, and insertion methods.
A small tree of four objects built using (a) top-down, (b) bottom-up, and (c) insertion construction.
Top-down Construction
It starts out by bounding the input set of primitives in a bounding volume. These primitives are then partitioned into two subsets. The procedure is now called recursively to form subhierarchies for the two subsets, which are then connected as children to the parent volume.
// Construct a top-down tree. Rearranges object[] array during construction |
Partitioning Strategies
A simple partitioning method is the medium-cut-algorithm. Here, the set is divided in two equal size parts with respect to their projection along the selected axis, resulting in a balanced tree.
Other possible partition strategies are:
- Minimize the sum of the volumes of the child volumes.
- Minimize the maximum volume of the child volumes.
- Minimize the volume of the intersection of the child volumes.
- Maximize the separation of child volumes.
- Divide primitives equally between the child volumes.
- Combinations of the previous strategies.
Partitioning stops and a node is considered a leaf when some particular stop criterion is reached. Common stop criteria are:
- The node contains just a single primitive, or less than some k primitives.
- The volume of the bounding volume has fallenbelow a set cut-off limit.
- The depth of the node has reached a predefind cut-off depth.
Partitioning can also fail early, before a stop criterion triggers, for instance when:
- All primitives fall on one side of the split plane.
- One or both child volumes end up with as many (or nearly as many) primitives as the parent volume.
- Both child volumes are almost as large as the parent volume.
Choice of Partitioning Axis
Common choices of axes are:
- Local x, y, z coordinate axes.
- Axes from the intended aligned bounding volume.
- Axes of the parent bounding volume.
- Axis through the two most distant points.
- Axis along which variance is greatest.
Choice of Split Point on the Partitioning Axis
- Median of the centroid coordinates (object median).
- Mean of the centroid coordinates (object mean).
- Median of the bounding volume projection extents (spatial median).
- Splitting at k evenly spaced points along the bounding volume projection extents. This brute force alternative simply tests some small number of evenly spaced points along the axis, picking the best one.
- Splitting between (random subset of ) the centroid coordinates.
- Splitting at the object median. (b) Splitting at the object mean. (c) Splitting at the spatial median.
Bottom-up Construction
In contrast to top-down methods, bottom-up methods are more complicated to implement and have a slower construction time but usually produce the best tress. To construct a tree hierarchy bottom up, the first step is to enclose each primitive within a bounding volume. These volumes form the leaf nodes of the tree. From the resulting set of volumes, two leaf nodes are selected based on some merging criterion (or called a clustering rule). These nodes are then bound within a bounding volume, which replaces the original nodes in the set. This pairing procedure repeats until the set consists of a single bounding volume representing the root node of the constructed tree.
Node *BottomUpBVTree(Object object[], int numObjects) { |
An improved method using priority queue is shown as below.
Node *BottomUpBVTree(Object object[], int numObjects) { |
Other Bottom-up Construction Strategies
Locating the point (or object) out of a set of points closest to a given query point is known as the nearest neighbor problem.
For forming larger clusters of objects, specific clustering algorithms can be used. One such approach is to treat the objects as vertices of a complete graph and compute a minimum spanning tree (MST) for the graph, with edge weights set to the distance between the two connected objects or some similar clustering measure. The MST can be computed using Prim’s algorithm or Kruskal’s algorithm.
Hierarchy Traversal
The two most fundamental tree-traversing methods are breadth-first search and depth-first search.
- Breadth-firstsearch, (b) depth-firstsearch, and (c) one possible best-firstsearch ordering.
Pure breadth-first and depth-first traversals are considered uninformed or blind search methods. Uninformed search methods do not examine and make traversal decisions based on the data contained in the traversed structure. In contrast to the uninformed methods is the group of informed search methods. These attempt to utilize known information about the domain being searched through heuristic rules.
Generic Informed Depth-first Traversal
A generic informed depth-first traversal is as follows:
// Generic recursive BVH traversal code. |
In the code
BVOverlap()
determines the overlap between two bounding volumes.IsLeaf()
return true if its argument is a leaf node and not an internal node.CollidePrimitives()
collides all contained primitives against one another. Accumulating any reported collisions to the suppliedCollisionResult
structure.DescendA()
implements the descent rule, and returns true if object hierarchy \(A\) should be descended or false for object hierarchy \(B\).
Some basic implementations of DescendA
is shown as
below.
// ‘Descend A’ descent rule |
Simultaneous Depth-first Traversal
// Recursive, simultaneous traversal |
Merging Bounding Volumes
During bottom-up construction an alternative to the rather costly operation of fitting the bounding volume directly to the data is to merge the child volumes themselves into a new bounding volume.
Merging Two AABBs
// Computes the AABB a of AABBs a0 and a1 |
Merging Two Spheres
The calculation is best split into two cases:
- Either sphere is fully enclosed by the other.
- They are either partially overlapping or disjoint.
Let two sphere \(S_0\) and \(S_1\), the distance between two centers is \(d = \| C_1 - C_0 \|\). If \(|d_1 - d_0| \geq d\), then one sphere is fully inside the other.
Merging spheres S0 and S1.
// Computes the bounding sphere s of spheres s0 and s1 |
Efficient Tree Representation and Traversal
Array Representation
// First level |
Grouping Queries
In games it is not uncommon to have a number of test queries originating from the same general area. A common example is testing the wheels of a vehicle for collision with the ground. If the wheels are tested for collision independently, because the vehicle is small with respect to the world the query traversals throught the topmost part of the world hierarchy. As such, it is benefitial to move all queries together throught the world hierrarchy up untial the point where they start branching out into different parts of the tree.
Sphere s[NUM_SPHERES]; |
Improved Queries Through Caching
Front Tracking
A number of node-node comparisons are made when two object hierarchies are tested agianst each other. These node pairs can be seen as forming the nodes of a three, the collision tree.
When the two objects are not colliding, as tree traversal stops when a node-node pair is not overlapping, all internal nodes of the collision tree correspond to colliding node-node pairs, and the leaves are the node-node pairs where noncollision was first determined. Consequently, the collection of these leaf nodes, forming what is known as the front of the tree.
Instead of repeatedly building and traversing the collision tree from the root, this coherence can be utilized by keeping track of and reusing the front between queries, incrementally updating only the portions that change.