Cinema 4D / BodyPaint 3D Program Documentation Tutorials XPresso Tutorial
Function available in CINEMA 4D Prime, Visualize, Broadcast, Studio & BodyPaint 3D

A Bouncing Ball

In this tutorial we will show you how to create and XPresso Expression with which you can make a ball bounce along a Spline. The bouncing movement will calculated automatically by the XPresso Expression. Also, the loss of inertia will be simulated via a simple calculation so that the height of the ball’s bounce will abate over the course of the animation.

Preparation

First we will need to create a Spline along which the ball will travel. We can best do so by working in the Top view. Press the F2 key to switch to the Top view and create a Spline with two points (of course any other Spline will work as well). Next, create a Sphere from the Create|Object menu, which will server as our bouncing ball.

Open the Sphere object’s context menu my right-clicking on its name in the Object Manager. Select the XPresso tag from the Cinema 4D Tags menu. The XPresso tag will automatically be assigned to the sphere and the XPresso Editor window will open.

In order to make the sphere move along the Spline we must first re-create the basic functionality of the Align to Spline tag. This means that we have to position the sphere on the Spline. This sounds more complicated than it really is. First, drag the Sphere object into the XPresso Editor window to create a new Object Node for the sphere.

Now we have to tell the Expression which Spline should be followed and where the sphere should lie on the Spline. This can be done most easily via the User Data. Select the Sphere object and then the Add User Data … command form the Attribute Manager’s User Data menu. In the window that opens, add a User Data item and name it "Spline". Set its Data Type to Link.

Add a second item and name it "Position". Set its Interface parameter to Float Slider.

Now click on OK to close the window and drag the Spline object from the Object Manager into the "Spline" Link field we just created.

In the XPresso Editor window, create an output Port on the Sphere Node for each User Data item. We now need a Spline Node (XPresso/General) with which we can ascertain the position at any point along the Spline. Connect this Node’s input Ports with the Sphere Node’s output Ports.

The Spline Node’s Position output Port now outputs the global position of a given point along the Spline. Which point’s position is output is defined by us via the Offset input Port. This position must of course be passed back to the Sphere object, for which we have to add another Object Node. This Node will be connected with the Sphere Node. Drag the Sphere object from the Object Manager into the XPresso Editor again. Add a Global Position input Port to the newly-created Object Node and connect this Port with the Spline Node’s Position output Port.

If we now move the "Position" slider in the Sphere object’s User Data the sphere will move along the Spline. Imagine the Spline runs along the floor, which means that the ball sinks halfway into the floor each time it reaches its lowest point. We will correct this behavior in the next section.

Correcting the sphere’s path

In order to make the sphere lie directly on the Spline we must move the sphere slightly higher. The distance the sphere will be moved depends on its Radius. The sphere’s Radius must be added to its Y position. Add a Radius output Port to the Sphere Node at the left (Object/Properties). The value that this Port puts out must be added to the Sphere object’s Y position.

However, the Radius value is a simple float comma value and the sphere’s position is a Vector value. In order to calculate the radius and position together we must first break the Vector down into its three float comma values. To do so, create a new Vector2Reals Node (XPresso/Adapter) and connect this Node’s input Port with the Spline Node’s Position output Port. Delete the connection between the Spline Node and the second Sphere Node for now.

Next we will turn our attention to addition. Create a Math Node (XPresso/Calculate) and connect one of its input Ports with the Vector2Reals Node’s Y output Port. Connect the remaining input Port with the first Sphere Node’s Radius output Port.

Create a Reals2Vector Node (XPresso/Adapter). Connect its output Port with the second Sphere Node’s Global Position input Port. Connect the Math Node’s output Port with the Reals2Vector Node’s Y input Port. Also connect the Adapter Nodes’ X and Z Ports.

Bounce movement

Now we will finally get to the core of the matter: the bouncing movement of the ball. The sinus function always comes in handy for the creation of hopping, jumping or other oscillating movements. Here is depiction of a typical sinus curve:

If the negative values are changed to positive values so the sinus curve only lies in the positive region it already reflects the motion path of a bouncing ball:

We will now create an animation for the sphere using XPresso that emulates this sinus curve. This is not as difficult as you may think. To create a sinus value we can use the Trigonometric Node (XPresso/Calculate). This Node’s Function parameter is set to Sin by default. Connect its input Port with the first Sphere Node’s Position input Port.

The result of the sinus calculation must subsequently be added to the sphere’s Y position. This is done using a Math Node (XPresso/Calculate), which we will place between the existing Math Node and the second Adapter Node.

Now the sinus’ values have to be made positive so the sinus curve can produce the correct movement. To do so, create a new Absolute Node (XPresso/Calculate) and place it between the Trigonometric Node and the second Math Node.

Are we finished? If we move the slider in the User Data the sphere appears to move just as before. Our Expression is in fact working correctly but we have overlooked a couple of important things. The sinus only outputs values between -1 and 1, which means that the height of the bounce is so low that we simply cannot perceive it. Also, the sinus values repeat in intervals equal to Pi, i.e., approx. every 3.141. However, since the value of the first Sphere Node’s Position output Port only ranges from 0 to 1 the sphere has a very low bounce frequency and therefore doesn’t even complete a single bounce movement. First, we will correct the height of the bounce. Since we do not want to directly control the height of the bounce we will create a new User Data item for the sphere. Set this item’s Units parameter to Meter.

Next, create a new User Data item for the first Sphere Node’s output Port. Create a new Math Node and set its Function parameter to Multiply. Now integrate this Node into the Expression so that it multiplies the Trigonometric Node’s output value by the User Data Height value, and passes the result to the Absolute Node.

If we enter a value in the Sphere object’s "Height" User Data (e.g., 200) and then move the slider, the sphere will gently rise from the floor. If we also correct the bounce frequency we will almost be finished. As we explained previously, the sinus cycles in intervals equal to Pi, which means the Expression should be modified with regard to this value so the ball bounces correctly while it moves along the Spline. To do so we will create a new Math Node and set its Function parameter to Multiply. Next, add a Constant Node and set its Constant parameter to PI. Now connect the Nodes to that the first Sphere Node’s Position value is multiplied by PI and the result is passed on to the Trigonometric Node.

If we move the slider now the sphere will begin its movement from the floor, complete a long jump and land exactly at the other end of the Spline. Now all we have to do is modify the bounce frequency by multiplying the Position value that was multiplied by Pi by the number of bounces we want the sphere to complete. To do so, add a User Data item to the Sphere object’s User Data and set its Units parameter to Real.

Now we will add another output Port for the new User Data item to the first Sphere Node. Create another Math Node and set its Function parameter to Multiply. Integrate this new Node so the Position value that is multiplied by Pi is in turn multiplied by the bounce frequency.

If, for example, we enter a value of 10 in the most recently created User Data item and then move the slider the sphere will bounce exactly ten times from beginning to end. If we want the sphere to begin its movement from a position above the floor all we have to do is us a cosine instead of a sinus. To do so, select the Trigonometric Node and set its Function parameter to Cos.

We are now as good as finished. All that’s missing now is a loss of inertia. In reality a ball will steadily loose inertia as it continues to bounce. We will simulate this effect in the following step.

Loss of inertia

We will now add a simple loss of inertia to our Expression. This will be a simulation of actual physics, as is most commonly the case in the field of 3D. To keep this tutorial as simple as possible will also limit the effect to its most important aspect: the falloff of the height of the bounce.

We want the ball to bounce to its maximum height (as defined in the User Data) at the beginning of the animation and should have a height of 0 at the end of the Spline. We can use the relative position of the sphere to the Spline to our advantage: At the beginning it has a value of 0 and at the end a value of 1. These are exactly the values we need - but inverted. If we multiply this inverted value with the height of the bounce the ball should begin with a maximum bounce height and end with a height of 0.

Tip:
Before we continue we should make our very large Expression a little more compact. Double-click on the title bar of each Node in the XPresso Editor to minimize the Nodes. This will create more room in the XPresso Editor window. To open a Node simply double-click its title bar again. Whether or not you minimize your Nodes is, of course, up to you but it can help when working with large Expressions.

Create another Constant Node and set its Value parameter to 1. Create a new Math Node, set its Function parameter to Subtract and connect its first two input Ports to the first Sphere Node’s Position output Port. Connect the second input Port with the newly-created Constant Node. Now the inverted position value we just mentioned will be calculated correctly. Now we have to multiply this value with the bounce height of the sphere. To do so we will create another Math Node and set its Function parameter to Multiply. Connect its first input Port to the Absolute Node’s output Port and the second input Port to the output Port of the previously created Math Node. Connect the newest Math Node’s output Port with the input Port of the Math:Add Node that we previously connected with the Absolute Node.

Click on the link below to load the finished scene, which you can compare to your own:


If we play the animation you will see that the height to which the ball bounces decreases as it moves along the Spline. Only a fraction of the effects that can be used for such an animation are included in this Expression. Hence, a lot can be done to improve this animation but that would exceed the bounds of this tutorial. Nevertheless we would like to give you a few ideas of what can be done:

- In our animation the loss of inertia is linear, which is not very realistic. A Spline Curve in the User Data can be used to make this effect much more realistic.

- The bounce frequency should actually increase the more inertia that is lost. This can be done quite easily by multiplying the Position value in the User Data with an additional Constant Node (increase of frequency) before it is passed on to the Trigonometric Node.

- The sphere could be made to rotate. You could, for example, use the Rotation Expression from the first example as a basis. In this case, however, the relevant value for the rotation would not be the scene time but the Position value from the User Data.

- The sphere should actually squash when it impacts the floor and stretch when it is repelled. This requires that a scaling be built into the Expression that is linked to the height of the bounce and falloff of inertia of the sphere.

For further practice with XPresso you can try to integrate some or all of the above-mentioned effects into your Expression. The result can look as follows once a non-linear loss of inertia, an increase in the bounce frequency and a cosine is used instead of a sinus:

 

Click on the link below to view the scene: