|
QSDK 1.1 Documentation |
The sample samples/gamedev/qamview animates a model using a Q animation machine.
QDemo1 and QDemo2 use Q animation machines to animate their creatures. QDemo and QDemo2 include QStudio projects to view and edit the animation machine of their creatures: Jan Seth, Margoss, the Bad Tract and the skrittles. The QDemo2 production guide also explains how the animation machines of its characters were authored.
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| walk1 | walk2 | run1 | run2 | walktorun | lookright | fire |
The purpose of an Animation Machine is to organize and sequence them together on a single timeline so that the end user only has to deal with a simple set of modes, e.g. "run", "walk" rather than with the details of which low-level animation segments to play.
An Animation Machine takes some animated geometry as an input and plays sequences of animation segments on it. It describes various animation cycles and how they interact together, and then lets the user choose one of them. Technically an animation machine is a structure made of:
Animation Machines are authored in QStudio and get stored in QAM files (files with the extension .qam). QAM stands for Q Animation Machine.
QStudio: read here how to view and edit animation machines in QStudio.
An animation machine has a speed. It controls how fast animations are played on the model. The speed is a positive number. It can be zero, in which case the model freezes.
QStudio: read here how to view and edit the speed of an animation machine.
Users may interact with the machine by setting its mode. Modes are names, e.g. walk, run, jump, crouch,... They are chosen by the QAM author. Each mode characterizes one particular animation cycle in order to guide the machine when transiting.
Let's say we have an animated character and we choose two modes: walk and run:
![]() |
![]() |
![]() |
![]() |
![]() |
etc... |
| walk1 | walk2 | walk1 | walk2 | walk1 | |
| walk mode | |||||
![]() |
![]() |
![]() |
![]() |
![]() |
etc... |
| run1 | run2 | run1 | run2 | run1 | |
| run mode | |||||
The walk mode alternates two animation segments showing the character walking. The run mode alternates two animation segments showing the character running. Modes are not necessarily that simple. They may group together any possible sequences of animations. They may not be always cyclic either. The following mode shows the character looking both ways, jumping and then firing. After that, she will probably go back to the walk mode.
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| lookleft | lookright | jump | fire | ||
| long_attack mode | |||||
The machine can only be in one mode at a time A machine describes the modes it accepts and the modes it refuses. Those refused are called failures. Failures are used to resolve conflicts between machines (see delegation). It is up to the author of the Q animation machine to define what are the modes and what are the failures. These are the user interface of the machine, this is how the user interacts with the model through the machine.
One way to look at a Q animation machine is to regard it as a remote control for animated models. You select the channel "walk" and the model animates walking. Then you select the channel "run" and the model smoothly goes from walking to running. You can select any channels you want and the model moves from one to the other, performing the right transition at the right time.
QStudio: read
here how to view
and edit the modes of an animation machine.
QStudio: read
here
how to view and edit the failures of an animation machine.
A state describe an animation sequence and its possible transitions when the mode changes. An animation machine is a set of states. It is in at most one state at a time, it may be in the empty state. In this case, it stops controlling the model and is said to be inactive, i.e. switched off. The machine is active if it is in a valid state.
QStudio: read here how to view and edit the states of an animation machine.
When the machine is in a valid state, it plays its sequence of actions. An action is a simple command that drives the machine.
QStudio: read here how to view and edit the actions of a state.
The most common action usually is playAnimation: it plays an animation segment on the model. In the example above, the walk mode is a succession of playAnimation actions.
![]() |
![]() |
![]() |
![]() |
etc... | |||
| playAnimation walk1 |
playAnimation walk2 |
playAnimation walk1 |
playAnimation walk2 |
||||
| walk mode | |||||||
The playAnimation action takes optional parameters. The speed at which the animation segment is played may be modified. The segment can also be played backwards. Using this feature allows you to quickly define the walkBackwards mode by playing the cycle in reverse.
![]() |
![]() |
![]() |
![]() |
etc... | |||
| playAnimation (reverse) walk1 |
playAnimation (reverse) walk2 |
playAnimation (reverse) walk1 |
playAnimation (reverse) walk2 |
||||
| walkBackwards mode | |||||||
QStudio: read here how to add and edit playAnimation actions.
In the example above, the character walks by alternatively playing two animations on and on. It is not possible to infinitely add playAnimation actions, so we could start defining states and cycle between them. The first states plays walk1 and moves to the second state. The second state plays walk2 and goes back to the first one.
![]() |
![]() |
|
| State WalkState1: playAnimation walk1 changeState WalkState2 |
|
State WalkState2: playAnimation walk2 changeState WalkState1 |
| walk mode | ||
This introduces a new kind of action, changeState, that requests the animation machine to move to another state. It allows factorizing sequences into states which then act as the building bricks of the animation cycle. The extra helper action loop is provided replay a state over and over. It actually is nothing else but the action changeState moving back to the same state. Using the same actions, we can also factorize the run animations.
![]() |
![]() |
|
| State RunState1: playAnimation run1 changeState RunState2 |
|
State RunState2: playAnimation run2 changeState RunState1 |
| run mode | ||
QStudio: read
here
how to add and edit changeState actions.
QStudio: read
here how to
add and edit loop actions.
So far, the examples group the states by mode. This seems to imply modes contain states, but this is abusive and not true. It was presented this way to make the explanation simpler. It actually works the other way round: states contains mode transitions. A state describes what happens for each mode. This is described in terms of actions, exactly like the sequence of the state. The transition is execution when the mode changes or when the state sequence terminates.
Let's illustrate how this works with our examples. The first state of the walk cycle (WalkState1) plays the animation walk1 and then moves to the second state of the cycle. This is fine when walking, but what happens if the user wants to run? The machine should move to the second state of the run cycle rather than the one of the walk cycle. As a consequence, the action changeState should be a transition, not an action in the sequence of the state. Let's rephrase the state. The playAnimation remains the same but we then split the transitions:
![]() |
||||
State
WalkState1:
|
walk |
![]() State WalkState2 |
||
| run |
![]() State RunState2 |
It becomes clear that the states prevail over the modes. States group actions and animation playbacks together and then describe what to do for each mode. If the sequence does not have the same transition when the mode changes (depending on when it changes) then the state is split into two. States are the smallest sequencing units. Using this rule, we can define an animation machine that describes both walking and running.
![]() |
![]() |
|||||
State
WalkState1:
|
walk |
State
WalkState2:
|
||||
| run
|
run
|
|||||
State
RunState2:
|
run |
State
RunState1:
|
||||
![]() |
![]() |
We made sure that right steps are followed by left steps, and vice-versa. This explains why RunState2 follows WalkState1 and why WalkState2 follows RunState1.
QStudio: read here how to view and edit state transitions.
Looking at the state diagram above, you can see how transitions and modes can be added to each state: they get added to the list of transitions and describe what happens when the new mode is chosen and how it affects the currently playing sequence. Let's say we add the new mode jump. If the animation machine stays as it is, the user will not be able to select the new mode in any states. By default, a mode gets refused if it is absent from the list of transitions of a state. We have to describe what happens if we want this mode to be accepted. A major drawback of this approach is that the author dully has to add an extra transition to every single state when a new mode is added. This is not acceptable and this can be solved using the default transition. The state can have a transition which is executed for all modes which are not in the list of modes. This is handy because it allows us to define the most natural transition for each state and this allows us to build flexible animation machines which effortlessly accept new modes.
The standard way to use the default mode is to use it for the implicit natural transition. The state WalkState1 plays the animation segment walk1 so naturally, the follow-up state is WalkState2 that plays walk2. The mode walk is naturally associated with the WalkState1 and WalkState2 states, the mode run with RunState1 and RunState2. We therefore use the default transition for these states.
![]() |
![]() |
|||||
State
WalkState1:
|
default |
State
WalkState2:
|
||||
| run
|
run
|
|||||
State
RunState2:
|
default |
State
RunState1:
|
||||
![]() |
![]() |
This way, rather than describing exactly what happens for each state in every single mode, all we have to do is to describe how states naturally connect together and how cycles relate to one another. In our case, how walking relates to running. We do not have to detail every single transition. We just have to describe the crucial places where a cycle moves to another cycle. When a new mode is added, the machine seamlessly accepts it and we only have to add the new transitions for this modes in the few places it is required.
Each animation machine has one and only start state. The start state is the state where the machine starts from when it becomes active. When omitted, the machine will remain inactive.
Start states are mainly used when importing puppets with animation machines into your application. Puppets are models with animation machines. By default, they start animating from the start state. If one is not defined, they will not automatically start and will require the user to manually switch them on by choosing a state.
QStudio: read here how to view and edit the start state of an animation machine.
So far, transitions are played when at the end of the state sequence. When walking, the animation machine plays the full segment walk1 then the full segment walk2 and so on... Even if the user changes the mode right at the beginning of WalkState2, the transition will not occur until before the segment terminates. The machine is not responsive enough. However transitions are allowed to immediately cut a sequence. The transition can also be performed over a specific duration of time. This is called tweening. If a transition is tweening, any animation segment it queues will be mixed with the currently playing one. In our example, we can mix running and walking segments so that the machine does not wait and goes straight to the relevant cycle when the user changes the mode. If the tweening time is zero, the cut will be sharp and the newly queued segments will immediately play.
QStudio: read here how to view and edit tweening values for transitions.
There may be several transitions for the same mode. In this case, the machine chooses any of them. This allows the user to add some randomness to the cycles. We could have different walking steps and different walking cycles. It is even allowed for the default transition. Multiple transitions are called fidgets.
Transitions can be weighted. The weighted is an integer value that determines how likely the transition is to be chosen among transitions for the same mode. If a transition has a weight of 3, it will be 3 times more likely to be chosen than those with a weight of 1. Transitions have a default weight of 1.
![]() |
![]() |
|||||
State
WalkState1:
|
default |
State
WalkState2:
|
||||
|
|
||||||
State
FastWalkState2:
|
default |
State
FastWalkState1:
|
||||
![]() |
![]() |
QStudio: read here how to view and edit transition weights.
Earlier examples have illustrated animation cycles which loop until the mode changes. This may not always be a desirable case. We may want a mode that triggers a sequence to play once and only once. Let us introduce a new mode: jump. We would like the character to jump once and then go back walking. This is what the changeMode action is for: it changes the mode of the machine. So when the character finishes jumping, the state transition changes the mode back to walk. This way, the jump only occurs once. If changeMode was not there, the character would keep on jumping.
![]() |
![]() |
|||||
State
WalkState1:
|
default |
State
WalkState2:
|
||||
|
jump
|
jump
|
|||||
State
JumpState:
|
||||||
![]() |
||||||
QStudio: read here how to add and edit changeMode actions.
The Event action allows the author to send events back to the user at relevant times. For instance, a user would like to know when the character puts a foot on the floor to produce a footstep sound. The author can add an event action right after having played the segment walk1 and walk2.
![]() |
![]() |
|||||
State
WalkState1:
|
default |
State
WalkState2:
|
Events can be caught by the user when playing the animation machine.
QStudio: read here how to add and edit event actions.
A state may reuse the transitions defined in another state. This mechanism is called inheritance. A state is said to extend another state when it reuses its transitions. It can refine which ones it inherits and which ones it overrides.
Possible transitions will first be looked up in the usual transition set. If a possible transition exists, it will be triggered. Otherwise, the transition will be tried against the transition set of the parent set. The inheritance mechanism allows quick creation of state variations and to define base state behaviors. Note that a state that extends another state only inherits its transitions. It does not inherit its sequence.
To illustrate this, let's say we have two states Idle and Attack each extending the state Base. This state defines a set of generic transitions that may be shared by several states in the machine. For instance, if the machine is in the state Attack and the mode gets set to hit1, then the machine will jump to the state HitReaction1 because the current state extends the base state.
State
Base:
|
||||||
|
|
|
|||||
State
Idle:
|
attack default |
State
Attack:
|
||||
Note that transitions may also be overridden to reflect the local oddities of a state:
State
Attack:
|
QStudio: read here how to extend states.
The user may define their own actions. The effect of these actions is defined by the application code. For instance, an extra action can play a sound so that the author of the animation machine can insert sound sample between animation segments. When adding user-defined actions, the author indicates which type of action it wants by name and can specify any required parameter as a string of characters.
The previous paragraphs have introduced a few actions that can be executed by the states of a machine. Here is an exhaustive list of all the possible actions (the branch and the merge actions are explained later in the advanced delegation paragraph).
| Actions | Effects | Parameters |
| playAnimation | play an animation segment | animation, speed |
| changeState | goes to another state | state |
| loop | replays the current state | |
| changeMode | changes the mode of the machine | mode |
| event | raise an event | event |
| branch | branch a sub-machine | sub-machine, start state, tweening |
| merge | merge a sub-machine back | |
| unknownUserAction | user-defined action | action name, parameters |
Q Animation Machines animate a model. Bindings describe which part of this model they control, usually by defining the bones of a skeleton that get animated, determining which geometry will be affected by the sequences and which will not. Each machine is associated with a binding.
Geometry can be accessed using markup points. Markups are names that can be associated with parts of interest of a model (for instance, an element in a cluster or in an animation bundle such as the head, the right toenail or the left wing). Markups are created at export time, as explained here for 3D Studio Max and here for Alias|Wavefront Maya.
A binding is a collection of markup points (also called bind-points) You pick all the joints you want the animation machine to control. When selecting a markup, you can choose to include all its sub-tree as well (because markup points are points in the geometry, they are organized as a tree hierarchy). A special markup called root represents the entire model and is always available. If you want an animation machine to control the whole model, just select the root as a binding.
Bindings can also be combined. You can add bindings to get the union of several of them. You can subtract bindings too.
Bindings are mainly used when delegating. Delegating is using several machines at the same time to control sub-parts of a model, e.g. one for the head, one for the arms and one for the rest of the body of a character.
QStudio: read
here how to view and
edit bindings.
QStudio: read here
how to view and edit model skeletons.
Bindings are not models. They point to specific joints of a model. An animation machine does not deal with actual points of a physical geometry. It deals with logical places, names chosen by the author that are mapped onto a geometry. Arms, legs, nose, wings and tails. Consequently an animation machine can be reused to animated several geometries which may not have the same skeleton. If your animation geometry animates a body with a head, two wings and a tail, you can use it for an eagle, a sparrow, a pterodactyl or a dragon.
|
Animation |
|
Binding |
maps |
Model: Eagle |
|
maps |
Model: Sparrow | |||
|
maps |
Model: Pterodactyl | |||
|
maps |
Model: Dragon |
Machines may delegate the control of a subpart of their model to a different machine so that the original target can be animated by overlapping timelines. This process is called delegation. Machines that take control of a sub-part of the model are called sub-machines.
So far, our animated characters were doing one thing and only one at any time: walking, running, jumping,... Nevertheless it is perfectly possible to think of mixing two actions together: walking and firing, jumping and clapping. If the two modes influenced two distinct parts of the body, creating two independent machines would suffice. However these actions may interleave and overlap. The entire body of the character may be walking when he suddenly decides to draw his gun and to fire. While firing, the character may still walk around. When this happens, the machine needs to delegate the firing cycle to another machine so that firing and walking can occur independently and simultaneously.
To achieve that goal, animation machines may have machines as children. Sub-machines are inactive by default. They might be activated by using the branch action. This action takes an animation machine as a parameter which specifies which sub-machine will be activated. When the action is executed, nothing happens if the parameter machine is already active. However, if it is not, it gets activated in the state specified by the parent machine with the specified tweening value. If no state is specified, the sub-machine will start in its default start state. You can regard this action as a transition into another animation machine rather than to another state. It can be either the default start state or a specific one. After this happened, the parent machine loses all control of the target of the sub-machine as long as the latter is active. Both machines are running, each controlling their targets.
Sub-machines may then be deactivated by executing the merge action. In this case they lose all control over their target which get controlled back by the parents. The merge action is the symmetric action of branch.
Let's illustrate with a simple example to make these concepts clearer. Let's try to mix walking and firing with our character. So far we had two independent cycles:
![]() |
![]() |
|||||
State
WalkState1:
|
default |
State
WalkState2:
|
||||
| Walking cycle | ||||||
![]() |
||
State
FireState:
|
||
| Firing cycle |
It is possible to joint them but if we do so, in a single animation machine, the character cannot fire and walk at the same time. She either walks or fire.
![]() |
![]() |
|||||
State
WalkState1:
|
default |
State
WalkState2:
|
||||
|
fire
|
fire
|
|||||
State
FireState:
|
||||||
![]() |
||||||
That is why we need to define two animation machines. The main one will be in charge of the entire character body and makes her walk. The sub-machine will take over the arm when firing.
|
|||||||||||||
|
|||||||||||||
|
|||||||||||||
The top main machine controls the whole character by defining root as its binding. It has a single mode walk and cycles between two states. When an extra mode fire is selected, it branches the sub-machine using the branch action. At this point, the sub-machine becomes active and takes over its binding: the arms of the character. It loops the fire animation segment. At this stage, the character is doing two things at the same time: her arms are firing and the rest of the body is walking. The user can then select the mode stopFire to deactivate the sub-machine by calling the action merge. The sub-machine will become inactive again and hand over what it controls to the main machine.
QStudio: read
here
how to view and edit sub-machines.
QStudio: read
here how
to add and edit branch actions.
QStudio: read
here how to
add and edit merge actions.
In a way, the structure above has two active modes at the same time: one for the main body and one for the arms. You may have noted that the mode fire is listed in the transitions of the main machine but it is not listed in its modes. This is allowed. Such modes are called external. Modes listed in the list of modes of an animation machine are called internal, those unlisted but used, external. External modes are actually only used for branching so they do not interfere with the general cycle of the machine. The following paragraph details the difference between internal and external modes.
QStudio: read here to know who external modes are distinguished from internal modes in QStudio.
A mode is internal if and only if it is part of the mode set of the machine (called external otherwise). An active machine can only be in one and only one mode at a time and this mode must be part of the mode set (i.e. internal)
|
in the transition set of the state |
not in the transition set of the state |
|
|
internal mode |
transition happens, |
transition fails |
|
external mode |
transition happens, |
nothing happens |
QStudio: read here to know who external modes are distinguished from internal modes in QStudio.
Failures are modes that are specifically disallowed for an animation machine. Failures are modes refused when the machine which defines them is active. This is useful, when child machines are used. Let's reuse our example with the character who walks and fires and let's introduce a new mode jump. The character can jump only if she does not fire, because the animation segments are not compatible. To forbid jumping while firing, we add the mode jump as a failure of the firing sub-machine. This way, jumping is disallowed when the sub-machine is active, i.e. when the character fires.
QStudio: read here how to view and edit the failures of an animation machine.
The QStudio documentation includes a tutorial on how create an animation machine.
When creating a new Q Animation Machine, the first question you should answer is "what do I want my model to do? Which actions do I want it to perform?". These actions will define the modes of the machine.
Then answer "Which part of the model do I want to animated?". This is the binding. Very often you will animate the whole model. This is the default setting of QStudio.
Once you have entered the binding and the modes of the animation machine, you can start creating states. It may be simpler to start with one mode in mind. For each animation segment you would like to play for this mode, you usually create a state that plays it and you then define the transitions for this mode. Try to use the default transition whenever you can rather than specifying the exact mode. This will make the animation machine more flexible and simpler to extend in the future. Once you have done that, you will have the cycle associated with a given mode.
You have two choices then. Either you start a new cycle for another mode. Or you add transitions associated with other modes to the existing states you created to describe what happens to them when the mode is changed. This way you will incrementally build the whole animation machine.
The last thing to so is to set the start state. Do not forget it, otherwise the animation machine will not start.
In QStudio, you can always go straight into a state or select a mode by pressing the return key when its node is selected.
Q Animation Machines are saved and stored into QAM files (files with the extension .qam).
You can load them into in QStudio and associate them with a model by creating a puppet. Read here how to load them in QStudio. The QDemo2 production guide also illustrate how to view its character animation machines in QStudio.
You can read them in your application from a file or a Q clip. The QDemo2 production guide illustrate how to read it reads its character animation machines from clips.
A C++ integration documentation is available here.
A Puppet combines a model and a Q Animation Machine. As explained here, Q Animation Machines may be re-used for several kinds of models. A puppet links the two by applying the animation machine onto the model.
![]() |
+ |
|
= |
Puppet |
| A model |
A Q Animation |
Puppets are convenient structures to import animated models in your application. They effectively can be regarded as a remote control to animate the geometry of an entity.
QStudio: read
here how to view puppets in QStudio.
QStudio: read
here how to create puppets in QStudio.
|
|
|
Qube Software Limited © 2000-2004
|
|