I have started working on the next iteration of my rigging tools and I wanted to try taking things up a notch. To that end I started some work on a custom locator that will be used as a layout object in the setup face of the rig. In this video I briefly show the locator and provide a peek at the menu that will hold the rigging tool set.
I busted this out today so people can test my concept for an ik leg.
There has been little action on my production blog due to the fact that I am back at the Rigging Dojo instructing students in the fine points of rigging and Python scripting. This does not mean that I haven’t been thinking about that project. I have been making slow progress, but I have nothing major to show just yet. I have however been writing some new widgets for my constantly under development Maya rigging system. To make things interesting, I have decided to develop widgets for both Maya and Max in tandem. This has been realy great because it has pushed me to think outside the box in both programs. Ideally I would like both systems to be able to pass information between one another in the form of .fbx and .xml. The idea here is that the rig generated in Maya will behave the same way as the Max rig. This means at the very least I need to use similar controls with matching rotation orders and orientation. Once I have constructed a rig in either system, I can save out the skeleton data in the form of fbx or xml. I can then use that information in the other program to generate a new rig. To finish things up, I will create a robust animation library that can pass animation data between rigs.
In today’s video, I would like to show you the prototype for the IK leg rig I will be using. This rig is built in Maya, and is already scripted except for the bendy part which is still in the R&D phase. The leg features a no-flip knee, bendy, stretchy, a foot pivot that can be animated, and a single attribute to control foot roll from heel to toe. As usual, comments are welcome. I will be providing a tutorial once I finish up with the prototype.
As promised I have returned with some Maxscript to share with you my loyal readers. You should know that I am no Maxscripting guru. In fact, I have only spent about 12 hours writing Maxscript so far. Luckily I find Maxscript to be similar to Python in many ways, so the transition is tough, but not too bad.
I would like to start off by giving some background into what I am trying to accomplish at this stage of my project. If you have been following along, then you have seen the rig I built by hand as a template for what I want to construct using Maxscript. There are many ways to go about scripting that rig, but I prefer to keep my rigging systems modular enough that I can build a rig for any type of creature that comes down the pipe. To that end I intend to use layout templates for each rigging component. To facilitate identifying one template from another in my scene, I have decided to leverage the user defined object properties of the root template object in my scene. If you don’t know what user defined object properties are, then right click on any object in your Max scene and look for “object properties”. You will then find a tab titled “user defined”. When you click this tab you will find a blank text field where you can type in anything you like. In my case, I will define things like “Layout Type”. Once I get the spine done, I will upload my Max file so you can see what I am doing here. So the idea is to use a layout object. In the case of the spine, I will be using a simple chain of helper objects to define the position of my spine Bones.
I can then import that template into the file with the character I intend to rig. With the template imported, I run a script and presto! I have a spine rig.
Thus far I have written some simple code that will find the children of the root template object. I have hard coded the name of my root object for testing purposes, but later on I will identify the root by looking for it’s object properties. I then find the child of each template object, and create pairs of parent and child object which are then stored in an array. Using that array I can build sets of helper objects that are later used as the start and end joints for ik chains. At this stage my code is messy and full of notes and comments, but I am ok with that. In my time as a Technical Artist I have learned several important lessons, but I think these two lessons are of paramount importance when it comes to any endeavor.
- Show your work often.
- Quickly make your mistakes so you can get them out of the way.
Thanks again for reading my ramblings. Before I log out, I leave you with my code.
--struct bp_info (bp_name, bpChild_name, bp_xform) -- Function to get all the children of a defined object fn addChildren obj hierarchy = ( -- add object to the array append hierarchy obj -- loop over children and recursively add their children for child in obj.children do addChildren child hierarchy hierarchy ) fn addSubChild = ( bpData = #() c = addChildren $BP_SplineRoot #() for i in c where i.children != undefined do append bpData #(i, i.children) return bpData ) fn drawBone = ( local bpBones = #() stuff = addSubChild() for item in stuff do( parentBP = item childBP = item parentBoneName = substitutestring parentBP.name "BP" "Bone" childBoneName = substitutestring childBP.name "BP" "CapBone" parentPos = parentBP.transform childPos = childBP.transform new_ParentBone = point name:parentBoneName size:10 box:on cross:off new_ChildBone = point name:childBoneName size:5 box:on cross:off new_ChildBone.parent = new_ParentBone new_ParentBone.transform = parentPos new_ChildBone.transform = childPos new_ParentBone.wirecolor = color 140 88 225 new_ChildBone.wirecolor = color 196 88 225 append bpBones #(new_ParentBone, new_ChildBone) ) return bpBones ) fn drawIKSpline bpBoneData = ( -- Draw an HIK between each parent / child grp for ikBone in bpBoneData do( solverName = substitutestring ikBone.name "Bone" "IK" IKChain = IKSys.ikChain ikBone ikBone "IKHISolver" IKChain.name = solverName ) -- Question: What is .count for? ) fn mainFunction = ( local bpBoneData = drawBone () local ikInfo = drawIKSpline bpBoneData ) mainFunction() -- These are some new concepts I got. I will save them here for later. --data = #() --for node in helpers while data.count == 0 where node.children != undefined do append data #(node, node.children) --for node in helpers collect #(node, node.children)
It has been to long since I posted on this project, but I do hold down a full time job and I have a family that gets upset if they are neglected for too long. I am happy to report that I have been making some great progress. I simply wanted to get my work to a certain point before doing a write up. This morning I made a major breakthrough where I finally got the whole rig working as expected. I can now successfully transfer animation data from motion builder to a mocap skeleton in Max. The mocap skeleton then drives my custom animation controls without keying the controls, thus leaving them free for hand keyed animation. Before I show the fruits of my labors, I want to talk about the rig and some of the design choices I made. I found that it was easy enough to hookup things like FK controls and IK arms. The real problem areas were the feet and spine. I could have gone with a simple FK solution for the spine and a straight reverse foot for the feet, but I wanted to use something that was a lot more animator friendly.
I tried a lot of different things when it came to the spine. Originally I thought I could do something like a Schliefer spine, but the built in spline IK in Max just plain stinks. I then thought I would try my hand at a ribbon spine, which actually worked well, but was a nightmare when it came to solving for my mocap skeleton. I finally ended up creating a custom solution which is similar to a spine rig I got years ago from this book.
The spine uses a motion path to control the position and aim of my bind bones. The twist is controlled by several HIK chains hooked up through float expressions. Here is a video of the spine in action.
A good foot rig is hard to come by, and I have spent a lot of time experimenting with different designs. Generally I prefer an attribute driven foot that uses an Ik solver to keep the ball and toe planted on the ground. The IK handles are grouped under dummies that are arranged like a reverse foot, and the rotation of those dummies are controlled by custom attributes on a main foot control. I don’t plan on creating a tutorial for this setup as hundreds probably exist by now. The tricky part of the foot setup is getting the mocap skeleton to drive the attributes without locking up the ability to create hand keyed animation later on. To be honest, I am still working on perfecting this part, but thanks to Brad over at RiggingDojo, I am very close to getting it just right.
I will get a couple images up showing the animation controls at work along side the motion capture data. I am away from my home machine ATM.
What needs to be done?
I think my rig is pretty solid, although I have yet to polish the skin weighting Next I want to work on creating a nice space switching system for the arms, legs, and weapon controls. I also want to go in and fine tune a few details, and make sure that everything is still working with animation layers. Lastly, I want to rebuild the whole rig, because I have been patching things together for the purposes of rapid prototyping. Now I need to clean up my mess. Rather than build everything from hand again, I intend to use Maxscript to do my work for me. Fortunately I have been scripting out parts of this process as I go, so this hopefully won’t be an enormous task… yea right.
In closing, I would like to thank everyone that helped me get this far. You know who you are, and you ROCK! I will like to give a special thank you to Denis Trofimov, with whom I have the honor of working with. Denis has been in the industry forever and has been using Max since the day it was born. You may even be using some of his tools without knowing it. Perhaps you have have a script that starts with LUX or DT? Anyhow, I am very grateful to have Denis as a constant resource, even though I feel like my brain is going to burst from the constant information dump. Funny enough, I am assisting Denis with some Max auto-rigging tools, which is perfect considering the nature of this project. I imagine my next post will be pretty Maxscipt heavy, but I do plan on doing a little side piece that delves into controllers and transforms in Max. I find that Max handles transforms and hierarchical relationships a little differently than Maya, and I would like to talk about some of my findings with the goal of making these concepts a little easier to understand.
I have spent many hours this week trying to decide how I want to approach building a system into my custom Max rig, that will be responsible for handling mocap data. Ideally I want the motion capture animation to drive my rig controls without baking keyframes to the controls. In this way I can still animate on top of the motion capture animation. Ideally I want a way to blend between my motion capture and hand keyed animation so I have more freedom when creating my final animation. Thus far I have come up with the following options for achieving this goal.
1. Use CAT or Biped. This is not a real option. I think CAT and Biped are great for what they are, however neither system is open to modification unless Autodesk decides to give direct access to the API Let’s face it, at some point I am going to want to rig a DragonBearSquid.
2. List Controllers. List controllers are basically designed to allow you to have multiple inputs for any controls transforms. With list controllers I could potentially drive my controls with a motion capture skeleton, while still maintaining the ability to animate my controls on another channel. So far this is looking like my favorite option, but I will need to do some more tests before I can be sure.
3. Animation Layers. As far as I can tell, animation layers are list controllers that are tied in with some sort of reaction manager system. I like the idea of animation layers because they provide an interface for interacting with animation inputs, and they support position and orientation constraints. I did find the ability to enable and disable animation layers to be another useful feature. The problem with animation layers is that they seem buggy and they tie a lot of extra information to your controller. From my limited experience with animation layers, I found them difficult to control, and nigh impossible to get rid of should you want to remove them.
4. Layered Controls. This is my Maya experience talking here. It might be possible to create a layered system of controllers. For instance, you could have your arm control linked to a dummy, and that dummy could be constrained to your mocap skeleton. This approach actually worked well in my initial tests, but failed to do the trick when I got into more complicated systems like a reverse foot. The other issue with a layered system is the number of object in your scene will be much greater and more difficult to wrangle.
The biggest problem I am facing in finding a suitable solution to my mocap transfer problem is dealing with a custom foot rig. I like to rely on a reverse foot or an attribute driven foot because they make life much easier for the animator. Both types of feet are causing issues when trying to use any of the above solutions, but I am optimistic that an answer is just on the horizon. Aside from the foot problem, I am having a lot of success, and I look forward to getting this system worked out so I can dive into some serious scripting.
As always, please feel free to share your thoughts and experience on any of the topics I am discussing here.
Someone was asking me how to create a new camera and window via a shelf button with the purpose of creating an image plane based UI. The base code is actually fairly simple to write in Python. Here is an example.
# Import maya python command library
import maya.cmds as mc
# Define a window
window = mc.window(title=’FaceCtrl_Window’, w=400, h=650)
# Create a pane layout to store the modelPanel
# The model panel can show a camera
# Show the window
You could then attach an image to the image plane of this camera to create the background for a nice slider UI like the one found in Victor Vinyals demo. http://www.youtube.com/watch?v=gxusrZiYzbw
I will elaborate on this code if anyone shows interest, but for now I just wanted to drop in and give a quick overview of the process. Here is a sweet image you can use to test your own setup.
Yea the animation is craptastic, but I got a nice overview of rigging in Max by doing this tutorial. The swim animation is just a wave deformer driving a custom spline IK. I will be back in a few days with a manual animation rig for this guy. Until then, cower before the terrifying visage of Shark!
Overall I am very pleased with the performance of the Nurbs surface based, joint driven facial rig. I figured out all of the issues with this latest revision, and I learned a great deal more about how to shape the surfaces. My primary goal in this exercise was to refine the rig, but I thought I may as well try it out in UDK so I could see how it looks in engine. The results are not as good as they could be due to several factors, however I think the next round will be spot on. Once I finish the final revision of the rig, I will walk you through the rigs advantages while describing how to create one of your own.