Choreography Classes

Realsoft 3D choreography system is based on construction stack idea. A number of choreographs can be attached to an object. Choreographs are executed one by one and each choreography object modifies the state resulted by the previous choreography.

For example, a radial deformer can be used for generating a bump to a mesh. Then a 'bend' deformer can bend the mesh. Because choreographs modify the state resulted by the previous choreography, also the bump get bent.

When any of the choreography parameters is modified, the object is rebuild accordingly.

The first choreography defines the initial shape of the mesh. The second choreography (radial deformer) generates a vertical bump to the mesh. The third choreography bends the mesh and the bump with it.

There are two ways in which the user can modify choreography attributes:


This choreography object is typically associated with the root level choreography and named 'init'. Its task is to maintain the initial state of the animated attributes.

To modify the initial values, make the init (the first) choreography the current choreography, and then modify the target object attribute.


Pose choreograph is similar to Assign choreography in that its job is to keep track of the current values of attributes. However, whereas Assign choreography saves the absolute values of attributes, Pose choreography stores attributes in relative way. Pose choreography allows you to 'translate' attribute values.

You can update the current Pose values simply by making the pose the current choreography and then modifying the attribute in question.

Pose choreography is special in that it is automatically created by the system. If animation recording is off and you modify an attribute that is already controlled by a choreography that doesn't allow target editing, a pose choreography is created to represent the attribute changes.


Keyframe choreography is also special in that it is automatically created by the system. If animation recording is on and you modify an attribute, key framer is created to record the attribute values in time sensitive way.

Keyframer does this maintaining animation curves. Every time you modify the target object, the keyframer inserts new point to the corresponding curve (inserts new key frames). Correspondingly, when time is changed, the choreography evaluates (interpolates) its animation curves and assigns the values back to the target object.


Noise choreography applies 3D fractal noise to the target attributes. Noise differs from assign, keyframe and pose choreographs in that its cannot update any of its parameters when the target object is modified. Noise choreography is handy for adding some randomness to animations.


Script choreography can be used for controlling animated attributes via scripting languages, such as JavaScript.

Scrip choreography defines the following variables for this:

    P - target attribute (in target object's local space)
    Time - current time (or the current input attribute)
    Input - input object, or null if input is time
    Target - target object (whose attribute 'P' is).

Because target attributes are all referred through the variable 'P', scripts created this way are reusable.

The type of the 'P' variable corresponds to the type of the target attribute (integer, number, vector, vector4, axis, coordsys).

The following examples assume basic knowledge about JavaScript.

Example 1 - a constraint:

Let us imagine you have animated the 'Translate' attribute and want to write a script that constraints the value of the attribute's y component above the ground level. You can achieve this by attaching the following script choreography to the Translate attribute.

    if(P.y < 0)
        P.y = 0;

Example 2 - a circular path animation:

To make an object to move along a circular path in its x-y plane:

    // uses JavaScript Math object to evaluate a circle
    P.x += Math.sin(Time * 2 * PI);
    P.y += Math.cos(Time * 2 * PI);

Example 3:

This example shows how one can implement a path animation using scripting.

Create a script choreography for the Translate attribute, with the following JavaScript program:

    uvw = new r3Vect(Time, 0, 0);
    p0 = new r3Vect();
    p1 = new r3Vect();
    // evaluate two points from the input object: one with time=0 and
    // another one corresponding the current time
    Input.EVALUATE(new r3Vect(0, 0, 0), R3SPACE_ABSOLUTE, p0);
    Input.EVALUATE(uvw, R3SPACE_ABSOLUTE, p1);

    // compute translation: delta = p1 - p0
    delta = p1.sub(p0);

    // we need to map 'delta' from abs space to target object's parent space
    // because target objects translation is defined in its parent's space
    parent = Target.GetParent();

    // add delta to the target attribute

Now, bind the script choreography to desired path object, say a nurbs curve and play the animation to see how the target object follows the curve.

Example 4 - a point deformator:

A typical deformator works as follows: it first maps a point to a simple geometry, such as a rectangle. Then it use the result to evaluate a point from another, typically more complex, geometry.

For example, let's imagine a deformator that turns any planar mesh to a sphere.

Such a deformator can be represented as a level object consisting of two sub objects: a rectangle and a sphere.

    /     \ 
 rect    sphere 

Then we can use this deformator object as an input for a script choreography, with the following script:

// this chor must be bound to an input object
// that has two sub objects defining desired deformation

if(Input) { 

    // map target point to abs (world) space 
    p = new r3Vect(P.x, P.y, P.z);

    // fetch sub objects from the input object
    from = Input.GETSUBBYORDNUM(0);
    to = Input.GETSUBBYORDNUM(1);

    // map point to from's param space
    uvw = new r3Vect();
    from.MAPTOPARAMSPACE(p, uvw);

    // evaluate out through to's param space

    // map point to target space 

    // add deformation effect to the target point 

Now save the choreography and you can later load and attach it to any target and input object. You can replace the 'sphere' with any geometric objects. For example, if you prefer a deformation that maps a rectangle to a cone, just use analytic cone instead.

[Note] Note

Never modify attributes through 'Target' object. For example, never call:


If you need to access an attribute of the target object, make the attribute animateable and access it through the 'P' variable.


Generic constructor doesn't define any animation effects by itself. Instead, it asks the associated input object (typically a geometric object, such as a skeleton) to apply the effect.

Generic constructor cannot be created directly. It is automatically created when the actual deformator object is created and bound to its target objects.

The points of 'arm' (SDS object) deformed by 'left arm' (skeleton)

Skeleton, bend, radial deformer, 3d lattice and many other geometric deformators are linked to the choreography system this way.