SFM/Animating with Python
Note! This information is very hack-y, and quite possibly wrong
How animation works
Animation is controlled by 'controls' and curves that denote how these controls change over time in SFM. Turns out, these curves are stored in the objects themselves, and you can see the data in the Element Viewer.
For instance, let's mess around with the animation curves of the Heavy. Load up the heavy model, then examine it in the Element Viewer. You can see the curves for the happybig motion, for instance, under heavy1->controls->happybig->channel->log->layers->float log, where you'll see the times and values array, which will give you the values that define the keyframes for the animation curve. Cool, right? But how do we mess with them?
Messing with some curves
Note: there's probably a better way to do this - there's some functions exposed here:
C:\Program Files (x86)\Steam\steamapps\common\SourceFilmmaker\game\sdktools\python\2.6\win32\Lib\site-packages\vs\movieobjects.py
CDmeFloatLogLayer stuff is around 17677, and probably gives the better way to set animation...
First, we need to select the control:
animSet = sfm.GetCurrentAnimationSet()
rootGroup = animSet.GetRootControlGroup()
happyBig = rootGroup.FindControlByName( 'happybig', True )
Now that we have the happyBig control, we can access the values. We use layers to pick the 'float log' item, since it has a space in it so python doesn't want to let you select it by name.
This gives you the value of the first point on the curve, which happens at happyBig.channel.log.layers.times
Modifying values is straightforward - give it a float, and you're good to go
happyBig.channel.log.layers.values = .5 #like this, for instance
Modifying time values is a bit trickier, since time is stored as a DmeTime_t type, and so assigning an integer to a time point won't work, so we use this code:
happyBig.channel.log.layers.times = vs.DmeTime_t(10000)
Note, time there is in 1/10,000ths of a second.
In order to add in new keyframes, we can just insert new values. We'll want to make sure that we add both a time and a value, like this:
indexToInsertBefore = 1 # or whatever. You'll probably change that programatically
newValue = 0.5
newTime = vs.DmeTime_t(15000)
If we want to delete values, we'll have to use the del keyword - again, you'll want to delete it from both lists:
elementToDelete = 1