# HG changeset patch # User John Tsiombikas # Date 1386554790 -7200 # Node ID 3c2428cb38f78f2f47a132bb30d1799b95fa9018 # Parent 35b813d504e7bb1ba4e6aff165ed4a09d53c7a40 added the option of lightweight pre-pass top-down recursive calculation of matrices instead of going through the existing lazy thread-specific caching algorithm. diff -r 35b813d504e7 -r 3c2428cb38f7 example/Makefile --- a/example/Makefile Sat Nov 16 12:31:03 2013 +0200 +++ b/example/Makefile Mon Dec 09 04:06:30 2013 +0200 @@ -3,7 +3,7 @@ bin = test CFLAGS = -pedantic -Wall -g -I../src -LDFLAGS = -L.. -lanim -lvmath $(libgl) -lm +LDFLAGS = -L.. -lanim -lvmath $(libgl) -lm -lpthread ifeq ($(shell uname -s), Darwin) libgl = -framework OpenGL -framework GLUT diff -r 35b813d504e7 -r 3c2428cb38f7 example/test.c --- a/example/test.c Sat Nov 16 12:31:03 2013 +0200 +++ b/example/test.c Mon Dec 09 04:06:30 2013 +0200 @@ -184,6 +184,10 @@ glRotatef(cam_phi, 1, 0, 0); glRotatef(cam_theta, 0, 1, 0); + /* first render a character with bottom-up lazy matrix calculation */ + glPushMatrix(); + glTranslatef(-2.5, 0, 0); + for(i=0; imatrix); + + glPushMatrix(); + glMultMatrixf((float*)xform_transp); + + glScalef(parts[i].sz.x, parts[i].sz.y, parts[i].sz.z); + glutSolidCube(1.0); + + glPopMatrix(); + } + glPopMatrix(); glutSwapBuffers(); assert(glGetError() == GL_NO_ERROR); diff -r 35b813d504e7 -r 3c2428cb38f7 src/anim.c --- a/src/anim.c Sat Nov 16 12:31:03 2013 +0200 +++ b/src/anim.c Mon Dec 09 04:06:30 2013 +0200 @@ -381,6 +381,30 @@ m4_inverse(mat, tmp); } +void anm_eval_node(struct anm_node *node, anm_time_t tm) +{ + anm_get_node_matrix(node, node->matrix, tm); +} + +void anm_eval(struct anm_node *node, anm_time_t tm) +{ + struct anm_node *c; + + anm_eval_node(node, tm); + + if(node->parent) { + /* due to post-order traversal, the parent matrix is already evaluated */ + m4_mult(node->matrix, node->parent->matrix, node->matrix); + } + + /* recersively evaluate all children */ + c = node->child; + while(c) { + anm_eval(c, tm); + c = c->next; + } +} + void anm_get_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm) { struct mat_cache *cache = pthread_getspecific(node->cache_key); diff -r 35b813d504e7 -r 3c2428cb38f7 src/anim.h --- a/src/anim.h Sat Nov 16 12:31:03 2013 +0200 +++ b/src/anim.h Mon Dec 09 04:06:30 2013 +0200 @@ -42,6 +42,9 @@ pthread_key_t cache_key; pthread_mutex_t cache_list_lock; + /* matrix calculated by anm_eval functions (no locking, meant as a pre-pass) */ + mat4_t matrix; + struct anm_node *parent; struct anm_node *child; struct anm_node *next; @@ -95,10 +98,24 @@ void anm_set_pivot(struct anm_node *node, vec3_t pivot); vec3_t anm_get_pivot(struct anm_node *node); +/* those return the start and end times of the whole tree */ +anm_time_t anm_get_start_time(struct anm_node *node); +anm_time_t anm_get_end_time(struct anm_node *node); + /* these calculate the matrix and inverse matrix of this node alone */ void anm_get_node_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm); void anm_get_node_inv_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm); +/* ---- top-down matrix calculation interface ---- */ + +/* calculate and set the matrix of this node */ +void anm_eval_node(struct anm_node *node, anm_time_t tm); +/* calculate and set the matrix of this node and all its children recursively */ +void anm_eval(struct anm_node *node, anm_time_t tm); + + +/* ---- bottom-up lazy matrix calculation interface ---- */ + /* These calculate the matrix and inverse matrix of this node taking hierarchy * into account. The results are cached in thread-specific storage and returned * if there's no change in time or tracks from the last query... @@ -106,10 +123,6 @@ void anm_get_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm); void anm_get_inv_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm); -/* those return the start and end times of the whole tree */ -anm_time_t anm_get_start_time(struct anm_node *node); -anm_time_t anm_get_end_time(struct anm_node *node); - #ifdef __cplusplus } #endif