diff options
Diffstat (limited to 'source/blender/blenkernel/intern/anim.c')
-rw-r--r-- | source/blender/blenkernel/intern/anim.c | 87 |
1 files changed, 84 insertions, 3 deletions
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index cff9fd4a7c8..c7730d8877b 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -35,6 +35,7 @@ #include "BLI_listbase.h" #include "BLI_math.h" +#include "BLI_dlrbTree.h" #include "BLT_translation.h" @@ -44,6 +45,7 @@ #include "DNA_scene_types.h" #include "BKE_anim.h" +#include "BKE_animsys.h" #include "BKE_action.h" #include "BKE_context.h" #include "BKE_curve.h" @@ -59,7 +61,12 @@ #include "DEG_depsgraph_query.h" #include "DEG_depsgraph_build.h" +#include "GPU_batch.h" + // XXX bad level call... +extern short compare_ak_cfraPtr(void *node, void *data); +extern void agroup_to_keylist(struct AnimData *adt, struct bActionGroup *agrp, struct DLRBT_Tree *keys, struct DLRBT_Tree *blocks); +extern void action_to_keylist(struct AnimData *adt, struct bAction *act, struct DLRBT_Tree *keys, struct DLRBT_Tree *blocks); /* --------------------- */ /* forward declarations */ @@ -106,6 +113,10 @@ void animviz_free_motionpath_cache(bMotionPath *mpath) /* free the path if necessary */ if (mpath->points) MEM_freeN(mpath->points); + + GWN_VERTBUF_DISCARD_SAFE(mpath->points_vbo); + GWN_BATCH_DISCARD_SAFE(mpath->batch_line); + GWN_BATCH_DISCARD_SAFE(mpath->batch_points); /* reset the relevant parameters */ mpath->points = NULL; @@ -130,6 +141,27 @@ void animviz_free_motionpath(bMotionPath *mpath) /* ------------------- */ +/* Make a copy of motionpath data, so that viewing with copy on write works */ +bMotionPath *animviz_copy_motionpath(const bMotionPath *mpath_src) +{ + bMotionPath *mpath_dst; + + if (mpath_src == NULL) + return NULL; + + mpath_dst = MEM_dupallocN(mpath_src); + mpath_dst->points = MEM_dupallocN(mpath_src->points); + + /* should get recreated on draw... */ + mpath_dst->points_vbo = NULL; + mpath_dst->batch_line = NULL; + mpath_dst->batch_points = NULL; + + return mpath_dst; +} + +/* ------------------- */ + /** * Setup motion paths for the given data. * \note Only used when explicitly calculating paths on bones which may/may not be consider already @@ -212,7 +244,7 @@ bMotionPath *animviz_verify_motionpaths(ReportList *reports, Scene *scene, Objec mpath->color[1] = 0.0; mpath->color[2] = 0.0; - mpath->line_thickness = 1; + mpath->line_thickness = 2; mpath->flag |= MOTIONPATH_FLAG_LINES; /* draw lines by default */ /* allocate a cache */ @@ -232,6 +264,8 @@ typedef struct MPathTarget { struct MPathTarget *next, *prev; bMotionPath *mpath; /* motion path in question */ + + DLRBT_Tree keys; /* temp, to know where the keyframes are */ /* Original (Source Objects) */ Object *ob; /* source object */ @@ -344,6 +378,13 @@ static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets) /* worldspace object location */ copy_v3_v3(mpv->co, ob_eval->obmat[3]); } + + float mframe = (float)(CFRA); + + /* Tag if it's a keyframe */ + if (BLI_dlrbTree_search_exact(&mpt->keys, compare_ak_cfraPtr, &mframe)) { + mpv->flag |= MOTIONPATH_VERT_KEY; + } } } @@ -387,13 +428,44 @@ static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets) if (mpt->pchan) { mpt->pchan_eval = BKE_pose_channel_find_name(mpt->ob_eval->pose, mpt->pchan->name); } + + AnimData *adt = BKE_animdata_from_id(&mpt->ob_eval->id); + + /* build list of all keyframes in active action for object or pchan */ + BLI_dlrbTree_init(&mpt->keys); + + if (adt) { + bAnimVizSettings *avs; + + /* get pointer to animviz settings for each target */ + if (mpt->pchan) + avs = &mpt->ob->pose->avs; + else + avs = &mpt->ob->avs; + + /* it is assumed that keyframes for bones are all grouped in a single group + * unless an option is set to always use the whole action + */ + if ((mpt->pchan) && (avs->path_viewflag & MOTIONPATH_VIEW_KFACT) == 0) { + bActionGroup *agrp = BKE_action_group_find_name(adt->action, mpt->pchan->name); + + if (agrp) { + agroup_to_keylist(adt, agrp, &mpt->keys, NULL); + BLI_dlrbTree_linkedlist_sync(&mpt->keys); + } + } + else { + action_to_keylist(adt, adt->action, &mpt->keys, NULL); + BLI_dlrbTree_linkedlist_sync(&mpt->keys); + } + } } - + /* calculate path over requested range */ for (CFRA = sfra; CFRA <= efra; CFRA++) { /* update relevant data for new frame */ motionpaths_calc_update_scene(bmain, depsgraph); - + /* perform baking for targets */ motionpaths_calc_bake_targets(scene, targets); } @@ -406,6 +478,7 @@ static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets) /* clear recalc flags from targets */ for (mpt = targets->first; mpt; mpt = mpt->next) { bAnimVizSettings *avs; + bMotionPath *mpath = mpt->mpath; /* get pointer to animviz settings for each target */ if (mpt->pchan) @@ -415,6 +488,14 @@ static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets) /* clear the flag requesting recalculation of targets */ avs->recalc &= ~ANIMVIZ_RECALC_PATHS; + + /* Clean temp data */ + BLI_dlrbTree_free(&mpt->keys); + + /* Free previous batches to force update. */ + GWN_VERTBUF_DISCARD_SAFE(mpath->points_vbo); + GWN_BATCH_DISCARD_SAFE(mpath->batch_line); + GWN_BATCH_DISCARD_SAFE(mpath->batch_points); } } |