Houdini 21.0 Muscles and tissue

Test Geometry: Otto Muscle and Tissue Simulation

On this page

There are several Otis muscle and tissue recipes available through the tab menu. These are similar to shelf tools that put down networks of nodes for learning purposes and plug and play processes. The Test Geometry: Otto Muscle and Tissue Simulation recipe helps to begin simulating muscles and tissue with minimal setup using either Otto’s muscle geometry or Otto’s muscles transferred to another biped character.

This recipe is customised for Otto’s muscles. The muscles are assumed to have the custom axialramp attribute that Otto’s muscles ship with, as well as the same muscle_id attribute values. If your character’s muscles aren’t transferred from Otto’s, it is recommended to use the more generic Otis Muscle and Tissue Simulation recipe as a starting point instead.

Note

This recipe uses the Otis Solver SOP, the FEM-like muscle and tissue solver in SOPs. Because the Otis solver is not available in Houdini Core, this recipe is not available in Core either. However, a .hip file containing this recipe can still be opened in Houdini Core, and only the Otis Solver will have its parameters greyed out.

Note

For this recipe, make sure to place it at the geometry context instead of the object level.

Important nodes

Inputs

INPUT_MUSCLES, INPUT_BONES, REST_JOINTS, ANIM_JOINTS, REST_SKIN

These are the required meshes unpacked from the Test Geometry: Otto SOP and then fed into these null inputs. This setup is designed to have the Test Geometry: Otto Muscle Transfer recipe plug into the inputs easily, so that you can use your own bipedal character. See Learning and using this example to replace it with your own transferred character.

Muscles

muscle_setup

This is a subnetwork that contains the nodes to:

  • Convert your muscle surface geometry into a tetrahedral mesh.

  • Create the fiber directions using the custom axialramp attribute from Otto.

  • Configure the muscle physical and constraint properties, with overrides for Otto-specific muscle_id muscles.

  • Create Otto-specific custom attributes to create single tension lines for some collections of muscles.

See Muscle setup for more information.

muscle_id

In this Muscle ID SOP, the muscle_id attribute is initialized from the path attribute that ships with Otto. Because we only want the second-to-last chunk from the / separated path, Extract Element from Path Attribute is enabled, and Element Pos from End is set to 1.

musclesolidify4

This Muscle Solidify SOP, converts the muscle surface geometry into tetrahedral meshes. The size of the tets are determined by the Min Size and Max Size in the Remesh Surfaces folder. It is configured to be a good balance between accurately representing the shape, and being lightweight enough to keep simulation times fast.

fibergroom_from_axialramp, fibergroom_override_transVAbs

These Fiber Groom SOPs, create the fiber direction attribute materialW. The first uses the axialramp attribute that ships with Otto’s mucles to get correct fiber directions even for complicated muscle shapes, such as those on the back. The second overrides the fiber direction on a single muscle that ended up working better with a more straightforward fiber direction.

musclepropertiesotis1

This Muscle Properties Otis SOP, assigns physical properties to your character’s muscles that will determine how they are simulated by the Otis Solver. These physical properties control muscle behaviors like how receptive or resistant muscles are to shape changes, which regions of a muscle are tendon, how stiff or floppy a muscle is, how much a muscle will bulge on contraction, and so on. One property override of note is that for the belly organs, which has a much lower Shape Stiffness, Mass Density and Fiber Strength applied to get it to behave more like organs than a muscle.

muscleconstraintpropertiesotis1

This Muscle Constraint Properties Otis SOP, creates and modifies the attributes that drive multiple layers of muscle Otis constraints. The overrides serve mainly to refine the Muscle End and Muscle Glue masks.

tensionendmask_for_tensionlines

This Attribute Combine SOP, makes a copy of the muscleendmask attribute called tensionendmask before muscleendmask is edited in the following node. The tensionendmask attribute is used in tension_lines.

zero_out_ends_in_glue_region

This Attribute Combine SOP subtracts the muscletomuscleglue attribute from the muscleendmask attribute. In the case of some of Otto’s muscles, especially his abdominals and obliques, the tendon regions of the muscles should not be muscle ends, because there are no bones that they attach to, instead they attach to their neighbouring muscles, using muscletomuscleglue.

tension_id

Here we use a Muscle ID SOP to create a new ID attribute called tension_id that is used in tension_lines. We initialize it from the existing muscle_id attribute, and then rename all the L_rectusAbdominis_* IDs into a single ID called L_rectusAbdominis so that only a single tension line is created. This is because there aren’t bones to deform the tension lines correctly in that region if they are kept separated. The same is done for the L_oblique_* muscles.

Muscle activation

tension_lines

This Muscle Auto Tension Lines SOP automatically creates a tension line for each tension_id value defined above. It also uses the custom attribute tensionendmask defined for Otto instead of the muscleendmask to determine where the ends of the tension lines should be.

activate

Activation parameters on this Muscle Tension Lines Activate SOP are customised for Otto. Note that this node allows tension lines to be activated in the rest pose, since even when standing, some muscles are engaged.

flex

The Muscle Flex SOP hardly requires any custom setup. The Attribute to Match parameter is set to tension_id to match the Muscle ID Attribute on the tension_lines node, and the Blend parameter is keyed in to ensure that the muscles are fully relaxed at the start of the simulation, since some tension lines are activated in the rest pose.

See Muscle tension lines and flex for more information.

Fascia or tissue

fascia_setup, tissue_setup

These two subnetworks contain nodes to setup and configure your fascia or tissue.

See Fascia and tissue setup for more information.

tissuesolidifyotis1

This Tissue Solidify Otis SOP is in both the fascia and tissue setup subnetworks: fascia_setup, tissue_setup. It prepares anatomical geometry for soft tissue simulation by generating a tetrahedralized volume from an exterior surface mesh, optionally using interior muscle and bone geometry for structural context. In the fascia_setup the Method parameter is set to Fascia while in the tissue_setup it is set to Fused Tissue and Core. The resolution of the fascia is also lower than that of the tissue, as it is only needed to hold the muscles in place, while the tissue needs to eventually drive the skin output.

tissuepropertiesotis1

This Tissue Properties Otis SOP is in both the fascia and tissue setup subnetworks: fascia_setup, tissue_setup. It activates and assigns the physical properties and constraint attributes that govern the behavior of the tissue’s simulation. The Tissue Solid Layer tab has no effect on the fascia, as the fascia only consists of the Tissue Core Layer.

switch_sim_tissue

This node allows you to switch between using a fascia or tissue simulation. See Learning and using this example on how to switch between the setups.

Otis configure and solver

otisconfiguremuscleandtissue1

This Otis Configure Muscle and Tissue SOP is the final preparation step before simulation. The node collects all geometry and attributes from upstream nodes for any final configuration, creates the constraints required from the incoming attributes, and then sends it all to the Otis solver.

See Otis configure and simulation workflow for more information.

otissolver1

This Otis Solver SOP, is a specialized solver for tetrahedral soft body constraints that is faster and more accurate than the Vellum Solver for this singular task. This makes it well suited to simulate muscle and tissue. Note that in this recipe the substeps are dependent on the Frame Rate of your file, so that a default FPS of 24 will run with 40 substeps, while a higher FPS of, for example, 60, will only run with 16 substeps.

Skin post-processing

deform_skin

This subnetwork contains the skin post-processing setup which gets applied when the tissue is simulated with the muscles.

See Skin post-processing for more information.

Note

Ensure the switch_sim_tissue switch is set to 1 for this subnet to work correctly.

cache11

This node helps to speed up the post-processing. With the Otis simulation cached out to disk, and the display flag set to this node, play through your frame range. This will cache the sim to memory.

skindeform1

This Skin Deform SOP takes the render skin animation as the first input, and the simulated tissue outer surface as the second input, and deforms the former with the latter. Regions that aren’t affected by the sim, namely the head, hands, and feet, are excluded from the deformation with the skinmask attribute which is created inside the deform_skin subnet. Toggle on Skin Sliding to enable quasistatic skin sliding which gives simulation-like results.

Skin deform without skin sliding (left), and with skin sliding (right).

wrinkledeformer1, switch_add_wrinkles

When the switch is set to 1, procedural wrinkles will be added with this Wrinkle Deformer SOP. Preview the wrinkles in the downstream deltamush_weak Delta Mush SOP or the wrinkles will look too harsh. Custom attributes can be created to control the look of the wrinkles in different areas.

deltamush_weak, deltamush_strong, blend_strong_deltamush

The deltamush_weak Delta Mush SOP is applied to the entire character and is very useful for fixing any small scale distortions in the mesh. The blend_strong_deltamush wrangle blends the more extreme deltamush_strong to only affect the transition regions between the sim and the anim geometry, namely wrists, ankles and top of the neck.

Learning and using this example

To...Do this

Use the Test Geometry: Otto Muscle Transfer recipe and connect it into this network.

The two recipes work directly with each other. You can complete the muscle transfer process, then feed your source and target assets directly into this recipe.

  1. In the node network, align the two recipes with the Test Geometry: Otto Muscle Transfer recipe above the Test Geometry: Otto Muscle and Tissue Simulation recipe.

  2. Delete the following nodes:

    • testgeometry_otto

    • unpack_muscles

    • BONES_TRACH

    • unpack_rest_joints

    • invoke_joint_anim

    • unpack_skin

  3. Connect REST_MUSCLES to the INPUT_MUSCLES node.

  4. Connect REST_BONES to the INPUT_BONES node.

  5. Connect REST_SKIN to the REST_SKIN node. If you are using your own target geometry, you might want to bypass the subdivide1 node, depending on the resolution of your render mesh.

  6. If you are using the transferred rig:

    • After your RIG output null, create an Unpack Folder SOP and set the Extract Pattern to /Base.skel.

    • Connect this to the REST_JOINTS null.

    • After your RIG output null, create an APEX Scene Animate SOP. Animate your character here.

    • Create an APEX Scene Invoke SOP after your Scene Animate:

      • Set Output to Unpacked Geometry,

      • Untoggle Character Shapes,

      • Under Extra Outputs set Scene Output Path to /Base.rig/output and Key to Base.skel.

    • Connect the Scene Invoke to the ANIM_JOINTS null.

    • For other options see the animation workflow page.

  7. Alternatively, if you have a cache of the animated bone and skin geometry, see Replace the animation with an animation cache below.

Switch between fascia and tissue setup.

  1. Locate the switch_sim_tissue node. By default, the node is set to fascia_setup.

  2. To change it to tissue_setup, set the Select Input parameter to 1.

  3. To change it back to fascia_setup, set the Select Input parameter to 0.

  4. The switch_sim_tissue1 node further down will automatically update to the same, because the parameter references that of switch_sim_tissue. This is in order to only run the deform_skin subnet when the tissue is also simulated.

Deform your animated skin with the simulation.

  1. Ensure your setup is switched to sim tissue and not fascia.

  2. It is recommended to first cache out your simulation to disk with a File Cache SOP placed between the otissolver1 and the deform_skin subnet.

  3. Dive inside the deform_skin subnet.

  4. Ensure the display flag is set to cache11 and play through the entire frame range to cache the simulation to memory.

  5. If you want to enable skin sliding, select skindeform1 and toggle on Skin Sliding.

  6. If you want to enable procedural wrinkles, select switch_add_wrinkles and set the Select Input parameter to 1.

Replace the animation with an animation cache.

  1. Replace bonedeform1 with a Surface Deform SOP.

    • The first input should be the bone_setup subnet, as before.

    • Connect the INPUT_BONES null to the second input.

    • Isolate the bones from your animation cache and plug it into the third input. Ensure that your animated bones have the same topology as the rest INPUT_BONES.

    • This ensures that the animated bones are triangulated.

  2. Isolate the renderable skin from your animation cache and plug it into the ANIM_SKIN null. Ensure that your ANIM_SKIN has the same topology as your REST_SKIN.

Use a different start frame.

  1. Update your frame range to the required range on the playbar. Make sure that there are some preroll frames included so that the simulation starts with the character in tpose.

  2. On the flex node:

    • on the Blend parameter and select Delete Channels.

    • Navigate to the start frame, set Blend to 0, Alt + on Blend to set a keyframe.

    • Jump a couple of frames forward (3-10 depending on your preroll length), set Blend to 1, Alt + on Blend to set a keyframe.

  3. On the otisconfiguremuscleandtissue1 node:

    • Set Reference Frame to your start frame, or $FSTART if you want to make it automatically use whatever the Frame Range start frame is set to.

    • If you have any rest length not equal to 1, key your Rest Blend attribute from 0 on the start frame to 1 a few frames later, as shown for the flex Blend above.

  4. On the otissolver1:

    • Set the Start Frame to your new start frame, or $FSTART if you want to make it automatically use whatever the Frame Range start frame is set to.

    • If you have any rest length not equal to 1, ensure that in the Target tab Rest Shape is toggled on.

  5. On the skindeform1 node inside the deform_skin subnet, set the Reference Frame to your new start frame, or $FSTART if you want to make it automatically use whatever the Frame Range start frame is set to.

Muscles and tissue

Basics

Working with muscles

Muscles recipes

Legacy Muscles (Vellum Solver)