Skip to content

2021.03.01

allgood

It's been an epic month of problem-solving, but it finally happened. :D Highlight for this release is.. drumroll.. Automatic Initial State!

Tiger Rig courtesy of www.cgspectrum.com


Auto Initial State

Have you ever used the Set Initial State button? It's useful, isn't it? It's what enables you to turn something dynamic but then change your mind about where it should start simulating.

With this release, that process is automatic! It's more or less what you expected would happen anyway. I mean, obviously the box should drop from where you left it, rather than where it was originally turned dynamic?

ragdollinitialstateX

initialstategood1

Disable Feature

If you would rather have none of it, or if it gives you trouble, you can switch it off like this.

NOTE: Changes take effect on next scene open and newly created rigids.

autoinitialstateenable

Parallel Only

That's right, automatic initial state will only work in Maya's Parallel Evaluation mode.

It may end up getting support for DG later on, the trouble lies in the callback we use to read an edited initial state is not reliable in DG. It's possible we'll find another means of achieving the same goal in the future, although DG really is part of the past. Ragdoll works best under Parallel for other reasons too; primarily performance but also stability and robustness.

Constraints Stay Behind

Constraints currently show you the true position of rigid bodies.

image

They stay behind because hierarchy preservation is "artificial". It's just for you and Maya. In a later release, I'll make rigids also stay behind, and only have your controls move with hierarchy, so that you get to visualise where rigid bodies really are (even when your controls have locked channels, like translate) whilst at the same time letting you move and see your controls and how they reflect that true position.

Caveat

There's one known "gotcha" with the automated initial state.

Namely, the initial state is "recorded" whenever you transition from the start time to the next frame. Evaluation on the next frame will automatically read whatever was evaluated previously, and store that as the initial state.

However! It is possible to trigger evaluation without actually changing time. Maya loves doing that. You can do it by either scrubbing the timeline, or holding K and dragging (effectively scrubbing) the viewport. As you scrub, even if time isn't actually changing, Maya will go ahead and re-evaluated the time.

When that happens, it won't actually record a new initial state, but instead restore the original value. Something to be aware of.

Journey

For the technically inclined, here you can witness last month's struggle first hand and all the kinks uncovered in Maya's API and evaluation graph.

image


Hierarchy Preservation

Like in the real world, physics happens in worldspace. There are no "children" and no "parents". As a result, as soon as you turn any of your controls dynamic, they start acting that way. But we don't want that.

With this release, you'll now get realism along with that familiar feeling of having children and being a parent!

Before

ragdollbefore

After

tigerafter2

Caveat

There is one known case to be aware of when it comes to children.

Passive Rigids

Hierarchy is currently preserved only if a rigid is active. The reason being.. well, I'll just show you.

bugfixed

In this case, the passive rigid bodies are driven by an external transform, those blue "controls". Hierarchy is coming from the blue rigids, so we wouldn't want the passive rigids to mess with that.

But now when we move the rigids themselves (gray, in this example) we aren't getting our hierarchy preservation.. :(

At the other extreme, if we do account for hierarchy then the problem pops up at the other end instead.

hierarchybug

I trust experience and feedback will light the way here for a more intuitive experience working with external controls.


Worldspace Constraints

If you thought automatic initial state was enough, think again! If your controls have animation already applied, Ragdoll will now translate it into physics in world- and local-space.

Default Behavior

Local animation, like a rotated arm, are imbued with a "local constraint" to preserve the relative angle between it and its parent. World animation, like in this case where there is no parent, get imbued with a "world constraint".

constraintsdefaults1

World Only

Here's what you get when constraining the child to its worldspace pose. Notice how it assumes the angle you give it regardless of whatever the parent is doing.

worldonly

Local Only

Conversely, with just the local constraint, it'll assume the relative angle and respects its parent.

localonly

World + Local

Things get interesting when you combine the two!

worldpluslocal

World + World + Local

..or combine the three! Here's the lower arm trying to adhere to both its worldspace and local orientation. Notice the constraint coming out of alignment at the root; the constraints are of equal strength per default so it'll end up averaging the desired poses.

worldplusworldpluslocal

There's one more thing happening here that I'll touch on in an upcoming release, which is the concept of world space forces. Notice how the joint chain follows animation


DG Viewport Bug

If you've ever had the viewport "remember" old frames as you scrub the timeline, this fix is for you.

ogsreset


Unload Plug-in

In the previous release, licencing was implemented as a Python binding. The trouble with compiled Python bindings in Maya is that they cannot be unloaded. As a result, Ragdoll could not be unloaded.

Licencing is now implemented as a native Maya command, accessible as ragdollLicence from MEL and cmds.ragdollLicence() from Python.


New Commands

Three new commands was added in this release, they are primarily intended for TDs and technically minded folk.

  • cmds.ragdollLicence()
  • cmds.ragdollPeek()
  • cmds.ragdollDump()

cmds.ragdollLicence

Synopsis: ragdollLicence [flags]
Flags:
   -q -query
   -a -activate     String
   -d -deactivate  
   -h -help        
   -i -init        
  -ia -isActivated 
  -ig -isGenuine   
  -it -isTrial     
  -iv -isVerified  
  -md -magicDays   
   -r -reverify    
   -s -serial      
  -td -trialDays   

You still typically interact with ragdoll.licence, as documented here. But under the hood, this is now the native Maya command being called.

from maya import cmds
cmds.ragdollLicence(serial=True, query=True)
# Your-Serial-Number-Here

cmds.ragdollPeek

Synopsis: ragdollPeek [flags]
Flags:
   -e -entity             UnsignedInt
   -h -help              
  -ps -physicsStatistics 
  -ss -sceneStatistics

Gain insight into what Maya sees in Ragdoll.

cmds.ragdollPeek(sceneStatistics=True)

# Ragdoll Peek Scene
 ____________ ___________________________ _______________
| Id         | Scene                     | Name          |
|------------|---------------------------|---------------|
| 71         | rSceneShape               | rSceneShape   |
| 70         | rSceneShape               | rRigid18      |
| 69         | rSceneShape               | rRigid17      |
| 67         | rSceneShape               | rRigid        |
| 65         | rSceneShape               | rRigid7       |
| 63         | rSceneShape               | rRigid8       |
| 61         | rSceneShape               | rRigid14      |
| 59         | rSceneShape               | rRigid15      |
| 57         | rSceneShape               | rRigid16      |
| 55         | rSceneShape               | rRigid11      |
| 53         | rSceneShape               | rRigid12      |
| 51         | rSceneShape               | rRigid13      |
| 49         | rSceneShape               | rRigid9       |
| 46         | rSceneShape               | rRigid10      |
| 44         | rSceneShape               | rRigid4       |
| 42         | rSceneShape               | rRigid5       |
| 40         | rSceneShape               | rRigid6       |
| 38         | rSceneShape               | rRigid1       |
| 36         | rSceneShape               | rRigid2       |
| 34         | rSceneShape               | rRigid3       |
| 15         | rSceneShape               | rRigid27      |
| 14         | rSceneShape               | rRigid28      |
| 13         | rSceneShape               | rRigid29      |
| 12         | rSceneShape               | rRigid30      |
| 11         | rSceneShape               | rRigid31      |
| 10         | rSceneShape               | rRigid32      |
| 9          | rSceneShape               | rRigid33      |
| 8          | rSceneShape               | rRigid34      |
| 7          | rSceneShape               | rRigid19      |
| 6          | rSceneShape               | rRigid20      |
| 5          | rSceneShape               | rRigid21      |
| 4          | rSceneShape               | rRigid22      |
| 3          | rSceneShape               | rRigid23      |
| 1048576    | rSceneShape               | rRigid24      |
| 1048578    | rSceneShape               | rRigid25      |
| 1048577    | rSceneShape               | rRigid26      |
|____________|___________________________|_______________|
cmds.ragdollPeek(physicsStatistics=True)

# Ragdoll Peek Solver
- Number of scenes: 1
- Number of shapes: 36
- Number of materials: 36
- Number of convex meshes: 0
- scene[71]
  - Number of dynamic actors: 35
  - Number of static actors: 1
  - Number of constraints: 18 # 

cmds.ragdollDump

Synopsis: ragdollDump
   -h -help              

This is more of a teaser of what's to come, but let me tell you about it for completeness of these release notes.

ragdollDumps is the start of an integration effort of Ragdoll into any and all external software, like Unreal and Blender. Anything able to parse JSON. Including web-applications.

What if you could rig and/or animate in Maya, but then export the physics setup into e.g. Unreal? I'm not talking about baking your animation and playing it back somewhere else. But of exporting the internal physics objects from Ragdoll, translating them to whatever the third-party software uses for physics, and re-using it there!

With that, you could bypass all of the horrible authoring tools of those applications and transfer a physics scene or setup across applications.

Later, you'll be able to load these into a standalone Ragdoll desktop and web-based application. Useful for sharing your creations and animations with others, and for debugging too!

import json
from maya import cmds

cmds.ragdollDump()
# {
#   "scenes": {
#     "0": {
#       "id": 0,
#       "name": "rSceneShape",
#       "entities": {
#         "0": {
#           "id": 0,
#           "components": {
#             "NameComponent": {
#               "type": "NameComponent",
#               "members": {
#                 "value": "rSceneShape"
#               }
#             }
#           }
#         },
#         "1": {
#           "id": 1,
#           "components": {
#             "NameComponent": {
#               "type": "NameComponent",
#               "members": {
#                 "value": "rRigid"
#               }
#             }
#           }
#         },
#         "2": {
#           "id": 2,
#           "components": {
#             "NameComponent": {
#               "type": "NameComponent",
#               "members": {
#                 "value": "rGuideConstraint"
#               }
#             }
#           }
#         }
#       }
#     }
#   }
# }

Turn this string into json, with the native Python json module.

import json
from maya import cmds

dump = cmds.ragdollDump()
dump = json.loads(dump)  # From string to dictionary

# The format is internal and yet to be documented, stay tuned
scene = dump["scenes"]["0"]
rigid = scene["entities"]["1"]
name = rigid["components"]["NameComponent"]["members"]["value"]
print(name)
# rRigid

Expect the output to grow throughout later releases as more internals get serialised to JSON.