AGI Components with Insight3D Alpha 2008 r8
Composite Primitive

Composite primitives group primitives together to create hierarchies of primitives for efficient rendering, layering, and aggregation/deaggregation.

Efficient rendering is achieved because primitives in the same composite are put into a bounding volume hierarchy (BVH), which enables efficient culling using view frustum and horizon culling.

Technical Details: The BVH is created using a surface area heuristic. The BVH is efficiently updated when a primitive in a composite changes position based on an algorithm in the 2007 paper Automatic Creation of Object Hierarchies for Ray Tracing of Dynamic Scenes. Removing primitives from a composite, and thus the BVH, is efficient and described on our blog. Horizon culling is also explained in our blog.

Layering is showing/hiding groups of primitives in the same general area based on display conditions. This is commonly used to show more detailed primitives as the viewer becomes closer. Aggregation and deaggregation extend the layering concept so it appears that primitives expand into more primitives or collapse into less. This is frequently done based on distance to a reference point or viewer altitude as the following example demonstrates.

For efficient display condition evaluation, primitives that share the same condition can be combined using a composite primitive. For example, consider primitives with two different constraints:

  • 1,000 models with the same viewer altitude constraint of [0, 1,000] meters
  • 1 model with a viewer altitude constraint of [1,000 to 10,000] meters

When the viewer zooms out, 1 model represents 1,000 models.

If these primitives are added to the primitive manager individually, 1,001 primitives need to be visited when the scene is rendered, regardless of viewer position. This is grossly inefficient once the viewer's altitude is above 1,000 meters. The CPU will spin and cache miss for nothing.

If the 1,000 models are added to a composite primitive instead, only 2 primitives need to be visited in this case (1 for the composite and 1 for the marker that is rendered). This is shown in the example code below.

CopyC#
IAgGxDisplayConditionAltitude closeCondition = new AgGxDisplayConditionAltitude();
IAgGxDisplayConditionAltitude farCondition = new AgGxDisplayConditionAltitude();

closeCondition.Initialize(0, 1000);
farCondition.Initialize(1000, 10000);

IAgGxPrimitiveComposite closePrimitives = new AgGxPrimitiveComposite();

closePrimitives.DisplayCondition = closeCondition;
closePrimitives.Add(model1);
closePrimitives.Add(model2);
// ...
closePrimitives.Add(model1000);
sceneManager.Primitives.Add(closePrimitives);   // Add composite of primitives to manager

aggregateModel.DisplayCondition = farCondition;
sceneManager.Primitives.Add(aggregateModel);    // Add single primitive to manager

Since composites are primitives themselves, you can add composites to composites to build hierarchies that efficently find and render the correct primitives based on display conditions.