3.7. Geometry nodes features

An important descendant of TVRMLNode is the TVRMLGeometryNode class. This is an abstract class. All visible VRML nodes (in VRML 1.0 and 2.0) are descendants of this class.

TVRMLGeometryNode class defines a couple of important methods, overridden in each descendant. All of these methods take a State parameter that describes VRML state at given point of the graph (this is typically obtained by a traverse callback), since we need this to have full knowledge about node's geometry.

3.7.1. Bounding boxes

LocalBoundingBox and BoundingBox methods calculate axis-aligned bounding box of given node.

Axis-aligned bounding box is one of the simplest bounding volume types. It's a cuboid with axes aligned to base coordinate system X, Y and Z axes. It can be easily expressed as a pair of 3D points. In our engine we require that the points' coordinates are correctly ordered, i.e. X position of the first point must always be less or equal than the X position of the second point, and analogously for Y and Z values. We also have the special value for designating empty bounding box. And while we're talking about empty bounding boxes, remember to not confuse empty box with a box with zero volume: a box with zero volume still has some position. For example, a PointSet VRML node with only one point has a non-empty bounding box with a zero volume. A PointSet without any points has empty bounding box.

I chose axis-aligned bounding boxes just because they are very simple to calculate and operate on. They have some disadvantages — as with all bounding volumes, there is some compromise between how accurately they describe bounding volumes and how comfortable it is to operate on them. But in practice they just work fast and are enough accurate.

LocalBoundingBox method returns a bounding box of given object without transforming it (i.e. assuming that State contains an identity transformation). BoundingBox method takes current transformation into account. Each descendant has to override at least one of these methods. If you override only LocalBoundingBox then BoundingBox will be calculated by transforming LocalBoundingBox (which can give poor bounding volume, much larger than necessary). If you override only BoundingBox then LocalBoundingBox will be calculated by calling BoundingBox with transformation matrix set to identity matrix (this can make LocalBoundingBox implementation much slower than a potential special LocalBoundingBox implementation that knows that there is no transformation, so no matrix multiplications have to be done).

3.7.2. Triangulating

VerticesCount and TrianglesCount calculate triangles and vertices count of given geometry.

LocalTriangulate and Triangulate methods are available in the TShape class. They calculate all the triangles of given geometry. Use TShape.GeometryArrays if you want the full information about every shape (including indexes, colors, and all the other information required for efficient rendering).

If you want to control how detailed the triangulation should be:

  • Programmers can use DefaultTriangulationSlices, DefaultTriangulationStacks and DefaultTriangulationDivisions global variables.

  • VRML / X3D authors can use the Geometry3D component - extensions: custom triangulation fields in node to control this.

  • Finally, my programs view3dscene and rayhunter allow you to control this by command-line options

    --detail-quadric-slices <integer>
    --detail-quadric-stacks <integer>
    --detail-rect-divisions <integer>