up to Schedule & Notes

Primitive Objects

A primitive object is a simple object with

A primitive circle would have

A primitive rectangle would have

A primitive sphere would have

A primitive cylinder would have

Pick the size and coordinate system to make the object easy to transform.

Instancing of Primitive Objects

"Instancing" is the act of creating a copy (an "instance") of the object.

An instance can have different dimensions, positions, and orientation than the primitive object.

A primitive object can be scaled, rotated, and translated when creating an instance. This transformation can be represented as a $4 \times 4$ matrix, $M$.

To create an instance of a primitive object with vertices $v_0, v_1, v_2, \ldots$ transformed by a matrix, $M$, create (in OpenGL) a VBO in which the vertex positions are $M v_0, M v_1, M v_2, \ldots$.

See 02-hierarchical/rectangle.cpp and 02-hierarchical/cylinder.cpp in openGL.zip for examples of object instancing.

Object Hierarchies

Objects are often represented hierarchically, with a "root" object that has "child" objects. Each child object can, itself, have child objects.

In the robot arm below, link $\ell_1$ has child $\ell_2$, and link $\ell_2$ has children $\ell_3$ and $\ell_4$.

The world can be thought of as an "object" which has, as its children, all the roots of all the hierarchical objects. In the robot arm above, the world has one child: the link $\ell_1$.

Each object stores:

Child-to-Parent Transformations

The transformation from object $O$ to its parent, $P$, is written as $T_P^O$.

In the robot arm above, each transformation is shown on an arrow. The arrow is directed from the child to its parent.

If $v_O$ is a point in the coordinate system of object $O$, then $v_P = T^O_P \; v_O$ is the same point, but in the coordinate system of object $P$.

In the robot arm, link $\ell_1$ has points defined in its own coordinate system. To position $\ell_1$ in the world coordinate system ($WCS$), the transformation $T^1_w$ is applied to the points of $\ell_1$.

Object-to-World Transformations

Similarly, link $\ell_2$ has points defined in its own coordinate system. To position $\ell_2$ in the world, $T^2_1$ is applied to the points of $\ell_2$ to bring them into $\ell_1$'s coordinate system. Then $T^1_w$ is applied to bring those points into the $WCS$.

So points in $\ell_2$'s coordinate system have the transformation $T^1_w \; T^2_1$ applied to bring them into the $WCS$.

Similarly, points in $\ell_4$'s coordinate system have the transformation $T^1_w \; T^2_1 \; T^4_2$ applied to bring them into the $WCS$.

Rendering Object Hierarchies

A hierarchical object can be rendered recursively. Recall that each object stores

To render the "root" link $\ell_1$, the $\ell_1$-to-$WCS$ transformation is applied to all vertices of $\ell_1$, so that they are rendered in the $WCS$.

This can be done by passing in the $4 \times 4$ matrix $T^1_w$ to the GPU's vertex shader, which will apply the transform as the vertices of $\ell_1$ are being rendered.

To render linkApply transformation
 
$\ell_1$$T^1_w$
$\ell_2$$T^1_w \; T^2_1$
$\ell_3$$T^1_w \; T^2_1 \; T^3_2$
$\ell_4$$T^1_w \; T^2_1 \; T^4_2$

The transformations are accumulated as the hierarchy is traversed downward, so the accumulated transformations of the ancestors of an object should be given to the object when the object is rendered.

So each object, upon rendering, is given its accumulated "parent-to-$WCS$" transformation:

To render linkApply transformationparent-to-$WCS$ transformationObject-to-parent transformation
 
$\ell_1$$T^1_w$$I$$T^1_w$
$\ell_2$$T^1_w \; T^2_1$$I \; T^1_w$$T^2_1$
$\ell_3$$T^1_w \; T^2_1 \; T^3_2$$I \; T^1_w \; T^2_1$$T^3_2$
$\ell_4$$T^1_w \; T^2_1 \; T^4_2$$I \; T^1_w \; T^2_1$$T^4_2$

and the transformation applied to the object's vertices is the product of the parent-to-$WCS$ transformation ($T^P_w$) and the object-to-parent transformation ($T^O_P$).

In the following code to render a hierarchical object, Tpw is the parent-to-world transform and Tow is the object-to-world transform:

renderObject( object O, transformation Tpw )
    Tow = Tpw x O.object_to_parent_transform 
    drawGeometry( O.geometry, Tow )
    for each child, C, in O.children:
        renderObject( C, Tow )

See Object::draw() in 02-hierarchical/object.cpp for an example of hierarchical object rendering.

up to Schedule & Notes