home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / FAQSYS18.ZIP / FAQS.DAT / BSP_FAQ.TXT < prev    next >
Text File  |  1996-08-18  |  53KB  |  1,501 lines

  1. BSP Tree Frequently Asked Questions (FAQ)
  2.  
  3. ---------------------------------------------------------------------------
  4.  
  5. This document is still under construction
  6.  
  7.      This document should not be considered to be in final form by any
  8.      stretch of the imagination. All comments are welcome. I expect to go
  9.      through several iterations of writing and improving, so don't give up
  10.      on me for a few months yet.
  11.  
  12. ---------------------------------------------------------------------------
  13.  
  14. Questions
  15.  
  16.   1. About this document
  17.   2. Acknowledgements
  18.   3. How can you contribute?
  19.   4. About the pseudo C++ code
  20.   5. What is a BSP Tree?
  21.   6. How do you build a BSP Tree?
  22.   7. How do you partition a polygon with a plane?
  23.   8. How do you remove hidden surfaces with a BSP Tree?
  24.   9. How do you remove hidden lines with a BSP Tree?
  25.  10. How do you accelerate ray tracing with a BSP Tree?
  26.  11. How do you perform boolean operations on polytopes with a BSP Tree?
  27.  12. How do you perform collision detection with a BSP Tree?
  28.  13. How do you handle dynamic scenes with a BSP Tree?
  29.  14. How do you compute shadows with a BSP Tree?
  30.  15. How do you extract connectivity information from BSP Trees?
  31.  16. How are BSP Trees useful for robot motion planning?
  32.  17. How are BSP Trees used in DOOM?
  33.  18. How can you make a BSP Tree more robust?
  34.  19. How efficient is a BSP Tree?
  35.  20. How can you make a BSP Tree more efficient?
  36.  21. How can you avoid recursion?
  37.  22. What is the history of BSP Trees?
  38.  23. Where can you find sample code and related resources?
  39.  24. References
  40.  
  41. ---------------------------------------------------------------------------
  42.  
  43. Answers
  44.  
  45.   1. About this document
  46.  
  47.      The purpose of this document is to provide answers to Frequently Asked
  48.      Questions about Binary Space Partitioning (BSP) Trees. This document
  49.      will be posted monthly to comp.graphics.algorithms. It is also
  50.      available via WWW at the URL:
  51.  
  52.           http://www.graphics.cornell.edu/bspfaq/
  53.  
  54.      You can also request that the FAQ be mailed to you in plain text and
  55.      HTML formats by sending e-mail to bsp-faq@graphics.cornell.edu with a
  56.      subject line of "SEND BSP TREE [what]". The "[what]" should be
  57.      replaced with any combination of "TEXT" and "HTML". Respectively,
  58.      these will return to you a plain text version of the FAQ, and an HTML
  59.      formatted version of the FAQ viewable with Mosaic or Netscape.
  60.  
  61.      This document is maintained by Bretton Wade, a graduate student at the
  62.      Cornell University Program of Computer Graphics.
  63.  
  64.      This document, and all its associated parts, are Copyright ⌐ 1995,
  65.      Bretton Wade. All rights reserved. Permisson to distribute this
  66.      collection, in part or full, via electronic means (emailed, posted or
  67.      archived) or printed copy are granted providing that no charges are
  68.      involved, reasonable attempt is made to use the most current version,
  69.      and all credits and copyright notices are retained. Requests for other
  70.      distribution rights, including incorporation in commercial products,
  71.      such as books, magazine articles, CD-ROMs, and binary applications
  72.      should be made to bsp-faq@graphics.cornell.edu.
  73.  
  74.      This article is provided as is without any express or implied
  75.      warranties. While every effort has been taken to ensure the accuracy
  76.      of the information contained in this article, the
  77.      author/maintainer/contributors assume(s) no responsibility for errors
  78.      or omissions, or for damages resulting from the use of the information
  79.      contained herein.
  80.  
  81.      The contents of this article do not necessarily represent the opinions
  82.      of Cornell University or the Program of Computer Graphics.
  83.      --
  84.      Last Update: 04/21/95 15:50:23
  85.  
  86.   2. Acknowledgements
  87.  
  88.      This document would not have been possible without the selfless
  89.      contributions and efforts of many individuals. I would like to take
  90.      the opportunity to thank each one of them. Please be aware that these
  91.      people may not be amenable to recieving e-mail on a random basis. If
  92.      you have any special questions, please contact Bretton Wade
  93.      (bwade@graphics.cornell.edu or bsp-faq@graphics.cornell.edu) before
  94.      trying to contact anyone else on this list. In no particular order:
  95.  
  96.         * Bruce Naylor (naylor@research.att.com)
  97.         * Richard Lobb (richard@cs.auckland.ac.nz)
  98.         * Dani Lischinski (danix@cs.washington.edu)
  99.         * Chris Schoeneman (crs@lightscape.com)
  100.         * Philip Hubbard (pmh@graphics.cornell.edu)
  101.         * Jim Arvo (arvo@graphics.cornell.edu)
  102.         * Kevin Ryan (kryan@access.digex.net)
  103.         * Joseph Fiore (fiore@cs.buffalo.edu)
  104.         * Lukas Rosenthaler (rosenth@foto.chemie.unibas.ch)
  105.         * Anson Tsao (ansont@hookup.net)
  106.         * Robert Zawarski (zawarski@chaph.usc.edu)
  107.         * Ron Capelli (capelli@vnet.ibm.com)
  108.         * Eric A. Haines (erich@eye.com)
  109.         * Ian CR Mapleson (mapleson@cee.hw.ac.uk)
  110.         * Richard Dorman (richard@cs.wits.ac.za)
  111.         * Steve Larsen (larsen@sunset.cs.utah.edu)
  112.         * Timothy Miller (tsm@cs.brown.edu)
  113.         * Ben Trumbore (wbt@graphics.cornell.edu)
  114.         * Richard Matthias (richardm@cogs.susx.ac.uk)
  115.         * Ken Shoemake (shoemake@graphics.cis.upenn.edu)
  116.         * Seth Teller (seth@theory.lcs.mit.edu)
  117.         * Peter Shirley (shirley@graphics.cornell.edu)
  118.  
  119.      If I have neglected to mention your name, and you contributed, please
  120.      let me know immediately!
  121.      --
  122.      Last Update: 03/29/95 14:12:10
  123.  
  124.   3. How can you contribute?
  125.  
  126.      Please send all new questions, corrections, suggestions, and
  127.      contributions to bsp-faq@graphics.cornell.edu.
  128.      --
  129.      Last Update: 03/29/95 14:12:10
  130.  
  131.   4. About the pseudo C++ code
  132.  
  133.      Overview
  134.      The general efficiency of C++ makes it a well suited language for
  135.      programming computer graphics. Furthermore, the abstract nature of the
  136.      language allows it to be used effectively as a psuedo code for
  137.      demonstrative purposes. I will use C++ notation for all the examples
  138.      in this document.
  139.  
  140.      In order to provide effective examples, it is necessary to assume that
  141.      certain classes already exist, and can be used without presenting
  142.      excessive details of their operation. Basic classes such as lists and
  143.      arrays fall into this category.
  144.  
  145.      Other classes which will be very useful for examples need to be
  146.      presented here, but the definitions will be generic to allow for
  147.      freedom of interpretation. I assume points and vectors to each be an
  148.      array of 3 real numbers (X, Y, Z).
  149.  
  150.      Planes are represented as an array of 4 real numbers (A, B, C, D). The
  151.      vector (A, B, C) is the normal vector to the plane. Polygons are
  152.      structures composited from an array of points, which are the vertices,
  153.      and a plane.
  154.  
  155.      The overloaded operator for a dot product (inner product, scalar
  156.      product, etc.) of two vectors is the '|' symbol. This has two
  157.      advantages, the first of which is that it can't be confused with the
  158.      scalar multiplication operator. The second is that precedence of C++
  159.      operators will usually require that dot product operations be
  160.      parenthesized, which is consistent with the linear algebra notation
  161.      for an inner product.
  162.  
  163.      The code for BSP trees presented here is intended to be educational,
  164.      and may or may not be very efficient. For the sake of clarity, the BSP
  165.      tree itself will not be defined as a class.
  166.      --
  167.      Last Update: 04/30/95 15:45:19
  168.  
  169.   5. What is a BSP Tree?
  170.  
  171.      Overview
  172.      A Binary Space Partitioning (BSP) tree represents a recursive,
  173.      hierarchical partitioning, or subdivision, of n-dimensional space. BSP
  174.      tree construction is a process which takes a subspace and partitions
  175.      it by any hyperplane that intersects the interior of that subspace.
  176.      The result is two new subspaces that can be further partitioned by
  177.      recursive application of the method.
  178.  
  179.      A "hyperplane" in n-dimensional space is an n-1 dimensional object
  180.      which can be used to divide the space into two half-spaces. For
  181.      example, in three dimensional space, the "hyperplane" is a plane. In
  182.      two dimensional space, a line is used.
  183.  
  184.      BSP trees are extremely versatile, because they are powerful sorting
  185.      and classification structures. They have uses ranging from hidden
  186.      surface removal and ray tracing hierarchies to solid modeling and
  187.      robot motion planning.
  188.  
  189.      Example
  190.      An easy way to think about BSP trees is to limit the discussion to two
  191.      dimensions. To simplify the situation, let's say that we will use only
  192.      lines parallel to the X or Y axis, and that we will divide the space
  193.      equally at each node. For example, given a square somewhere in the XY
  194.      plane, we select the first split, and thus the root of the BSP Tree,
  195.      to cut the square in half in the X direction. At each slice, we will
  196.      choose a line of the opposite orientation from the last one, so the
  197.      second slice will divide each of the new pieces in the Y direction.
  198.      This process will continue recursively until we reach a stopping
  199.      point, and looks like this:
  200.  
  201.      +-----------+      +-----+-----+      +-----+-----+
  202.  
  203.      |           |      |     |     |      |     |     |
  204.  
  205.      |           |      |     |     |      |  d  |     |
  206.  
  207.      |           |      |     |     |      |     |     |
  208.  
  209.      |     a     |  ->  |  b  X  c  |  ->  +--Y--+  f  |  -> ...
  210.  
  211.      |           |      |     |     |      |     |     |
  212.  
  213.      |           |      |     |     |      |  e  |     |
  214.  
  215.      |           |      |     |     |      |     |     |
  216.  
  217.      +-----------+      +-----+-----+      +-----+-----+
  218.  
  219.      The resulting BSP tree looks like this at each step:
  220.  
  221.            a                  X                  X           ...
  222.  
  223.                             -/ \+              -/ \+
  224.  
  225.                             /   \              /   \
  226.  
  227.                            b     c            Y     f
  228.  
  229.                                             -/ \+
  230.  
  231.                                             /   \
  232.  
  233.                                            e     d
  234.  
  235.      Other space partitioning structures
  236.      BSP trees are closely related to Quadtrees and Octrees. Quadtrees and
  237.      Octrees are space partitioning trees which recursively divide
  238.      subspaces into four and eight new subspaces, respectively. A BSP Tree
  239.      can be used to simulate both of these structures.
  240.      --
  241.      Last Update: 04/30/95 15:45:19
  242.  
  243.   6. How do you build a BSP Tree?
  244.  
  245.      Overview
  246.      Given a set of polygons in three dimensional space, we want to build a
  247.      BSP tree which contains all of the polygons. For now, we will ignore
  248.      the question of how the resulting tree is going to be used.
  249.  
  250.      The algorithm to build a BSP tree is very simple:
  251.  
  252.        1. Select a partition plane.
  253.        2. Partition the set of polygons with the plane.
  254.        3. Recurse with each of the two new sets.
  255.  
  256.      Choosing the partition plane
  257.      The choice of partition plane depends on how the tree will be used,
  258.      and what sort of efficiency criteria you have for the construction.
  259.      For some purposes, it is appropriate to choose the partition plane
  260.      from the input set of polygons. Other applications may benefit more
  261.      from axis aligned orthogonal partitions.
  262.  
  263.      In any case, you want to evaluate how your choice will affect the
  264.      results. It is desirable to have a balanced tree, where each leaf
  265.      contains roughly the same number of polygons. However, there is some
  266.      cost in achieving this. If a polygon happens to span the partition
  267.      plane, it will be split into two or more pieces. A poor choice of the
  268.      partition plane can result in many such splits, and a marked increase
  269.      in the number of polygons. Usually there will be some trade off
  270.      between a well balanced tree and a large number of splits.
  271.  
  272.      Partitioning polygons
  273.      Partitioning a set of polygons with a plane is done by classifying
  274.      each member of the set with respect to the plane. If a polygon lies
  275.      entirely to one side or the other of the plane, then it is not
  276.      modified, and is added to the partition set for the side that it is
  277.      on. If a polygon spans the plane, it is split into two or more pieces
  278.      and the resulting parts are added to the sets associated with either
  279.      side as appropriate.
  280.  
  281.      When to stop
  282.      The decision to terminate tree construction is, again, a matter of the
  283.      specific application. Some methods terminate when the number of
  284.      polygons in a leaf node is below a maximum value. Other methods
  285.      continue until every polygon is placed in an internal node. Another
  286.      criteria is a maximum tree depth.
  287.  
  288.      Pseudo C++ code example
  289.      Here is an example of how you might code a BSP tree:
  290.  
  291.      struct  BSP_tree
  292.  
  293.      {
  294.  
  295.         plane     partition;
  296.  
  297.         list      polygons;
  298.  
  299.         BSP_tree  *front,
  300.  
  301.                   *back;
  302.  
  303.      };
  304.  
  305.      This structure definition will be used for all subsequent example
  306.      code. It stores pointers to its children, the partitioning plane for
  307.      the node, and a list of polygons coincident with the partition plane.
  308.      For this example, there will always be at least one polygon in the
  309.      coincident list: the polygon used to determine the partition plane. A
  310.      constructor method for this structure should initialize the child
  311.      pointers to NULL.
  312.  
  313.      void    Build_BSP_Tree (BSP_tree *tree, list polygons)
  314.  
  315.      {
  316.  
  317.         polygon   *root = polygons.Get_From_List ();
  318.  
  319.         tree->partition = root->Get_Plane ();
  320.  
  321.         tree->polygons.Add_To_List (root);
  322.  
  323.         list      front_list,
  324.  
  325.                   back_list;
  326.  
  327.         polygon   *poly;
  328.  
  329.         while ((poly = polygons.Get_From_List ()) != 0)
  330.  
  331.         {
  332.  
  333.            int   result = tree->partition.Classify_Polygon (poly);
  334.  
  335.            switch (result)
  336.  
  337.            {
  338.  
  339.               case COINCIDENT:
  340.  
  341.                  tree->polygons.Add_To_List (poly);
  342.  
  343.                  break;
  344.  
  345.               case IN_BACK_OF:
  346.  
  347.                  backlist.Add_To_List (poly);
  348.  
  349.                  break;
  350.  
  351.               case IN_FRONT_OF:
  352.  
  353.                  frontlist.Add_To_List (poly);
  354.  
  355.                  break;
  356.  
  357.               case SPANNING:
  358.  
  359.                  polygon   *front_piece, *back_piece;
  360.  
  361.                  Split_Polygon (poly, tree->partition, front_piece, back_piece);
  362.  
  363.                  backlist.Add_To_List (back_piece);
  364.  
  365.                  frontlist.Add_To_List (front_piece);
  366.  
  367.                  break;
  368.  
  369.            }
  370.  
  371.         }
  372.  
  373.         if ( ! front_list.Is_Empty_List ())
  374.  
  375.         {
  376.  
  377.            tree->front = new BSP_tree;
  378.  
  379.            Build_BSP_Tree (tree->front, front_list);
  380.  
  381.         }
  382.  
  383.         if ( ! back_list.Is_Empty_List ())
  384.  
  385.         {
  386.  
  387.            tree->back = new BSP_tree;
  388.  
  389.            Build_BSP_Tree (tree->back, back_list);
  390.  
  391.         }
  392.  
  393.      }
  394.  
  395.      This routine recursively constructs a BSP tree using the above
  396.      definition. It takes the first polygon from the input list and uses it
  397.      to partition the remainder of the set. The routine then calls itself
  398.      recursively with each of the two partitions. This implementation
  399.      assumes that all of the input polygons are convex.
  400.  
  401.      One obvious improvement to this example is to choose the partitioning
  402.      plane more intelligently. This issue is addressed separately in the
  403.      section, "How can you make a BSP Tree more efficient?".
  404.      --
  405.      Last Update: 05/08/95 13:10:25
  406.  
  407.   7. How do you partition a polygon with a plane?
  408.  
  409.      Overview
  410.      Partitioning a polygon with a plane is a matter of determining which
  411.      side of the plane the polygon is on. This is referred to as a
  412.      front/back test, and is performed by testing each point in the polygon
  413.      against the plane. If all of the points lie to one side of the plane,
  414.      then the entire polygon is on that side and does not need to be split.
  415.      If some points lie on both sides of the plane, then the polygon is
  416.      split into two or more pieces.
  417.  
  418.      The basic algorithm is to loop across all the edges of the polygon and
  419.      find those for which one vertex is on each side of the partition
  420.      plane. The intersection points of these edges and the plane are
  421.      computed, and those points are used as new vertices for the resulting
  422.      pieces.
  423.  
  424.      Implementation notes
  425.      Classifying a point with respect to a plane is done by passing the (x,
  426.      y, z) values of the point into the plane equation, Ax + By + Cz + D =
  427.      0. The result of this operation is the distance from the plane to the
  428.      point along the plane's normal vector. It will be positive if the
  429.      point is on the side of the plane pointed to by the normal vector,
  430.      negative otherwise. If the result is 0, the point is on the plane.
  431.  
  432.      For those not familiar with the plane equation, The values A, B, and C
  433.      are the coordinate values of the normal vector. D can be calculated by
  434.      substituting a point known to be on the plane for x, y, and z.
  435.  
  436.      Convex polygons are generally easier to deal with in BSP tree
  437.      construction than concave ones, because splitting them with a plane
  438.      always results in exactly two convex pieces. Furthermore, the
  439.      algorithm for splitting convex polygons is straightforward and robust.
  440.      Splitting of concave polygons, especially self intersecting ones, is a
  441.      significant problem in its own right.
  442.  
  443.      Pseudo C++ code example
  444.      Here is a very basic function to split a convex polygon with a plane:
  445.  
  446.      void Split_Polygon (polygon *poly, plane *part, polygon *&front, polygon *&back)
  447.  
  448.      {
  449.  
  450.         int   count = poly->NumVertices (),
  451.  
  452.               out_c = 0, in_c = 0;
  453.  
  454.         point ptA, ptB,
  455.  
  456.               outpts[MAXPTS],
  457.  
  458.               inpts[MAXPTS];
  459.  
  460.         real sideA, sideB;
  461.  
  462.         ptA = poly->Vertex (count - 1);
  463.  
  464.         sideA = part->Classify_Point (ptA);
  465.  
  466.         for (short i = -1; ++i < count;)
  467.  
  468.         {
  469.  
  470.            ptB = poly->Vertex (i);
  471.  
  472.            sideB = part->Classify_Point (ptB);
  473.  
  474.            if (sideB > 0)
  475.  
  476.            {
  477.  
  478.               if (sideA < 0)
  479.  
  480.               {
  481.  
  482.                  // compute the intersection point of the line
  483.  
  484.                  // from point A to point B with the partition
  485.  
  486.                  // plane. This is a simple ray-plane intersection.
  487.  
  488.                  vector v = ptB - ptA;
  489.  
  490.                  real   sect = part->Classify_Point (-ptA) / (part->Normal () | v);
  491.  
  492.                  outpts[out_c++] = inpts[in_c++] = ptA + (v * sect);
  493.  
  494.               }
  495.  
  496.               outpts[out_c++] = ptB;
  497.  
  498.            }
  499.  
  500.            else if (sideB < 0)
  501.  
  502.            {
  503.  
  504.               if (sideA > 0)
  505.  
  506.               {
  507.  
  508.                  // compute the intersection point of the line
  509.  
  510.                  // from point A to point B with the partition
  511.  
  512.                  // plane. This is a simple ray-plane intersection.
  513.  
  514.                  vector v = ptB - ptA;
  515.  
  516.                  real   sect = part->Classify_Point (-ptA) / (part->Normal () | v);
  517.  
  518.                  outpts[out_c++] = inpts[in_c++] = ptA + (v * sect);
  519.  
  520.               }
  521.  
  522.               inpts[in_c++] = ptB;
  523.  
  524.            }
  525.  
  526.            else
  527.  
  528.               outpts[out_c++] = inpts[in_c++] = ptB;
  529.  
  530.            ptA = ptB;
  531.  
  532.            sideA = sideB;
  533.  
  534.         }
  535.  
  536.         front = new polygon (outpts, out_c);
  537.  
  538.         back = new polygon (inpts, in_c);
  539.  
  540.      }
  541.  
  542.      A simple extension to this code that is good for BSP trees is to
  543.      combine its functionality with the routine to classify a polygon with
  544.      respect to a plane.
  545.  
  546.      Note that this code is not robust, since numerical stability may cause
  547.      errors in the classification of a point. The standard solution is to
  548.      make the plane "thick" by use of an epsilon value.
  549.      --
  550.      Last Update: 05/08/95 13:10:25
  551.  
  552.   8. How do you remove hidden surfaces with a BSP Tree?
  553.  
  554.      Overview
  555.      Probably the most common application of BSP trees is hidden surface
  556.      removal in three dimensions. BSP trees provide an elegant, efficient
  557.      method for sorting polygons via a depth first tree walk. This fact can
  558.      be exploited in a back to front "painter's algorithm" approach to the
  559.      visible surface problem, or a front to back scanline approach.
  560.  
  561.      BSP trees are well suited to interactive display of static (not
  562.      moving) geometry because the tree can be constructed as a preprocess.
  563.      Then the display from any arbitrary viewpoint can be done in linear
  564.      time. Adding dynamic (moving) objects to the scene is discussed in
  565.      another section of this document.
  566.  
  567.      Painter's algorithm
  568.      The idea behind the painter's algorithm is to draw polygons far away
  569.      from the eye first, followed by drawing those that are close to the
  570.      eye. Hidden surfaces will be written over in the image as the surfaces
  571.      that obscure them are drawn. One condition for a successful painter's
  572.      algorithm is that there be a single plane which separates any two
  573.      objects. This means that it might be necessary to split polygons in
  574.      certain configurations. For example, this case can not be drawn
  575.      correctly with a painter's algorithm:
  576.  
  577.                                +------+
  578.  
  579.                                |      |
  580.  
  581.                +---------------|      |--+
  582.  
  583.                |               |      |  |
  584.  
  585.                |               |      |  |
  586.  
  587.                |               |      |  |
  588.  
  589.                |      +--------|      |--+
  590.  
  591.                |      |        |      |
  592.  
  593.             +--|      |--------+      |
  594.  
  595.             |  |      |               |
  596.  
  597.             |  |      |               |
  598.  
  599.             |  |      |               |
  600.  
  601.             +--|      |---------------+
  602.  
  603.                |      |
  604.  
  605.                +------+
  606.  
  607.      One reason that BSP trees are so elegant for the painter's algorithm
  608.      is that the splitting of difficult polygons is an automatic part of
  609.      tree construction. Note that only one of these two polygons needs to
  610.      be split in order to resolve the problem.
  611.  
  612.      To draw the contents of the tree, perform a back to front tree
  613.      traversal. Begin at the root node and classify the eye point with
  614.      respect to its partition plane. Draw the subtree at the far child from
  615.      the eye, then draw the polygons in this node, then draw the near
  616.      subtree. Repeat this procedure recursively for each subtree.
  617.  
  618.      Scanline hidden surface removal
  619.      It is just as easy to traverse the BSP tree in front to back order as
  620.      it is for back to front. We can use this to our advantage in a
  621.      scanline method method by using a write mask which will prevent pixels
  622.      from being written more than once. This will represent significant
  623.      speedups if a complex lighting model is evaluated for each pixel,
  624.      because the painter's algorithm will blindly evaluate the same pixel
  625.      many times.
  626.  
  627.      The trick to making a scanline approach successful is to have an
  628.      efficient method for masking pixels. One way to do this is to maintain
  629.      a list of pixel spans which have not yet been written to for each scan
  630.      line. For each polygon scan converted, only pixels in the available
  631.      spans are written, and the spans are updated accordingly.
  632.  
  633.      The scan line spans can be represented as binary trees, which are just
  634.      one dimensional BSP trees. This technique can be expanded to a two
  635.      dimensional screen coverage algorithm using a two dimensional BSP tree
  636.      to represent the masked regions. Any convex partitioning scheme, such
  637.      as a quadtree, can be used with similar effect.
  638.  
  639.      Implementation notes
  640.      When building a BSP tree specifically for hidden surface removal, the
  641.      partition planes are usually chosen from the input polygon set.
  642.      However, any arbitrary plane can be used if there are no intersecting
  643.      or concave polygons, as in the example above.
  644.  
  645.      Pseudo C++ code example
  646.      Using the BSP_tree structure defined in the section, "How do you build
  647.      a BSP Tree?", here is a simple example of a back to front tree
  648.      traversal:
  649.  
  650.      void    Draw_BSP_Tree (BSP_tree *tree, point eye)
  651.  
  652.      {
  653.  
  654.         real   result = tree->partition.Classify_Point (eye);
  655.  
  656.         if (result > 0)
  657.  
  658.         {
  659.  
  660.            Draw_BSP_Tree (tree->back, eye);
  661.  
  662.            tree->polygons.Draw_Polygon_List ();
  663.  
  664.            Draw_BSP_Tree (tree->front, eye);
  665.  
  666.         }
  667.  
  668.         else if (result < 0)
  669.  
  670.         {
  671.  
  672.            Draw_BSP_Tree (tree->front, eye);
  673.  
  674.            tree->polygons.Draw_Polygon_List ();
  675.  
  676.            Draw_BSP_Tree (tree->back, eye);
  677.  
  678.         }
  679.  
  680.         else // result is 0
  681.  
  682.         {
  683.  
  684.            // the eye point is on the partition plane...
  685.  
  686.            Draw_BSP_Tree (tree->front, eye);
  687.  
  688.            Draw_BSP_Tree (tree->back, eye);
  689.  
  690.         }
  691.  
  692.      }
  693.  
  694.      If the eye point is classified as being on the partition plane, the
  695.      drawing order is unclear. This is not a problem if the
  696.      Draw_Polygon_List routine is smart enough to not draw polygons that
  697.      are not within the viewing frustum. The coincident polygon list does
  698.      not need to be drawn in this case, because those polygons will not be
  699.      visible to the user.
  700.  
  701.      It is possible to substantially improve the quality of this example by
  702.      including the viewing direction vector in the computation. You can
  703.      determine that entire subtrees are behind the viewer by comparing the
  704.      view vector to the partition plane normal vector. This test can also
  705.      make a better decision about tree drawing when the eye point lies on
  706.      the partition plane. It is worth noting that this improvement
  707.      resembles the method for tracing a ray through a BSP tree, which is
  708.      discussed in another section of this document.
  709.  
  710.      Front to back tree traversal is accomplished in exactly the same
  711.      manner, except that the recursive calls to Draw_BSP_Tree occur in
  712.      reverse order.
  713.      --
  714.      Last Update: 05/08/95 13:10:25
  715.  
  716.   9. How do you remove hidden lines with a BSP Tree?
  717.  
  718.      Overview
  719.  
  720.      --
  721.      Last Update: 04/30/95 15:45:19
  722.  
  723.  10. How do you accelerate ray tracing with a BSP Tree?
  724.  
  725.      Overview
  726.      Ray tracing a BSP tree is very similar to hidden surface removal with
  727.      a BSP tree. The algorithm is a simple forward tree walk, with a few
  728.      additions that apply to ray casting.
  729.  
  730.      MORE TO COME
  731.  
  732.      --
  733.      Last Update: 04/30/95 15:45:19
  734.  
  735.  11. How do you perform boolean operations on polytopes with a BSP Tree?
  736.  
  737.      Overview
  738.      There are two major classes of solid modeling methods with BSP trees.
  739.      For both methods, it is useful to introduce the notion of an in/out
  740.      test.
  741.  
  742.      An in/out test is a different way of talking about the front/back test
  743.      we have been using to classify points with respect to planes. The
  744.      necessity for this shift in thought is evident when considering
  745.      polytopes instead of just polygons. A point can not be merely in front
  746.      or back of a polytope, but inside or outside. Somewhat formally, a
  747.      point is inside of a polytope if it is inside of, or in back of, each
  748.      hyperplane which composes the polytope, otherwise it is outside.
  749.  
  750.      Incremental construction
  751.      Incremental construction of a BSP Tree is the process of inserting
  752.      convex polytopes into the tree one by one. Each polytope has to be
  753.      processed according to the operation desired.
  754.  
  755.      It is useful to examine the construction process in two dimensions.
  756.      Consider the following figure:
  757.  
  758.      A               B
  759.  
  760.       +-------------+
  761.  
  762.       |             |
  763.  
  764.       |             |
  765.  
  766.       |      E      |        F
  767.  
  768.       |       +-----+-------+
  769.  
  770.       |       |     |       |
  771.  
  772.       |       |     |       |
  773.  
  774.       |       |     |       |
  775.  
  776.       +-------+-----+       |
  777.  
  778.      D        |      C      |
  779.  
  780.               |             |
  781.  
  782.               |             |
  783.  
  784.               +-------------+
  785.  
  786.              H               G
  787.  
  788.      Two polygons, ABCD, and EFGH, are to be inserted into the tree. We
  789.      wish to find the union of these two polygons. Start by inserting
  790.      polygon ABCD into the tree, choosing the splitting hyperplanes to be
  791.      coincident with the edges. The tree looks like this after insertion of
  792.      ABCD:
  793.  
  794.                      AB
  795.  
  796.                    -/  \+
  797.  
  798.                    /    \
  799.  
  800.                   /      *
  801.  
  802.                  BC
  803.  
  804.                -/  \+
  805.  
  806.                /    \
  807.  
  808.               /      *
  809.  
  810.              CD
  811.  
  812.            -/  \+
  813.  
  814.            /    \
  815.  
  816.           /      *
  817.  
  818.          DA
  819.  
  820.        -/  \+
  821.  
  822.        /    \
  823.  
  824.       *      *
  825.  
  826.      Now, polygon EFGH is inserted into the tree, one polygon at a time.
  827.      The result looks like this:
  828.  
  829.      A               B
  830.  
  831.       +-------------+
  832.  
  833.       |             |
  834.  
  835.       |             |
  836.  
  837.       |      E      |J       F
  838.  
  839.       |       +-----+-------+
  840.  
  841.       |       |     |       |
  842.  
  843.       |       |     |       |
  844.  
  845.       |       |     |       |
  846.  
  847.       +-------+-----+       |
  848.  
  849.      D        |L    :C      |
  850.  
  851.               |     :       |
  852.  
  853.               |     :       |
  854.  
  855.               +-----+-------+
  856.  
  857.              H      K        G
  858.  
  859.                              AB
  860.  
  861.                            -/  \+
  862.  
  863.                            /    \
  864.  
  865.                           /      *
  866.  
  867.                          BC
  868.  
  869.                        -/  \+
  870.  
  871.                        /    \
  872.  
  873.                       /      \
  874.  
  875.                      CD       \
  876.  
  877.                    -/  \+      \
  878.  
  879.                    /    \       \
  880.  
  881.                   /      \       \
  882.  
  883.                  DA       \       \
  884.  
  885.                -/  \+      \       \
  886.  
  887.                /    \       \       \
  888.  
  889.               /      *       \       \
  890.  
  891.              EJ              KH       \
  892.  
  893.            -/  \+          -/  \+      \
  894.  
  895.            /    \          /    \       \
  896.  
  897.           /      *        /      *       \
  898.  
  899.          LE              HL              JF
  900.  
  901.        -/  \+          -/  \+          -/  \+
  902.  
  903.        /    \          /    \          /    \
  904.  
  905.       *      *        *      *        FG     *
  906.  
  907.                                     -/  \+
  908.  
  909.                                     /    \
  910.  
  911.                                    /      *
  912.  
  913.                                   GK
  914.  
  915.                                 -/  \+
  916.  
  917.                                 /    \
  918.  
  919.                                *      *
  920.  
  921.      Notice that when we insert EFGH, we split edges EF and HE along the
  922.      edges of ABCD. this has the effect of dividing these segments into
  923.      pieces which are inside ABCD, and outside ABCD. Segments EJ and LE
  924.      will not be part of the boundary of the union. We could have saved our
  925.      selves some work by not inserting them into the tree at all. For a
  926.      union operation, you can always throw away segments that land in
  927.      inside nodes. You must be careful about this though. What I mean is
  928.      that any segments which land in inside nodes of side the pre-existing
  929.      tree, not the tree as it is being constructed. EJ and LE landed in an
  930.      inside node of the tree for polygon ABCD, and so can be discarded.
  931.  
  932.      Our tree now looks like this:
  933.  
  934.      
  935.  
  936.      A               B
  937.  
  938.       +-------------+
  939.  
  940.       |             |
  941.  
  942.       |             |
  943.  
  944.       |             |J       F
  945.  
  946.       |             +-------+
  947.  
  948.       |             |       |
  949.  
  950.       |             |       |
  951.  
  952.       |             |       |
  953.  
  954.       +-------+-----+       |
  955.  
  956.      D        |L    :C      |
  957.  
  958.               |     :       |
  959.  
  960.               |     :       |
  961.  
  962.               +-----+-------+
  963.  
  964.              H      K        G
  965.  
  966.                              AB
  967.  
  968.                            -/  \+
  969.  
  970.                            /    \
  971.  
  972.                           /      *
  973.  
  974.                          BC
  975.  
  976.                        -/  \+
  977.  
  978.                        /    \
  979.  
  980.                       /      \
  981.  
  982.                      CD       \
  983.  
  984.                    -/  \+      \
  985.  
  986.                    /    \       \
  987.  
  988.                   /      \       \
  989.  
  990.                  DA       \       \
  991.  
  992.                -/  \+      \       \
  993.  
  994.                /    \       \       \
  995.  
  996.               *      *       \       \
  997.  
  998.                              KH       \
  999.  
  1000.                            -/  \+      \
  1001.  
  1002.                            /    \       \
  1003.  
  1004.                           /      *       \
  1005.  
  1006.                          HL              JF
  1007.  
  1008.                        -/  \+          -/  \+
  1009.  
  1010.                        /    \          /    \
  1011.  
  1012.                       *      *        FG     *
  1013.  
  1014.                                     -/  \+
  1015.  
  1016.                                     /    \
  1017.  
  1018.                                    /      *
  1019.  
  1020.                                   GK
  1021.  
  1022.                                 -/  \+
  1023.  
  1024.                                 /    \
  1025.  
  1026.                                *      *
  1027.  
  1028.      Now, we would like some way to eliminate the segments JC and CL, so
  1029.      that we will be left with the boundary segments of the union. Examine
  1030.      the segment BC in the tree. What we would like to do is split BC with
  1031.      the hyperplane JF. Conveniently, we can do this by pushing the BC
  1032.      segment through the node for JF. The resulting segments can be
  1033.      classified with the rest of the JF subtree. Notice that the segment BJ
  1034.      lands in an out node, and that JC lands in an in node. Remembering
  1035.      that we can discard interior nodes, we can eliminate JC. The segment
  1036.      BJ replaces BC in the original tree. This process is repeated for
  1037.      segment CD, yielding the segments CL and LD. CL is discarded as
  1038.      landing in an interior node, and LD replaces CD in the original tree.
  1039.      The result looks like this:
  1040.  
  1041.      
  1042.  
  1043.      A               B
  1044.  
  1045.       +-------------+
  1046.  
  1047.       |             |
  1048.  
  1049.       |             |
  1050.  
  1051.       |             |J       F
  1052.  
  1053.       |             +-------+
  1054.  
  1055.       |                     |
  1056.  
  1057.       |                     |
  1058.  
  1059.       |        L            |
  1060.  
  1061.       +-------+             |
  1062.  
  1063.      D        |             |
  1064.  
  1065.               |             |
  1066.  
  1067.               |             |
  1068.  
  1069.               +-----+-------+
  1070.  
  1071.              H      K        G
  1072.  
  1073.                              AB
  1074.  
  1075.                            -/  \+
  1076.  
  1077.                            /    \
  1078.  
  1079.                           /      *
  1080.  
  1081.                          BJ
  1082.  
  1083.                        -/  \+
  1084.  
  1085.                        /    \
  1086.  
  1087.                       /      \
  1088.  
  1089.                      LD       \
  1090.  
  1091.                    -/  \+      \
  1092.  
  1093.                    /    \       \
  1094.  
  1095.                   /      \       \
  1096.  
  1097.                  DA       \       \
  1098.  
  1099.                -/  \+      \       \
  1100.  
  1101.                /    \       \       \
  1102.  
  1103.               *      *       \       \
  1104.  
  1105.                              KH       \
  1106.  
  1107.                            -/  \+      \
  1108.  
  1109.                            /    \       \
  1110.  
  1111.                           /      *       \
  1112.  
  1113.                          HL              JF
  1114.  
  1115.                        -/  \+          -/  \+
  1116.  
  1117.                        /    \          /    \
  1118.  
  1119.                       *      *        FG     *
  1120.  
  1121.                                     -/  \+
  1122.  
  1123.                                     /    \
  1124.  
  1125.                                    /      *
  1126.  
  1127.                                   GK
  1128.  
  1129.                                 -/  \+
  1130.  
  1131.                                 /    \
  1132.  
  1133.                                *      *
  1134.  
  1135.      As you can see, the result is the union of the polygons ABCD and EFGH.
  1136.  
  1137.      To perform other boolean operations, the process is similar. For
  1138.      intersection, you discard segments which land in exterior nodes
  1139.      instead of internal ones. The difference operation is special. It
  1140.      requires that you invert the polytope before insertion. For simple
  1141.      objects, this can be achieved by scaling with a factor of -1. The
  1142.      insertion process is then cinducted as an intersection operation,
  1143.      where segments landing in external nodes are discarded.
  1144.  
  1145.      Tree merging
  1146.  
  1147.      --
  1148.      Last Update: 04/30/95 15:45:20
  1149.  
  1150.  12. How do you perform collision detection with a BSP Tree?
  1151.  
  1152.      Overview
  1153.      Detecting whether or not a point moving along a line intersects some
  1154.      object in space is essentially a ray tracing problem. Detecting
  1155.      whether or not two complex objects intersect is something of a tree
  1156.      merging problem.
  1157.  
  1158.      Typically, motion is computed in a series of Euler steps. This just
  1159.      means that the motion is computed at discrete time intervals using
  1160.      some description of the speed of motion. For any given point P moving
  1161.      from point A with a velocity V, it's location can be computed at time
  1162.      T as P = A + (T * V).
  1163.  
  1164.      Consider the case where T = 1, and we are computing the motion in one
  1165.      second steps. To find out if the point P has collided with any part of
  1166.      the scene, we will first compute the endpoints of the motion for this
  1167.      time step. P1 = A + V, and P2 = A + (2 * V). These two endpoints will
  1168.      be classified with respect to the BSP tree. If P1 is outside of all
  1169.      objects, and P2 is inside some object, then an intersection has
  1170.      clearly occurred. However, if P2 is also outside, we still have to
  1171.      check for a collision in between.
  1172.  
  1173.      Two approaches are possible. The first is commonly used in
  1174.      applications like games, where speed is critical, and accuracy is not.
  1175.      This approach is to recursively divide the motion segment in half, and
  1176.      check the midpoint for containment by some object. Typically, it is
  1177.      good enough to say that an intersection occurred, and not be very
  1178.      accurate about where it occurred.
  1179.  
  1180.      The second approach, which is more accurate, but also more time
  1181.      consuming, is to treat the motion segment as a ray, and intersect the
  1182.      ray with the BSP Tree. This also has the advantage that the motion
  1183.      resulting from the impact can be computed more accurately.
  1184.      --
  1185.      Last Update: 04/30/95 15:45:20
  1186.  
  1187.  13. How do you handle dynamic scenes with a BSP Tree?
  1188.  
  1189.      Overview
  1190.      So far the discussion of BSP tree structures has been limited to
  1191.      handling objects that don't move. However, because the hidden surface
  1192.      removal algorithm is so simple and efficient, it would be nice if it
  1193.      could be used with dynamic scenes too. Faster animation is the goal
  1194.      for many applications, most especially games.
  1195.  
  1196.      The BSP tree hidden surface removal algorithm can easily be extended
  1197.      to allow for dynamic objects. For each frame, start with a BSP tree
  1198.      containing all the static objects in the scene, and reinsert the
  1199.      dynamic objects. While this is straightforward to implement, it can
  1200.      involve substantial computation.
  1201.  
  1202.      If a dynamic object is separated from each static object by a plane,
  1203.      the dynamic object can be represented as a single point regardless of
  1204.      its complexity. This can dramatically reduce the computation per frame
  1205.      because only one node per dynamic object is inserted into the BSP
  1206.      tree. Compare that to one node for every polygon in the object, and
  1207.      the reason for the savings is obvious. During tree traversal, each
  1208.      point is expanded into the original object.
  1209.  
  1210.      Implementation notes
  1211.      Inserting a point into the BSP tree is very cheap, because there is
  1212.      only one front/back test at each node. Points are never split, which
  1213.      explains the requirement of separation by a plane. The dynamic object
  1214.      will always be drawn completely in front of the static objects behind
  1215.      it.
  1216.  
  1217.      A dynamic object inserted into the tree as a point can become a child
  1218.      of either a static or dynamic node. If the parent is a static node,
  1219.      perform a front/back test and insert the new node appropriately. If it
  1220.      is a dynamic node, a different front/back test is necessary, because a
  1221.      point doesn't partition three dimesnional space. The correct
  1222.      front/back test is to simply compare distances to the eye. Once
  1223.      computed, this distance can be cached at the node until the frame is
  1224.      drawn.
  1225.  
  1226.      An alternative when inserting a dynamic node is to construct a plane
  1227.      whose normal is the vector from the point to the eye. This plane is
  1228.      used in front/back tests just like the partition plane in a static
  1229.      node. The plane should be computed lazily and it is not necessary to
  1230.      normalize the vector.
  1231.  
  1232.      Cleanup at the end of each frame is easy. A static node can never be a
  1233.      child of a dynamic node, since all dynamic nodes are inserted after
  1234.      the static tree is completed. This implies that all subtrees of
  1235.      dynamic nodes can be removed at the same time as the dynamic parent
  1236.      node.
  1237.  
  1238.      Advanced methods
  1239.      Tree merging, "ghosts", real dynamic trees... MORE TO COME
  1240.      --
  1241.      Last Update: 04/29/95 03:14:22
  1242.  
  1243.  14. How do you compute shadows with a BSP Tree?
  1244.  
  1245.      Overview
  1246.  
  1247.      --
  1248.      Last Update: 04/30/95 15:45:20
  1249.  
  1250.  15. How do you extract connectivity information from BSP Trees?
  1251.  
  1252.      Overview
  1253.  
  1254.      --
  1255.      Last Update: 04/30/95 15:45:20
  1256.  
  1257.  16. How are BSP Trees useful for robot motion planning?
  1258.  
  1259.      Overview
  1260.  
  1261.      --
  1262.      Last Update: 04/30/95 15:45:20
  1263.  
  1264.  17. How are BSP Trees used in DOOM?
  1265.  
  1266.      Overview
  1267.      Before you can understand how DOOM uses a BSP tree to accelerate its
  1268.      rendering process, you have to understand how the world is represented
  1269.      in DOOM. When someone creates a DOOM level in a level editor they draw
  1270.      linedefs in a 2d space. Yes, that's right, DOOM is only 2d. These
  1271.      linedefs (ignoring the special effects linedefs) must be arranged so
  1272.      that they form closed polygons. One linedef may be used to form the
  1273.      outline of two polygons (in which case it is known as a two-sided
  1274.      linedef) and one polygon may be contained within another, but no
  1275.      linedefs may cross. Each enclosed area of the world (i.e. polygon) is
  1276.      assigned a floor height, ceiling height, floor and ceiling textures, a
  1277.      lower texture and an upper texture. The lower texture is visible when
  1278.      a linedef is viewed from a direction where the floor is lower in the
  1279.      adjoining area. An equivalent thing is true for the upper texture. A
  1280.      set of these enclosed areas that all have the same attributes is known
  1281.      as a sector.
  1282.  
  1283.      When the level is saved by the editor some new information is created
  1284.      including the BSP tree for that level. Before the BSP tree can be
  1285.      created, all the sectors have to be split into convex polygons known
  1286.      as sub-sectors. If you had a sector that was a square area, then that
  1287.      would translate exactly into a sub-sector. Whereas if that sector was
  1288.      contained inside another larger square sector, the larger one would
  1289.      have to be split into four, four sided sub-sectors to make all the
  1290.      sub-sectors convex. When more complex sectors are split into
  1291.      sub-sectors the linedefs that bound that sector may need to be broken
  1292.      into smaller lengths. These linedef sections are called segs.
  1293.  
  1294.      Given a point on the 2d map, the renderer (which isn't discussed here)
  1295.      wants a list of all the segs that are visible from that viewpoint in
  1296.      closest first order. Because of the restrictions placed on the DOOM
  1297.      world, the renderer can easily tell when the screen has been filled so
  1298.      it can stop looking for segs at this time. This is quicker than
  1299.      rendering all the segs from back to front and using a method like
  1300.      painters algorithm.
  1301.  
  1302.      Each node in the BSP tree defines a partition line (this does not have
  1303.      be a linedef in the world but usually is) which is the equivalent to
  1304.      the partition plane of a 3d BSP tree. It then has left and right
  1305.      pointers which are either another node for further sub-division or a
  1306.      leaf, the leaf being a sub-sector in DOOM. The BSP tree in DOOM is
  1307.      effectively being used to sort whole sub-sectors rather than
  1308.      individual lines front to back. Each node also defines an orthogonal
  1309.      bounding box for each side of the partition. All segs on a particular
  1310.      side of the partition must be within that box. This speeds up the
  1311.      searching process by allowing whole branches of the tree to be
  1312.      discarded if that bounding box isn't visible. The test for visibility
  1313.      is simply if the bounding box lies wholly or partly within the cone
  1314.      defined by the left and right edges of the screen.
  1315.  
  1316.      During the display update process the BSP tree is searched starting
  1317.      from the node containing the sub-sector that the player is currently
  1318.      in. The search moves outwards through the tree (searching the other
  1319.      half of the current node before moving onto the other half of the
  1320.      parents node). When a partition test is performed the branch chosen is
  1321.      the one on the same side as the player. This facilitates the front to
  1322.      back searching. Each time a leaf is encountered the segs in that
  1323.      sub-sector are passed to the renderer. If the renderer has returned
  1324.      that the screen is filled then the process stops, otherwise it
  1325.      continues until the tree has been fully searched (in which case there
  1326.      is an error in the level design).
  1327.  
  1328.      In case you're thinking that it is inefficient to dump a whole
  1329.      sub-sectors worth of segs into the renderer at once, the segs in a
  1330.      sub-sector can be back-face culled very quickly. DOOM stores the angle
  1331.      of linedefs (of which segs are part). When the angle of the players
  1332.      view is calculated this allows segs to be culled in a single
  1333.      instruction! Angles are stored as a 16 bit number where 0 is east an
  1334.      65535 is 1/63336 south of east.
  1335.      --
  1336.      Last Update: 04/30/95 15:45:20
  1337.  
  1338.  18. How can you make a BSP Tree more robust?
  1339.  
  1340.      Overview
  1341.  
  1342.      --
  1343.      Last Update: 04/30/95 15:45:20
  1344.  
  1345.  19. How efficient is a BSP Tree?
  1346.  
  1347.      Space complexity
  1348.      For hidden surface removal and ray tracing accelleration, the upper
  1349.      bound is O(n ^ 2) for n polygons. The expected case is O(n) for most
  1350.      models. MORE LATER
  1351.  
  1352.      Time complexity
  1353.      For hidden surface removal and ray tracing accelleration, the upper
  1354.      bound is O(n ^ 2) for n polygons. The expected case is O(n) for most
  1355.      models. MORE LATER
  1356.      --
  1357.      Last Update: 04/30/95 15:45:20
  1358.  
  1359.  20. How can you make a BSP Tree more efficient?
  1360.  
  1361.      Bounding volumes
  1362.      Bounding spheres are simple to implement, take only a single plane
  1363.      comparison, using the center of the sphere.
  1364.  
  1365.      Tree balancing
  1366.      For hidden surface problem, doesn't affect runtime, assuming that no
  1367.      splitting occurs...
  1368.  
  1369.      Balancing vs. splitting
  1370.      Reference Counting
  1371.      Other Optimizations
  1372.  
  1373.      --
  1374.      Last Update: 03/02/95 23:40:07
  1375.  
  1376.  21. How can you avoid recursion?
  1377.  
  1378.      standard binary tree search/sort techniques apply.
  1379.      --
  1380.      Last Update: 03/02/95 23:40:07
  1381.  
  1382.  22. What is the history of BSP Trees?
  1383.  
  1384.      Overview
  1385.  
  1386.      --
  1387.      Last Update: 04/30/95 15:45:20
  1388.  
  1389.  23. Where can you find sample code and related resources?
  1390.  
  1391.      The companion source code to this document is available via FTP at:
  1392.  
  1393.         * file://ray.graphics.cornell.edu/pub/bsptree/
  1394.  
  1395.      or, you can also request that the source be mailed to you by sending
  1396.      e-mail to bsp-faq@graphics.cornell.edu with a subject line of "SEND
  1397.      BSP TREE SOURCE". This will return to you a UU encoded copy of the
  1398.      sample C++ source code.
  1399.  
  1400.      Pat Fleckenstein and Rob Reay have put together a FAQ on 3D graphics,
  1401.      which includes a blurb on BSP Trees, and an ftp site with some sample
  1402.      code. They seem to have an unusual affinity for ftp sites, and
  1403.      therefore won't link the BSP tree FAQ from their document:
  1404.  
  1405.         * 3D FAQ
  1406.         * file://ftp.csh.rit.edu/pub/3dfaq/
  1407.  
  1408.      Implementing and Using BSP Trees
  1409.  24. Accompanying C++ source
  1410.  
  1411. Other sources for sample BSP Tree code are:
  1412.  
  1413.    * file://ftp.idsoftware.com/tonsmore/utils/level_edit/node_builders/
  1414.    * file://ftp.princeton.edu/pub/Graphics/GraphicsGems/GemsIII/
  1415.      A C code implementation of ray tracing with BSP trees.
  1416.    * file://ftp.princeton.edu/pub/Graphics/GraphicsGems/GemsV/
  1417.      Norman Chin has provided extensive C code for BSP trees. An excellent
  1418.      resource.
  1419.    * file://ftp.cs.brown.edu/pub/sphigs.tar.Z
  1420.  
  1421. If you are interested in game programming, check out the
  1422. rec.games.programmer FAQ.
  1423. --
  1424. Last Update: 05/14/95 02:14:24
  1425.  
  1426. * References
  1427.  
  1428. * Dadoun, N., Kirkpatrick, D., and Walsh, J., The Geometry of Beam Tracing,
  1429. Proceedings of the ACM Symposium on Computational Geometry, 55--61, jun
  1430. 1985.
  1431.  
  1432. * Chin, N., and Feiner, S., Near Real-Time Shadow Generation Using BSP
  1433. Trees, Computer Graphics (SIGGRAPH '89 Proceedings), 23(3), 99--106, jul
  1434. 1989.
  1435.  
  1436. * Chin, N., and Feiner, S., Fast object-precision shadow generation for
  1437. area light sources using BSP trees, Computer Graphics (1992 Symposium on
  1438. Interactive 3D Graphics), 25(2), 21--30, mar 1992.
  1439.  
  1440. * Chrysanthou, Y., and Slater, M., Computing dynamic changes to BSP trees,
  1441. Computer Graphics Forum (EUROGRAPHICS '92 Proceedings), 11(3), 321--332,
  1442. sep 1992.
  1443.  
  1444. * Naylor, B., Amanatides, J., and Thibault, W., Merging BSP Trees Yields
  1445. Polyhedral Set Operations, Computer Graphics (SIGGRAPH '90 Proceedings),
  1446. 24(4), 115--124, aug 1990.
  1447.  
  1448. * Chin, N., and Feiner, S., Fast object-precision shadow generation for
  1449. areal light sources using BSP trees, Computer Graphics (1992 Symposium on
  1450. Interactive 3D Graphics), 25(2), 21--30, mar 1992.
  1451.  
  1452. * Naylor, B., Interactive solid geometry via partitioning trees,
  1453. Proceedings of Graphics Interface '92, 11--18, may 1992.
  1454.  
  1455. * Naylor, B., Partitioning tree image representation and generation from 3D
  1456. geometric models, Proceedings of Graphics Interface '92, 201--212, may
  1457. 1992.
  1458.  
  1459. * Naylor, B., {SCULPT} An Interactive Solid Modeling Tool, Proceedings of
  1460. Graphics Interface '90, 138--148, may 1990.
  1461.  
  1462. * Gordon, D., and Chen, S., Front-to-back display of BSP trees, IEEE
  1463. Computer Graphics and Applications, 11(5), 79--85, sep 1991.
  1464.  
  1465. * Ihm, I., and Naylor, B., Piecewise linear approximations of digitized
  1466. space curves with applications, Scientific Visualization of Physical
  1467. Phenomena (Proceedings of CG International '91), 545--569, 1991.
  1468.  
  1469. * Vanecek, G., Brep-index: a multidimensional space partitioning tree,
  1470. Internat. J. Comput. Geom. Appl., 1(3), 243--261, 1991.
  1471.  
  1472. * Arvo, J., Linear Time Voxel Walking for Octrees, Ray Tracing News, feb
  1473. 1988.
  1474.  
  1475. * Jansen, F., Data Structures for Ray Tracing, Data Structures for Raster
  1476. Graphics, 57--73, 1986.
  1477.  
  1478. * MacDonald, J., and Booth, K., Heuristics for Ray Tracing Using Space
  1479. Subdivision, Proceedings of Graphics Interface '89, 152--63, jun 1989.
  1480.  
  1481. * Naylor, B., and Thibault, W., Application of BSP Trees to Ray Tracing and
  1482. CSG Evaluation, Tech. Rep. GIT-ICS 86/03, feb 1986.
  1483.  
  1484. * Sung, K., and Shirley, P., Ray Tracing with the BSP Tree, Graphics Gems
  1485. III, 271--274, 1992.
  1486.  
  1487. * Fuchs, H., Kedem, Z., and Naylor, B., On Visible Surface Generation by A
  1488. Priori Tree Structures, Conf. Proc. of SIGGRAPH '80, 14(3), 124--133, jul
  1489. 1980.
  1490.  
  1491. * Paterson, M., and Yao, F., Efficient Binary Space Partitions for
  1492. Hidden-Surface Removal and Solid Modeling, Discrete and Computational
  1493. Geometry, 5(5), 485--503, 1990.
  1494.  
  1495. --
  1496. Last Update: 04/30/95 15:45:20
  1497.  
  1498. ---------------------------------------------------------------------------
  1499. This document was last updated on Sunday, 26-Mar-95 19:22:54 EST
  1500. Bretton Wade (bwade@graphics.cornell.edu)
  1501.