Houdini - Animating Constraints
Since a Constraint Network is nothing more than geometry, we can animate it.
Here, we have a line connecting two points, constraining a ball. We move the line up, the ball follows along. Easy.
But not really. First, let’s do what is “intuitive” and setup a network like so:
The Transform SOP
(red) moves the entire line up. And this is what we get:
When the sim runs, the constraint network moves up, but the ball doesn’t come along.
Which leads to a very strange conclusion: you can only animate “world constraint” points, not the points bound to the object.
So, we replace the Transform with a Wrangle, and wrangle only the top point with @P.y += @Time
.
Which stupidly gives us this constraint network that gets longer as the top point moves up.
The result is the first animation. So what’s happening?
Houdini “captures” the constraint in Frame 1, then attempts to maintain the rest length of that constraint while the top point is moving away. And the only way to maintain the length is to move the ball.
Rotating Balls
We have a buncha balls in a circle, each constrained to the perimeter of a circle:
[Left] Inside the DOP, the balls are Hard constrained with a buncha lines [Right] The constraint network in SOPs.
As before, if we rotate the entire constraint network – that would move the outer points as well (which are bound to the balls). What we need to do instead is rotate only the inner points.
To make it simple, group the inner points, and rotate them with a Transform SOP. This results in this weirdass thing:
[Above] Only the inner points rotate, the outer points remain where they are.
Which gets us this delightful buncha spinning balls:
Rotating with @orient and @constraint_type
Same setup, 2 points, a polyline and a ball.
So far, we’ve only ever set s@constraint_name
on the polyline. Since we want the ball to be locked when we swing it in a circle, we’ll need to probably lock its rotation.
We do this by adding s@constraint_type = "all"
to the polyline’s attributes.
Constraint Type
s@constraint_type
can beposition
,rotation
, orall
. It defaults toposition
when this attribute is not set.
Now we animate @orient
on the top point and it should work.
Sorta. How do we stop the ball from spinning? Turns out, we need two of the exact same network. One for position
and another for rotation
.
First we do the “intuitive” thing and setup the network as usual, explicitly constraining position. In the blue Wrangle:
s@constraint_name = "Hard";
s@constraint_type = "position";
f@restlength = primintrinsic(0, "measuredperimeter", 0);
Right at the end, we fork the whole thing out, overwrite s@constraint_type = "rotation"
in the red Wrangle, and merge it back (essentially, duplicating).
In the Primitive Spreadsheet, right before the DOP:
This is the Points Spreadsheet as the DOP runs:
The top points [0,2] on each constraint respectively are “rotating”. The bottom points [1,3] remain static and bound to the ball. There is no visual change of the constraints in the viewport since we are simply changing @orient
on the points.