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.
This commit is contained in:
parent
1934ee422a
commit
68f4465cdc
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue