Skip to content

Constraint Networks 3: A new hope.

I've been building my own constraint lines so far because it made it nice and clear in my head. Since 17.5 there's been a bunch of sops to help make these things for you. When they arrived I had a quick play, couldn't make them work, swore, didn't touch them again.

Well we're now at 18.5, I'm on a project that needs RBD again, seemed a good time to dive back in.

New workflow

The new RBD tools conform to the newish multi-in-multi-out networks favoured by Vellum and Kinefx.

Like Vellum, the idea is you do a lot of your prep work in sops, setting physics properties, building constraints, and then connect it all to a wrapped up rbd solver, as shown in the picture above.

Again like Vellum, the first connection is simulation geo, the second pink connection are the constraints, but the third and 4th when they appear are usually for proxy geo and bounding geo, not collisions.

Looking back, my frustration when these nodes first arrived stemmed from not really understanding Vellum, much less ported Vellum concepts to RBD. I think I'm in a better place now, the nodes make more sense.

Fun side fact; these tools don't require packed geo. In fact for some of the constraint tools, they work better without packing (eg, constraints can be made between the surfaces of things rather than from centroids), in those cases just let all your polys hang out, and the RBD solver sop (and RBD configure sop) will helpfully pack for you.

Standard constraints

Download hip: rbd_constraint_sops_basic.hip

Chain of things, a rope bridge, a collapsing sidefx logo, you know the deal.

  • Assemble sop, ensures you have names on things
  • RBD Constraints from Rules, one of several ways to create the lines between the RBD geo. Note that it ONLY makes the lines, for this to work with RBD requires attributes, which you get with a...
  • RBD Constraint Properties - Set constraint type, stiffness etc.
  • RBD Configure - Used to configure the RBD geo itself. You can select by group, or direct selection, or in this case intersecting with some boxes. The selection is used to pin the left and right sides.
  • RBD bullet solver sop - do the actual solve.

Pins

If you read the previous sections then you'll know my workflow for creating constraints:

  • Duplicate the point
  • Create a line between those points
  • Give the line a @constraint_name
  • Set one of the points to have @name = ""
  • Create a constraint network in dops (which is another 4 or 5 nodes and easily broken).

Quite a lot of work, lots of places to make mistakes. Here's how you do it with the new workflow:

Yep, a single checkbox.

The RBD Configure sop makes this setup trivially easy to do, and because it presents itself like a regular sop should, you can use groups to define the pinned geo, or a bounding box selector built into the sop. It's pretty handy. However...

Slidey pins

Download hip: rbd_pin_slidey.hip

...most of the time you want a pin locked down, immovable, and that's the default behaviour. But as you can see in the gif I had an issue; if the shapes intersected while pinned, they'd go on intersecting. The pins are too strong, and didn't allow for any play.

From inspecting the geo attributes and thinking about it just now, I realised my original method wasn't really pinning as suggested by Sidefx; they use attributes to pin, while I was making constraints to lock things in place.

At any rate, the default behaviour doesn't give you any controls over the pin strength. This little setup takes the pins, removes the pin specific attributes, and renames them to be default constraints. This now allows for hard-but-slippy constraints as shown in the middle, which allows shapes to push past each other, or soft constraints, which allows for a little bit of spring behaviour.

Googly eyes with animated pin constraints

Download hip: rbd_googly_eyes_v06.hip

Finally managed to get a more complex example of the sop constraint nodes doing their thing. Whenever I've built a vex heavy system it always annoys me, and when I hear sidefx have made a node based solution, I'll try to rebuild whatever I've done in their workflow. This still has a little bit of vex, but mostly I think it's pretty kosher.

The workflow is broadly this:

  1. make a cartoon googly eye out of a large white disc and a small black pupil disk
  2. copy it to lots of points
  3. ensure the white/pupil pairs have unique names
  4. set the whites to be inactive rbd objects, the pupils to be active
  5. add animation to the entire system
  6. create constraint lines
  7. set seperate rotation and translation hard constraints with condir/condof limits, and ensure those constraint directions stay consistent with the animation
  8. solve

Easy right?

If you step through the nodes it should all make sense, the only tricky bit is the condir/condof stuff. Hard constraints will default to position only, allowing for free rotation. You can set a point v@condir vector attribute which defines an axis, and i@condof as an integer which will either pin translation along a single line, a 2d plane, or full motion, and similar features for rotation.

Because this is set at the point level, the axis needs to be updated as the base shapes rotate. To do that I use the original points that the eyes are copied onto, using its N from the surface, and rename it to condof. This is copied to the constraints further downstream.

This is the only thing that requires vex for these constraints, but it's pretty simple really. On the position constraints:

vex
i@condof = 3; // fully locked position
i@condof = 3; // fully locked position

and for the rotation constraints:

vex
i@condof = 2; // can rotate around condir axis
i@condof = 2; // can rotate around condir axis

HUGE thanks to Nick Taylor and his great RBD examples that helped me decipher what I was doing wrong (mainly setting those condir/condof attributes on prims, when it should've been on points). https://nicholas-taylor.com/assorted-bullet

Stephan Walsch correctly pointed out that these aren't real googly eyes in that these act like they're on frictionless clock hands, while real googly eyes are just a smal disk bouncing around a small cavity. I'm fairly sure that behaviour could be faked with constraints too, or worse case make a little fakey concave collider shape to let the pupils bounce around it. Something for later.

Stephan Walsh also pointed out that this setup is a million times easier to setup with vellum and its shape match modes. He's probably right.

Constrained deintersect

Download hip: rbd_deintersect_v02.hip

Paul Esteves asked if the original deintersect example on the site could be updated to use the new constraint workflow. Yes it can! You still need to set that magical @found_overlap attribute manually, but getting the constraints setup is much easier and ripe for experimentation.

In the gif you can see that its easy to change between only making constraints between the leaves and the ground, or between everything, which helps the system try and maintain the original layout. It's also easy to experiment with only position or position+rotation constraints, and the stiffness of those constraints, letting you quickly dial in the right amount of control for your needs.

I also found that using soft constraints worked much better, they have enough slack and looseness in the system to let it all resolve quickly. Hard constraints jitter like crazy and need a lot of substeps.