View
218
Download
0
Embed Size (px)
Citation preview
3
Brief History of Animation
Shadow Puppets
Persistence of Vision
Flipbook
Thaumotrope
Phenakistiscope
Zoetrope
4
Muybridge
Eadweard Muybridge
Settled bet for Leland Stanford:
Is there a point when all four of a horse's hooves are off the ground?
7
Disney’s 12 Principles of Animation1. Squash and stretch
2. Anticipation
3. Staging
4. Straight Ahead Action and Pose to Pose
5. Follow through and overlapping action
6. Slow In and Slow Out
7. Arcs
8. Secondary Action
9. Timing
10.Exaggeration
11.Solid Drawing
12.Appeal
http://www.youtube.com/watch?NR=1&v=xqGL1ZLk3n8
8
Squash and stretch
Exaggerate deformation for comedic effect.
However, the volume should remain fixed.
11
Follow through
Each action leads to the next
Audience needs to see the resolution
50 seconds in
http://www.youtube.com/watch?v=5V-QsiPiN_k
12
Slow In and Out
Bouncing Ballhttp://www.siggraph.org/education/materials/HyperGraph/animation/
character_animation/principles/bouncing_ball_example_of_slow_in_out.htm
13
Secondary Motion
A secondary action caused by the primary action
Increases interest, if it does not detract from primary
14
Flour Sack
Can we use these simple ideas to inject personality?
Common challenge: animate a half filled flour sack
http://www.youtube.com/watch?v=FbG3UCY-9Xw
15
Traditional Animation ProcessStoryboard
Sequence of drawings with descriptions
Story-based description
Voice recording
Match animation to draft soundtrack
Final soundtrack with music and sound effects done last
Key frames
Draw key frames as line drawings
Fill in the intermediate images (Inbetweens)
Painting
Paint the drawings
17
Key Frames(Keyframes) – draw key poses in a sequence
Often a way of splitting up work: senior artist draws keyframees
Novice draws the transitions - inbetweening
18
Putting it all together
Which effects you can recognize in Pixar's Luxo Jr?
Graphical effects
Taditional animation effects
How does Lasseter convey personality? Emotions?
How does he direct your attention?
http://www.youtube.com/watch?v=PvCWPZfK8pI
19
Kinematics
Given a description of a system, describe how it moves
Interested in positions of each component, not in the speed
20
KinematicsKinematics
Considers only motion given the disposition
Dynamics
Considers underlying forces
Compute motion from initial conditions and physics
Easy to do with particles
21
Particle SystemsThe genesis effect, from the Wrath of Kahn
http://www.youtube.com/watch?v=NM1r37zIBOQ
22
Sample Point system
We often use differential equations to model behavior
Our particles are corks bobbing in sea currents
Differential equations define a vector field
Our goal is to follow the path of a cork
23
Evaluating path
The program pointDiffyQ.c
compares two ways to follow paths
Euler method - yellow
Trapezoid method – blue
The point this visualization tries to make is that the additional work for the trapazoid method gives a much more stable solution
Higher order methods, such as Runge-Kutta, are not much more work, but are much more stable
24
Animation/* One step of the animation */
void tic()
{ ...
updatePoint(euler[i], deltaT);
}
/* The timer has rung: update the animation */
static void timerCallback (int value)
{
tic();
glutTimerFunc (value, timerCallback, value);
}
int main(int argc, char** argv)
{ ...
glutTimerFunc (100, timerCallback, 50);
glutMainLoop();
...
}
25
Fountain of points
/* One step of the animation */
void tic()
{
static int count = 0;
if (count < 2*NUM_BALLS)
{
if (count % 2) {
euler[count/2] = malloc(sizeof(struct point));
initPoint(euler[count/2]);
}
else {
rk[count/2] = malloc(sizeof(struct point));
initPoint(rk[count/2]);
}
count++;
}
26
Euler Update
/* dx/dt: how x will change this step */
double xprime(double x, double y)
{
return (cy - y);
}
/* dy/dt: how y will change this step */
double yprime(double x, double y)
{
return (x - cx);
}
/* Use the slope at (x, y) to predict the next step */
/* This is simple, but not very good */
void eulerUpdate(double x, double y, double *newx, double *newy, double deltaT)
{
*newx = x + deltaT*xprime(x, y);
*newy = y + deltaT*yprime(x, y);
}
27
Trapezoid Update
double xprime(double x, double y);
double yprime(double x, double y);
/* Average slope at (x, y)
* and the slope at the endpoint Euler would predict */
/* This is better than simple Euler */
void trapUpdate(double x, double y, double *newx, double *newy, double deltaT)
{
double approxX = x + deltaT*xprime(x, y);
double approxY = y + deltaT*yprime(x, y);
*newx = x + deltaT*(xprime(x, y) + xprime(approxX, approxY))/2.0;
*newy = y + deltaT*(yprime(x, y) + yprime(approxX, approxY))/2.0;
}
28
Hierarchical Modeling
System needs to be complex to capture realistic movement
You have over two dozen bones in each foot
We will settle for less
What is focus for figure running?
Core
Foot on the ground
Look at a very small example
Bicep and forearm
Forward Kinematics
This simple system is described by two angles
Position is given by
Length of arms a1 and a2
Angles θ1 and θ2
We can compute O1, O2
This is Forward Kinematics
2
1
a1
a2
O2
O1
O0
x1
x0
x2
y1
y2
y0
Forward Kinematics
€
O1 = (a1 cosθ1,a1 sinθ1)
O2 = O1 +(a2 cos(θ1 +θ2 ),a2 sin(θ1 +θ2 ))
(x, y) = (a1 cosθ1 +(a2 cos(θ1 +θ2 ),a1 sinθ1 + a2 sin(θ1 +θ2 ))
31
Inverse KinematicsGiven a complex system, figure out how to
make it reach an object
Typically we position a tool
Pen for writing
Soldering Gun
Tongue for eating snowflakes
Description is a vector of joint angles
Or a sequence of such vectors
Jeff Lew
Motion Capture
One way to solve the problem of kinematics
Record motion from instrumented live actor
Tom Hanks in Polar Express
Work Space vs. Configuration Space
Work spaceObject space: 3D for our Burning ManDimensionality:
R3 for most thingsR2 for our extended linkage example
Configuration spaceThe space of possible object configurations
Often much higher dimension than work spaceDegrees of Freedom
The number of parameters that necessary and sufficient to define position in configuration
Return to our Example
Work space: 2D WasherConfiguration Space: 2D Torus (2π == 0)
Ambiguity in the middle: two ways to reach a positionElbow up or down?
Singularities at the boundaries of Work Space
Puma Robot
Degrees of Freedom?
Base
Shoulder
Elbow
Wrist
Work space
http://www.youtube.com/watch?v=kzddvCo3RNshttp://www.youtube.com/watch v=kEed8DVO21I
Solving Inverse Kinematics
Given end effector position, compute required joint angles
In simple case, analytic solution exists
Use trig, geometry, and algebra to solve
In larger examples, need to use Numerical Methods
Why is the problem hard?
Solutions may not exist
Might not be unique
In our case, solution is simple
Compute distance from tip to tail
Position second arm for distance,
First arm to position it
2
1
a1
a2
O2
O1
O0
x1
x0
x2
y1
y2
y0
(x,y)
2
22
221
22
22222
211
2
222
21
22
22222
21
22
21
2221
22
21
222122
21
22
21
22
2
22122
21
22
tan2
2
2
cos1
cos1
2tan
accuracygreater for
2cos
)cos(2
aayx
yxaa
aayx
yxaa
aayxaa
aayxaa
aa
aayx
aaaayx
Twin solutions: elbow up or down
Iterative Solutions
Frequently it is not possible to find a closed form One technique is to use the multi-dimensional derivativeThe Jacobian is the the derivative relative to each input
If y is function of three inputs and one output
33
22
11
321 ),,(
xx
fx
x
fx
x
fy
xxxfy
Compute JacobianIn our case, Jacobian is a square matrix since dimension
of configuration space = dimension of the work space
Not true for 3 segment planar linkage, or the Puma
To move towards a goal, invert the Jacobian and use that as directive on where to start to move
Make small change, recompute Jacobian, and try again
Jacobian
The Jacobian tells us how the output changes as we change the input
We know current position of the effector, and know where we want it
The difference is Delta Y (Y dot)
We want to find Delta X (X dot) that gets us there
Invert the Jacobian and solve for Delta X
XXJY )(
Invert Jacobian
We can invert non-singular square matrices
There is also a pseudo inverse that can be used if the matrix is not square
Inverting a 2x2 matrix is especially easy
Jacobian is non-singular when we can divide by (ad-bc)
€
a b
c d
⎛
⎝ ⎜
⎞
⎠ ⎟
1
(ad −bc)
d −b
−c a
⎛
⎝ ⎜
⎞
⎠ ⎟
⎛
⎝ ⎜
⎞
⎠ ⎟=
1
(ad −bc)
ad −bc ab − ab
dc − dc ad −bc
⎛
⎝ ⎜
⎞
⎠ ⎟=
1 0
0 1
⎛
⎝ ⎜
⎞
⎠ ⎟
Compute Jacobian
€
(x, y) = (a1 cosθ1 +(a2 cos(θ1 +θ2 ),a1 sinθ1 + a2 sin(θ1 +θ2 ))
€
∂x
∂θ1
∂x
∂θ2
∂y
∂θ1
∂y
∂θ2
⎛
⎝
⎜ ⎜ ⎜ ⎜
⎞
⎠
⎟ ⎟ ⎟ ⎟=
a1 sinθ1 + a2 sin(θ1 +θ2 ) a2 sin(θ1 +θ2 )
−a1 cosθ1 − a2 cos(θ1 +θ2 ) −a2 cos(θ1 +θ2 )
⎛
⎝ ⎜
⎞
⎠ ⎟
SingularitiesConsider the case when the angles are both 0
Linkage lies on x axis
Assume we wish to move endpoint towards origin
Small changes in either angle move us in y direction
Happens whenever linkage touches rim of workspace:
when θ2 = 0 or π Below, we have used θ2 = 0
Determinate is 0: cannot invert
Solution – Jiggle the linkage and try again
€
∂x
∂θ1
∂x
∂θ2
∂y
∂θ1
∂y
∂θ2
⎛
⎝
⎜ ⎜ ⎜ ⎜
⎞
⎠
⎟ ⎟ ⎟ ⎟=
a1 sinθ1 + a2 sinθ1 a2 sinθ1
−a1 cosθ1 − a2 cosθ1 −a2 cosθ1
⎛
⎝ ⎜
⎞
⎠ ⎟=
(a1 + a2 )sinθ1 a2 sinθ1
−(a1 + a2 )cosθ1 −a2 cosθ1
⎛
⎝ ⎜
⎞
⎠ ⎟
46 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Hierarchical Models
Examine the limitations of linear modeling
Symbols and instances
Introduce hierarchical models
Articulated models
Robots
Introduce Tree and DAG models
47 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Instance Transformation
Start with a prototype object (a symbol)
Each appearance of the object in the model is an instance
Must scale, orient, position
Defines instance transformation
48 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Symbol-Instance Table
Can store a model by assigning a number to each symbol and storing the parameters for the instance transformation
49 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Relationships in Car Model
Symbol-instance table does not show relationships between parts of model
Consider model of carChassis + 4 identical wheelsTwo symbols
Rate of forward motion determined by rotational speed of wheels
50 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Structure Through Function Calls
car(speed){ chassis() wheel(right_front); wheel(left_front); wheel(right_rear); wheel(left_rear);}
Fails to show relationships wellLook at problem using a graph
51 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Tree
Graph in which each node (except the root) has exactly one parent node
May have multiple children
Leaf or terminal node: no children
root node
leaf node
53 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Robot Arm
robot armparts in their own coodinate systems
54 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Articulated Models
Robot arm is an example of an articulated model
Parts connected at joints
Can specify state of model by
giving all joint angles
55 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Relationships in Robot Arm
Base rotates independentlySingle angle determines position
Lower arm attached to baseIts position depends on rotation of baseMust also translate relative to base and rotate about
connecting jointUpper arm attached to lower arm
Its position depends on both base and lower armMust translate relative to lower arm and rotate about joint
connecting to lower arm
56 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Required MatricesRotation of base: Rb
Apply M = Rb to base
Translate lower arm relative to base: Tlu
Rotate lower arm around joint: Rlu
Apply M = Rb Tlu Rlu to lower arm
Translate upper arm relative to upper arm: Tuu
Rotate upper arm around joint: Ruu
Apply M = Rb Tlu Rlu Tuu Ruu to upper arm
57 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
OpenGL Code for Robot
robot_arm(){ glRotate(theta, 0.0, 1.0, 0.0); base(); glTranslate(0.0, h1, 0.0); glRotate(phi, 0.0, 1.0, 0.0); lower_arm(); glTranslate(0.0, h2, 0.0); glRotate(psi, 0.0, 1.0, 0.0); upper_arm();}
58 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Tree Model of Robot
Note code shows relationships between parts of model
Can change “look” of parts easily without altering relationships
Simple example of tree model
Want a general node structure for nodes
59 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Possible Node StructureCode for drawing part orpointer to drawing function
linked list of pointers to children
matrix relating node to parent
60 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Generalizations
Need to deal with multiple children
How do we represent a more general tree?
How do we traverse such a data structure?
Animation
How to use dynamically?
Can we create and delete nodes during execution?
61 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Objectives
Build a tree-structured model of a humanoid figure
Examine various traversal strategies
Build a generalized tree-model structure that is independent of the particular model
63 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Building the Model
Can build a simple implementation using quadrics: ellipsoids and cylinders
Access parts through functions
torso()
left_upper_arm()
Matrices describe position of node with respect to its parent
Mlla positions left lower leg with respect to left upper arm
65 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Display and Traversal
The position of the figure is determined by 11 joint angles (two for the head and one for each other part)
Display of the tree requires a graph traversal
Visit each node once
Display function at each node that describes the part associated with the node, applying the correct transformation matrix for position and orientation
66 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Transformation Matrices
There are 10 relevant matrices
M positions and orients entire figure through the torso which is the root node
Mh positions head with respect to torso
Mlua, Mrua, Mlul, Mrul position arms and legs with respect to torso
Mlla, Mrla, Mlll, Mrll position lower parts of limbs with respect to corresponding upper limbs
67 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Stack-based Traversal
Set model-view matrix to M and draw torso
Set model-view matrix to MMh and draw head
For left-upper arm need MMlua and so on
Rather than recomputing MMlua from scratch or using an inverse matrix, we can use the matrix stack to store M and other matrices as we traverse the tree
68 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Traversal Code
figure() { glPushMatrix() torso(); glRotate3f(…); head(); glPopMatrix(); glPushMatrix(); glTranslate3f(…); glRotate3f(…); left_upper_arm(); glPopMatrix(); glPushMatrix();
save present model-view matrix
update model-view matrix for head
recover original model-view matrix
save it again
update model-view matrix for left upper arm
recover and save original model-view matrix again
rest of code
69 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Analysis
The code describes a particular tree and a particular traversal strategy
Can we develop a more general approach?
Note that the sample code does not include state changes, such as changes to colors
May also want to use glPushAttrib and glPopAttrib to protect against unexpected state changes affecting later parts of the code
70 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
General Tree Data Structure
Need a data structure to represent tree and an algorithm to traverse the tree
We will use a left-child right sibling structure
Uses linked lists
Each node in data structure is two pointers
Left: next node
Right: linked list of children
72 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Sibling Tree
I cannot make sense of Angel's drawingHere is my version of this treeLeft pointer is to first childRight pointer is to siblingNode contents are not shown
73 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Tree node Structure
At each node we need to store
Pointer to sibling
Pointer to child
Pointer to a function that draws the object represented by the node
Homogeneous coordinate matrix to multiply on the right of the current model-view matrix
Represents changes going from parent to node
In OpenGL this matrix is a 1D array storing matrix by columns
74 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
C Definition of treenode
typedef struct treenode
{
GLfloat m[16];
void (*f)();
struct treenode *sibling;
struct treenode *child;
} treenode;
75 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Defining the torso nodetreenode torso_node, head_node, lua_node, … ; /* use OpenGL functions to form matrix */glLoadIdentity();glRotatef(theta[0], 0.0, 1.0, 0.0); /* move model-view matrix to m */glGetFloatv(GL_MODELVIEW_MATRIX, torso_node.m)
torso_node.f = torso; /* torso() draws torso */Torso_node.sibling = NULL;Torso_node.child = &head_node;
76 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Notes
The position of figure is determined by 11 joint angles stored in theta[11]
Animate by changing the angles and redisplaying
We form the required matrices using glRotate and glTranslate
More efficient than software
Because the matrix is formed in model-view matrix, we may want to first push original model-view matrix on matrix stack
Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Preorder Traversal
void traverse(treenode *root){ if(root == NULL) return; glPushMatrix(); glMultMatrix(root->m); root->f(); if(root->child != NULL) traverse(root->child); glPopMatrix(); if(root->sibling != NULL) traverse(root->sibling);}
78 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Notes
We must save model-view matrix before multiplying it by node matrix Updated matrix applies to children of node but not to siblings which
contain their own matricesThe traversal program applies to any left-child right-sibling tree
The particular tree is encoded in the definition of the individual nodesThe order of traversal matters because of possible state changes in the
functions
79 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Dynamic Trees
If we use pointers, the structure can be dynamic
typedef treenode *tree_ptr;
tree_ptr torso_ptr;
torso_ptr = malloc(sizeof(treenode));
Definition of nodes and traversal are essentially the same as before but we can add and delete nodes during execution
80
Keyframes
To reduce the work of animating, define key frames
Two dimensional array: time vs angle
Each column has all the angles for one pose
Interpolate between key frames
Metadata might include
Time, so poses are not at fixed intervals
As above
Movement between poses – linear? Slow in, out?
T = 0 1.5 2 3
θ1= 45 90 45 90
θ2= 0 15 30 45
θ3= 180 175 200 120
Parts
/* Define the three parts */
/* Note use of push/pop to return modelview matrix
to its state before functions were entered and use
rotation, translation, and scaling to create instances
of symbols (cube and cylinder */
void base()
{
mat4 instance = ( Translate( 0.0, 0.5 * BASE_HEIGHT, 0.0 ) *
Scale( BASE_WIDTH, BASE_HEIGHT, BASE_WIDTH ) );
glUniformMatrix4fv( ModelView, 1, GL_TRUE, model_view * instance );
glDrawArrays( GL_TRIANGLES, 0, NumVertices );
}
82
Partsvoid upper_arm()
{
mat4 instance = ( Translate( 0.0, 0.5 * UPPER_ARM_HEIGHT, 0.0 ) *
Scale( UPPER_ARM_WIDTH, UPPER_ARM_HEIGHT, UPPER_ARM_WIDTH ) );
glUniformMatrix4fv( ModelView, 1, GL_TRUE, model_view * instance );
glDrawArrays( GL_TRIANGLES, 0, NumVertices );
}
void lower_arm()
{
mat4 instance = ( Translate( 0.0, 0.5 * LOWER_ARM_HEIGHT, 0.0 ) *
Scale( LOWER_ARM_WIDTH, LOWER_ARM_HEIGHT, LOWER_ARM_WIDTH ) );
glUniformMatrix4fv( ModelView, 1, GL_TRUE, model_view * instance );
glDrawArrays( GL_TRIANGLES, 0, NumVertices );
}
83
display()void
display( void )
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
// Accumulate ModelView Matrix as we traverse the tree
model_view = RotateY(Theta[Base] );
base();
model_view *= ( Translate(0.0, BASE_HEIGHT, 0.0) * RotateZ(Theta[LowerArm]) );
lower_arm();
model_view *= ( Translate(0.0, LOWER_ARM_HEIGHT, 0.0) *
RotateZ(Theta[UpperArm]) );
upper_arm();
glutSwapBuffers();
}
84
mouse()void mouse( int button, int state, int x, int y )
{
if ( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN ) {
// Incrase the joint angle
Theta[Axis] += 5.0;
if ( Theta[Axis] > 360.0 ) { Theta[Axis] -= 360.0; }
}
if ( button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN ) {
// Decrase the joint angle
Theta[Axis] -= 5.0;
if ( Theta[Axis] < 0.0 ) { Theta[Axis] += 360.0; }
}
glutPostRedisplay();
}
85
main()int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
glutInitWindowSize( 512, 512 );
glutCreateWindow( "robot" );
init();
glutDisplayFunc( display );
glutReshapeFunc( reshape );
glutKeyboardFunc( keyboard );
glutMouseFunc( mouse );
86
main() (cont)int main( int argc, char **argv )
{
...
glutCreateMenu( menu );
// Set the menu values to the relevant rotation axis values (or Quit)
glutAddMenuEntry( "base", Base );
glutAddMenuEntry( "lower arm", LowerArm );
glutAddMenuEntry( "upper arm", UpperArm );
glutAddMenuEntry( "quit", Quit );
glutAttachMenu( GLUT_MIDDLE_BUTTON );
glutMainLoop();
return 0;
}
87
init()void init( void )
{
colorcube();
// Create a vertex array object
GLuint vao;
glGenVertexArraysAPPLE( 1, &vao );
glBindVertexArrayAPPLE( vao );
// Create and initialize a buffer object
GLuint buffer;
glGenBuffers( 1, &buffer );
glBindBuffer( GL_ARRAY_BUFFER, buffer );
glBufferData( GL_ARRAY_BUFFER, sizeof(points) + sizeof(colors),
NULL, GL_DYNAMIC_DRAW );
glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof(points), points );
glBufferSubData( GL_ARRAY_BUFFER, sizeof(points), sizeof(colors), colors );
88
init() (cont)// Load shaders and use the resulting shader program
GLuint program = InitShader( "vshader81.glsl", "fshader81.glsl" );
glUseProgram( program );
GLuint vPosition = glGetAttribLocation( program, "vPosition" );
glEnableVertexAttribArray( vPosition );
glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, 0,
BUFFER_OFFSET(0) );
GLuint vColor = glGetAttribLocation( program, "vColor" );
glEnableVertexAttribArray( vColor );
glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0,
BUFFER_OFFSET(sizeof(points)) );
ModelView = glGetUniformLocation( program, "ModelView" );
Projection = glGetUniformLocation( program, "Projection" );
glEnable( GL_DEPTH );
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glClearColor( 1.0, 1.0, 1.0, 1.0 );
}
89
Robotclass MatrixStack {
int _index;
int _size;
mat4* _matrices;
public:
MatrixStack( int numMatrices = 32 ):_index(0), _size(numMatrices)
{ _matrices = new mat4[numMatrices]; }
~MatrixStack() { delete[]_matrices; }
void push( const mat4& m ) {
assert( _index + 1 < _size );
_matrices[_index++] = m;
}
mat4& pop( void ) {
assert( _index - 1 >= 0 );
_index--;
return _matrices[_index];
}
};
90
Body Parts
#define TORSO_HEIGHT 5.0
#define TORSO_WIDTH 1.0
#define UPPER_ARM_HEIGHT 3.0
#define LOWER_ARM_HEIGHT 2.0
#define UPPER_LEG_WIDTH 0.5
#define LOWER_LEG_WIDTH 0.5
#define LOWER_LEG_HEIGHT 2.0
#define UPPER_LEG_HEIGHT 3.0
#define UPPER_LEG_WIDTH 0.5
#define UPPER_ARM_WIDTH 0.5
#define LOWER_ARM_WIDTH 0.5
#define HEAD_HEIGHT 1.5
#define HEAD_WIDTH 1.0
91 http://www.fleshmap.com/listen/music.html
Matrix Stack
// Set up menu item indices, which we can also use with the joint angles
enum {
Torso,
Head1,
Head2,
RightUpperArm,
RightLowerArm,
LeftUpperArm,
LeftLowerArm,
RightUpperLeg,
RightLowerLeg,
LeftUpperLeg,
LeftLowerLeg,
NumJointAngles,
Quit
};
92
Matrix Stack
// Joint angles with initial values
GLfloat
theta[NumJointAngles] = {
0.0, // Torso
0.0, // Head1
0.0, // Head2
0.0, // RightUpperArm
0.0, // RightLowerArm
0.0, // LeftUpperArm
0.0, // LeftLowerArm
180.0, // RightUpperLeg
0.0, // RightLowerLeg
180.0, // LeftUpperLeg
0.0 // LeftLowerLeg
};
93
Torso
void torso()
{
mvstack.push( model_view );
mat4 instance = ( Translate( 0.0, 0.5 * TORSO_HEIGHT, 0.0 ) *
Scale( TORSO_WIDTH, TORSO_HEIGHT, TORSO_WIDTH ) );
glUniformMatrix4fv( ModelView, 1, GL_TRUE, model_view * instance );
glDrawArrays( GL_TRIANGLES, 0, NumVertices );
model_view = mvstack.pop();
}
94
Head,
void head()
{
mat4 instance = (Translate( 0.0, 0.5 * HEAD_HEIGHT, 0.0 ) *
Scale( HEAD_WIDTH, HEAD_HEIGHT, HEAD_WIDTH ) );
glUniformMatrix4fv( ModelView, 1, GL_TRUE, model_view * instance );
glDrawArrays( GL_TRIANGLES, 0, NumVertices );
}
void left_upper_arm()
{
mat4 instance = (Translate( 0.0, 0.5 * UPPER_ARM_HEIGHT, 0.0 ) *
Scale( UPPER_ARM_WIDTH, UPPER_ARM_HEIGHT, UPPER_ARM_WIDTH ) );
glUniformMatrix4fv( ModelView, 1, GL_TRUE, model_view * instance );
glDrawArrays( GL_TRIANGLES, 0, NumVertices );
}
95
display()
void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
mvstack.push( model_view );
model_view = RotateY( theta[Torso] );
torso();
model_view *= ( Translate( 0.0, TORSO_HEIGHT + 0.5 * HEAD_HEIGHT, 0.0 )
* RotateX( theta[Head1] ) * RotateY( theta[Head2] )
* Translate( 0.0, -0.5 * HEAD_HEIGHT, 0.0 ) );
head();
model_view = mvstack.pop();
...
96
display()
mvstack.push( model_view );
model_view *= ( Translate( -( TORSO_WIDTH + UPPER_ARM_WIDTH ),
0.9 * TORSO_HEIGHT, 0.0 ) * RotateX( theta[LeftUpperArm] ) );
left_upper_arm();
model_view *= ( Translate( 0.0, UPPER_ARM_HEIGHT, 0.0 ) *
RotateX( theta[LeftLowerArm] ) );
left_lower_arm();
model_view = mvstack.pop();
mvstack.push( model_view );
model_view *= ( Translate( TORSO_WIDTH + UPPER_ARM_WIDTH,
0.9 * TORSO_HEIGHT, 0.0 ) * RotateX( theta[RightUpperArm] ) );
right_upper_arm();
...
97
98 Angel: Interactive Computer Graphics 4E © Addison-Wesley
2005
Left-Child Right-Sibling Tree
I cannot make sense of Angel's drawingHere is my version of this treeLeft pointer is to first childRight pointer is to siblingNode contents are not shown
Nodestruct Node {
mat4 transform;
void (*render)( void );
Node* sibling;
Node* child;
Node() :
render(NULL), sibling(NULL), child(NULL) {}
Node( mat4& m, void (*render)( void ), Node* sibling, Node* child ) :
transform(m), render(render), sibling(sibling), child(child) {}
};
Node nodes[NumNodes];
Traversevoid traverse( Node* node )
{
if ( node == NULL ) { return; }
mvstack.push( model_view );
model_view *= node->transform;
node->render();
if ( node->child != NULL) { traverse( node->child ); }
model_view = mvstack.pop();
if ( node->sibling != NULL) { traverse( node->sibling ); }
}
Traversevoid
left_upper_arm()
{
mvstack.push( model_view );
mat4 instance = (Translate( 0.0, 0.5 * UPPER_ARM_HEIGHT, 0.0 ) *
Scale( UPPER_ARM_WIDTH, UPPER_ARM_HEIGHT, UPPER_ARM_WIDTH ) );
glUniformMatrix4fv( ModelView, 1, GL_TRUE, model_view * instance );
glDrawArrays( GL_TRIANGLES, 0, NumVertices );
model_view = mvstack.pop();
}
102
ResourcesMuybridge http://en.wikipedia.org/wiki
http://www.youtube.com/watch?v=Q8X0sHS0g8A
Classic Animation http://www.idleworm.com/how/anm/01b/bball.shtml
http://www.siggraph.org/education/materials/HyperGraph/animation/character_animation/principles/bouncing_ball_example_of_slow_in_out.htm
Ball + Flour sack: http://www.youtube.com/watch?v=FbG3UCY-9Xw
Walk cycle http://www.angryanimator.com/word/2008/11/01/animation-tutorial-2-walk-cycle/
Luxo, Jr http://www.youtube.com/watch?v=PvCWPZfK8pI
Puma Robot http://www.youtube.com/watch?v=kEed8DVO21I
Wall-E Trailer http://www.youtube.com/watch?v=TpDcVDAPAeo
103
Sumary
Review steps
Model
Scripting – how the models will move
Inverse Kinematics, Dynamic Modeling
Inbetweening to thread between steps in the script
Rendering
Image processing – post processing for effects
Animation is a huge industry
Computers are widely used
Goal is to remove the tedium, while preserving room for artistry