Saturday, April 29, 2006

This is how it turned out...


So this is how it turned out. It has common wildcards for control names, a textfield to enter combinations of control names or animated objects which may not be controls. The list will only show objects which have animated attributes. If "none" is selected, all the animated objects in the scene will be listed.

For saving animation, the saver will by default save the animation for everything in the list. If you select objects from the list, it will save animation only from those objects, and only on channels that are animated.

There is an option to save animation only from the selected referenced character, so if there are multiple characters in a scene, only the selected reference gets saved. This is currently only a single selection option, but if there's a need, I can make it multiple selection.

I've added an "Animation Offset" option, which allows animation that may not start until the middle of the scene to be synchronized with the scene on load, and a "Motion Capture" option for saving, which makes for file sizes that are 25% or less the size of the full animation file which has weight and tangent information.

I also added a "No Character Reference" mode, so that animation can be transferred to and from characters which are not referenced, as many files coming to me through motion builder haven't been referenced yet. When "No Character Reference" is checked, the text that says "Reference Character Controls" changes to "Character Controls".

The remapper automatically loads the available animated channels from the file on read into the left hand column below in the "Anim File Controls" column, and selecting a character from the "Reference List" above automatically loads its available objects based on the "Select Wildcard" choices at the top of the interface (including the wildcards entered into the text field).

I've also made the selection process much faster. A single click on either of the objects in the "Anim File Controls" or "Reference Character Controls" text boxes will add the from => to mapping to the Animation File => Character text box. The Animation File => Character display is self correcting, so if you make a mistake and change the object mapping to the "Reference Character Controls" object, it will replace the map you previously entered with the updated one.

I've left all the manual buttons for conveying data in the interface like "Get Info from File" , "Get Character Controls" and "Map to New Character" even though I've added more automation for those features so they generally aren't necessary. If all the automated stuff continues to work under production use, then I might take the buttons out.

Reading mapped files is a "What you see is what you get" process, since the information is actually taken from the "Animation File => Character" text box, and not the variables used to create the box.

Making everything in these text boxes update automatically when options were changed turned out to be more challenging than I thought. It's still not perfect, and sometimes to get the "Character List" (at the top) to update with the proper amount of rows, I have to turn "Show Objects Selected With Wildcard" checkbox on and off.

Another challenge was getting a perfect match on tangents and weights on curves. It turned out that if the animation had options like "Weighted Tangents" or "Lock Tangent Weights" turned on or off, I'd get incorrect information in the saved file. It was solved by caching the current state of the tangents and weights, turning weighted tangents on, unlocking tangent weights, breaking the tangents, saving the information, and then turning them back on with the cached state. All of that information is saved unless the "Motion Capture" checkbox is checked, in which case no tangent information is saved (everything is assumed to be linear since there's a key on every frame), and no "infinity" information is saved ("infinity" is assumed to be constant).

I'm using my own file format rather than an existing one. It doesn't seem like there's a truly universal animation file format being used, and I can add to this one or subtract from it at will based on the needs of the production. I've already had to add additional variables for accurate tangent weight replication. Since the format easy to parse out, it can be translated to anything else that's ASCII based with pretty little effort, though the translation can be time consuming if a lot of recursion is needed. The downside is that the files can be huge, but they are "human readable".

The "Name" basis of this file format makes it particularly suited to production, since hierarchies can change during production, particularly the number of children of a particular hierarchy, which I've found throws things off a great deal and can make old animation incompatible with new animation. The remapping feature seems to be a pretty obvious need, and it's amazing that it's not something that's become a standard feature set in Maya.

I would really like to resolve a memory issue with using the animation file loader, particularly with motion capture files, which have a huge amount of data. During loading, it will suck up a ton of memory, even sending my machine into "swap" virtual memory space. And it doesn't give it back when the process is finished. The only solution I have right now is to save the scene, kill Maya and then restart Maya. If anyone has any solutions to this problem, I'd love to hear them.

Plans for the future:
The underlying code can be used for scene loading, bypassing the reference process in Maya if it becomes necessary, providing the code proves to be reliable enough and I resolve the annoying memory issues. If there's a use for it, I can use a "Save by timeline" feature, and maybe a "hide until first frame" feature for characters that have no animation until the middle of a shot.

I may also add an "animation copy" feature, to copy animation between two characters loaded at the same time, possibly deploying the techniques I'm using in another tool that turns hierarchical straight FK rotation keys into IK translational keys between dissimilarly proportioned characters.

If it can be made more efficient, I might make a multi-select reference mode that can load the same animation on multiple characters for crowd scenes, with a random range of time offset to the characters aren't all moving at the same time. I've thought of ways to also randomize initial character placement so the characters are at a fixed proximity to the other characters, but it would be hard to duplicate some of the features I've heard about in Massive. Also, I'd have to work on my use of matrices to determine location within a bound distance.

Monday, April 24, 2006

A little something I'm working on


This is the start of an interface for animation tools I'm coming up with. It allows animators to save in a format I came up with that is entirely name based, and allows remapping to characters that are dissimilarly named.

The advantage of using a custom animation file format is that I can add features to it as needed and put parsing hooks in that lower the coding time.

I've already thought of a lot of features to add to this interface, including attribute break downs, detection of missing attributes and an ability to add them or skip them, and various failure and recovery modes.

I've also thought about ways to write a remap into the referenced character file so this doesn't have to be repeated if the remapping is something that's done repeatedly.

Saturday, April 08, 2006

Bet you thought I'd never update this thing

So I got a job as a character rigger at Threshold Animation Studios. It turns out everything I learned along the way has come in handy.

I walked in with a suite of rigging tools I created. This turned out to be a real good thing. The first thing I had to do was mod them to conform to the in-house naming conventions. This would have been harder using downloadable rigging tools, since most of them have multiple library calls and tracking down the naming conventions in all the disparate global procs would have been daunting.

The other thing, is that the studio has special requirements which required serious modifications to the functionality of the rigging scripts.

If you look at http://casadiablos.com/steph/stephInterfaces.htm, you can see the base interfaces I use in my tool kit. I've added a spur builder, which creates customized bone spurs to tailor autoskinning. I can interactively resize them to fit the character, then move them around to where the autoskinning needs the greatest influence from the parent bone.

The other advantages to having a whole suite of tools, is naming conformity. This makes it easier to have all other tools act on the given objects. In the case of the spurs, it's [bone name]_A(B,C,D,etc)_SPUR.

I wrote a script that takes the skin assignments for every vertex and CV, and writes them to a file. All of them. For every object. This kind of duplicates the functionality of skin maps, but at the same time, it's a one stop process. Not a bunch of individual files for each object. I had to create my own file format for that.

This was a fortuitous development, because the character models are frequently revised. If the modifications are minor, like character proportions, with no added vertices/CVs, then I just save out the weights on the old character, reposition the skeleton and reload the file. Voila!

While objects that are modified severely or have new vertices added can't necessarily use the old weight assignments, often it's only part of the character that's been modded, and I can go back to the spurred version of the character before the skin weighting spurs were removed, and reassign that part of the character.

Another handy tool I developed allows me to de-assign unwanted weights. You don't want the abdomen to deform when you move the arm. I have a checkbox arrangement for the common bones, and a text entry field for bones added later. These bones include all the child spurs.

I updated sg_syncOb. I haven't uploaded it yet, since it uses the house naming convention and is proprietary at this time. But it now includes a zooty arrow-ball as a controller type. When it's fully updated, it will also offer the option of creating a joint with selectable shapes to select that joint as a controller. This had the advantage of being able to use the jointOrient attribute for externally rotating the controller, such as using the forearm to rotate an IK control foreward kinematically, while still being able to animate that controller's rotation on top of it. Very useful, but it's tricky to get working and not without it's pathologies.

So here are the features of the rigging suite:
Skeleton: creates guide spheres that are interactively scaleable to get close to the character's proportions, and creates a base FK skeleton conforming to the house naming convention. Options are selectable number of fingers, and number of bones in the fingers, back, head, neck, arms and legs. The code is there for tail, ears and pony tail, but I haven't connected it to the interface. There's also a checkbox to turn axes on and off for the entire skeleton interactively. The guide sphere portion has a mirror function so I only have to align half the spheres in the appendages. All numeric options for number of bones and scaling of the guide spheres use sliders but numbers can be manually entered as well.
Make Control Objects: This just brings up the latest revision of syncOb.
Create Spurs: This makes the bone spurs for skinning. It arranges the bones in a circle around the parent bone, and names them as mentioned above. There's a selectable number of bones, the axis of the bone to arrange them in a circle, and interactive radius adjustment. The interactive radius can be used by selecting the parent bone at a later time and using the slider as well. Buttons are "Create Spurs", "Spur to Joint" (which takes all the spur assignments and adds them to the parent bone), and "Delete Spurs" (which deletes the no-longer needed spurs after using "Spur to Joint").
Rename Skeleton and Control Objects: This allows me to create joints by hand, say additional spurs going in a non-circular orientation, and then rename them to conform to the naming convention. The text fields include "Jointname", starting letter, and suffix (JNT, CTL, etc). Works on any number of selected object and indexes them with increasing alphabetical representation (B, C, D, etc).
Remove Unwanted Weights: As mentioned above, this removes weight influences from bones that you don't want influencing that section of the character. There are checkboxes for non-left-right bones, and individual checkboxes for the left and right appendages so I can remove the influences from autoskinning like the left femur, tibia, and foot bones from influencing the right. There's also the aformentioned text field for entering bone names not represented by a check box. Buttons are "Delete Weights" and "Clear Check Boxes" (which also clears the text field).
Save/Read Weights: This has a filename field that you can manually type, as well as buttons that call up a file requester to set your directory path and name for the file. I have a filetype I created, and the suffix is automatically added. There's a "Get" button to get the file with the same type of requester. Unfortunately, I couldn't customize the default filetype, so you have to enter *.weight (that's not the actual suffix name) to see the .weight files. Buttons are "Save Weights", "Delete Existing Weights" (removes all current skin assignments, required to read the file or it will error on read if it doesn't double assign, a bad thing), "Read/Reset Weights" (which will delete and read the weights), and "Read Weights Only".
Make Chain Stretchy: This allows me to select the start joint and end joint for a stretchy chain, using either RP (standard IK) or SplineIK. It also strictly names (with the joint base names) all the various nodes it takes to make a stretchy chain so they can be easily identified when manually editing the conditional, multiply/divide, distance and curveInfo nodes. Radio buttons for the axes select the the axes along the joint that are scaled by the stretchy command. There are also radio buttons for RP and Spline construction, and an option to create a stretchy single bone.

I'm also working on a conversion utility to take the "animation" information off of a skeleton with House of Moves channel data brought in to Maya through the FBX importer, and convert that to combined rotational and positional data to drive an advanced IK rig for hand keying over motion capture without a slow, double rig being needed (the way you can do it in Motion Builder). The tool also takes frames numbered using a time code scheme and puts them at frame 1. I'll add a feature to the interface that lets you set the start frame at an arbitrary number. This also allows for importation of the data onto reskinned characters, and I'll probably figure out a way to allow the data to be put onto non proportionally similar characters for crowd scenes.

A parallel project of mine is an addition to the autorigger that sets up all of the controls automatically (usually a standard feature of autoriggers), with the addition of a double hierarchy so the mocap data can be imported, but you can animate using stretchy IK on top of that. I'm dubious about the ability of this system to use space switching techniques because of the underlying motion capture data, but we'll see. As far as I can plan, if there is space switching, it has to be done before the mocap data is applied. This represents a similar problem for foot axis pivot switching.

I've started learning about dynamics. My initial impression is that to get the results you want for complex limbs and such, it takes so much tweaking that it would just be faster to hand animate it. But we'll see where I can make it useful.

At this time, I'm not going to be doing tutorials. I don't really have the time, and I'd really rather wait until my tools and techniques have been battle tested a bit more.

Thanks for reading. Hopefully I'll have a chance to update this a little more often.