Computer Graphics Matrix Hierarchies / Animation CO2409 Computer Graphics Week 21
Lecture Contents Model Animation Model/Matrix Hierarchies Limitations of Hierarchies Rendering a Model Hierarchy Matrix Stacks Process
Model Animation So far we have looked at individual models: Each a fixed piece of geometry No moving parts We have animated these models in a way: By moving and rotating them each frame However, now we will focus on manipulating (animating) geometry that is: Made of several rigid parts (this lecture) Flexible with an underlying skeleton (next lecture)
Rigid Body Animation We start with models made up of several rigid parts that can move with respect to each other Mainly mechanical models, such as vehicles, doors, guns, robots… A common assumption for such models is that the parts form a hierarchy A tree structure defining how the parts are connected
Limitations of Hierarchies Most multi-part objects fit naturally into a hierarchical form In particular it’s usually easy to determine a root for the object But consider a bicycle chain – which link is the root? A hierarchical form also assumes that each part has only one parent that directly controls its movement Not true when multiple forces involved Train carriage with two engines Two people carrying a stretcher Need more complex solution for these cases Use a “solver” – part of a physics engine
Matrix Hierarchies In such a hierarchy: Each part has a parent, or is the root of the tree A part can have any number of children (including 0) Each part in the hierarchy has a world matrix Defining its position and orientation - just like a model However, the world matrix for each part is stored relative to its parent So each part is defined in the local space of its parent Root is stored in absolute world space Implies that child parts inherit their parent’s movement
Matrix Hierarchy: Diagram Such hierarchies are sometimes called Matrix Hierarchies or Transform Hierarchies
Building Hierarchies The position of a child’s origin determines where it will pivot relative to its parent The orientation of its axes will determines how it will rotate (in X, Y and Z) So the part’s matrix defines the joint with its parent Must ensure that we build the hierarchies and position matrices correctly To allow required animation Actually this is an issue for the 3D artist to resolve
Rendering Hierarchies We want to render a hierarchy of model parts We need absolute world matrices for each part rather that the parent-relative world matrix that is stored Can simply make the existing rendering code recursive – the code for each part is: Get absolute world matrix by combining this part’s relative matrix with the parent’s absolute world matrix Render part with absolute matrix Repeat process for each child part This process dictates a depth-first traversal of the hierarchy tree structure To pass matrices from parent to child easily (see lab)
Rendering Hierarchies: Matrix Stack Recursion may be inefficient for a real-world app that has many 100s or 1000s of models with many parts A human model may have 50 or 60 parts We can convert this recursive process to an iterative one To help us we use a Matrix Stack To store the matrices for ancestors of the current part DirectX provides such a feature Not difficult to write our own if necessary This is an efficient LIFO structure for pushing and popping matrices
Rendering Hierarchies Efficiently Put parts into a list in depth-first order Done in advance Also store depth in the hierarchy of each part Each part has its parent-relative matrix Call it the local matrix In the example will use M0, M1 etc.
Rendering Hierarchies Efficiently Iterating through the list is now the same as traversing the tree depth-first At each step, will keep track of: Absolute world matrix – call it W Current depth in hierarchy – call it CurrentDepth Initialise the process: Set W = the identity / unit matrix Set CurrentDepth = 0 Start with empty matrix stack
Rendering Hierarchies cont… For each part x in the hierarchy list: Get depth of part x, call it NewDepth If NewDepth > CurrentDepth, push W onto stack If NewDepth = CurrentDepth, do nothing to stack If NewDepth < CurrentDepth, pop matrices from stack Pop (CurrentDepth – NewDepth) times E.g. CurrentDepth = 3, NewDepth = 1, pop stack twice Set W = Matrix at top of stack * Mx Render part x using absolute world matrix W CurrentDepth = NewDepth
Rendering Hierarchies Example Starting with W = identity(I) & CurrentDepth = 0 0. NewDepth = 1 > CurrentDepth: push W (Stack:I) W = Stack Top * M0 = M0: render base with world matrix M0 1. NewDepth = 2 > current: push W (Stack: I, M0) W = Stack Top * M1 = M0.M1: render arm with matrix M0.M1 2. NewDepth = 3 > current: push W (Stack: I, M0, M0.M1) W = Stack Top * M2 = M0.M1.M2: render grip1 w. matrix M0.M1.M2 3. NewDepth = 3 = current: no change (Stack :I, M0, M0.M1) W = Stack Top * M3 = M0.M1.M3: render grip2 w. matrix M0.M1.M3 4. NewDepth = 2 < current: pop stack 1 time (Stack: I, M0) W = Stack Top * M4 = M0.M4: render switch with matrix M0.M4
Rendering Hierarchies Example Looking just at the render steps: Render base with world matrix M0 Render arm with matrix M0.M1 Render grip1 with matrix M0.M1.M2 Render grip2 with matrix M0.M1.M3 Render switch with matrix M0.M4 These are the correct combined matrices The process described is fairly simple to implement More efficient than recursive version