## Animating objects along curves

Hi again,

in this small tutorial I try to explain a workflow I’m using frequently, when I have to animate streams of objects. Here is a example for what I’m talking about:

Client
Product
Agency
Production
Post

Procter & Gamble
Dash 2 in 1
Grey
Saga Film

As you can see different instances of flowers move along an curve. To get this working I make use of the u coordinate of curves and map it to an point array I’m generating. Next I guide you through how you do this in Houdini.

First hit tab do generate a new geometry, dive in add an add sop to generate the fist point. Next add a duplicate sop to duplicate the point as often as you want. With this done let’s create some attributes. We need Shape, Orientation and Scale. Give the Shape a integer, the Orientation a vector and the Scale a float type. To randomize the Orientation randomize the different channels with this function “fit(rand(\$PT),0,1,-360,360)” – this will give us a rotation between -360 to 360 in the different channels. For the expression of the shape we will add a function later. Optional we can create a fourth node to randomize the color. Just generate a Attribute Randomize node give it the Cd attribute and connect it to the stream. Great, that’s the fist one of the three base streams.

Let’s create the second stream. This will be the curve our points will fly on. Draw and curve, resample it and add a polyframe sop to get a Normal (N) and TangentU (tangentu) attribute.

Now we’ll do the fun part – Create a Point VOP to combine the two streams. Dive in and wire everything as shown on the picture below. As you can see see, our network got three inputs: Start, End and add. As the names of the parameters say, they will define the start and end point of our flying points. The add parameter is there to animate the points. The range will be between 0-1, which is a great range to remap with the u coordinate.

At this point it should look like this:

Ok so following build the third stream! Add a sphere, box, torus and connect them to a switch. Connect the switch to a transform node an take this as the primitives to copy input of a copy sop. Now take a Attribute Delete sop, connect the Point VOP to it and delete the point attribute N, tangentu and tangentv. This is impotent when working with the copy sop because it tracks the N attribute. I personally like to transfer the real rotation through the copy sop – so deleting is just fine. From this follows a OUT Null to keep things organized and to have always the same node to grap attributes from. Connect the null to the copy sop and do some stamping.

particleShape point(“../OUT_Values”, \$PT, Shape,0)

OrientationX point(“../OUT_Values”, \$PT, Orientation,0)

OrientationY point(“../OUT_Values”, \$PT, Orientation,1)

OrientationZ point(“../OUT_Values”, \$PT, Orientation,2)

Scale point(“../OUT_Values”, \$PT, Scale,0)

Afterwards stamp the variables in the transform sop. To do so we can use this functions.

RotateX stamp(“../copy_ObjectsToPoints”, “OrientationX”, 0)

RotateY stamp(“../copy_ObjectsToPoints”, “OrientationY”, 0)

RotateZ stamp(“../copy_ObjectsToPoints”, “OrientationZ”, 0)

Unifrom Scale stamp(“../copy_ObjectsToPoints”, “Scale”, 0)

For the correct setup we need to streamline the switch and the shape variable. First get the Shape attribute in place. fit01(rand(\$PT),0,(opninputs(“../switch1”))) gets the number of imputs of the switch sop. In the switch sop set the item selector to stamp(“../copy_ObjectsToPoints”, “particleShape”, 2). To understand what’s going on go to the geometry spreadsheet. There should be a Shape variable that goes from 0-2, which is the number of elements that are connected to the switch. The switch knows from the copy sops particleShape variable which element to pick.

With all this done we got this result. It is already what I wanted. Control over the object movement and shape. The next step will be the variation of the different channels, to get a more irregular shape.

Before starting to randomize the position we need to store the pointpostion on the curve, as reference point for the rotation manipulation that will follow later. Create an attribute wrangle right after the Point VOP on the right side. type in this code:

vector @PCrv;
@PCrv = @P;

This will generate a Variable PCrv what represents the curve postion. Following we need a Randomize Attribute VOP to give the points an initial position variance. This looks like this:

Fine. Lets randomize the point position along the u coordinate. There for add a Point VOP after the Randomize Attribute SOP. Dive in and build the setup like this. The setup shown below is just a random vector per point that will be ramped trough the u coordinate of the curve. I have promoted the add2 (Seed), multyply2 (random multiply), mix1 (effect blend) and the ramp.

That’s it for the position. Now let’s create another Point VOP for the rotation. Don’t become scarred it’s not as hard as it seems. We see three sections. A align orientation to curve tangentu section. Here I crate a euler rotation of the tangent vector that can be blended with the original rotation we set in the beginning. The lower part is to set the amount of rotation along the u variable. It is working exactly as in the last Point VOP. In the “Roate_along_CrvP” section I’m rotating the Points and orientations around the curve position point I’ve stored in the Attrib Wrangle earlier. I have promoted degtorad1 (the degrees to rotate), mix1 (blending between tangent vector and init roation), mix2 (effect blend) and the ramp.

Last but not least I have done the same thing for the scaling of the objects. Lay down another Point VOP and setup the network as shown below. I have promoted parm1(Seed), fit1 (size range), mix1 (effect blend) and a ramp

To finish, it is always nice to remove some more attributes that are not used. In the Attribute Delete SOP type in this list “N tangentu u PCrv tangentv”. At the end my tree looked like this.

With the final setup, a movement of many objects would look like this.

As a resume – We saw how to animate objects along a path and control effectively all parameters. For real production purposes it would be necessary to customize everything just a little bit more, depending on the requests of the job.

If you are interested in the setup. Here is a HIP file for Houdini 15. Thanks for reading.