MRS: Time Context and ANTHEM!

Current Sprint: MK Base

  • mrsAnimate
    • Time Context
    • Bugs/workflow
  • Workflow
    • Pushed a javelin like proxy through the new setup to find issues
  • UnitTests


I’m pumped for Anthem and wanted to try the new MRS workflow with a javelin proxy and work through any issues with the new setup.

Stuff to fix:

  • Add an attr sort to the rigBlock to make finding stuff easier in the channel box
  • loftStart/End not setting up properly for mirroring block
  • End handle on quad leg aiming weird by default. CHeck
  • Rotate plane
    • off by default
    • hook up vis for that and measure
  • Look at segment aiming. Saw a few flips
  • Add a way to lock the position/rotation of the prerig handles/template handles when you’re moving other stuff.
  • Add a forceNew toggle on the push states to make everything not have to rebuild unless you want

Working at finding good loftList defaults for the various blockProfiles

  • Arm
  • Finger
  • Spine

Here was an early test

Found some issues with the design and so iterated.

  • Bigger torso and arms
  • Smaller head
  • looked at some more javelins on google for ref

Ended up here. Feels pretty good for a test and got some good notes for working on MRS

Have a one day poll up on facebook to see about releasing the proxy. Will be putting the template for the asset on the MRS section of the site for members.


Time Context

Been wanting to add time context for awhile now. First things first, plan.

  • Current | frame we’re on
  • BookEnd | Previous and next, includes current IF there is a key
  • Next | current and next or just next if none current
  • Forward | current and all ahead
  • Previous | …
  • Back | ….
  • All | all keys in range
  • Selected | Work off the timeline selection

Then I need a way to say which module’s have a function. For example, say the left arm has keys on f 100 but right does not so I need a way to say right arm does switch in that case and it doesn’t. What’s a simple way to describe that?

My first block out will be as follows: calling this Keys context with the following option.

  • Each | each chunk in context be that part, puppet or whatever, if it is keyed, do it.
  • Combined | Get all the keys generated in the selection context and then those keys will be combined to a new set. So if selection list one generates key indices of [1,2,5] and list two is [1,6,8], the new list of keys to set will be
  • All | My brain is failing me why I wanted this one too so it’ll probably go

Frame out

Take a first pass on layout of the buttons.

Then we look at it. Is this clear? Kinda. I think the time context line is busy because of the radio button setup. I’m gonna try something else…

  • Instead of the radio buttons, we do regular buttons. These frees up ui space. Then we needed a way to show what mode we were in
  • We have a header bar in the form of our frame layout so we just update that when we make a change
  • Add a couple of calls to set and update and I think this is a much better place to start. I really kinda like this feel and you may see it again in other bits of ui should it work as well as I hope

Time Context Plan

Now we have to figure out what’s what. I like to plan out where I want to get to and then figure out how to do that so….

  • Controls
    • Per control, find key indices in our time range
    • control:{f11.0,f23.0,f34.0}
  • Part
    • Per part in context, find key indices of any control of that part? Should I make it only certain controls?
    • part:{f11.0,f23.0,f34.0}
  • Puppet
    • Per puppet in context, find key indicies of any control of the puppet
    • puppet:{f11.0,f23.0,f34.0}
  • Scene
    • puppet:{f11.0,f23.0,f34.0}

Then how would that work with combined:

  • Case 1
    • Modules
      • armLeft:{11,23,34}
      • armRight:{12,55}
    • Each – as is
    • Combined
      • armLeft:{f11,12,23,34,55}
      • armRight:{f11,12,23,34,55}

For the processing loop I want to get the data indexed to frames so I don’t process the same key twice to something like.

  • {11:[armLeft],12:[armRight]}


Time Query

To do

  • Add slider time context
  • BookEnd includes any frames between

Checklist checking contexts

  • Control
    • Current
    • BookEnd
    • Next
    • Forward 
    • Previous 
    • Back 
    • All
    • Selected 
  • Part
    • Current
    • BookEnd
    • Next
    • Forward 
    • Previous 
    • Back 
    • All
    • Selected 
  • Puppet
    • Current
    • BookEnd – not supporting. too many issues
    • Next
    • Forward
    • Previous
    • Back
    • All
    • Selected

Got everything working. Here’s an example report for puppet/each/slider.

|cgm.core.mrs.Animate.get_contextTimeDat| >> Time >> = 1.6290 seconds
# cgm.core.mrs.Animate : Context: puppet | keys: 9 | sources: 23 # 
# cgm.core.mrs.Animate : Sources ...________________________________________________________________________________ # 
# cgm.core.mrs.Animate : [R_arm_limb] || controls: 26 # 
# cgm.core.mrs.Animate : [R_thumb_limb] || controls: 11 # 
# cgm.core.mrs.Animate : [spine_segment] || controls: 13 # 
# cgm.core.mrs.Animate : [face_muzzle] || controls: 24 # 
# cgm.core.mrs.Animate : [L_eye] || controls: 9 # 
# cgm.core.mrs.Animate : [L_leg_limb] || controls: 27 # 
# cgm.core.mrs.Animate : [head] || controls: 9 # 
# cgm.core.mrs.Animate : [L_middle_limb] || controls: 14 # 
# cgm.core.mrs.Animate : [R_middle_limb] || controls: 14 # 
# cgm.core.mrs.Animate : [R_ring_limb] || controls: 14 # 
# cgm.core.mrs.Animate : [R_leg_limb] || controls: 27 # 
# cgm.core.mrs.Animate : [L_pinky_limb] || controls: 14 # 
# cgm.core.mrs.Animate : [L_holster_limb] || controls: 6 # 
# cgm.core.mrs.Animate : [R_eye] || controls: 9 # 
# cgm.core.mrs.Animate : [R_pinky_limb] || controls: 14 # 
# cgm.core.mrs.Animate : [mDrake_puppetNetwork] || controls: 3 # 
# cgm.core.mrs.Animate : [full_brow] || controls: 15 # 
# cgm.core.mrs.Animate : [L_ring_limb] || controls: 14 # 
# cgm.core.mrs.Animate : [L_arm_limb] || controls: 26 # 
# cgm.core.mrs.Animate : [R_index_limb] || controls: 14 # 
# cgm.core.mrs.Animate : [L_index_limb] || controls: 14 # 
# cgm.core.mrs.Animate : [pistol_limb] || controls: 6 # 
# cgm.core.mrs.Animate : [L_thumb_limb] || controls: 11 # 
# cgm.core.mrs.Animate : Keys ...________________________________________________________________________________ # 
# cgm.core.mrs.Animate : f[4.0] : [(node: 'R_arm_limb' | mClass: cgmRigModule | class: <class 'cgm.core.mrs.RigBlocks.cgmRigModule'>)] # 
# cgm.core.mrs.Animate : f[6.0] : [(node: 'R_arm_limb' | mClass: cgmRigModule | class: <class 'cgm.core.mrs.RigBlocks.cgmRigModule'>)] # 
# cgm.core.mrs.Animate : f[8.0] : [(node: 'R_arm_limb' | mClass: cgmRigModule | class: <class 'cgm.core.mrs.RigBlocks.cgmRigModule'>)] # 
# cgm.core.mrs.Animate : f[9.0] : [(node: 'L_arm_limb' | mClass: cgmRigModule | class: <class 'cgm.core.mrs.RigBlocks.cgmRigModule'>)] # 
# cgm.core.mrs.Animate : f[11.0] : [(node: 'spine_segment' | mClass: cgmRigModule | class: <class 'cgm.core.mrs.RigBlocks.cgmRigModule'>)] # 
# cgm.core.mrs.Animate : f[12.0] : [(node: 'L_arm_limb' | mClass: cgmRigModule | class: <class 'cgm.core.mrs.RigBlocks.cgmRigModule'>)] # 
# cgm.core.mrs.Animate : f[15.0] : [(node: 'R_arm_limb' | mClass: cgmRigModule | class: <class 'cgm.core.mrs.RigBlocks.cgmRigModule'>)] # 
# cgm.core.mrs.Animate : f[16.0] : [(node: 'L_arm_limb' | mClass: cgmRigModule | class: <class 'cgm.core.mrs.RigBlocks.cgmRigModule'>)] # 
# cgm.core.mrs.Animate : f[24.0] : [(node: 'spine_segment' | mClass: cgmRigModule | class: <class 'cgm.core.mrs.RigBlocks.cgmRigModule'>), (node: 'L_arm_limb' | mClass: cgmRigModule | class: <class 'cgm.core.mrs.RigBlocks.cgmRigModule'>)] # 


Now that we have our data we need to do stuff with it.

  • Made a list of functions that are allowed through the time context. Other calls force to current only mode
  • Got reset,key stuff working quickly
  • Mirror and fk/ik stuff we had data for so wasn’t too bad. The speed thing referred to in the next section was a hang up here.
  • Space switching – we need to rewrite this to work with time


The time context/control processing is a bit slower than I’d like with puppet mode because it’s walking the nodes every call. It’s about 1.2 seconds. It doesn’t feel great. So what can we do about it?

Most straight forward solution will be to implement a cache for contextual calls. Not going to have time to do it right now but will be adding this to the roadmap for the tool after we get initial time context working.

In the meantime came accross a couple of items:

  • mc.currentTime(f,update=False) | This sped things up but broke some call because we actually need the nodes to evaluate to key them properly
  • mc.refresh(su=1)/mc.refresh(su=0) | hat tip to Benn Garnish. This call makes the viewport not update. This works faster and doesn’t break out calls (so far)


There’s some issues from Bo.

  • Context
    • children include the part – This was from master not working and causing confusion
  • BUG – Master not recognized
    • Need to acquire
      • master
      • Space pivots
      • rootMotion
    • Added a couple of new calls for getting puppet controls
      • PUPPETUTILS.controls_getDat
      • PUPPETUTILS.controls_get
  • Marking Menu
    • Puppet pose flip requested

Kinda works…

Unit Tests

Had an issue where I rolled up update into a branch and broke some stuff for a user. I need to add better MRS unit testing and so that’s going on the to do list.

Josh Burton

[MRS Project Lead | CG Monks] Josh is an animator turned TD who hails from Oklahoma, pre-undergrad in the Marine Corps, animation basics at Savannah College of Art and Design, cut his teeth in gaming and commercials before co-founding CG Monks and more recently the CG Monastery. The Morpheus Rigging System is a culmination of years of R&D and he is now thrilled to see what users can create, collaborate and expand on with this open source MRS platform.