OpenGLContext.scenegraph.boundingvolume
Bounding volume implementation
Based on code from:
http://www.markmorley.com/opengl/frustumculling.html
Notes regarding general implementation:
BoundingVolume objects are generally created by Grouping
and/or Shape nodes (or rather, the geometry nodes of Shape
nodes). Grouping nodes are able to create union
BoundingVolume objects from their children's bounding
volumes.
The RenderPass object (for visiting rendering passes)
defines a children method which will use the bounding
volumes to filter out those children which are not visible.
The first attempt to do that filtering will recursively
generate and cache the bounding volumes.
Setting your contextDefinition's debugBBox flag to True
will cause rendering of the bounding boxes when using
the Flat renderer.
Functions
cacheVolume(
node
,
volume
,
nodeFieldPairs
= ()
)
Cache bounding volume for the given node
- node
- the node associated with the volume
- volume
- the BoundingVolume object to be cached
- nodeFieldPairs
- set of (node,fieldName) tuples giving the dependencies for the volume. Should normally include the node itself. If fieldName is None a dependency is created on the node itself.
volumeFromCoordinate(
node
)
Calculate a bounding volume for a coordinate node
This should work for all of:
IndexedFaceSet
IndexedLineSet
PointSet
IndexedPolygons
This just takes advantage of the common features of the
coordinate-based geometry types, ignoring the fact
that individual pieces of geometry may not actually use
all of the points within a volume.
Note:
this method is cache aware, it will return a cached
bounding box if possible, or calculate and cache the
bounding box before returning it.
XXX There is a pathological case which may be encountered
due to an optimization seen in certain VRML97
generators. Namely, these generators will create
an entire file with a single coordinate node with each
individual piece of geometry indexing into that
universal coordinate node. This would, in many designs
provide an optimization because the coordinate node
would never be swapped out, allowing the geometry to
remain within the GL as the current vertex/color
matrices. In this case, OpenGLContext will have no
bounding volume optimization at all, as it will take
rebounding volume of each piece of geometry to be the
bounding volume of the entire world.
Classes
class AABoundingBox(
BoundingBox
):
Representation of an axis-aligned bounding box
The axis-aligned bounding box defines the entire
bounding box with two pieces of data, a center position
and a size vector. Other than this, it is just a
point-based bounding box implementation.
center
field SFVec3f center (0, 0, 0)
query
field SFInt32 query 0
size
field SFVec3f size (0, 0, 0)
debugRender(
self
)
Render this bounding box for debugging mode
Draws the bounding box as a set of lines in the
current OpenGL matrix (in OpenGLContext's visiting
pattern, this is the matrix of the parent of the
node which is determining whether to cull the node
to which this bounding box is attached)
getPoints(
self
)
Return set of points to test against the frustum
If self.points field is not set, will calculate the
points from the center and size fields.
class BoundingBox(
BoundingVolume
):
Generic representation of a bounding box
A bounding box is a bounding volume which is implemented
as a set of points which can be tested against a frustum.
Although at the moment we don't use the distinction between
BoundingBox and AABoundingBox, the BoundingBox may
eventually be used to provide specialized support for
bitmap Text nodes (which should only need four points
to determine their visibility, rather than eight).
points
field MFVec4f points []
debugRender(
self
)
Render this bounding box for debugging mode
XXX Should really use points for rendering GL_POINTS
geometry for the base class when it gets used.
union(
boxes
,
matrix
= None
)
Create BoundingBox union for the given bounding boxes
This uses the getPoints method of the given
bounding boxes to retrieve the extrema points
which must be present in the union. It then
calculates an Axis-Aligned bounding box shape
taking into account the matrix given.
It would seem somewhat more efficient here to
use the points array directly, but that would
have the effect of geometrically increasing the
number of checks for each succeeding parent,
while creating the axis-aligned bounding box
trades more work here to keep the constant-time
operation for the "visible" check.
Group nodes pass a None as the matrix, while
Transform nodes should pass their individual
transformation matrix (not the cumulative matrix).
- boxes
- list of AABoundingBox instances
- matrix
- if specified, the matrix to be applied to the box coordinates before calculating the resulting axis-aligned bounding box.
visible(
self
,
frust
,
matrix
= None
,
occlusion
= 0
,
mode
= None
)
Determine whether this bounding-box is visible in frustum
- frustum
- Frustum object holding the clipping planes for the view
- matrix
- a matrix which transforms the local coordinates to the (world-space) coordinate system in which the frustum is defined.
This version of the method uses the frustcullaccel
C extension module to do the actual culling once
the volume's points are multiplied by the matrix.
class BoundingVolume(
Node
):
Base class for all bounding volumes
BoundingVolume is both a base class and a functional
bounding volume which is always considered visible.
Geometry which wishes to never be visible can return
a BoundingVolume as their boundingVolume.
class UnboundedObject(
ValueError
):
Error raised when an object does not support bounding volumes
class UnboundedVolume(
BoundingVolume
):
A bounding volume which is always visible
Opposite of a BoundingVolume, geometry can return
an UnboundedVolume if they always wish to be visible.