abrash-black-book/59-01.md
2013-12-30 20:26:41 +11:00

127 lines
6.6 KiB
Markdown

Chapter 59\
The Idea of BSP Trees {#Heading1}
----------------------
### What BSP Trees Are and How to Walk Them {#Heading2}
The answer is: Wendy Tucker.
The question that goes with that answer isn't particularly interesting
to anyone but me—but the manner in which I came up with the answer is.
I spent many of my childhood summers at Camp Chingacook, on Lake George
in New York. It was a great place to have fun and do some growing up,
with swimming and sailing and hiking and lots more.
When I was 14, Camp Chingacook had a mixer with a nearby girls' camp. As
best I can recall, I had never had any interest in girls before, but
after the older kids had paired up, I noticed a pretty girl looking at
me and, with considerable trepidation, I crossed the room to talk to
her. To my amazement, we hit it off terrifically. We talked non-stop for
the rest of the evening, and I walked back to my cabin floating on air.
I had taken a first, tentative step into adulthood, and my world would
never be quite the same.
That was the only time I ever saw her, although I would occasionally
remember that warm glow and call up an image of her smiling face. That
happened less frequently as the years passed and I had real girlfriends,
and by the time I got married, that particular memory was stashed in
some back storeroom of my mind. I didn't think of her again for more
than a decade.
A few days ago, for some reason, that mixer popped into my mind as I was
trying to fall asleep. And I wondered, for the first time in 20 years,
what that girl's name was. The name was there in my mind, somewhere; I
could feel the shape of it, in that same back storeroom, if only I could
figure out how to retrieve it.
I poked and worried at that memory, trying to get it to come to the
surface. I concentrated on it as hard as I could, and even started going
through the alphabet one letter at a time, trying to remember if her
name started with each letter. After 15 minutes, I was wide awake and
totally frustrated. I was also farther than ever from answering the
question; all the focusing on the memory was beginning to blur the
original imprint.
At this point, I consciously relaxed and made myself think about
something completely different. Every time my mind returned to the
mystery girl, I gently shifted it to something else. After a while, I
began to drift off to sleep, and as I did a connection was made, and a
name popped, unbidden, into my mind.
Wendy Tucker.
There are many problems that are amenable to the straight-ahead, purely
conscious sort of approach that I first tried to use to retrieve Wendy's
name. Writing code (once it's designed) is often like that, as are some
sorts of debugging, technical writing, and balancing your checkbook. I
personally find these left-brain activities to be very appealing because
they're finite and controllable; when I start one, I know I'll be able
to deal with whatever comes up and make good progress, just by plowing
along. Inspiration and intuitive leaps are sometimes useful, but not
required.
The problem is, though, that neither you nor I will ever do anything
great without inspiration and intuitive leaps, and especially not
without stepping away from what's known and venturing into territories
beyond. The way to do that is not by trying harder but, paradoxically,
by trying less hard, stepping back, and giving your right brain room to
work, then listening for and nurturing whatever comes of that. On a
small scale, that's how I remembered Wendy's name, and on a larger
scale, that's how programmers come up with products that are more than
me-too, checklist-oriented software.
Which, for a couple of reasons, brings us neatly to this chapter's
topic, Binary Space Partitioning (BSP) trees. First, games are probably
the sort of software in which the right-brain element is most
important—blockbuster games are almost always breakthroughs in one way
or another—and some very successful games use BSP trees, most notably id
Software's megahit DOOM. Second, BSP trees aren't intuitively easy to
grasp, and considerable ingenuity and inventiveness is required to get
the most from them.
Before we begin, I'd like to thank John Carmack, the technical wizard
behind DOOM, for generously sharing his knowledge of BSP trees with me.
### BSP Trees {#Heading3}
A BSP tree is, at heart, nothing more than a tree that subdivides space
in order to isolate features of interest. Each node of a BSP tree splits
an area or a volume (in 2-D or 3-D, respectively) into two parts along a
line or a plane; thus the name "Binary Space Partitioning." The
subdivision is hierarchical; the root node splits the world into two
subspaces, then each of the root's two children splits one of those two
subspaces into two more parts. This continues with each subspace being
further subdivided, until each component of interest (each line segment
or polygon, for example) has been assigned its own unique subspace. This
is, admittedly, a pretty abstract description, but the workings of BSP
trees will become clearer shortly; it may help to glance ahead to this
chapter's figures.
Building a tree that subdivides space doesn't sound particularly
profound, but there's a lot that can be done with such a structure. BSP
trees can be used to represent shapes, and operating on those shapes is
a simple matter of combining trees as needed; this makes BSP trees a
powerful way to implement Constructive Solid Geometry (CSG). BSP trees
can also be used for hit testing, line-of-sight determination, and
collision detection.
#### Visibility Determination {#Heading4}
For the time being, I'm going to discuss only one of the many uses of
BSP trees: The ability of a BSP tree to allow you to traverse a set of
line segments or polygons in back-to-front or front-to-back order as
seen from any arbitrary viewpoint. This sort of traversal can be very
helpful in determining which parts of each line segment or polygon are
visible and which are occluded from the current viewpoint in a 3-D
scene. Thus, a BSP tree makes possible an efficient implementation of
the painter's algorithm, whereby polygons are drawn in back-to-front
order, with closer polygons overwriting more distant ones that overlap,
as shown in Figure 59.1. (The line segments in Figure 1(a) and in other
figures in this chapter, represent vertical walls, viewed from directly
above.) Alternatively, visibility determination can be performed by
front-to-back traversal working in conjunction with some method for
remembering which pixels have already been drawn. The latter approach is
more complex, but has the potential benefit of allowing you to early-out
from traversal of the scene database when all the pixels on the screen
have been drawn.