nuclear@27: #ifndef LIBANIM_H_ nuclear@27: #define LIBANIM_H_ nuclear@27: nuclear@27: #include "config.h" nuclear@27: nuclear@27: #include nuclear@27: #include nuclear@27: #include nuclear@27: #include "track.h" nuclear@27: nuclear@27: enum { nuclear@27: ANM_TRACK_POS_X, nuclear@27: ANM_TRACK_POS_Y, nuclear@27: ANM_TRACK_POS_Z, nuclear@27: nuclear@27: ANM_TRACK_ROT_X, nuclear@27: ANM_TRACK_ROT_Y, nuclear@27: ANM_TRACK_ROT_Z, nuclear@27: ANM_TRACK_ROT_W, nuclear@27: nuclear@27: ANM_TRACK_SCL_X, nuclear@27: ANM_TRACK_SCL_Y, nuclear@27: ANM_TRACK_SCL_Z, nuclear@27: nuclear@27: ANM_NUM_TRACKS nuclear@27: }; nuclear@27: nuclear@27: struct anm_node { nuclear@27: char *name; nuclear@27: nuclear@27: struct anm_track tracks[ANM_NUM_TRACKS]; nuclear@27: vec3_t pivot; nuclear@27: nuclear@27: /* matrix cache */ nuclear@27: struct mat_cache { nuclear@27: mat4_t matrix, inv_matrix; nuclear@27: anm_time_t time, inv_time; nuclear@27: } cache; nuclear@27: nuclear@27: struct anm_node *parent; nuclear@27: struct anm_node *child; nuclear@27: struct anm_node *next; nuclear@27: }; nuclear@27: nuclear@27: #ifdef __cplusplus nuclear@27: extern "C" { nuclear@27: #endif nuclear@27: nuclear@27: /* node constructor and destructor */ nuclear@27: int anm_init_node(struct anm_node *node); nuclear@27: void anm_destroy_node(struct anm_node *node); nuclear@27: nuclear@27: /* recursively destroy an animation node tree */ nuclear@27: void anm_destroy_node_tree(struct anm_node *tree); nuclear@27: nuclear@27: /* helper functions to allocate/construct and destroy/free with nuclear@27: * a single call. They call anm_init_node and anm_destroy_node nuclear@27: * internally. nuclear@27: */ nuclear@27: struct anm_node *anm_create_node(void); nuclear@27: void anm_free_node(struct anm_node *node); nuclear@27: nuclear@27: /* recursively destroy and free the nodes of a node tree */ nuclear@27: void anm_free_node_tree(struct anm_node *tree); nuclear@27: nuclear@27: int anm_set_node_name(struct anm_node *node, const char *name); nuclear@27: const char *anm_get_node_name(struct anm_node *node); nuclear@27: nuclear@27: void anm_set_interpolator(struct anm_node *node, enum anm_interpolator in); nuclear@27: void anm_set_extrapolator(struct anm_node *node, enum anm_extrapolator ex); nuclear@27: nuclear@27: /* link and unlink nodes with parent/child relations */ nuclear@27: void anm_link_node(struct anm_node *parent, struct anm_node *child); nuclear@27: int anm_unlink_node(struct anm_node *parent, struct anm_node *child); nuclear@27: nuclear@27: void anm_set_position(struct anm_node *node, vec3_t pos, anm_time_t tm); nuclear@27: vec3_t anm_get_node_position(struct anm_node *node, anm_time_t tm); nuclear@27: nuclear@27: void anm_set_rotation(struct anm_node *node, quat_t rot, anm_time_t tm); nuclear@27: quat_t anm_get_node_rotation(struct anm_node *node, anm_time_t tm); nuclear@27: nuclear@27: void anm_set_scaling(struct anm_node *node, vec3_t scl, anm_time_t tm); nuclear@27: vec3_t anm_get_node_scaling(struct anm_node *node, anm_time_t tm); nuclear@27: nuclear@27: /* these three return the full p/r/s taking hierarchy into account */ nuclear@27: vec3_t anm_get_position(struct anm_node *node, anm_time_t tm); nuclear@27: quat_t anm_get_rotation(struct anm_node *node, anm_time_t tm); nuclear@27: vec3_t anm_get_scaling(struct anm_node *node, anm_time_t tm); nuclear@27: nuclear@27: void anm_set_pivot(struct anm_node *node, vec3_t pivot); nuclear@27: vec3_t anm_get_pivot(struct anm_node *node); nuclear@27: nuclear@27: /* these calculate the matrix and inverse matrix of this node alone */ nuclear@27: void anm_get_node_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm); nuclear@27: void anm_get_node_inv_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm); nuclear@27: nuclear@27: /* These calculate the matrix and inverse matrix of this node taking hierarchy nuclear@27: * into account. The results are cached in thread-specific storage and returned nuclear@27: * if there's no change in time or tracks from the last query... nuclear@27: */ nuclear@27: void anm_get_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm); nuclear@27: void anm_get_inv_matrix(struct anm_node *node, mat4_t mat, anm_time_t tm); nuclear@27: nuclear@27: /* those return the start and end times of the whole tree */ nuclear@27: anm_time_t anm_get_start_time(struct anm_node *node); nuclear@27: anm_time_t anm_get_end_time(struct anm_node *node); nuclear@27: nuclear@27: #ifdef __cplusplus nuclear@27: } nuclear@27: #endif nuclear@27: nuclear@27: #endif /* LIBANIM_H_ */