![]() |
| INTRODUCTION |
| BspLib is a C++ class library from which a BSP compiler for 3-D objects can be built very easily. It consists of a class hierarchy for handling three-dimensional objects, together with various processing functions, the most important of which is BSP compilation. An I/O class hierarchy is provided for importing and exporting 3-D data. Aside from proprietary formats BspLib is capable of reading VRML V1.0 data files. A slightly modified version of Silicon Graphics' QvLib is employed for parsing the VRML V1.0 file format. Apart from the included version of QvLib, BspLib is completely self-contained, i.e., only the standard C++ run-time library (no STL needed!) need be linked to be able to use all functions. This, for example, means that VRML primitives (spheres, boxes, cones, cylinders) have to be tessellated on-the-fly prior to BSP compilation, in order to convert them to b-reps that can be BSP compiled. Since BspLib is able to create BSP trees for entire VRML scene graphs this also means that all transformations and modifications demanded by the scene graph have to be applied to achieve correct spatial relationships between contained objects, without which BSP compilation is not possible. Normally, all this would only be done when rendering the scene, since OpenGL supports exactly those operations very easily. That is, primitives would be submitted to OpenGL in implicit (non-polygonal) form and transformations would be done on-the-fly through OpenGL's matrix stack. Since one goal of BspLib was to make it possible to build a purely command-line BSP compiler without any additional libraries, potentially running on a large variety of platforms (which only need to support C++), OpenGL could not be used to alleviate the problem of supporting an entire VRML scene graph. So, in contrast to many VRML viewers, some basic OpenGL functionality had to be duplicated within BspLib. |
| CONTENTS |
| The BspLib documentation
consists of the following sections:
1. GENERAL
STRUCTURE
|
| 1. GENERAL STRUCTURE |
| BspLib consists of a collection
of C++ classes. All of BspLib's classes are contained in the BspLib
namespace (this may be turned off via a preprocessor macro and subsequent
recompilation, though). With only very few exceptions, each class's interface
is contained in its own header file (class-name.h). If a class contains
non-inline functions, its implementation is contained in a single separate
C++ file (class-name.cpp). Some global definitions and declarations
are contained in BspLibDefs.h, which is included by every header
of BspLib. All in all, BspLib is comprised of 56 classes and two class
templates. Additionally, in order to be able to read VRML V1.0 files, a
slightly modified version of Silicon Graphics' QvLib must be linked.
All interface classes of BspLib (that is, all classes normally used by the user) using dynamic storage are separated into handle and representation classes. The handle class is what the application programmer actually uses. Basically, a handle class is just a pointer to the representation class. Every time a handle is instanced, the reference count contained in the representation is incremented. Dynamic storage will only be freed when this count reaches zero. This scheme allows for efficient copying of objects containing large amounts of dynamically allocated data (without provoking storage maintenance problems, or mandating deep-copy of objects). A representation class for a handle class Test is named TestRep. The representation class should never be used directly, in order to allow for correct reference-counting and avoid problems with handling of dynamic storage! Another important concept in BspLib is the so-called chunk. A chunk (implemented via templates Chunk<> and ChunkRep<>) basically is just an array that expands itself if too few indexes are available, performs index validation, and so on. Primitives in BspLib are most of the time either stored in singly linked lists or in such chunks. For example, a 3-D object contains chunks for vertices, faces, textures, mappings, and a list for polygons. The basic array nature of a chunk notwithstanding it is dynamic storage referenced via a pointer, can be copied very easily (using reference-counting to avoid deep-copy, see preceding paragraph) and provides data abstraction, since the implementation is hidden from the user. Note that BspLib uses RTTI (run-time type information), so this feature must be supported and enabled in order to compile and use BspLib. |
| 2. CLASS HIERARCHIES |
| Most classes in BspLib belong to one of two distinct class hierarchies. First, there is a class hierarchy encompassing all geometrical classes. This includes very low-level primitives like vertices and vectors (e.g., class Vertex3 and class Vector3), and linesegments (class LineSeg2, class LineSeg3), primitives of intermediate complexity like polygons (class Polygon), and very powerful aggregate classes like class BspObject, which represents an entire geometrical object and utilizes many of the more primitive classes in order to be able to store and manipulate them. This collection of classes is no strict hierarchy. In fact, most of these classes may be bound to other classes at run-time via pointers but are not related through inheritance. The second class hierarchy where virtually all classes are related through inheritance is the I/O class hierarchy. These classes are responsible for parsing input data files, creating the scene graph, and writing the current scene graph to output data files of various formats. An input data file can be read and parsed by simply instancing class InputData3D, for example. Finally, since BspLib uses Silicon Graphics' QvLib to parse VRML V1.0 files there is also a number of classes with the 'Qv' prefix to the class name, comprising QvLib. |
| 3. INPUT/OUTPUT CLASS HIERARCHY |
| In order to be able to import
and export three-dimensional data BspLib contains a hierarchy of I/O classes.
These classes are used for all input and output purposes. The application
programmer basically just needs to instance InputData3D and OutputData3D
objects to read and write object data. These will be explained in detail
below.
BspLib's I/O hierarchy currently supports input and output of the proprietary AOD and BSP formats, as well as VRML V1.0 input (VRML output is not available). The following figure shows the entire I/O class hierarchy of BspLib, arrows denote inheritance:
![]() In the following we describe each of these I/O classes briefly (the only two classes important for an application programmer using BspLib are InputData3D and OutputData3D):
This is the base class for all I/O classes (and also all other classes needing host system-services, e.g., message output). It encapsulates host system-dependent code and provides basic facilities like file access, error message output, and the like. This is the base class for all classes related to file I/O. This class encapsulates all input functionality. It provides an abstract input interface to the application programmer. The user can instance an InputData3D object, passing the input file's name and an object of class BspObjectList to the constructor. The input file will then be read and parsed automatically, the input format is directly determined from the specified file itself. The passed in BspObjectList will then contain 3-D object representations for all data contained in the input file. That is, after correctly instancing an InputData3D object, the resulting BspObjectList is ready to be used for geometrical processing, rendering, and so on. InputData3D will instance AodInput, BspInput, and VrmlFile objects, according to the detected input format. If automatic format detection is not desired these classes may be used directly. This class encapsulates all output functionality. It provides an abstract output interface to the application programmer. The user can instance an OutputData3D object, passing the output file's name and an object of class BspObjectList to the constructor. Everything described by the passed in BspObjectList will then be written to the output file upon destruction of the OutputData3D object, the output format being determined by the file name's extension. Alternatively, an InputData3D object may be provided to the constructor, along with the desired output format. The input file name with an accordingly altered file name extension will then be used as output file. OutputData3D will instance AodOutput and BspOutput objects, according to the desired output format. If this semi-automatic output format detection is not desired these classes may be used directly. A VrmlFile object is used to read and parse VRML V1.0 files. This class employs Silicon Graphics' QvLib for parsing. An object of class BRep is used to interface QvLib to BspLib. BRep is capable of tessellating VRML primitives and converting VRML shape nodes to BspLib 3-D objects. This class will also apply necessary transformations and other conversions (e.g., texture transformations via VRML's Texture2Transform node, material application, and so on) to facilitate BspLib's further operation on the VRML scene graph. SingleFormat contains everything AOD and BSP files have in common. SingleInput provides input functionality for the common part of AOD and BSP files. SingleOutput provides output functionality for the common part of AOD and BSP files. These classes contain everything that the AOD format supports in addition to the common format (SingleFormat). These classes contain everything that the BSP format supports in addition to the common format (SingleFormat). Inherits 3-D object properties from BspObject and file format properties from AodFormat. The result is an object that is able to write 3-D information in AOD format. Inherits 3-D object properties from BspObject and file format properties from BspFormat. The result is an object that is able to write 3-D information in BSP format. |
| 4. GEOMETRY CLASSES |
| A large part of BspLib is
responsible for representing geometrical entities. Normally, input data
is read from any of the input formats supported by the I/O class hierarchy
and 3-D representations are created during parsing. As soon as the geometrical
representation has been created it can be used for rendering, for instance.
Rendering has to be done by the application using BspLib, though. The library
itself provides no such functionality, it only represents three-dimensional
data and provides various geometry processing functions that can be invoked
to operate on objects. The most important object processing function provided
by BspLib is, of course, BSP compilation.
The most important graphical entity in BspLib is the BspObject (class BspObject) which describes a single b-rep object, its material properties, and - if already compiled - its BSP tree. In order to be able to operate on many objects at once, BspObjects can be part of a BspObjectList (class BspObjectList). Normally, a BspObjectList is used to represent the entire scene. Processing functions can be invoked for such a list and BspLib will process all objects contained in it in the same way. Thus, the entire scene can be operated upon (for example, BSP compiled) very easily. The following figure shows
what a scene consisting of multiple objects could look like on the data-structure
level:
![]() The most important member of each BspObject is a PolygonList, which essentially is the object's boundary representation. For a description of a BspObject and all its fields see class BspObject. (Remember that all interface objects in BspLib are separated into handle and representation classes. Thus, the actual lists are of classes BSPObjectListRep and PolygonListRep, respectively, although the user uses class BSPObjectList and class PolygonList.) Here is a list of all other major geometry-related classes provided/used by BspLib:
4.1 Geometry class descriptions4.1.1 class BspObjectThis is the single most powerful class in BspLib. It represents a graphical object in its entirety. Thus, it necessarily contains all the geometrical data associated with such an object. A BspObject is comprised of the following parts:
An object's vertices are triplets specifying the vertex's x, y, and z coordinates. (Well, actually there is also a w component, but this is normally not used for ordinary vertices.) A polygon is comprised of a list of vertexindexes. These index into the vertexlist and specify the polygon's vertices as seen from their front-side in clockwise order. The polygonlist contains all polygons prior to BSP compilation in no specific order. During BSP compilation the original polygonlist is dissolved. Afterwards, polygons can only be accessed through the BSP tree. Every BSP node has one or more polygons attached to it. (There may also be BSP nodes with no attached polygons at all, these are separator planes only.) In contrast to polygons, faces primarily specify surface properties, say, in terms of material and color (there may be color information not already included in the material). A face is comprised of one to many polygons. Originally, faces and polygons have a one to one correspondence. During BSP compilation, however, polygons have to be split. Split polygons retain their original properties apart from geometry, that is, they still belong to the same face afterwards. This also holds for face normals, which, of course, stay the same when polygons get split. Hence, normals are also associated with faces instead of with every polygon. This list specifies all textures that may be used by this object. This specification is only done in terms of texture properties, texture coordinates are not involved here! This list specifies correspondences for texture mapping. This is normally only used during parsing, correspondences will be converted to affine mappings and be contained directly in the faces of the object later on. If a BSP tree has been compiled for this object, it is contained in this field. Such a BSP tree is dynamically linked. In addition to a dynamically linked BSP tree there may be a flat (array) version of it. This is usually used immediately after parsing, because it's easier to parse the tree line by line into an array and build the dynamic version afterwards. A general transformation matrix may be attached. As long as this transformation is only attached, it has not been applied yet. In order to actually transform the object and alter vertex coordinates accordingly, BspObject::ApplyTransformation() must be invoked. Every BspObject may have a name assigned to it. This field points to the next node in the list of BspObjects. 4.1.2 class BspObjectListRepresents a list of BspObjects. Since every BspObject includes a next field, the actual list is internal to the BspObjects themselves. A BspObjectList is primarily used as a standard interface to the entire list, to invoke processing functions for all BspObjects contained in the list, and for list handling in general, e.g., copying with reference counting. BspObjectList is the most important class for an application programmer using BspLib, since it is normally used to represent the entire scene. Objects in a scene are usually nodes of a BspObjectList in no particular order. The most important member function of a BspObjectList is BspObjectList::ProcessObjects(). This function is invoked with an integer parameter which is interpreted as a bit field. That is, every bit controls a specific processing function. BspObjectList::ProcessObjects() scans the entire list and invokes the corresponding processing functions for each node.4.1.3 class BoundingBoxA BoundingBox can be attached to each BSP tree node, encompassing all polygons of this node and its children. Therefore it can be used for viewing frustum culling, for instance. Every BoundingBox is axial and specified via its minimum and maximum extents in all three coordinate axes. BoundingBoxes can be merged and a spatial partitioning can be created, yielding a BSP tree of BoundingBoxes (objects). This can be used to separate objects cleanly as long as possible without splitting any polygons. BoundingBoxes that cannot be separated will be merged.4.1.4 class BSPNodeThis class defines a single node of a BSP tree. Each node may contain polygons lying in the same plane (the node's plane) and may have front-, and back-subtrees (pointers to other BSPNodes).Each BSPNode consists
of the following fields:
So, each node actually contains
two lists of polygons. The first list contains polygons lying in the same
plane as the splitter (the first element of the front-facing list) and
also facing in the same direction as the splitter. The second list contains
polygons facing in the opposite direction (and also lying in the same plane,
of course). Simple nodes with only one polygon (i.e, no coplanar polygons)
have a front-facing list of just one polygon (the splitter itself) and
no back-facing list at all (i.e., the field is NULL).
4.1.5 class BSPNodeFlatThis class is nearly identical to class BSPNode, but instead of pointers the links to subtrees consist of array-indexes. In this way the entire BSP tree can be contained in a single array, following links is just stepping to another array index.4.1.6 class BspTreeThis class encapsulates the root of a BSP tree (which is of class BSPNode). The actual tree consists of BSPNodes, though.4.1.7 class BspTreeFlatThis class provides an interface to a BSP tree contained in an array. The array will be dynamically allocated and maintained by an object of this class.4.1.8 class FaceA Face is used to describe face properties that are defined over an entire plane. First of all, this is the plane equation. A face also describes material properties (color, shading type), texture, and texture parameterization specified via an affine mapping. Every face has a unique id, all polygons that belong to this face (are part of this face and are contained in this face's plane) refer to this id.4.1.9 class Lineseg2, class Lineseg3These are simple classes describing line segments. A member function for "point on line segment"-test is available. This is used to test polygon edges for contained vertices, for instance.4.1.10 class MappingA mapping is used to specify arbitrary texture coordinates for all vertices of a face. If the face is non-planar it will be split into planar parts and this mapping will be used to derive affine parameterizations for each of these planes. From then on, only affine mappings (class TriMapping) will be used.4.1.11 class MaterialThis class can be used to specify a face's material properties in OpenGL style. That is, it describes a material via ambient color, diffuse color, specular color, emissive color, shininess, and transparency. A material object can be attached to a face in order to describe its material properties.4.1.12 class ObjectBSPNodeAn ObjectBSPNode is the basic building block for BSP trees separating objects in their entirety. Each such node corresponds either to a separating plane, or contains an entire object referenced via its bounding box. This class is tightly coupled to class BoundingBox, since the latter provides a member function to partition space containing bounding boxes and return an ObjectBSPNode as root of the resulting tree.4.1.13 class ObjectBSPTreeThis class encapsulates an object BSP tree consisting of ObjectBSPNodes. Basically it is just a pointer to the root node together with a few interface member functions, testing the tree against NULL, for instance.4.1.14 class PlaneA plane in three-space is defined by a normal vector and its distance to the origin along this normal vector. A Plane provides member functions to determine if a point lies in its positive or negative halfspace, or is contained in the plane itself.4.1.15 class PolygonThis is a very important class within BspLib. Polygons basically consist of a list of vertex-indexes listed in clock-wise order. A Polygon also contains a pointer to the next polygon in a list, so a polygon is always a node of such a (singly-linked) list. Each polygon has a unique id and contains the id of the face it belongs to. Polygons lying in the same plane may be part of the same face. A Polygon contains the entire functionality needed to compile a polygon BSP tree. That is, the Polygon::PartitionSpace() member function may be used to compile a BSP tree containing all polygons of this list (this polygon and the list pointed to by the next-field). Note that this BSP compilation function should only be used by BspLib itself, BSP compilation functionality for the user is presented through other, much more abstract and powerful, interfaces.4.1.16 class PolygonListA PolygonList is primarily only a wrapper around a list of Polygons. It encapsulates the list's head polygon, provides centralized access to the entire list and list maintenance functions..4.1.17 class TextureThis class describes a texture in terms of its texture name, file name, and geometry (width and height). If the specified texture's format is recognized (which currently is only the case for 3DF files) its geometry and texel format (e.g., ARGB4444) will be retrieved from the texture header.4.1.18 class Transform2, class Transform3These classes provide the ability to perform homogeneous transformations in two and three dimensions, respectively. The elementary transformations rotation, scale, and translation are supported. Transformations can be concatenated, both in natural and reversed order.4.1.19 class TriMappingAll texture-map parameterization in BspLib is done with affine mappings. To specify such a (two-dimensional) mapping three point-correspondences are used. These are stored in TriMapping objects. The use of point-correspondences instead of directly specifying the mapping is useful to avoid problems with singularities. Collinear vertices need only be detected as soon as the actual mapping is calculated.4.1.20 class Vector2, class Vector3The vector classes describe homogeneous vectors, that is, they contain an additional w coordinate and therefore consist of (x,y,w) and (x,y,z,w), respectively. A number of overloaded operators and member functions are provided for vector calculations, e.g., dot product, cross product, vector addition, and the like. Vectors are derived from vertices, since they are only vertices augmented by these operations. Vectors can be normalized, homogenized, tested for vanishing length, and so on.4.1.21 class Vertex2, class Vertex3Vertices describe points in projective space, i.e., homogeneous coordinates are used. Since vertices are just points, calculations are only possible in conjunction with vectors. A vector can be added to a vertex to translate this vertex, for instance.4.1.22 class VIndxThis class describes a single vertex-index and is normally only used by Polygons as part of the list of vertex-indexes defining the polygon. A VIndx also contains the link field necessary for this purpose. |
| 5. BSP TREE TYPES |
BspLib employs two distinct
types of BSP trees, each with its own set of classes. The first type is
a BSP tree containing polygons (class BSPTree).
The second type contains whole objects that are referenced via their bounding
boxes (class ObjectBSPTree). We are
now going to have a look at these two different types of BSP trees.
5.1 Polygon BSP treesPolygon BSP trees are used to describe a single object defined by its boundary representation. A node may contain one or more polygons, or it may be a separator node only. Separator-only nodes are used to partition space into two halfspaces without an actual polygon lying in the separator plane. If at least one polygon is attached to the BSP node, the separator plane need not be defined explicitly (by an attached Plane), since the plane can always be derived from the polygon itself. BspLib creates separator-only nodes only when merging objects contained in an object BSP tree into a single polygon BSP tree. During this process all ObjectBSPNodes become BSPNodes with no polygons attached to them but specifying a separator plane. All BSP trees attached to the contained BSPObjects become subtrees with all nodes containing polygons. This creates a unified BSP tree describing a single object that is identical to the union of all objects contained in the original ObjectBSPTree.The structure of a polygon
BSP tree in BspLib can be seen in the following figure:
![]() (Remember that all interface objects in BspLib are separated into handle and representation classes. Thus, the actual tree is of class BSPTreeRep, although the user uses class BSPTree.) An overview of all the fields
comprising a BSPNode may be found at the description of class
BSPNode. This class description also describes how lists of polygons
may be attached to each BSPNode.
5.2 Object BSP treesObject BSP trees can be used to partition space containing objects as a whole. That is, no polygons will be split at all, since objects are only considered in their entirety. During the creation of such a BSP tree BspLib tries to separate the bounding boxes of the contained objects with separator planes. If this is not possible for any two given objects of a scene, these objects will be merged and considered as a single object from then on. Actually, BSP compilation proceeds like follows: The scene is described by a list of objects in arbitrary order (class BspObjectList). First, this list of objects is used to create a list of bounding boxes, each bounding box containing a pointer to each of these objects. A BoundingBox has the capability to partition space via the BoundingBox::PartitionSpace() member function (see also class BoundingBox). This function is used to create an object BSP tree containing bounding boxes. This object BSP tree contains objects that are not BSP compiled themselves yet (although the spatial relationship between objects as a whole is already described by the object BSP tree). In order to use BspLib's capability to process a list of objects identically, an auxiliary data structure is created for the object BSP tree: A list of all the objects contained in the tree (note that, since objects might have been merged, this list need not be identical to the original BspObjectList!) is built using ObjectBSPTree::CreateObjectList(). This resulting BspObjectList is used to compile a polygon BSP tree for each of the contained objects (via BspObjectList::ProcessObjects()). At this stage we have two different types of BSP trees: One object BSP tree for the entire scene, and many polygon BSP trees for the objects contained in the scene. The object BSP tree can be used to access all of these trees! The tree can now either be used directly (by distinguishing between single objects and the entire scene), or, alternatively, a single, unified BSP tree can be created for the entire scene. This unified BSP tree can be compiled by using the BspObjectList::MergeObjectBSPTree() member function, yielding a BspObjectList containing a single BspObject with a single BspTree.The structure of an object
BSP tree in BspLib can be seen in the following figure:
![]() (Remember that all interface objects in BspLib are separated into handle and representation classes. Thus, the actual tree is of class ObjectBSPTreeRep, although the user uses class ObjectBSPTree.) This figure shows an object BSP tree containing two objects that are separated with a single separator plane. The tree itself references objects' bounding boxes which in turn reference the objects themselves. Such an object BSP tree containing multiple objects may be used to create a single object and BSP tree that is the union of all contained objects and BSP trees. This can be achieved by using the ObjectBSPTree::CreateMergedBSPTree() member function. (If the resulting BspObject should be the sole object contained in a BspObjectList the BspObjectList::MergeObjectBSPTree() member function may be used, as described in the preceding paragraph.) |
| 6. PROCESSING FUNCTIONS |
| BspLib exports most of its
object processing functionality via a single member function: BspObjectList::ProcessObjects().
This function takes a single int parameter where each bit determines whether
a specific processing function should be applied. The specified functions
are applied to each of the BspObjects contained in the BspObjectList.
If more than one function should be applied the corresponding flags can
simply be OR'ed together.
Valid object processing flags are:
6.1 Object processing flags6.1.1 APPLY_TRANSFORMATIONSIf this flag is specified, the transformation attached to each BspObject is applied to all vertices. The transformation will be set to an identity mapping afterwards. This function is often necessary prior to other processing, since many geometrical properties might not be correct if a transformation is applied after their calculation. For example, if bounding boxes are calculated before an arbitrary transformation is applied they will be invalid afterwards, because the transformation does not transform the bounding box information accordingly.6.1.2 CALC_PLANE_NORMALSIf this flag is specified, explicit plane normals (actually, the entire plane equation) are calculated for all polygons if this has not already been done. Plane information must be valid prior to BSP compilation!6.1.3 BUILD_FROM_FLATUsing this flag, a dynamically linked BSP tree can be built from a flat BSP tree contained in a BspObject. This can be used if a flat BSP tree has been read from an input file, for instance.6.1.4 CHECK_PLANESThis function should be performed prior to BSP compilation, since it checks all polygons for planarity. If some polygons are non-planar they will be split into several different polygons.6.1.5 BUILD_BSPThis is the most important processing function! If this flag is specified a BSP tree will be compiled for each of the BspObjects contained in the BspObjectList.6.1.6 BUILD_BSP_WITH_CHECKSThis flag is identical to specifying CHECK_PLANES, BUILD_BSP, CHECK_VERTICES, and CHECK_EDGES separately.6.1.7 CHECK_VERTICESThis can be used to check for multiple vertices. Vertices that are exactly the same (that is, contained within the same epsilon-volume) are only reported, not removed!6.1.8 CALC_BOUNDING_BOXESNormally, explicit bounding box information is not calculated for BSP tree nodes. If this flag is specified bounding boxes will be calculated for all nodes, however. This also implies that bounding box information will be written to the output file.6.1.9 CALC_SEPARATOR_PLANESNormally, explicit plane information is not calculated for ordinary BSP tree nodes (that is, nodes that are not separator planes only). If this flag is specified explicit plane information will be calculated for all nodes, however. This also implies that explicit plane information for each node will be written to the output file.6.1.10 CHECK_EDGESThis function checks all polygon edges for contained vertices. If any vertices are lying exactly on an edge they will be inserted into the vertex-index list of the corresponding polygons. This is useful to create trace-vertices. These are vertices contained in an edge for the sole purpose of eliminating pixel-dropouts in the presence of t-junctions.6.1.11 DISPLAY_STATSThis flag can be used to display some statistical information about objects after BSP compilation. It is only useful if BspLib's message output is rooted to a text-display or a log-file. |
| 7. A MINIMAL BSP COMPILER |
| In this section we are going
to show you how a minimal BSP compiler can be built using BspLib. The resulting
"program" will read a file called test.wrl,
compile the contained scene, and write the resulting output to test.bsp.
First, let's state that we want to use BspLib's classes without prefixing them with BspLib:: every time: using namespace BspLib; As first real action, we have to create an (initially empty) object of class BspObjectList, which will contain our entire input scene: BspObjectList testscene; Next, we have to create an object of class InputData3D, which reads and parses our input file, and builds a scene representation in memory (that is, it fills our testscene object), all during its construction: InputData3D inputdata( testscene, "test.wrl" ); Now, if everything went alright (if not, BspLib will already have exited with an appropriate error message; to avoid this, error response must be overridden/configured) the entire scene specified within the VRML file is in memory, contained in BspLib's 3-D data structures. Given this, we are going to perform some functions to get ready for BSP compilation: testscene.ProcessObjects(
BspObjectList::CALC_PLANE_NORMALS );
This is necessary to ensure plane information (plane normal and distance to origin) is available for every polygon and all polygons are indeed planar. (These two function calls could be combined into one by OR'ing the two flags together, avoiding the overhead of scanning the BspObjectList twice.) Next, we will compile an object BSP tree for all objects contained in the scene (see Object BSP trees and class ObjectBSPTree): ObjectBSPTree objbsptree;
Now, we get to something really interesting: BSP compilation! A polygon BSP tree will be compiled for each object (see Polygon BSP trees): testscene.ProcessObjects( BspObjectList::BUILD_BSP_WITH_CHECKS ); At this stage, the object BSP tree is valid and contains polygon BSP trees for each of the objects. We, however, want a unified BSP tree in order to be able to write a single object to the output file: testscene.MergeObjectBSPTree( objbsptree ); Well, we are nearly finished! Let's quickly write our (only) object to the output file using an object of class OutputData3D: OutputData3D outputdata( inputdata, IOData3D::BSP_FORMAT_1_1 ); That's it! The output file will be written when our outputdata object goes out of scope (and therefore its destructor is invoked). Note that, since we have used BspLib's default options we didn't have to configure them. Note also that all that object BSP tree stuff is only necessary since a VRML file may contain multiple objects. If we would have read an AOD file, or a VRML file containing only one object, we could have shortened this process even more! |