Houdini 22.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 customized for Otto’s muscles. It assumes the muscles include Otto’s custom axialramp attribute and use the same muscle_id values. If your character’s muscles are not transferred from Otto’s, you should use the more generic Otis Muscle and Tissue Simulation recipe as a starting point.

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 fed into these null inputs. The setup allows you to connect the Test Geometry: Otto Muscle Transfer recipe and use your own bipedal character. See Learning and using this example for instructions on using your transferred character. r.

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

This Muscle ID SOP initializes the muscle_id attribute from Otto’s path attribute. To extract only the second-to-last element of the path, turn on Extract Element from Path Attribute and set Element Pos from End to 1.

musclesolidify1

This Muscle Solidify SOP converts the muscle surface geometry into tetrahedral meshes. The sizes 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 remaining lightweight enough to keep simulation times fast.

fibergroom_from_axialramp, fibergroom_override_transVAbs

These Fiber Groom SOPs create materialW, the fiber direction attribute. The first uses Otto’s axialramp attribute to create accurate fiber directions for complex muscle shapes, including muscles on the back. The second overrides the fiber direction for one muscle because a simpler direction produces better results.

musclepropertiesotis1

This Muscle Properties Otis SOP assigns the physical properties that determine how the Otis Solver simulates your character’s muscles. These properties control how muscles respond to shape changes, including how stiff or flexible they are. They also define tendon regions and how much a muscle bulges during contraction. One notable override applies much lower Shape Stiffness, Mass Density, and Fiber Strength to the belly organs so they behave more like organs than muscles.

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. For some of Otto’s muscles, especially his abdominals and obliques, the tendon regions should not be muscle ends because they do not attach to bones. Instead, they attach to neighboring muscles using muscletomuscleglue.

tension_id

This Muscle ID SOP creates the tension_id attribute for the tension_lines node. It initializes tension_id from muscle_id, then renames all L_rectusAbdominis_* IDs to L_rectusAbdominis so the network creates a single tension line. Separate tension lines cannot deform correctly in this region because no bones drive them. The node applies the same process to the L_oblique_* muscles.

Muscle activation

tension_lines

This Muscle Auto Tension Lines SOP automatically creates a tension line for each tension_id value. It uses Otto’s custom tensionendmask attribute instead of muscleendmaskto define the tension line ends.

activate

The activation parameters on this Muscle Tension Lines Activate SOP are customized for Otto. This node can activate tension lines in the rest pose because some muscles remain engaged while Otto is standing.

flex

The Muscle Flex SOP requires little custom setup. The Attribute to Match parameter is set to tension_id to match the Muscle ID Attribute on the tension_lines node. The Blend parameter is keyframed so the muscles are fully relaxed at the start of the simulation since some tension lines are active in the rest pose.

See Muscle tension lines and flex for more information.

Fascia or tissue

fascia_setup, tissue_setup, sliding_tissue_setup

These three 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 all three fascia and tissue setup subnetworks: fascia_setup, tissue_setup, sliding_tissue_setup. It prepares anatomical geometry for soft tissue simulation by generating a tetrahedralized volume from an exterior surface mesh and can use interior muscle and bone geometry for structural context.

The fascia uses a lower resolution because it only holds the muscles in place. The tissue uses a higher resolution because it drives the skin output.

tissuepropertiesotis1

This Tissue Properties Otis SOP is in all three fascia and tissue setup subnetworks: fascia_setup, tissue_setup, sliding_tissue_setup. It activates and assigns the physical properties and constraint attributes that govern the tissue simulation. The Shell Layer tab has no effect on the fascia because fascia consists only of the Core Layer. The Shell to Core tab applies only to sliding_tissue_setup, where the shell and core layers are separated, and controls the sliding constraints between them.

switch_sim_tissue

This node allows you to switch between using a fascia, tissue, or sliding 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 upstream geometry and attributes for final configuration, creates constraints from the incoming attributes, and sends the result 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 task. This makes it well suited for muscle and tissue simulation. In this recipe, the substep count depends on the file’s frame rate. For example, the default frame rate of 24 FPS uses 40 substeps, while 60 FPS uses 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 caches the simulation in memory to speed up post-processing. After caching the Otis simulation to disk, set the display flag to this node and play through the frame range.

skindeform1

This Skin Deform SOP takes the render skin animation as the first input and the simulated tissue outer surface as the second input, then deforms the former with the latter. The skinmask attribute created inside the deform_skin subnet excludes regions not affected by the simulation, namely the head, hands, and feet. Turn on Skin Sliding to use quasistatic skin sliding for 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, this Wrinkle Deformer SOP adds procedural wrinkles. Preview the wrinkles in the downstream deltamush_weak Delta Mush SOP, otherwise, they appear too harsh. You can create custom attributes to control the wrinkles in different areas.

deltamush_weak, deltamush_strong, blend_strong_deltamush

The deltamush_weak Delta Mush SOP is applied to the entire character to correct small scale mesh distortions. The blend_strong_deltamush wrangle blends deltamush_strong so it affects only the transition regions between the simulated and animated geometry, namely the 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 together. After completing the muscle transfer process, connect the source and target assets directly to 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_JOINTS to the REST_JOINTS node.

  6. Connect ANIM_JOINTS to the ANIM_JOINTS node.

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

  8. If you want to create your own animation using the transferred rig:

    • After your RIG output null, create an APEX Scene Add Character SOP and connect the rig to the second input. Leave the first input empty. Specify a name for your character in the Character Name parameter.

    • Connect an APEX Scene Animate SOP to this node. Animate your character here.

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

      • Set Output to Unpacked Geometry,

      • Untoggle Character Shapes,

      • In Extra Outputs, click the dropdown next to the Scene Output Path field and select the option ending with /Base.rig/output. For Key select Base.skel from the dropdown.

    • Connect the Scene Invoke to the ANIM_JOINTS null from the simulation recipe.

    • For other options see the animation workflow page.

  9. 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, tissue, and sliding tissue setup.

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

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

  3. To change it to sliding_tissue_setup, set the Select Input parameter to 2.

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

  5. The downstream switch_sim_tissue1 node automatically uses the same input because its parameter references switch_sim_tissue. This ensures the network only runs the deform_skin subnet when the tissue is also simulated.

Deform your animated skin with the simulation.

  1. Ensure your setup uses one of the tissue options, not fascia.

  2. You should first cache your simulation to disk with a File Cache SOP placed between the otissolver1 and the deform_skin subnet.

  3. Dive into 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 turn on skin sliding, select skindeform1 and turn on Skin Sliding.

  6. If you want to turn on 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 and retain a consistent topology throughout the frame range.

  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 the playbar to the required frame range. Include preroll frames so 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.

    • Move a few 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 to use the Frame Range start frame automatically.

    • If any rest length differs from 1, keyframe Rest Blend from 0 on the start frame to 1 a few frames later, as shown for the flex Blend above.

  4. On the otissolver1:

    • Set Start Frame to the new start frame, or $FSTART to use the Frame Range start frame automatically.

    • If any rest length differs from 1, turn on Rest Shape in the Target tab.

  5. On the skindeform1 node inside the deform_skin subnet, set Reference Frame to the new start frame, or $FSTART to use the Frame Range start frame automatically.

Muscles and tissue

Basics

Working with muscles

Muscles recipes

Legacy Muscles (Vellum Solver)