Summer of Code 2007: High level animation control plugin (including IK support)
Student: Jaroslaw Kochanowicz (jarek108)
Mentor: Paul Cheyrou-lagreze (tuan kuranes)
Status: Failed at Midterm
Introduction (taken from proposal)
Based on ogre3d forum discussions and project ideas:
Iâ€™d like to build a high level animation control plug-in for ogre. It would enable user to blend together multiple animations in a way similar to proposed here by ogre mentor tuan kuranes:
and to apply procedural animation controllers(eg apply IK and physics) blending them all together.
-supply users with interfaces allowing them to define on a high (by scripts?) authored animations to be blended and the way that should be blended(like in example in post above)
- provide abstract interface for animation controllers influencing the actor to build later user defined controllers(IK algorithms etc)
- allow user to easily attach external physics engine that will influence the actor.
-implement of CCD IK algorithm using the abstract interface
-if time allows work monitor mentors/users for any feature that will be expected and possible to implement
Fast remarks on interface with current ogre code.
- Project will replace and expand current implementation of animation blender.
- The bottom level of the system will directly use ogre classes: Bone, Skeleton, NodeAnimationTrack etc to allow programmer define how animations should be blended together.
- Higher levels will allow to have easy controll over complex animation proceses with few lines of code.
this point will be expanded later.
Some of the artifices/www pages that are a source of inspiration for the project. Good introduction.
- mechwarior animation blending system: http://www.gamasutra.com/features/20030704/edsall_pfv.htm. this is a main source of inspiration for my system. describes system of animation blending used in commercial game addresses many pitfalls and gives solutions proven to be useful.
- CCD algorithm description http://number-none.com/product/IK%20with%20Quaternion%20Joint%20Limits/index.html
- Ogre animation blender: http://www.ogre3d.org/wiki/index.php/AnimationBlender. Old simple system that will be replaced and expanded by the lowest pars of my system.
- . proposal + basic interface from tuan kuranes: http://www.ogre3d.org/phpBB2/viewtopic.php?t=28812&postdays=0&postorder=asc&start=50. General idea of what high level user interface could look like.
- articles on IK and procedural controllers for human-like characters:
thesis on procedural - ik interaction:
Some articles that provide ideas of what kind of expansions are possible to the system.
All kinds of procedural vs data driven(artist created) animation interactions are described.
Introduction. Use case.
Ok. how could you use a system like that? i`ll try to make it possible to do that in many ways, according to your needs. there are increasing levels on witch you can use the system. so let`s start from the buttom.
First, imagine you have shooting and walking animations. want to combine them. normally in ogre you can do that, but the effect will not be nice. because in shooting your legs are still, after you blend the animations the poor guy will start to walk slow, like an old men. also the hands may not behave so nice - swinging from walking can be too big...
Second. you have running. you have walking. why not jog? with any given speed between walk and run? sounds easy: just set weights like: 50/50 for something exactly in between, or 10/90 for almost full run. but there is a problem - the run/walk periods are very different. this will cause random behaviour like changing speed, stopping, even walking back.
To deal with the first problem, the system will allow you to define for example that lower body(or any set of joints) will not be taken into consideration in shooting. in fact it can take a neutral position and propose the joints that are not used in the animation as the ones to be weighted with zero.
To solve the other problem we will go step further. we will use a concept of an animation tree.
JOG(speed) WALK RUNthis means that jog is a combination of RUN and WALK animations. speed variable is controlling the process. the animations will be synchronised. if the period of walking is longer, they will be scaled according to the weights of the animations. now you can just tell the system to set the variable to the desired value and... it is done. you can even tell it to go over time from walking to running in let`s say 1.5 second if you want realistic acceleration.
This is some basic "pictorial" explanation. Below Later you will find more technical info on how exacly the system will work and what will it be able to do.
Some other use cases:
...just altering that...
Let us say that we want to have a ninja running, sneaking and fighing a bit.
This is to present how simple variables can be used to alter the behaviour of the character.
so far i use: registerVar, varSetTo, varGoTo methods. i agree they are not nice. will change them as soon as someone proposes in ogre forum: how they want to perform this control alternatively.
We assume that "a" was provided with animations used as a base for blending(running etc).
n is game data representing ninja. holds some variables describing his state.
a.registerVar("speed",n.speed); //we can watch/change external variables to control animation behaviour a.registerVar("IK Parameter 1", x) // x will represent variable used in some IK animations n.speed = 0; //we can now control animation directly through n.speed: ninja starts standing //this is for example purpose. we could also use a.varSetTo("speed", 0); with the same result. a.varSetTo("crouch", 2); //another way of setting variable, we start in full stand ...// lazy ninja just stands around... a.varGoTo("speed", 1); // we can also use "a" to control n.speed. Here "a" takes care of smooth transition from stand to walk //and than plays walking animation in loop. when varGoTo used, change from current value to goal occurs //every frame with a default (if user will not change it) ...//"Stand To Walk" animation is played, than we continue with looped "Walking" ...//ofcourse we should also make sure animation direction and velocity of object are correct, we only focus on animations a.varGoTo("speed", 2); //our ninja accelerates going from walk to run animation smoothly then mainteining runing .....//our ninja sees an enemy who is turned back so... a.varGoTo("crouch", 1); //ninja starts sneaking (still at full running speed!); .....//we are getting close... a.varGoTo("speed", 1) //ninja goes really sneaking (crouch + walk) .....//target in reach... x = target.getPosition(); //we set some variable responsible for ik procedure a.varSetTo("attack phase", 1); // and we tell "a" to start the attack animation //(goes to 0 with default speed, representing animation progress) ...... //ninja preforms attack sequance WHILE walking and WHILE sneaking, target is silenced a.varGoTo("croach", 2); // no need to hide any more a.varGoTo("speed", 2); // ninja runs once again ..... x = weapon.getPosition(); a.varSetTo("grab", 1); //ninja sees nicer sword, and grabs it in full run .... a.varSetTo("small hit", 1); // but... takes a hit from a small gun while grabing and runnung. ouch. a.varSetTo("damaged", 1); // from now on his motion is going to be a bit less cat-like .... //ninja runs for the guy with the gun a.varSetTo("dodge", 1); //a bit of matrix-like bullet avoiding ... x = target.getPosition(); a.varSetTo("attack", 1); // attack the guy not waiting for the dodge to finish... ... a.varSetTo("big hit", 1); // but unfortunately there was another guy with a shootgun that ninja just did not notice ... a.varSetTo("attack", 0); //ninja does not feel like continuing the attack a.varGoTo("speed", 0); //also the missing head is to much to run, he stops smoothly a.varGoTo("croach", 0); //and takes his time to rest ... a.varGoTo("die", 1); //....forever
Again. This is just to illustrate the type of operations one can expect from this level of the system. I`m preety sure specific
classes/methods, default variable names etc will change.
Will come... hopefully after some nice interaction/ideas from community.
System basic structure(more technical stuff...)
Core blending system itself:
remarks for entire system
- low level flat list animation blending(elimination of low weighted animations) - middle level graph structure(heart of the system): leafs = animations, nodes = blend controllers or procedural operators - high level: *play("x") using lower levels for all the dirt work, *logical animation states, possible transitions for character - some animation assumptions: *some animations will have to be synchronized(egz. "walk" and "run" both start with the same leg in front and have one full walk cycle) *if we decide to process character`s velocity in this system we assume that animations(and procedural controllers) return velocities for further calculations
some info on low level "flat" blender
-extension of ogre animation blender -cheap animation blending(at least i hope so:)), because of skeleton level approach -flat list for blending created from middle level graph -flat list only refreshed when weights change(and only in a sub tree where the change appeared) -when procedural controllers are used as internal nodes, for each a flat blend has to be locally applied to children animations
basic features and structure description of middle level graph
- blending multiple skeletal animations - allowing to blend IK and other user defined procedural skeletal animations - easy, intuitive high level access to blending parameters, including: *automatic blending transition between given animations with defined time/runDegree, both cyclic and single shoot animations *external variable monitoring as blending control (egz. runDegree controls stand/walk/run blends) *support for using artist animations as transitions(egz. "walk to run", "crouch to lay" will not be effects of a blend) - underneath: hierarchical animation tree holding animation priorities, blending weights and logical structure
DETAILS ON TREE STRUCTURE AND BLENDING CONTROLLERS(INNER TREE NODES)
- named blending controllers(inner tree nodes) *allow high level controlled automatic weight transitions(egz go smooth from "run" after user calls "walk" animation) *internal nodes map input parameters into children animation weights (hold animation weight distribution in control parameter space) *different blending weight control types: -direct input parameters(observe external variables to adjust blend weight) -indirect, binary like - controller gets order to go to bound state using defined transition speed to produce smooth result, use tree managed variable to keep transition progress -indirect, with special animation for transition(when starting to walk from stand, walk+stand blend could produce awkward solution) -inner nodes do not care about the type of control: tree menages variables for binary controllers allow uniform interface *faze synchronisation of blended animations -faze synchronization is required for blending animations of the same nature(egz. walk + run) to achive appropriate "between" animations (we cannot blend them when one is startin and the other is in the middle of cycle) -synchronized animations monitor external variable that sets their faze instead of perform time based updates -tree variable management *used for controlling automatic transitions between requred states and *used for synchronizing animation fazes(instead of using local animation faze control) *other purposes? *monitored by the control nodes like external variables *altered by user requests and time update in a way dependent on the variable type *will require some logic to determine behaviours egz. cyclic for walkFaze var, single transition for walk to run control *decide interface for higher levels, i think tree should make no logical decisions about how to react on play("x") when currently running, how when standing), this should be left to higher level layers *do we send notification about finalisation of transition to higher levels so they know that some state is reached? - procedural(egz. IK) animation controllers as internal nodes *if they are not leafs they require separate flat list blend, to produce input start pose for procedural altering *if char. velocity is determined in the tree, procedural controllers have to return it also *will be implemented: -CCD (see below(in the future:)) for details) -abstract interfaces for other, user defined controllers - configurable default settings on appropriate levels all over the system, example: *animation(=managed variable) transition runDegree *play type for animation - cyclic or single *default tree for humanoid(others can be created, used, reused and modified for special needs),
EXAMPLE ANIMATION TREE
LEGEND: y(x) - animation y monitors x variable as a parameter xTRANS - control node plays Transition animations(named T01, T10) to go between extremes, instead of blending border animation 0/1 x - indicates that x animation is a border animation either for 0 or 1 parameter value for the father node T01/T10 x - x is an artist created Transition animation used by the father node to go between border animations xIK - x animation uses IK to modify skeleton according to external variables(steepens of terrain or direction of walk), could be simulated by blending extreme states: Walk(X,Y) = X*WalkUp + Y*WalkRight + Walk*(2-X-Y) but more work for artist + not that good result? xPart - partial animation only modifies certain bones. Remark: sons of a node represent animations whitch weights are controled by father. leafs are artist created animations. 0 and 1 in the picture just mean "border animation" not actual value of a parameter for witch this border is achieved in a particular node. FullMotion Hit(CroachDegree) LieHit(hitSize) SmallLieHit BigLieHit StandHit(hitSize) SmallStandHit BigStandHit DamagedMotion(damageDegree) Damage(croachDegree) WalkDamaged(walkFaze) <-------holds damage motion features sheared for all walk like animations CrawlDamaged(walkFaze) <-----------------"""""----------------- but lie down Motion(croachlDegree) 0 LieMotion(runDegree) Crawl/Roll(direction, steepnes, walkFaze) Lie (steepnes) T01 LieToCroach T10 CroachToLie 1 StandMotion(startWalkDegree) 0 StandCtrl(croachDegree) 0 Stand 1 Croach T01 StandToWalk(croachDegree) 0 StandToWalkIK(steapness, direction) 1 CroachToSneakIK(steapness, direction) T10 WalkToStand(croachDegree) WalkToStandIK(steapness, direction) SneakToCroachIK(steapness, direction) 1 WalkCtrl(croachDegree) 0 Jog(runDegree) WalkIK(steapness, direction, walkFaze) RunIK(steapness, direction, walkFaze) 1 Sneak(runDegree) SneakIK(steapness, direction, walkFaze) SneakRunIK(steapness, direction, walkFaze)(perhaps this is not needed, just RunIK for running efects?) external/tree menaged variables: croachDegree - single transition. controlls transition between croach and stand, walk/run and sneek. When it is menaged it represents a system where character either stands or croaches and tree just provides transition, if it is an external variable all kinds of behaviours are posible(all staten between sneak and walk, etc.) programmer would be responsible for variable control, tree would provide blending acordingly. This example goes also for other variables like runDegree (walk/run just transition or all states between possible?) etc. Example scale: 0 - lie down, 0.5 - croach, 1 stand runDegree - single transition. stand/walkrun controll. startWalkDegree - single transition. starting and stoping walking. walkFaze - cyclic. synchronization of walk like animations steapness - external. angle of terrian direction - external. front, back, left, right?. damageDegree - external. 0 - not wounded, 1 - maximal damage hitSize - static, zero after hit animation finished. 0 - no hit right now, 0.5 - small hit, 1 big hit
When smome simple interpretations(changing parameter values) for animation calls would be provided,
adressing that tree by calls like: play("run") (makes runDegree goes to 1 with default speed), play("croach"/"lie")
(croachDegree goes to 0.5/1.0) or by changing monitored variables, user could quite easily controll the animation.
Still because much care has to be taken when creating tree to avoid strange situations like go from lie to jump, and for
ease of definition of how play("x") influences tree depending on current animation state, we will provide another abstraction
layer for state and transition based definition of character`s legal animation blendings.
This could also provide easy, powerful tool to modify not only the parameters but also tree structure without going into rather
complicated manual tree constructing.
high level controll system
This will be some kind of graph representing legal character states, transitions between them and actions modifying blending tree
when a state in entered or transition is made.
CCD and other algorithms.
AnimationPhisics - IK interaction