Click or drag to resize
DigitalRuneGeometric Objects and Shapes

This section introduces the concept of shapes and geometric objects.

This topic contains the following sections:

Defining objects with shape and position

Defining a shape

The class Shape defines the space that is occupied by an object. Several classes derived from Shape let you define a range of different shapes. For example: BoxShape, SphereShape, PlaneShape, HeightField, etc. See DigitalRune.Geometry.Shapes or Class Diagram of Namespace DigitalRune.Geometry.Shapes for a list of available shapes.

Shapes are defined in the local coordinate system of the owning object (also known as local space, object space or body space). Most shapes, like spheres, boxes or capsules, do not have a position or orientation. They are centered and axis-aligned at the origin of the local space. This is because these shapes are typically defined only by parameters that describe their dimension ("width", "height", "radius", etc.).

Some shapes, like points, triangles or rays, are typically defined using position and orientation vectors ("Vertex0", "Origin", "Direction", etc.). Thus, they can be easily positioned in local space.

Defining complex shapes

Several shape classes can be used to build new shapes from simpler shapes, for example: CompositeShape, ConvexHullOfPoints, ConvexHullOfShapes, MinkowskiSumShape, TransformedShape. Here are a few examples of new shapes that can be created:

  • A filled convex polygon or polyhedron can be defined with a ConvexHullOfPoints.
  • A "hammer" like shape can be created with CompositeShape by combining a cylinder and a box.
  • The MinkowskiSumShape creates a new shape by "adding" existing shapes using an operation called "Minkowski Sum". For example, the Minkowski Sum of a box and a sphere creates a box with rounded edges.
  • A TransformedShape can be used to create a shape that has an offset or rotation in local space.

Positioning an object

The type Pose plays a central role in DigitalRune Geometry. The type is used to describe the position and orientation of an object in the world. Whenever transformations are applied to a geometric object, they are applied in the following order:

  1. Scale: First the scale is applied to the shape of a geometric object.
  2. Rotate: Then the object is rotated around its local origin.
  3. Translate: Then the object is moved to its position in world space.

Geometric objects

The interface IGeometricObject defines an object that has a shape and a pose. Objects that implement this interface can be used with DigitalRune Geometry. The type GeometricObject is the default implementation of this interface. You can use GeometricObject directly, or write your own classes that inherit from GeometricObject or implement IGeometricObject. Henceforth, we use the term geometric object to refer to an object with a shape and a pose.

Shape structures vs. shape classes

The namespace DigitalRune.Geometry.Shapes contains types for shapes. Specifically, there are structures for basic shapes (Aabb, Line, Ray, Triangle etc.) and classes for shapes (LineShape, LineSegmentShape, RayShape, TriangleShape etc.). The structure types are lightweight types that can be used for local computations and when allocation of heap memory should be avoided. The class types derive from the base class Shape and must be used when the shape of a IGeometricObject should be defined.

Using scaling

IGeometricObjects have a Scale property that can be used to scale shapes. Scaling is always applied to a shape before the Pose (position and orientation) is applied.

Scaling can be applied to all shapes with following exceptions:

  • Non-uniform scaling cannot be used with CompositeShapes if any of the Children of the composite shape is rotated.
  • HeightFields currently do not support a negative scaling.

Sometimes positions and directions are given in the local space of a geometric objects (for example PositionALocal of a Contact). This local space is the space where the scaling is already applied but the pose of the geometric object was not yet applied. In other words, the local space of a geometric object and the world space differ by the translation and rotation defined in the pose. The scaling is treated as if it is part of the shape.

For example: Geometric object A has a pose, a sphere shape with radius 2 and no scaling. Geometric object B has the same pose as A, a sphere shape with radius 1 and a uniform scale of (2, 2, 2). The local space of A and B is identical because the scale is treated as if it is a part of the shape.

Memory leaks in geometric objects

Each IGeometricObject handles the ShapeChanged event of its shape. That means, the shape has to store a reference to the geometric object. This can lead to problems ("life extension bugs" a.k.a "memory leaks") because it may prevent the geometric object from being garbage collected. For example, if several geometric objects share the same shape, then the shape stores references to all geometric objects. If one of the geometric objects is not needed anymore, the shape might prevent it from being garbage collected.

Therefore, if a shape is still needed but a geometric object is not needed anymore, the Shape property should be set to ShapeEmpty or ShapeInfinite. These are special immutable shapes that will never raise ShapeChanged events and therefore they do not store a strong reference to the geometric object. Those shapes will never prevent a geometric object from being garbage collected.

See Also