diff options
author | Joshua Leung <aligorith@gmail.com> | 2009-09-17 14:14:56 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2009-09-17 14:14:56 +0400 |
commit | 68f4465cdc0925ec22584e404a895982f6a74de0 (patch) | |
tree | 557826ae5fbf3cc79a4267e136b6dee8ef97436d /source/blender | |
parent | 1934ee422a47f7dcc5e63cfff5811873798561d8 (diff) |
2.5 - Animation Utility Function
Added a utility function to check which transforms for an object or bone are animated, returning these as bitflags and/or optionally retrieving the relevant F-Curves too. Beware that this method may not be working correctly yet, but it shouldn't hurt anyone in the meantime :)
Also, split RNA-path building function up into a version which only creates the path up to the given struct, with the other parts being added later.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_action.h | 30 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/action.c | 100 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/anim_sys.c | 2 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_listbase.h | 4 | ||||
-rw-r--r-- | source/blender/blenlib/intern/listbase.c | 14 | ||||
-rw-r--r-- | source/blender/makesrna/RNA_access.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_access.c | 21 |
7 files changed, 163 insertions, 9 deletions
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index 4724ee19aaa..f079cc08281 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -51,7 +51,7 @@ struct ID; extern "C" { #endif -/* Action API ----------------- */ +/* Action Lib Stuff ----------------- */ /* Allocate a new bAction with the given name */ struct bAction *add_empty_action(const char name[]); @@ -65,6 +65,31 @@ void free_action(struct bAction *act); // XXX is this needed? void make_local_action(struct bAction *act); + +/* Action API ----------------- */ + +/* types of transforms applied to the given item + * - these are the return falgs for action_get_item_transforms() + */ +typedef enum eAction_TransformFlags { + /* location */ + ACT_TRANS_LOC = (1<<0), + /* rotation */ + ACT_TRANS_ROT = (1<<1), + /* scaling */ + ACT_TRANS_SCALE = (1<<2), + + /* all flags */ + ACT_TRANS_ALL = (ACT_TRANS_LOC|ACT_TRANS_ROT|ACT_TRANS_SCALE), +} eAction_TransformFlags; + +/* Return flags indicating which transforms the given object/posechannel has + * - if 'curves' is provided, a list of links to these curves are also returned + * whose nodes WILL NEED FREEING + */ +short action_get_item_transforms(struct bAction *act, struct Object *ob, struct bPoseChannel *pchan, ListBase *curves); + + /* Some kind of bounding box operation on the action */ void calc_action_range(const struct bAction *act, float *start, float *end, short incl_modifiers); @@ -73,6 +98,9 @@ short action_has_motion(const struct bAction *act); /* Action Groups API ----------------- */ +/* Get the active action-group for an Action */ +struct bActionGroup *get_active_actiongroup(struct bAction *act); + /* Make the given Action Group the active one */ void set_active_action_group(struct bAction *act, struct bActionGroup *agrp, short select); diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 2bde61818bf..1ff5d9b5c01 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -212,9 +212,10 @@ bAction *copy_action (bAction *src) return dst; } +/* *************** Action Groups *************** */ /* Get the active action-group for an Action */ -static bActionGroup *get_active_actiongroup (bAction *act) +bActionGroup *get_active_actiongroup (bAction *act) { bActionGroup *agrp= NULL; @@ -404,7 +405,7 @@ bActionGroup *action_groups_find_named (bAction *act, const char name[]) return NULL; } -/* ************************ Pose channels *************** */ +/* *************** Pose channels *************** */ /* usually used within a loop, so we got a N^2 slowdown */ bPoseChannel *get_pose_channel(const bPose *pose, const char *name) @@ -818,7 +819,7 @@ void pose_remove_group (Object *ob) } } -/* ************** time ****************** */ +/* ************** F-Curve Utilities for Actions ****************** */ /* Check if the given action has any keyframes */ short action_has_motion(const bAction *act) @@ -916,6 +917,99 @@ void calc_action_range(const bAction *act, float *start, float *end, short incl_ } } + +/* Return flags indicating which transforms the given object/posechannel has + * - if 'curves' is provided, a list of links to these curves are also returned + */ +short action_get_item_transforms (bAction *act, Object *ob, bPoseChannel *pchan, ListBase *curves) +{ + PointerRNA ptr; + FCurve *fcu; + char *basePath=NULL; + short flags=0; + + /* build PointerRNA from provided data to obtain the paths to use */ + if (pchan) + RNA_pointer_create((ID *)ob, &RNA_PoseChannel, pchan, &ptr); + else if (ob) + RNA_id_pointer_create((ID *)ob, &ptr); + else + return 0; + + /* get the basic path to the properties of interest */ + basePath= RNA_path_from_ID_to_struct(&ptr); + if (basePath == NULL) + return 0; + + /* search F-Curves for the given properties + * - we cannot use the groups, since they may not be grouped in that way... + */ + for (fcu= act->curves.first; fcu; fcu= fcu->next) { + char *bPtr=NULL, *pPtr=NULL; + + /* if enough flags have been found, we can stop checking unless we're also getting the curves */ + if ((flags == ACT_TRANS_ALL) && (curves == NULL)) + break; + + /* just in case... */ + if (fcu->rna_path == NULL) + continue; + + /* step 1: check for matching base path */ + bPtr= strstr(fcu->rna_path, basePath); + + if (bPtr) { + /* step 2: check for some property with transforms + * - to speed things up, only check for the ones not yet found + * unless we're getting the curves too + * - if we're getting the curves, the BLI_genericNodeN() creates a LinkData + * node wrapping the F-Curve, which then gets added to the list + * - once a match has been found, the curve cannot possibly be any other one + */ + if ((curves) || (flags & ACT_TRANS_LOC) == 0) { + pPtr= strstr(fcu->rna_path, "location"); + if ((pPtr) && (pPtr >= bPtr)) { + flags |= ACT_TRANS_LOC; + + if (curves) + BLI_addtail(curves, BLI_genericNodeN(fcu)); + continue; + } + } + + if ((curves) || (flags & ACT_TRANS_SCALE) == 0) { + pPtr= strstr(fcu->rna_path, "scale"); + if ((pPtr) && (pPtr >= bPtr)) { + flags |= ACT_TRANS_SCALE; + + if (curves) + BLI_addtail(curves, BLI_genericNodeN(fcu)); + continue; + } + } + + if ((curves) || (flags & ACT_TRANS_ROT) == 0) { + pPtr= strstr(fcu->rna_path, "rotation"); + if ((pPtr) && (pPtr >= bPtr)) { + flags |= ACT_TRANS_ROT; + + if (curves) + BLI_addtail(curves, BLI_genericNodeN(fcu)); + continue; + } + } + } + } + + /* free basePath */ + MEM_freeN(basePath); + + /* return flags found */ + return flags; +} + +/* ************** Pose Management Tools ****************** */ + /* Copy the data from the action-pose (src) into the pose */ /* both args are assumed to be valid */ /* exported to game engine */ diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 643aa6bc779..522297da1d7 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -1485,7 +1485,7 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime) } /* nodes */ - // TODO... + EVAL_ANIM_IDS(main->nodetree.first, ADT_RECALC_ANIM); /* textures */ EVAL_ANIM_IDS(main->tex.first, ADT_RECALC_ANIM); diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index d0b106b59c3..21b4c83bd88 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -34,6 +34,7 @@ //#include "DNA_listbase.h" struct ListBase; +struct LinkData; #ifdef __cplusplus extern "C" { @@ -56,6 +57,9 @@ int BLI_countlist(struct ListBase *listbase); void BLI_freelinkN(struct ListBase *listbase, void *vlink); void BLI_duplicatelist(struct ListBase *list1, struct ListBase *list2); /* copy from 2 to 1 */ +/* create a generic list node containing link to provided data */ +struct LinkData *BLI_genericNodeN(void *data); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index 3194593374f..b3a4722d6d9 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -359,3 +359,17 @@ void BLI_duplicatelist(ListBase *list1, ListBase *list2) /* copy from 2 to 1 */ } } +/* create a generic list node containing link to provided data */ +LinkData *BLI_genericNodeN (void *data) +{ + LinkData *ld; + + if (data == NULL) + return NULL; + + /* create new link, and make it hold the given data */ + ld= MEM_callocN(sizeof(LinkData), "BLI_genericNodeN()"); + ld->data= data; + + return ld; +} diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 40f640473db..b1f5292f9d4 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -692,6 +692,7 @@ char *RNA_path_back(const char *path); int RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop); +char *RNA_path_from_ID_to_struct(PointerRNA *ptr); char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop); #if 0 diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 738d52bfbcd..55893b42a92 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -2387,12 +2387,11 @@ char *RNA_path_back(const char *path) return result; } -char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop) +char *RNA_path_from_ID_to_struct(PointerRNA *ptr) { - char *ptrpath=NULL, *path; - const char *propname; + char *ptrpath=NULL; - if(!ptr->id.data || !ptr->data || !prop) + if(!ptr->id.data || !ptr->data) return NULL; if(!RNA_struct_is_ID(ptr->type)) { @@ -2418,6 +2417,20 @@ char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop) else return NULL; } + + return ptrpath; +} + +char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop) +{ + const char *propname; + char *ptrpath, *path; + + if(!ptr->id.data || !ptr->data || !prop) + return NULL; + + /* path from ID to the struct holding this property */ + ptrpath= RNA_path_from_ID_to_struct(ptr); propname= RNA_property_identifier(prop); |