Categories
Autodesk Blog Post

Mastering Matrices for 3D animation and Rigging

AKA- Constraints are out! The Matrix is in!

Jean-Paul Tossings

Founder and Technical Director at Polder Animation

Mastering Matrices for 3D animation

Matrices are a big part of my toolkit as Technical Director at ?@PolderAnimation? Since maya 2020 the matrix workflow for rigging has finally been updated to use them to their full potential. But to use them correctly, you have to understand how matrices work and what matrices are. So in this video I try to explain in a visual way how matrices are build up and how they work without showing to much raw math.

Rigging with matrices

Part 01 – intro

The introduction to the rigging with matrices video series

The rigs that I build for animation production, for example the rigs for the feature film Miss Moxy are all build out of modules, which are self contained parts of the rig that only communicate with other parts via a few matrix connections through its input and output interface. A few guides determine the positioning and proportions of the module to dynamically adjust the rigs rest pose. This way all the characters, including humans, quadrupeds and birds could use the same building blocks, with only a few custom modules to add character type specific functionality.

So in this video series I want to put the knowledge about matrices to a practical use by building an arm rig module from scratch using matrices. Along the way a lot of maya matrix nodes will be explained. The series will include the following topics:

  • Fk control rig
  • IK control rig using maya ik solver
  • IK control rig using custom node based ik solver
  • node based soft or smooth IK to prevent ik popping
  • ik fk blending
  • manual arm segment scaling
  • control space switching
  • elbow locker
  • simple linear twist joints
  • bendy twist joints
  • squash and stretch thickness scaling
  • rig mirroring
  • publish script optimizations

Part 02 – FK

In this episode I build the initial arm module structure with a dynamic fk control rig using guides. Ik make use of the offsetParentMatrix plug on maya’s transform node to directly plug matrices into the controls. EDIT: I was just recording another video and I noticed that when the arm was straight the fk controls did not align correctly, because the aimMatrices for them where still set to use aim mode for the secondary alignment. I correct this in a later video (episode 8) when I come across this. If you want to fix this now, on the aimMatrix nodes for both the upper and lower arm, set the secondary mode to align, the secondary input axis to 0,1,0, the secondary target vector to 0,0,-1 and plug the worldMatrix[0] of the arm_L_upper_guide into the secondaryTargetMatrix. Sorry for this, but I’m (luckily) still human and make mistakes some times πŸ˜‰

  • 00:00 tranform node
  • 03:38 offsetParentMatrix as buffer
  • 06:57 use guides to drive buffer
  • 10:42 flatten control hierarchy with multMatrix
  • 17:07 flatten guide hierarchy
  • 22:18 automatic guide orientation with aimMatrix
  • 38:47 guided rotation plane orientation
  • 53:51 create rig module structure
  • 58:18 add and connect root module

Part 03 – IK

In part 3 I add the arm IK control setup using the same guides to keep the rig dynamically adjustable. For now I’m using the default Maya IK solver.

Part 04 – custom node based IK solver

In this episode I create a custom ik solver using maya default nodes. Using the Pythagorean Theorem and the Law of Cosines to solve the angles of the arm.

  • 00:00 why use custom ik solver
  • 02:04 law of cosines explained
  • 03:49 solving the upper arm angle
  • 10:52 solving the lower arm angle
  • 15:08 align ik joints with worldspace arm rotation plane
  • 20:18 replace upper and lower joints with worldspace matrices
  • 38:38 fixing scale issue in ik solver
  • 42:29 replace hand joint with worldspace matrix

Part 05 – soft IK

In this episode I build a node based setup for reducing the popping effect right before an ik solver reaches its max length. Also known as soft ik or smooth ik.

EDIT: The script I use for timing the evaluation duration can be optimized to skip the file save, making it a lot faster:

def getAverageEvaluationTime(n=1000, range_size=20):
    buffer_size = 100
    current_frame = int(mc.currentTime(q=True))
    mc.profiler( b=buffer_size )
    average_duration = 0
    for i in range(n):
        frame = current_frame + 1 + i%range_size
        mc.profiler( r=True )
        mc.profiler( s=True )
        mc.currentTime( frame )
        mc.profiler( s=False )
        event_count = mc.profiler( q=True, eventCount=True )
        for event_id in range(event_count):
            if mc.profiler( q=True, eventName=True, eventIndex=event_id ) == "EvaluationGraphExecution":
                duration = mc.profiler( q=True, eventDuration=True, eventIndex=event_id )
                average_duration += duration
                break
    average_duration /= n
    print(f'{average_duration=} micro seconds\nPure fps={1000000/average_duration}')
    mc.currentTime(current_frame)

getAverageEvaluationTime()
  • 00:00 explaining soft ik workflow
  • 18:28 construct the upper heigth
  • 30:04 construct the upper target heigth
  • 44:09 construct the upper scale value
  • 46:34 construct the lower scale value
  • 56:52 apply soft ik to upper and lower segments
  • 01:03:08 fixing NaN value error
  • 01:07:24 testing different blend and heigth curves
  • 01:20:36 profiling soft ik performance
  • 01:30:43 explaining soft ik with lower segment scale only

Part 06 – custom node based IK solver optimization

A small optimization that could be made to the node based ik solver shat we build, so this is a small update to that video.

Part 07 – Bifrost custom IK solver

In this episode I show the same node based IK solver as in episode 4, but now inside a Bifrost graph.

I will not show the creation itself, but the result as the creation would be a repetition of episode 4.
A small nuance to the performance comparison: it does depend on the system that you run, I tested it on 3 systems.

Intel i9 7960X (16 core) (2017)

  • Maya rp ik-solver 796 ?s
  • Custom ik-solver 928 ?s
  • Bifrost custom ik-solver 766 ?s

AMD Ryzen9 5950X (16 core) (2020)

  • Maya rp ik-solver 400 ?s
  • Custom ik-solver 390 ?s
  • Bifrost custom ik-solver 350 ?s

AMD Ryzen9 9950X (16 core)(2024)

  • Maya rp ik-solver 302 ?s
  • Custom ik-solver 294 ?s
  • Bifrost custom ik-solver 297 ?s

So the difference becomes close to negligible the faster the CPU becomes.

Part 08 – IK/FK blending

In this episode I go over how to set up the blending between the IK and FK matrices to produce the final arm segment matrices.

  • 00:00 fix fk control orientation issue
  • 03:32 add settings control with switch attribute
  • 07:15 blending in worldSpace with issue
  • 14:34 blending in localSpace
  • 23:57 cleaning up
  • 26:49 add skin joint hierarchy
  • 29:53 flatten skin joint hierarchy

Part 09 – segment length scaling

In this episode I add manual length scaling capability to the upper and lower arm segments in the ik and fk rig. As well fix the issue with the global rig scale.

  • 00:00 add manual segment scaling to ik solver
  • 06:45 add soft ik enabler
  • 11:03 add manual segment scaling to fk
  • 29:19 cleanig up
  • 30:14 fixing global scale issue

Part 10 – space switching

In this episode space switching capability is added to the IK and FK controls. And a barebone spine control module (hip, chest and COM controls only) and simple but effective clavicle module are added as well to have something to space-switch to.

Part 11 – driving shape data

In this episode we look at how to drive NURBS curves, surfaces, meshes and lattice deformers without using clusters. A lot of riggers still use clusters to drive the cv’s or vertices, but in a lot of cases this is not necessary an we can drive the cv positions with a simple connection.

  • 00:00 drive nurbs curve cv’s
  • 05:25 drive nurbs surface cv’s
  • 10:13 drive mesh vertices
  • 13:56 drive lattice FFD cv’s

Part 12 – IK elbow locker

In this episode we add an extra control that can be used to lock the elbow to a fixed position in space. This can be handy when a character rests the elbows on a table or on its knee’s for example.

  • 00:00 add elbow lock control
  • 06:34 add space switches to elbow lock control
  • 16:56 create poleVector switch for ik solver
  • 29:45 calculate lock upper and lower ik segment lengths 36:36 switch segments lengths
  • 42:50 add helper line as visual aid
  • 48:19 optional extra spaces

Part 13 – control space scaling

In this episode we add the ability to scale the parent spaces of controls. If a control has multiple spaces due to a space switch, every parent space has potentially a different world scale, so we filter the scaling matrices so that only the main scale remains.

Additional Math resources

And for our most advanced rig training on building high performance rigs that fully take advantage over the Maya Parallel and GPU based rigging check out Optimizing Rigs for Parallel Evaluation, success story β€œGoro”

Thank you to Jean-Paul for allowing us to publish this great series on our blog.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.