22 May, 2012

No-pop implementation challenges

One of the key features of the constraint system I am developing is auto correction of "pop effect" when animation changes. This problem is quite complex due to a lot of different scenarios involved and based on how Maya architecture is designed.

It is very easy to calculate offset and store it when a constraint switches between different spaces to avoid pop. That's the general idea, however maintaining this offset when animation is constantly changing is difficult due to some of the reasons mentioned below:

  • User can update keys in the graph editor at any time value, this does not cause the compute since you might be on a frame that is not related to the changes. Hence we have to detect this as animation callback.
  • Maya's animation callbacks are not much useful in giving details about which keyframe was deleted so in this case we have to update all the key offsets from the beginning to make sure we resolve pop. Because deleting a driver key means that space will change and hence the offset at the next nearest keyframe.  
  • A space can be animated not only by its own transform but any parent in the hierarchy or a constraint. The constraint driver(master) itself might be animated by a transform up in the hierarchy.
  • This means that when animation for a space changes in the scene we have to first detect if the animation affects the constraint. In addition to using generic animation callbacks we also have to look at the input/output graph and also the hierarchy to detect if our constraint is affected. 
  • What if drivers are not keyed exactly on the switching keyframes?  This means that if I update animation curve handles it will update the driver transform at the switch and hence creating a pop.
  • One change in the earlier keyframe can cause update of offsets in all the subsequent keyframes to remove pop effect. To remove the pop we need to update drivers by either updating offset or adding extra transform on the affected switching keys, however that could mean that the offset/positioning in next switching frame is invalidated and will create a pop. This can lead to a cascading effect, creating a pop in each next frame when fixing the current one. This is true in my case especially since all the driven nodes are free to move while constrained to the driver of the system. I have some ideas to avoid this cascading effect, but I still need to test them first. 
  • To remove the pop we can match the current driver and previous drivers of the system at switching keyframe, but there are few tricky situations to look for:
    • What if both, current and previous, drivers are updated at the switch? Which one should be matched to the other one?
    • What if a driver has incoming connections and its transform cannot be keyed directly?

Below is a simple example:
We have two objects A(bluish) and B(reddish). They are animated as shown in the image below.



Questions:
Think of the following scenarios after switching at frame 3:
  1. If B, the current driver, moves at frame 3
    This means that A will move as well since B is the current driver
  2. If A, the previous driver, moves at frame 3
    In this case B does not move since A is not the current driver

As for the status of GroupConstraint, the basics work quite nice with the animation. The problem arises when the animation changes creating a pop. The constraint handles pop for certain cases, but not all. I have finished writing logic for detecting keyframe changes and checking if it affects the constraint output or not based on graph connections and also DAG hierarchy. I also have all the functions ready to update offset information at any switch keyframe. The last (hopefully last) part now is to make sure that the auto-pop correction works when changing the existing animation in different cases. For me, I have to look at few more scenarios since I am also working hard to make switching possible with only one keyframe instead of two consecutive keyframes. And the possibility of animating the followers independently while driven by the driver of the system also adds to the difficulty.