<-previous
index -- map
The Main Concept

In fact, all that Puppeteer does is to choose an object (the source), measure it's PSR data (Position, Scale and Rotation), possibly change it a bit, choose another object (the destination), and feed it the (changed) PSR data. Result: the second object moves when the first object does. For full flexibility, it is of course possible to, for example, use the source's position to change the destination's rotation, or any other combination you might think of. Just imagine that there are nine cables running from the source object to the destination object. Each of these cables takes it's input from one of the nine PSR variables (the x, y and z of position, scale and rotation) and can be plugged into any of the nine PSR variables of the destination object, directly linking the two to eachother. On top of this, it is possible to boost or supress the signal running through such a cable, invert it, clamp it below a certain value, apply a curve to it, etcetera.
To be able to do this properly, the signal that runs through the cable is of a certain unit-less scale which I call charge, determined by the source object's two nodes. The nodes are reference-PSR sets, so to say. Imagine an object's x-position of 50m being fed to Puppeteer. When this value is fed into one of the cables, it is compared to the x-position values of both node1 and node2. Let's say that these are 0m and 100m. The resulting value then is exactly 0.5, or half a charge, since 50m is exactly between 0m and 100m. If the input value would have been 200m, the charge would have been 2, and in the case of -100m it would have been -1. Now, when this charge of 0.5 reaches the destination object, and the cable is plugged into it's b-rotation parameter, the charge is compared to the destination object's two nodes. If these have, respectively, a b-rotation of 0 degrees and 90 degrees, the resulting rotation will be 45 degrees. Another way to say it is each 100m of movement will result in a rotation of 90 degrees. If you want to have a different influence of input on output, you simply change the corresponding values in the nodes.
Now there is another advantage to using this cables-and-charge approach, regarding changing the charge in the cables themselves (and not the reference nodes). This can all be easily done with a simple curve, like in Photoshop. You feed the charge to the curve's x axis, and use the resulting value on the y axis as the charge that the destination object will receive. Furthermore you can limit the charge to stay between 0 and 1, or make it loop or pingpong beyond those values, boost it up to 2 beyond a certain point, etcetera.
For a graphical idea of how an object's x-position is scaled, curved, re-scaled and fed back to another object's b-rotation, have a look at the illustration.

That all sounds mighty intriguing, but what use does it have? Well imagine you have a bending arm, and want the biceps to scale up when it bends? Simply define the two objects in the Puppeteer tag, link up the appropriate rotation angle of the source object (the lower arm) to the appropriate scale axes of the biceps controller, then define two extreme positions for both the arm bending and the biceps scaling, and record them in the nodes. Done. Want to point your characters foot into the same direction as it's IK target? Define both objects, link up the rotation channels, and set both to global. Done. Want to limit an object's rotation? Simply use the object as both the source and the destination object, link up the rotation channels, rotate the object to the two extreme rotations, record them in both source and destination nodes, and set the limits to 'end'. Done. Want to create a slider for an object's rotation? Define the slider object as source object, the other as the destination object, again define the extremes by recording them into the nodes, link the slider's Y position to the object's appropriate rotation angle, turn on 'feedback'. Done.
Now how you actually use the interface to make all these things happen is explained in the following pages.

a Few of the features
Puppeteer uses an extremely flexible way to define which objects to use as source and destination. It can be linked to the object the Puppeteer tag is attached to, but also to any other object in the document, be it as a source or target object. This means that you could, conceivably, put all Puppeteer tags onto a single object, while they influence objects elsewhere in the hierarchy.
There are some often-used object searches embedded as well. For example you can use parent or child objects as sources, or maybe an object's neighbour object. Puppeteer can also perform an object search in a closed domain, for example it can search for the object called 'Sphere' that is a child of the object the tag is attached to. On top of this there are some extra functions making object selection a simple point-and-click affair.
Although the concept of nodes may seem rather intricate, Puppeteer offers a way to make it a breeze. You can define exactly what position-change of one object does to the rotation of the other object for example, by simply moving and rotating the two objects in 3D space.
Other than manually or automatically defining the nodes, you can make the Puppeteer tag use two points in time as reference. Puppeteer will then secretly animate the objects, and use the data it gets from that. This also means that you can copy a tag from one object to another, and have it automatically generate suitable reference nodes by checking the new object's animation.
Puppeteer's dialog is completely non-modal and realtime. This means you can dock it into your standard C4D interface, and keep it opened all the time. It will automatically update when you select a new Puppeteer tag, and any change you make in the dialog will update the scene in real time. Even better, it remembers what Puppeteer tag you selected last, and leave you free to select and edit other tags and objects in the scene while still giving you hands-on control of the Puppeteer tag at the same time.
A special built-in 'feedback' option makes slider creation a breeze, because it will automatically constrain the movement of the slider to just the motion that actually influences the destination object.

<-previous