Skip to content

MOPs DOPs Tutorial

toadstorm edited this page Oct 2, 2021 · 21 revisions

Important: MOPs Plus is in early access. This means that it is under rapid development and may change significantly before the first full release. Please report any bugs or strange behavior!

MOPs Plus adds new DOP context nodes to help drive simulations using familiar MOPs concepts. These nodes can interact with any dynamics solvers that are point-based, which includes Bullet (Packed RBD), POPs (particles), and Vellum. This means you can use MOPs to control packed primitives and get realistic collision behavior, or use Falloffs or other forces inside DOPs to guide simulations or modify attributes.

A very important distinction between MOPs in SOPs and MOPs in DOPs is that SOPs are procedural and DOPs are not procedural. In the SOP context, you use keyframes to animate parameters over time. Each frame is entirely independent from any frames around it; each frame is solved "just-in-time". For example, let's say you're using MOPs Apply Attributes in SOPs. You have a starting transform, an ending transform, and a falloff value of 0.5. Every frame will evaluate exactly the same way, with the output halfway in between your starting and ending transforms:

apply attributes sop

Apply Attributes in SOPs with a falloff of 0.5. Every frame is the same.

In DOPs, however, every frame is dependent on the frame prior to it; this is the nature of a simulation. If you have a static falloff value of 0.5, your object will find the halfway point between its current position and the goal position on each timestep. Here's the exact same setup, but using the MOPs Apply Attributes DOP instead of SOP:

apply attributes dop

Apply Attributes in DOPs with a falloff of 0.5. Every frame is solved based on the results from the previous frame.

It's very important to remember this distinction! You can't use MOPs DOPs in exactly the same way that you'd use regular MOPs. You'll potentially need to use a combination of animated goals in SOPs, animated falloff values, and the Activation parameter built into every MOPs DOP to control how and when objects meet their goal transforms. Falloff attributes work in MOPsDOPs the same as they work in SOPs... a value of 1.0 means the full "strength" of the transformation is applied, and a value of 0.0 means no transformation applied. If you need to keyframe the activation of an entire node at once, use the Activation parameter. A value of zero means the node will not be solved on a given timestep.

All of the example images below are derived from the example files included with MOPs+.

General Usage Notes

MOPs DOPs can be wired pretty much anywhere you'd expect to wire a POP DOP. This means that you can use them with the RBD Solver, the POP solver, or the Vellum Solver by wiring them to either the Pre-Solve, Post-Solve, or Particle Forces inputs depending on the exact solver you're working with. If you're using one of the self-contained dynamics solvers in SOPs such as the Vellum Solver SOP, you can double-click on the solver and wire any MOPs DOPs to the provided "force_output" Null SOP. Remember that the DOP evaluation order works top to bottom, left to right. You can either wire up MOPs DOPs in a single chain, or you can merge them all into a Merge DOP that then is connected to the appropriate solver input.

basic dops flow

All MOPs DOPs have an Activation parameter built-in, as well as a Geometry parameter. The Activation parameter you might recognize already from other DOP nodes. If the channel value is non-zero, the node will evaluate. If it's zero, it'll be bypassed. You can keyframe or channel reference this parameter to toggle individual nodes at different times of the simulation. The Geometry parameter determines what DOP subdata the node should operate on. In most cases, you want to operate on the Geometry subdata; this is the visible "stuff" you see on the screen, such as particles, rigid bodies, or Vellum points. However, you may want to use MOPs DOPs on some other subdata... most commonly, the ConstraintGeometry subdata that you'd typically find in a Packed RBD or Vellum simulation. For example, if you want to use a MOPs Falloff DOP inside the simulation to affect the strength attribute of Vellum constraint primitives, you would want to change the Geometry parameter to ConstraintGeometry (and change the Run Over parameter to "Primitives"). 99% of the time, you'll be using either Geometry or ConstraintGeometry for this parameter. If you're not sure what your targeted subdata is called, check in the Geometry Spreadsheet while in the DOPs context.

vellum falloff

Using MOPs Falloff inside the Vellum Solver to adjust the stiffness of the ConstraintGeometry primitives. (examples/vellum_falloff.hip)

MOPs Apply Attributes DOP

apply attributes


The MOPs Apply Attributes DOP is the most fundamental node of the MOPs DOPs system. Given a set of goal transforms (defined by any SOP or DOP data with matching name or id attributes), Apply Attributes will compute the forces necessary to reach those goals and write them to the appropriate point attributes that will then be read by whatever solver you're using (Bullet, Vellum, etc.). These forces are optionally scaled by a falloff attribute, and can be interpreted in a number of ways: you can directly set the transform without forces, update the velocity and angular velocity directly, apply the forces as wind, or use traditional (and bouncy) force and torque attributes. Apply Attributes also supports "snapping", which will temporarily bypass collisions and force the objects to meet their goal transforms that they might not otherwise be able to meet due to collisions or other impeding forces.

apply attributes explode rebuild


The first thing you'll want to set up when using Apply Attributes is the Inputs tab. This works just like the Inputs tab of a POP Wrangle. Just specify a context geometry (an input to the DOP network) or a SOP path (or a DOP data path if you're feeling fancy). The goal geometry needs to have an id or name attribute to match your simulation geometry. Once that's done, Force Update is your next stop. This is where you define what kind of forces you want to generate to meet your goal transforms. The default, Velocity/Spin with "Treat As Wind" enabled, is generally the most stable and produces the least "twitchy" results while still allowing for collisions. Position/Rotation mode will simply bypass other forces to reach the goals by directly updating the transforms. This is a brute force method, and won't mix well with other forces, but it always gets to the goal. Note that if you want collisions to be solved in Position/Rotation mode, you'll need to connect Apply Attributes to the "Pre-Solve" input of the solver instead of the typical "Post-Solve" input. Speed limit options exist to prevent Position/Rotation from accelerating too quickly at the beginning of a move; if you need speed limits for other Update Modes, use Houdini's POP Speed Limit DOP.

Snapping options ensure that objects will always reach their goals, regardless of collisions or other forces in the scene. Snap by Attribute is the most common method to use here. By default, if this is enabled, once the falloff attribute reaches 1.0 the object will disable collisions and internally switch to the "Position/Rotation" update mode, blending from its current transform to the goal transform over the length of the Snap Time parameter. If you have other strong forces in your scene, you might notice a "hiccup" as the object transitions between these modes. You can try reducing the Snap Time, reducing the strength of these other forces, or adjusting the Snap Ease curve to minimize any visible artifacts.

If you don't enable snapping and you're not using the Position/Rotation Update Mode, you might notice that your geometry is slightly offset from your goal geometry, often in the Y-direction. This is because of gravity or other forces in your scene. Enabling snapping will fix this.

Using Falloffs

Falloffs in MOPs DOPs serve the same purpose as falloffs in SOPs: creating attributes that control the "strength" of another effect. You can create these attributes in SOPs and then read them in DOPs if you like, or, you can use the MOPs DOPs Falloff nodes to create them during a simulation. The main difference between these two approaches is that a Falloff you set in SOPs will not be updated during the simulation unless you do so manually using a Geometry Wrangle or SOP Solver. This means that if you set a radial Falloff on some geometry in SOPs, unless you update during the simulation as mentioned previously, the Falloff will not change, even if geometry is moved around relative to the falloff's center point.

mops falloff sop

Using a SOP falloff before the simulation. The attribute doesn't update during the simulation, so the falloff never changes. Example file: examples/mopsdops_falloff.hip

Using MOPs DOPs, on the other hand, will update Falloff attributes constantly throughout the simulation. If you don't want this to happen, you have a few options: either use SOPs to do it instead, or keyframe the Activation parameter on the Falloff node so that its value is zero anytime you don't want the attribute updated, or keyframe the Blend parameter (exact values would depend on the Blend Mode you've chosen).

mops falloff dop

The same falloff shape, but in DOPs. The attribute updates on every timestep as long as the Activation parameter isn't zero. Example file: examples/mopsdops_falloff.hip

Remember that in DOPs, everything you do to change attributes in one frame will affect any frames after it! This means that if you're writing to a single falloff attribute with multiple DOPs in the simulation, the falloff value is going to be constantly overwritten each frame, and that value will carry through to the next timestep. It can sometimes be a safer bet to write to multiple different falloff attributes to ensure that they don't overwrite each other in an unexpected way, and then configure any Modifiers to use the appropriate attribute.

Art Directing Tips

In most cases, you're going to want to handle the bulk of your animation in SOPs, then use Apply Attributes and Falloff nodes to blend between goals as needed. You can use multiple Falloff attributes, each with their own associated MOPs Apply Attributes DOP set to use that Falloff attribute, to blend between any number of SOP goals. For example, here's an animation that shatters and reassembles a mirror twice. One goal is rotating around the Y axis, the other around Z. The first falloff (a spherical Shape Falloff setting mops_falloff) animates on first, reassembling the shattered pieces to match the Y-axis spinning goal. That falloff is then keyframed off, allowing the mirror to shatter again. A second falloff (a linear Shape Falloff setting mops_falloff2) then sweeps in from the side, and the second Apply Attributes DOP (also set to use mops_falloff2!) uses this goal. You could, of course, blend these goal transforms in SOPs instead and use a single Apply Attributes DOP to link to them. It's up to you to determine what's easier to work with for your setup.

apply attributes explode rebuild


For more specific types of motion, such as movement along a path, pseudo-random noise forces, or local transformations over time, the MOPsDOPs Modifiers are often more appropriate, but if you really just need things to get to a specific point in space I highly recommend keyframing in SOPs and then using Apply Attributes to attract your objects to those keyframed goals.

Sneaky Houdini gotchas

I've tried to smooth over as many fiddly bits of Houdini as possible with MOPs+, but there's always going to be little things that get you. Here's a few common issues you might run into.

RBD Pivots

Rigid body simulations in Houdini can alter the pivots of each packed primitive multiple times during the simulation. This will happen on the first solved frame if "Compute Center of Mass" is enabled on your RBD Packed Object, and it can also happen during collisions mid-simulation. This means that if you are trying to use Apply Attributes to tightly match defined positions in SOPs, you could notice an initial "bump" as the pivots are shifted before settling into the correct locations. Disabling "Compute Center of Mass" can often resolve this.

Scaling the RBD Bullet SOP

The RBD Bullet SOP doesn't currently fetch scaling data from packed primitives. This means that if you want to use the RBD Bullet SOP with MOPs DOPs, and you want to scale your geometry at some point, you'll have to do a little hack to get the attributes you need. Instead of using the direct outputs from the RBD Bullet SOP, use a DOP Import SOP to fetch the Geometry data from the DOP network embedded inside the RBD Bullet SOP (../rbdbulletsolver1/dopnet by default). You can then run MOPs Extract Attributes to extract the necessary template attributes from the transform intrinsics, and then use MOPs Apply Attributes (match by name because id is overwritten when you scale RBDs in DOPs!) to apply the simulated transforms to your original pre-sim geometry.

This is also exactly how you'd fetch data from any other RBD simulation in a traditional DOP network and apply it to packed primitives, and you'll see this method used often in the included example files.

fetch from bullet sop

In case you're scaling geometry using MOPs DOPs inside an RBD Bullet Solver SOP, you need to manually import the Geometry data and transform it like you would if you were using a regular DOP Network.

RBD Bullet SOP and the orient attribute

The RBD Bullet Solver SOP doesn't like having an orient attribute on your input pieces. You'll likely want to delete it (if it exists) before simulating. If you don't, you might see your pieces snap to an unexpected orientation on the first simulation frame. This isn't necessary if you're using a traditional DOP network workflow.

Vellum Constraints and the Vellum Solver SOP

The Vellum Solver SOP scrambles the primitive order of your constraints before the simulation starts. This means that if you're trying to use Falloffs or other MOPs nodes to manipulate constraint attributes, you'll be affecting the wrong constraints unless you create an id or name attribute on the primitives before the simulation, and then tell any MOPsDOPs nodes to match by that attribute. This isn't necessary if you're using a traditional DOP network workflow.