diff options
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_anim.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/anim.c | 62 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/armature.c | 8 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 17 | ||||
-rw-r--r-- | source/blender/editors/armature/poseobject.c | 230 | ||||
-rw-r--r-- | source/blender/editors/include/ED_object.h | 4 | ||||
-rw-r--r-- | source/blender/editors/object/object_edit.c | 112 | ||||
-rw-r--r-- | source/blender/editors/object/object_intern.h | 2 | ||||
-rw-r--r-- | source/blender/editors/object/object_ops.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawanimviz.c | 3 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawarmature.c | 195 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 16 |
12 files changed, 228 insertions, 427 deletions
diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h index 4862f4e5c46..c664469527e 100644 --- a/source/blender/blenkernel/BKE_anim.h +++ b/source/blender/blenkernel/BKE_anim.h @@ -53,7 +53,9 @@ void animviz_free_motionpath_cache(struct bMotionPath *mpath); void animviz_free_motionpath(struct bMotionPath *mpath); struct bMotionPath *animviz_verify_motionpaths(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan); -void animviz_calc_motionpaths(struct Scene *scene, struct Object *ob); + +void animviz_get_object_motionpaths(Object *ob, ListBase *targets); +void animviz_calc_motionpaths(struct Scene *scene, ListBase *targets); /* ---------------------------------------------------- */ /* Curve Paths */ diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 507fc520a85..6d95df3ca84 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -154,7 +154,7 @@ void animviz_free_motionpath(bMotionPath *mpath) /* ------------------- */ -/* Setup motion paths for the given data +/* Setup motion paths for the given data * - scene: current scene (for frame ranges, etc.) * - ob: object to add paths for (must be provided) * - pchan: posechannel to add paths for (optional; if not provided, object-paths are assumed) @@ -226,8 +226,10 @@ typedef struct MPathTarget { /* ........ */ -/* get list of motion paths to be baked (assumes the list is ready to be used) */ -static void motionpaths_get_bake_targets(Object *ob, ListBase *targets) +/* get list of motion paths to be baked for the given object + * - assumes the given list is ready to be used + */ +void animviz_get_object_motionpaths(Object *ob, ListBase *targets) { MPathTarget *mpt; @@ -260,6 +262,8 @@ static void motionpaths_get_bake_targets(Object *ob, ListBase *targets) } } +/* ........ */ + /* perform baking for the targets on the current frame */ static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets) { @@ -270,8 +274,10 @@ static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets) bMotionPath *mpath= mpt->mpath; bMotionPathVert *mpv; - /* current frame must be within the range the cache works for */ - if (IN_RANGE(CFRA, mpath->start_frame, mpath->end_frame) == 0) + /* current frame must be within the range the cache works for + * - is inclusive of the first frame, but not the last otherwise we get buffer overruns + */ + if ((CFRA < mpath->start_frame) || (CFRA >= mpath->end_frame)) continue; /* get the relevant cache vert to write to */ @@ -297,36 +303,30 @@ static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets) } } -/* ........ */ - /* Perform baking of the given object's and/or its bones' transforms to motion paths * - scene: current scene * - ob: object whose flagged motionpaths should get calculated * - recalc: whether we need to */ // TODO: include reports pointer? -void animviz_calc_motionpaths(Scene *scene, Object *ob) +void animviz_calc_motionpaths(Scene *scene, ListBase *targets) { - ListBase targets = {NULL, NULL}; MPathTarget *mpt; int sfra, efra; int cfra; - /* sanity checks */ - if (ob == NULL) - return; - - /* get motion paths to affect */ - motionpaths_get_bake_targets(ob, &targets); - - if (targets.first == NULL) + /* sanity check */ + if (ELEM(NULL, targets, targets->first)) return; /* set frame values */ cfra = CFRA; sfra = efra = cfra; - for (mpt= targets.first; mpt; mpt= mpt->next) { + // TODO: this method could be improved... + // 1) max range for standard baking + // 2) minimum range for recalc baking (i.e. between keyfames, but how?) + for (mpt= targets->first; mpt; mpt= mpt->next) { /* try to increase area to do (only as much as needed) */ sfra= MIN2(sfra, mpt->mpath->start_frame); efra= MAX2(efra, mpt->mpath->end_frame); @@ -340,23 +340,29 @@ void animviz_calc_motionpaths(Scene *scene, Object *ob) * that doesn't force complete update, but for now, this is the * most accurate way! */ - scene_update_for_newframe(scene, ob->lay); // XXX is the layer flag too restrictive? + scene_update_for_newframe(scene, scene->lay); // XXX this is the best way we can get anything moving /* perform baking for targets */ - motionpaths_calc_bake_targets(scene, &targets); + motionpaths_calc_bake_targets(scene, targets); } /* reset original environment */ CFRA= cfra; - scene_update_for_newframe(scene, ob->lay); // XXX is the layer flag too restrictive? - - // TODO: make an API call for this too? - ob->avs.recalc &= ~ANIMVIZ_RECALC_PATHS; - if (ob->pose) - ob->pose->avs.recalc &= ~ANIMVIZ_RECALC_PATHS; + scene_update_for_newframe(scene, scene->lay); // XXX this is the best way we can get anything moving - /* free temp data */ - BLI_freelistN(&targets); + /* clear recalc flags from targets */ + for (mpt= targets->first; mpt; mpt= mpt->next) { + bAnimVizSettings *avs; + + /* get pointer to animviz settings for each target */ + if (mpt->pchan) + avs= &mpt->ob->pose->avs; + else + avs= &mpt->ob->avs; + + /* clear the flag requesting recalculation of targets */ + avs->recalc &= ~ANIMVIZ_RECALC_PATHS; + } } /* ******************************************************************** */ diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index e4079eac31b..3a7d79b8e00 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1602,7 +1602,13 @@ void armature_rebuild_pose(Object *ob, bArmature *arm) int counter=0; /* only done here */ - if(ob->pose==NULL) ob->pose= MEM_callocN(sizeof(bPose), "new pose"); + if(ob->pose==NULL) { + /* create new pose */ + ob->pose= MEM_callocN(sizeof(bPose), "new pose"); + + /* set default settings for animviz */ + animviz_settings_init(&ob->pose->avs); + } pose= ob->pose; /* clear */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 8975dcd4c67..96b2b793267 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -10381,9 +10381,16 @@ static void do_versions(FileData *fd, Library *lib, Main *main) avs->ghost_sf= arm->ghostsf; avs->ghost_ef= arm->ghostef; + if ((avs->ghost_sf == avs->ghost_ef) && (avs->ghost_sf == 0)) { + avs->ghost_sf= 1; + avs->ghost_ef= 100; + } /* type */ - avs->ghost_type= arm->ghosttype; + if (arm->ghostep == 0) + avs->ghost_type= GHOST_TYPE_NONE; + else + avs->ghost_type= arm->ghosttype + 1; /* stepsize */ avs->ghost_step= arm->ghostsize; @@ -10394,9 +10401,15 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* ranges */ avs->path_bc= arm->pathbc; avs->path_ac= arm->pathac; + if ((avs->path_bc == avs->path_ac) && (avs->path_bc == 0)) + avs->path_bc= avs->path_ac= 10; avs->path_sf= arm->pathsf; avs->path_ef= arm->pathef; + if ((avs->path_sf == avs->path_ef) && (avs->path_sf == 0)) { + avs->path_sf= 1; + avs->path_ef= 250; + } /* flags */ if (arm->pathflag & ARM_PATH_FNUMS) @@ -10419,6 +10432,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main) if (avs->path_step == 0) avs->path_step= 1; } + else + animviz_settings_init(&ob->pose->avs); } } diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index d26238150ca..ee6e87292fa 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -51,6 +51,7 @@ #include "DNA_view3d_types.h" #include "DNA_userdef_types.h" +#include "BKE_anim.h" #include "BKE_animsys.h" #include "BKE_action.h" #include "BKE_armature.h" @@ -200,6 +201,7 @@ int ED_pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan) } /* ********************************************** */ +/* Motion Paths */ /* For the object with pose/action: update paths for those that have got them * This should selectively update paths that exist... @@ -208,120 +210,25 @@ int ED_pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan) */ void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob) { - bArmature *arm; - bPoseChannel *pchan; - Base *base; - float *fp; - int cfra; - int sfra, efra; - - /* sanity checks */ - if ELEM(NULL, ob, ob->pose) - return; - arm= ob->data; - - /* set frame values */ - cfra = CFRA; - sfra = efra = cfra; - for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if ((pchan->bone) && (arm->layer & pchan->bone->layer)) { - if (pchan->path) { - /* if the pathsf and pathef aren't initialised, abort! */ - // XXX can now have negative frames, so this check needs improvement - if (ELEM(0, pchan->pathsf, pchan->pathef)) - return; - - /* try to increase area to do (only as much as needed) */ - sfra= MIN2(sfra, pchan->pathsf); - efra= MAX2(efra, pchan->pathef); - } - } - } - if (efra <= sfra) return; - - /* hack: for unsaved files, set OB_RECALC so that paths can get calculated */ - if ((ob->recalc & OB_RECALC)==0) { - ob->recalc |= OB_RECALC; - DAG_id_update_flags(&ob->id); - } - else - DAG_id_update_flags(&ob->id); - - /* calculate path over requested range */ - for (CFRA=sfra; CFRA<=efra; CFRA++) { - /* do all updates */ - for (base= FIRSTBASE; base; base= base->next) { - if (base->object->recalc) { - int temp= base->object->recalc; - - if (base->object->adt) - BKE_animsys_evaluate_animdata(&base->object->id, base->object->adt, (float)CFRA, ADT_RECALC_ALL); - - /* update object */ - object_handle_update(scene, base->object); - base->object->recalc= temp; - } - } - - for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if ((pchan->bone) && (arm->layer & pchan->bone->layer)) { - if (pchan->path) { - /* only update if: - * - in range of this pchan's existing path - * - ... insert evil filtering/optimising conditions here... - */ - if (IN_RANGE(CFRA, pchan->pathsf, pchan->pathef)) { - fp= pchan->path+3*(CFRA-sfra); - - if (arm->pathflag & ARM_PATH_HEADS) { - VECCOPY(fp, pchan->pose_head); - } - else { - VECCOPY(fp, pchan->pose_tail); - } - - mul_m4_v3(ob->obmat, fp); - } - } - } - } - } + ListBase targets = {NULL, NULL}; - /* reset flags */ - CFRA= cfra; - ob->pose->flag &= ~POSE_RECALCPATHS; + /* set flag to force recalc, then grab the relevant bones to target */ + ob->pose->avs.recalc |= ANIMVIZ_RECALC_PATHS; + animviz_get_object_motionpaths(ob, &targets); - /* flush one final time - to restore to the original state */ - for (base= FIRSTBASE; base; base= base->next) { - if (base->object->recalc) { - int temp= base->object->recalc; - - if (base->object->adt) - BKE_animsys_evaluate_animdata(&base->object->id, base->object->adt, (float)CFRA, ADT_RECALC_ALL); - - object_handle_update(scene, base->object); - base->object->recalc= temp; - } - } + /* recalculate paths, then free */ + animviz_calc_motionpaths(scene, &targets); + BLI_freelistN(&targets); } -/* --------- */ - /* For the object with pose/action: create path curves for selected bones * This recalculates the WHOLE path within the pchan->pathsf and pchan->pathef range */ static int pose_calculate_paths_exec (bContext *C, wmOperator *op) { - wmWindow *win= CTX_wm_window(C); ScrArea *sa= CTX_wm_area(C); Scene *scene= CTX_data_scene(C); Object *ob; - bArmature *arm; - bPoseChannel *pchan; - Base *base; - float *fp; - int cfra; - int sfra, efra; /* since this call may also be used from the buttons window, we need to check for where to get the object */ if (sa->spacetype == SPACE_BUTS) @@ -329,109 +236,20 @@ static int pose_calculate_paths_exec (bContext *C, wmOperator *op) else ob= CTX_data_active_object(C); - /* only continue if there's an object */ - if ELEM(NULL, ob, ob->pose) - return OPERATOR_CANCELLED; - arm= ob->data; - - /* version patch for older files here (do_versions patch too complicated) */ - if ((arm->pathsf == 0) || (arm->pathef == 0)) { - arm->pathsf = SFRA; - arm->pathef = EFRA; - } - if (arm->pathsize == 0) { - arm->pathsize = 1; - } - - /* get frame values to use */ - cfra= CFRA; - sfra = arm->pathsf; - efra = arm->pathef; - - if (efra <= sfra) { - BKE_report(op->reports, RPT_ERROR, "Can't calculate paths when pathlen <= 0"); + if (ELEM(NULL, ob, ob->pose)) return OPERATOR_CANCELLED; - } - /* hack: for unsaved files, set OB_RECALC so that paths can get calculated */ - if ((ob->recalc & OB_RECALC)==0) { - ob->recalc |= OB_RECALC; - DAG_id_update_flags(&ob->id); - } - else - DAG_id_update_flags(&ob->id); - - /* alloc the path cache arrays */ - for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) { - if (arm->layer & pchan->bone->layer) { - pchan->pathlen= efra-sfra+1; - pchan->pathsf= sfra; - pchan->pathef= efra+1; - if (pchan->path) - MEM_freeN(pchan->path); - pchan->path= MEM_callocN(3*pchan->pathlen*sizeof(float), "pchan path"); - } - } - } - - /* step through frame range sampling the values */ - for (CFRA=sfra; CFRA<=efra; CFRA++) { - /* for each frame we calculate, update time-cursor... (may be too slow) */ - WM_timecursor(win, CFRA); - - /* do all updates */ - for (base= FIRSTBASE; base; base= base->next) { - if (base->object->recalc) { - int temp= base->object->recalc; - - if (base->object->adt) - BKE_animsys_evaluate_animdata(&base->object->id, base->object->adt, (float)CFRA, ADT_RECALC_ALL); - - object_handle_update(scene, base->object); - base->object->recalc= temp; - } - } - - for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) { - if (arm->layer & pchan->bone->layer) { - if (pchan->path) { - fp= pchan->path+3*(CFRA-sfra); - - if (arm->pathflag & ARM_PATH_HEADS) { - VECCOPY(fp, pchan->pose_head); - } - else { - VECCOPY(fp, pchan->pose_tail); - } - - mul_m4_v3(ob->obmat, fp); - } - } - } - } + /* set up path data for bones being calculated */ + CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones) + { + /* verify makes sure that the selected bone has a bone with the appropriate settings */ + animviz_verify_motionpaths(scene, ob, pchan); } + CTX_DATA_END; - /* restore original cursor */ - WM_cursor_restore(win); - - /* reset current frame, and clear flags */ - CFRA= cfra; - ob->pose->flag &= ~POSE_RECALCPATHS; - - /* flush one final time - to restore to the original state */ - for (base= FIRSTBASE; base; base= base->next) { - if (base->object->recalc) { - int temp= base->object->recalc; - - if (base->object->adt) - BKE_animsys_evaluate_animdata(&base->object->id, base->object->adt, (float)CFRA, ADT_RECALC_ALL); - - object_handle_update(scene, base->object); - base->object->recalc= temp; - } - } + /* calculate the bones that now have motionpaths... */ + // TODO: only make for the selected bones? + ED_pose_recalculate_paths(C, scene, ob); /* notifiers for updates */ WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob); @@ -464,12 +282,12 @@ void ED_pose_clear_paths(Object *ob) if ELEM(NULL, ob, ob->pose) return; - /* free the path blocks */ + /* free the motionpath blocks */ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) { - if (pchan->path) { - MEM_freeN(pchan->path); - pchan->path= NULL; + if (pchan->mpath) { + animviz_free_motionpath(pchan->mpath); + pchan->mpath= NULL; } } } @@ -491,7 +309,7 @@ static int pose_clear_paths_exec (bContext *C, wmOperator *op) if ELEM(NULL, ob, ob->pose) return OPERATOR_CANCELLED; - /* for now, just call the API function for this (which is shared with backend functions) */ + /* use the backend function for this */ ED_pose_clear_paths(ob); /* notifiers for updates */ diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 91b297b7581..aa6914ab0ad 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -95,6 +95,10 @@ void ED_object_single_users(struct Scene *scene, int full); int object_is_libdata(struct Object *ob); int object_data_is_libdata(struct Object *ob); +/* object motion paths */ +void ED_objects_clear_paths(struct bContext *C, struct Scene *scene); +void ED_objects_recalculate_paths(struct bContext *C, struct Scene *scene); + /* constraints */ struct ListBase *get_active_constraints(struct Object *ob); struct ListBase *get_constraint_lb(struct Object *ob, struct bConstraint *con, struct bPoseChannel **pchan_r); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 54fa3f51eb6..e2d714fac0d 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1610,6 +1610,118 @@ void copy_attr_menu(Scene *scene, View3D *v3d) copy_attr(scene, v3d, event); } +/* ********************************************** */ +/* Motion Paths */ + +/* For the object with pose/action: update paths for those that have got them + * This should selectively update paths that exist... + * + * To be called from various tools that do incremental updates + */ +void ED_objects_recalculate_paths(bContext *C, Scene *scene) +{ + ListBase targets = {NULL, NULL}; + + /* loop over objects in scene */ + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) + { + /* set flag to force recalc, then grab the relevant bones to target */ + ob->avs.recalc |= ANIMVIZ_RECALC_PATHS; + animviz_get_object_motionpaths(ob, &targets); + } + CTX_DATA_END; + + /* recalculate paths, then free */ + animviz_calc_motionpaths(scene, &targets); + BLI_freelistN(&targets); +} + +/* For the object with pose/action: create path curves for selected bones + * This recalculates the WHOLE path within the pchan->pathsf and pchan->pathef range + */ +static int object_calculate_paths_exec (bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + + /* set up path data for bones being calculated */ + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) + { + /* verify makes sure that the selected bone has a bone with the appropriate settings */ + animviz_verify_motionpaths(scene, ob, NULL); + } + CTX_DATA_END; + + /* calculate the bones that now have motionpaths... */ + // TODO: only make for the selected bones? + ED_objects_recalculate_paths(C, scene); + + /* notifiers for updates */ + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_paths_calculate (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Calculate Object Paths"; + ot->idname= "OBJECT_OT_paths_calculate"; + ot->description= "Calculate paths for the selected bones."; + + /* api callbacks */ + ot->exec= object_calculate_paths_exec; + ot->poll= ED_operator_object_active_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/* --------- */ + +/* for the object with pose/action: clear path curves for selected bones only */ +void ED_objects_clear_paths(bContext *C, Scene *scene) +{ + /* loop over objects in scene */ + CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) + { + if (ob->mpath) { + animviz_free_motionpath(ob->mpath); + ob->mpath= NULL; + } + } + CTX_DATA_END; +} + +/* operator callback for this */ +static int object_clear_paths_exec (bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + + /* use the backend function for this */ + ED_objects_clear_paths(C, scene); + + /* notifiers for updates */ + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_paths_clear (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Clear Object Paths"; + ot->idname= "OBJECT_OT_paths_clear"; + ot->description= "Clear path caches for selected bones."; + + /* api callbacks */ + ot->exec= object_clear_paths_exec; + ot->poll= ED_operator_object_active_editable; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; +} + + /********************** Smooth/Flat *********************/ static int shade_smooth_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index cfb4cda2460..a11ead1fe9d 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -79,6 +79,8 @@ void OBJECT_OT_restrictview_clear(struct wmOperatorType *ot); void OBJECT_OT_proxy_make(struct wmOperatorType *ot); void OBJECT_OT_shade_smooth(struct wmOperatorType *ot); void OBJECT_OT_shade_flat(struct wmOperatorType *ot); +void OBJECT_OT_paths_calculate(struct wmOperatorType *ot); +void OBJECT_OT_paths_clear(struct wmOperatorType *ot); /* object_select.c */ void OBJECT_OT_select_all(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 8b29e2ca2ae..80992887e97 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -81,6 +81,8 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_restrictview_set); WM_operatortype_append(OBJECT_OT_shade_smooth); WM_operatortype_append(OBJECT_OT_shade_flat); + WM_operatortype_append(OBJECT_OT_paths_calculate); + WM_operatortype_append(OBJECT_OT_paths_clear); WM_operatortype_append(OBJECT_OT_parent_set); WM_operatortype_append(OBJECT_OT_parent_no_inverse_set); diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c index b8184a60cee..c57fad96a94 100644 --- a/source/blender/editors/space_view3d/drawanimviz.c +++ b/source/blender/editors/space_view3d/drawanimviz.c @@ -104,6 +104,7 @@ void draw_motion_paths_init(Scene *scene, View3D *v3d, ARegion *ar) * - assumes that the viewport has already been initialised properly * i.e. draw_motion_paths_init() has been called */ +// FIXME: the text is still drawn in the wrong space - it includes the current transforms of the object still... void draw_motion_path_instance(Scene *scene, View3D *v3d, ARegion *ar, Object *ob, bPoseChannel *pchan, bAnimVizSettings *avs, bMotionPath *mpath) { @@ -273,7 +274,7 @@ void draw_motion_path_instance(Scene *scene, View3D *v3d, ARegion *ar, glPointSize(1.0f); /* Draw frame numbers of keyframes */ - if (avs->path_viewflag & (MOTIONPATH_VIEW_FNUMS|MOTIONPATH_VIEW_KFNOS)) { + if (avs->path_viewflag & MOTIONPATH_VIEW_FNUMS) { for (i=0, mpv=mpv_start; i < len; i++, mpv++) { float mframe= (float)(sfra + i); diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index c59c5cddb3f..bfdeaef1834 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -2118,200 +2118,21 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt) */ static void draw_pose_paths(Scene *scene, View3D *v3d, ARegion *ar, Object *ob) { - RegionView3D *rv3d= ar->regiondata; - AnimData *adt= BKE_animdata_from_id(&ob->id); + bAnimVizSettings *avs= &ob->pose->avs; bArmature *arm= ob->data; bPoseChannel *pchan; - ActKeyColumn *ak; - DLRBT_Tree keys; - float *fp, *fp_start; - int a, stepsize; - int sfra, efra, len; - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - glPushMatrix(); - glLoadMatrixf(rv3d->viewmat); - - /* version patch here - cannot access frame info from file reading */ - if (arm->pathsize == 0) arm->pathsize= 1; - stepsize = arm->pathsize; + /* setup drawing environment for paths */ + draw_motion_paths_init(scene, v3d, ar); + /* draw paths where they exist and they releated bone is visible */ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if (pchan->bone->layer & arm->layer) { - if (pchan->path) { - /* version patch here - cannot access frame info from file reading */ - if ((pchan->pathsf == 0) || (pchan->pathef == 0)) { - pchan->pathsf= SFRA; - pchan->pathef= EFRA; - } - - /* get frame ranges */ - if (arm->pathflag & ARM_PATH_ACFRA) { - int sind; - - /* With "Around Current", we only choose frames from around - * the current frame to draw. However, this range is still - * restricted by the limits of the original path. - */ - sfra= CFRA - arm->pathbc; - efra= CFRA + arm->pathac; - if (sfra < pchan->pathsf) sfra= pchan->pathsf; - if (efra > pchan->pathef) efra= pchan->pathef; - - len= efra - sfra; - - sind= sfra - pchan->pathsf; - fp_start= (pchan->path + (3*sind)); - } - else { - sfra= pchan->pathsf; - efra = sfra + pchan->pathlen; - len = pchan->pathlen; - fp_start = pchan->path; - } - - /* draw curve-line of path */ - glShadeModel(GL_SMOOTH); - - glBegin(GL_LINE_STRIP); - for (a=0, fp=fp_start; a<len; a++, fp+=3) { - float intensity; /* how faint */ - - /* set color - * - more intense for active/selected bones, less intense for unselected bones - * - black for before current frame, green for current frame, blue for after current frame - * - intensity decreases as distance from current frame increases - */ - #define SET_INTENSITY(A, B, C, min, max) (((1.0f - ((C - B) / (C - A))) * (max-min)) + min) - if ((a+sfra) < CFRA) { - /* black - before cfra */ - if (pchan->bone->flag & BONE_SELECTED) { - // intensity= 0.5f; - intensity = SET_INTENSITY(sfra, a, CFRA, 0.25f, 0.75f); - } - else { - //intensity= 0.8f; - intensity = SET_INTENSITY(sfra, a, CFRA, 0.68f, 0.92f); - } - UI_ThemeColorBlend(TH_WIRE, TH_BACK, intensity); - } - else if ((a+sfra) > CFRA) { - /* blue - after cfra */ - if (pchan->bone->flag & BONE_SELECTED) { - //intensity = 0.5f; - intensity = SET_INTENSITY(CFRA, a, efra, 0.25f, 0.75f); - } - else { - //intensity = 0.8f; - intensity = SET_INTENSITY(CFRA, a, efra, 0.68f, 0.92f); - } - UI_ThemeColorBlend(TH_BONE_POSE, TH_BACK, intensity); - } - else { - /* green - on cfra */ - if (pchan->bone->flag & BONE_SELECTED) { - intensity= 0.5f; - } - else { - intensity= 0.99f; - } - UI_ThemeColorBlendShade(TH_CFRAME, TH_BACK, intensity, 10); - } - - /* draw a vertex with this color */ - glVertex3fv(fp); - } - - glEnd(); - glShadeModel(GL_FLAT); - - glPointSize(1.0); - - /* draw little black point at each frame - * NOTE: this is not really visible/noticable - */ - glBegin(GL_POINTS); - for (a=0, fp=fp_start; a<len; a++, fp+=3) - glVertex3fv(fp); - glEnd(); - - /* Draw little white dots at each framestep value */ - UI_ThemeColor(TH_TEXT_HI); - glBegin(GL_POINTS); - for (a=0, fp=fp_start; a<len; a+=stepsize, fp+=(stepsize*3)) - glVertex3fv(fp); - glEnd(); - - /* Draw frame numbers at each framestep value */ - if (arm->pathflag & ARM_PATH_FNUMS) { - for (a=0, fp=fp_start; a<len; a+=stepsize, fp+=(stepsize*3)) { - char str[32]; - - /* only draw framenum if several consecutive highlighted points don't occur on same point */ - if (a == 0) { - sprintf(str, "%d", (a+sfra)); - view3d_cached_text_draw_add(fp[0], fp[1], fp[2], str, 0); - } - else if ((a > stepsize) && (a < len-stepsize)) { - if ((equals_v3v3(fp, fp-(stepsize*3))==0) || (equals_v3v3(fp, fp+(stepsize*3))==0)) { - sprintf(str, "%d", (a+sfra)); - view3d_cached_text_draw_add(fp[0], fp[1], fp[2], str, 0); - } - } - } - } - - /* Keyframes - dots and numbers */ - if (arm->pathflag & ARM_PATH_KFRAS) { - /* build list of all keyframes in active action for pchan */ - BLI_dlrbTree_init(&keys); - - if (adt) { - bActionGroup *agrp= action_groups_find_named(adt->action, pchan->name); - if (agrp) { - agroup_to_keylist(adt, agrp, &keys, NULL); - BLI_dlrbTree_linkedlist_sync(&keys); - } - } - - /* Draw slightly-larger yellow dots at each keyframe */ - UI_ThemeColor(TH_VERTEX_SELECT); - glPointSize(5.0f); - - glBegin(GL_POINTS); - for (a=0, fp=fp_start; a<len; a++, fp+=3) { - for (ak= keys.first; ak; ak= ak->next) { - if (ak->cfra == (a+sfra)) - glVertex3fv(fp); - } - } - glEnd(); - - glPointSize(1.0f); - - /* Draw frame numbers of keyframes */ - if ((arm->pathflag & ARM_PATH_FNUMS) || (arm->pathflag & ARM_PATH_KFNOS)) { - for(a=0, fp=fp_start; a<len; a++, fp+=3) { - for (ak= keys.first; ak; ak= ak->next) { - if (ak->cfra == (a+sfra)) { - char str[32]; - - sprintf(str, "%d", (a+sfra)); - view3d_cached_text_draw_add(fp[0], fp[1], fp[2], str, 0); - } - } - } - } - - BLI_dlrbTree_free(&keys); - } - } - } + if ((pchan->bone->layer & arm->layer) && (pchan->mpath)) + draw_motion_path_instance(scene, v3d, ar, ob, pchan, avs, pchan->mpath); } - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - glPopMatrix(); + /* cleanup after drawing */ + draw_motion_paths_cleanup(scene, v3d, ar); } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index c3e248c9d7c..b10b74ff160 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -5180,6 +5180,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* no return after this point, otherwise leaks */ view3d_cached_text_draw_begin(); + /* draw keys? */ #if 0 // XXX old animation system @@ -5260,8 +5261,19 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* patch? children objects with a timeoffs change the parents. How to solve! */ /* if( ((int)ob->ctime) != F_(scene->r.cfra)) where_is_object(scene, ob); */ - /* draw paths... */ - // TODO... + /* draw motion paths (in view space) */ + if (ob->mpath) { + bAnimVizSettings *avs= &ob->avs; + + /* setup drawing environment for paths */ + draw_motion_paths_init(scene, v3d, ar); + + /* draw motion path for object */ + draw_motion_path_instance(scene, v3d, ar, ob, NULL, avs, ob->mpath); + + /* cleanup after drawing */ + draw_motion_paths_cleanup(scene, v3d, ar); + } /* multiply view with object matrix. * local viewmat and persmat, to calculate projections */ |