Overview
Two kinds of BSP trees are axis-aligned and polygon-aligned (AA-BSP and PA-BSP).
A BSP node has two child nodes metaphorically named left and right.
"BSP" usually refers to an AA-BSP tree.
Axis-Aligned BSP Trees
Axis-aligned is much simpler and faster to construct than polygon-aligned.
Axis-aligned is useful for containing 3D objects in rectangular volumes.
Objects can be coarsely (imprecisely) sorted in back-to-front order by traversing
an axis-aligned using the distance between a partition vs. viewpoint
as the criteria for branching left or right.
The granularity of sorting is the rectangular volume of a BSP node.
A BSP node may contain multiple Objects, but sorting (by BSP traversal) goes no further
(this is why sorting isn't precise).
Bypassing finely sorting the Objects of a BSP node is possible
if none of the Objects are translucent.
Rendering opaque objects out-of-order relies on the hardware Z buffer.
Note that the purpose of sorting is to properly alpha-blend translucent Objects.
Polygon-Aligned BSP Trees
Polygon-aligned BSP trees are well-suited for precise
collision-detection
of objects having irregular shapes.
Though they have disadvantages such as being complex and slow to construct.
Polygons intersecting a plane must be split into two polygons.
Traversal Path of BSP Varies According to Viewpoint
The key to understanding a BSP tree is that the traversal path
varies according to a
branch condition
and a stop condition.
Unlike a regular binary tree, these conditions are variable.
For example, when adding Objects, the branch condition is
whether an Object can fit inside a partition.
When culling/sorting, the branch condition is determined by
distance and orientation of a partition relative to the viewpoint
Culling and Sorting Objects by Traversing
Culling and sorting objects are done simultaneously by traversing a BSP tree.
Traversing is sorting.
Reaching a stop condition that evaluates true is culling.
A BSP node and its descendants outside the view frustum are culled
since they won't be visible.
This culling method is efficient, since a whole subtree of invisible objects
are eliminated in one step.
To properly render translucent polygons, furthest-to-nearest order is necessary.
During traversal, if two partitions are visible, the partition
that is furthest from the viewpoint is selected.
A partition's distance and whether inside the frustrum are sub-conditions of the branch condition.
The target of the traversal path is to reach the smallest and most distant partition.
The branch condition determines which ways to branch:
- If left is farther than right from viewpoint:
- If left is facing, branch.
- If right is facing, branch.
- If right is farther than left from viewpoint:
- If right is facing, branch.
- If left is facing, branch.
The stop condition determines when to stop recursing:
if partition is not facing or partition is outside view frustrum.
Ignoring the view frustrum for a moment,
possibly all the partitions or none will be visible.
For example, if the viewpoint is at the corner of a partition
and facing outwards, then none are visible.
If the viewpoint is rotated 180', then all become visible.
Adding Objects to a BSP Tree
Adding objects to a AA-BSP is similar to octrees.
The tree is recursed until a node (corresponding to an octant) is found
that the object doesn't fit or the maximum depth is reached,
then the object is attached to its parent node.
Objects that Intersect a BSP Plane
There are several cases where an Object can intersect a BSP plane.
One case is a Dyna that moves between any two partitions.
The worst case is a very large Object that, besides intersecting
one or more planes, overlays partitions in multiple BSP trees.
A way to solve intersection is to let multiple BSP nodes
reference the same Object in case the Object occupies
at least one partition that wasn't culled, but keep a flag
(or frame number) to remember that the Object was drawn in a frame
in case one or more of its partitions are visible (to avoid redraw).
Collision-Detection using a Polygon-Aligned BSP tree
Testing if a 3D vertex is inside a PA-BSP is done by traversing.
If the vertex is inside, then the vertex will be behind every polygon
encountered during traversal.
Eventually, traversal will stop at a leaf node,
which means a collision was detected.