Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Leung <aligorith@gmail.com>2009-09-19 15:59:23 +0400
committerJoshua Leung <aligorith@gmail.com>2009-09-19 15:59:23 +0400
commit9710673192f5ed972343c8e9cc6438fc97eb573e (patch)
tree1dd494be72243af1876835dfb9a5b6365ced9a32 /source/blender/editors/armature/poseSlide.c
parent1ec44f3bb2f371b4f4c389e5f0d4a0c655672c9a (diff)
2.5 - Animation Bugfixes:
* Breakdown tool for Poses (Shift-E in PoseMode) now works. Now this works as a modal operator when invoked, with the horizontal movement of the mouse (left to right) corresponding the placement of the breakdown relative to the endpoint keyframes. * Moving bones between armature layers in Edit Mode didn't work (wrong variable name used) * Fixed several notifier-related bugs regarding editing armature settings and the 3d-view not refreshing * Duplicating bones preserves the rotation mode * Animation Data for Nodes is now show in Datablocks viewer (i.e. AnimData for NodeTrees has now been wrapped)
Diffstat (limited to 'source/blender/editors/armature/poseSlide.c')
-rw-r--r--source/blender/editors/armature/poseSlide.c158
1 files changed, 113 insertions, 45 deletions
diff --git a/source/blender/editors/armature/poseSlide.c b/source/blender/editors/armature/poseSlide.c
index 464dbcba54b..bbc9ef4d09c 100644
--- a/source/blender/editors/armature/poseSlide.c
+++ b/source/blender/editors/armature/poseSlide.c
@@ -103,6 +103,7 @@ typedef struct tPoseSlideOp {
Scene *scene; /* current scene */
ARegion *ar; /* region that we're operating in (needed for */
Object *ob; /* active object that Pose Info comes from */
+ bArmature *arm; /* armature for pose */
ListBase pfLinks; /* links between posechannels and f-curves */
DLRBT_Tree keys; /* binary tree for quicker searching for keyframes (when applicable) */
@@ -151,6 +152,7 @@ static int pose_slide_init (bContext *C, wmOperator *op, short mode)
/* get info from context */
pso->scene= CTX_data_scene(C);
pso->ob= CTX_data_active_object(C);
+ pso->arm= (pso->ob)? pso->ob->data : NULL;
pso->ar= CTX_wm_region(C); /* only really needed when doing modal() */
pso->cframe= pso->scene->r.cfra;
@@ -162,7 +164,7 @@ static int pose_slide_init (bContext *C, wmOperator *op, short mode)
pso->nextFrame= RNA_int_get(op->ptr, "next_frame");
/* check the settings from the context */
- if (ELEM3(NULL, pso->ob, pso->ob->adt, pso->ob->adt->action))
+ if (ELEM4(NULL, pso->ob, pso->arm, pso->ob->adt, pso->ob->adt->action))
return 0;
else
act= pso->ob->adt->action;
@@ -204,6 +206,11 @@ static int pose_slide_init (bContext *C, wmOperator *op, short mode)
}
CTX_DATA_END;
+ /* set depsgraph flags */
+ /* make sure the lock is set OK, unlock can be accidentally saved? */
+ pso->ob->pose->flag |= POSE_LOCKED;
+ pso->ob->pose->flag &= ~POSE_DO_UNLOCK;
+
/* do basic initialise of RB-BST used for finding keyframes, but leave the filling of it up
* to the caller of this (usually only invoke() will do it, to make things more efficient).
*/
@@ -289,8 +296,8 @@ static void pose_slide_apply_vec3 (tPoseSlideOp *pso, tPChanFCurveLink *pfl, flo
/* using this path, find each matching F-Curve for the variables we're interested in */
while ( (ld= find_next_fcurve_link(&pfl->fcurves, ld, path)) ) {
FCurve *fcu= (FCurve *)ld->data;
- float w1, w2, wtot, ctrl, ictrl;
float sVal, eVal;
+ float w1, w2;
int ch;
/* get keyframe values for endpoint poses to blend with */
@@ -302,21 +309,26 @@ static void pose_slide_apply_vec3 (tPoseSlideOp *pso, tPChanFCurveLink *pfl, flo
/* get channel index */
ch= fcu->array_index;
- /* get the influence of the control */
- ctrl= pso->percentage;
- ictrl= 1.0f - pso->percentage;
-
- /* calculate the relative weights of the endpoints
- * - these weights are derived from the relative distance of these
- * poses from the current frame
- * - they then get normalised, with the results of these normalised
- */
- w1 = cframe - (float)pso->prevFrame;
- w2 = (float)pso->nextFrame - cframe;
-
- wtot = w1 + w2;
- w1 = w1/wtot;
- w2 = w2/wtot;
+ /* calculate the relative weights of the endpoints */
+ if (pso->mode == POSESLIDE_BREAKDOWN) {
+ /* get weights from the percentage control */
+ w1= pso->percentage; /* this must come second */
+ w2= 1.0f - w1; /* this must come first */
+ }
+ else {
+ /* - these weights are derived from the relative distance of these
+ * poses from the current frame
+ * - they then get normalised so that they only sum up to 1
+ */
+ float wtot;
+
+ w1 = cframe - (float)pso->prevFrame;
+ w2 = (float)pso->nextFrame - cframe;
+
+ wtot = w1 + w2;
+ w1 = (w1/wtot);
+ w2 = (w2/wtot);
+ }
/* depending on the mode, */
switch (pso->mode) {
@@ -332,10 +344,8 @@ static void pose_slide_apply_vec3 (tPoseSlideOp *pso, tPChanFCurveLink *pfl, flo
break;
case POSESLIDE_BREAKDOWN: /* make the current pose slide around between the endpoints */
- // NOTE: just linear interpolation for now, but could add small component of our key if necessary...
- // TODO: this doesn't work at all
- w2= 1.0f - w1;
- vec[ch]= ((sVal * w1) + (eVal * w2));
+ /* perform simple linear interpolation - coefficient for start must come from pso->percentage... */
+ vec[ch]= ((sVal * w2) + (eVal * w1));
break;
}
@@ -449,15 +459,18 @@ static void pose_slide_apply (bContext *C, wmOperator *op, tPoseSlideOp *pso)
}
}
- /* funky depsgraph flags - are these still needed? */
- pso->ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
-
- /* do depsgraph flush */
- DAG_id_flush_update(&pso->ob->id, OB_RECALC_DATA);
+ /* old optimize trick... this enforces to bypass the depgraph
+ * - note: code copied from transform_generics.c -> recalcData()
+ */
+ // FIXME: shouldn't this use the builtin stuff?
+ if ((pso->arm->flag & ARM_DELAYDEFORM)==0)
+ DAG_id_flush_update(&pso->ob->id, OB_RECALC_DATA); /* sets recalc flags */
+ else
+ where_is_pose(pso->scene, pso->ob);
/* note, notifier might evolve */
- //WM_event_add_notifier(C, NC_OBJECT|ND_POSE, pso->ob);
- WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, pso->ob);
+ WM_event_add_notifier(C, NC_OBJECT|ND_POSE, pso->ob);
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
}
/* ------------------------------------ */
@@ -482,7 +495,7 @@ static int pose_slide_invoke_common (bContext *C, wmOperator *op, tPoseSlideOp *
/* consolidate these keyframes, and figure out the nearest ones */
BLI_dlrbTree_linkedlist_sync(&pso->keys);
- /* cancel if no keyframes found... */
+ /* cancel if no keyframes found... */
if (pso->keys.root) {
ActKeyColumn *ak;
@@ -491,14 +504,24 @@ static int pose_slide_invoke_common (bContext *C, wmOperator *op, tPoseSlideOp *
if (ak == NULL) {
/* current frame is not a keyframe, so search */
+ ActKeyColumn *pk= cfra_find_nearest_next_ak(pso->keys.root, pso->cframe, 0);
+ ActKeyColumn *nk= cfra_find_nearest_next_ak(pso->keys.root, pso->cframe, 1);
+
+ /* check if we found good keyframes */
+ if ((pk == nk) && (pk != NULL)) {
+ if (pk->cfra < pso->cframe)
+ nk= nk->next;
+ else if (nk->cfra > pso->cframe)
+ pk= pk->prev;
+ }
+
+ /* new set the frames */
/* prev frame */
- ak= cfra_find_nearest_next_ak(pso->keys.root, pso->cframe, 0);
- pso->prevFrame= (ak)? (ak->cfra) : (pso->cframe - 1);
+ pso->prevFrame= (pk)? (pk->cfra) : (pso->cframe - 1);
RNA_int_set(op->ptr, "prev_frame", pso->prevFrame);
/* next frame */
- ak= cfra_find_nearest_next_ak(pso->keys.root, pso->cframe, 1);
- pso->nextFrame= (ak)? (ak->cfra) : (pso->cframe + 1);
- RNA_int_set(op->ptr, "next_frame", pso->prevFrame);
+ pso->nextFrame= (nk)? (nk->cfra) : (pso->cframe + 1);
+ RNA_int_set(op->ptr, "next_frame", pso->nextFrame);
}
else {
/* current frame itself is a keyframe, so just take keyframes on either side */
@@ -515,18 +538,63 @@ static int pose_slide_invoke_common (bContext *C, wmOperator *op, tPoseSlideOp *
return OPERATOR_CANCELLED;
}
+ // FIXME: for now, just do modal for breakdowns...
+ if (pso->mode == POSESLIDE_BREAKDOWN) {
+ /* initial apply for operator... */
+ pose_slide_apply(C, op, pso);
+
+ /* add a modal handler for this operator */
+ WM_event_add_modal_handler(C, op);
+ return OPERATOR_RUNNING_MODAL;
+ }
+ else {
+ /* temp static operator code... until a way to include percentage in the formulation comes up */
+ pose_slide_apply(C, op, pso);
+ pose_slide_exit(C, op);
+ return OPERATOR_FINISHED;
+ }
+}
+
+/* common code for modal() */
+static int pose_slide_modal (bContext *C, wmOperator *op, wmEvent *evt)
+{
+ tPoseSlideOp *pso= op->customdata;
- // TODO -----------------------------------
- // from here on, we should just invoke the modal operator, but for now, just do static...
+ switch (evt->type) {
+ case LEFTMOUSE: /* confirm */
+ pose_slide_exit(C, op);
+ return OPERATOR_FINISHED;
+
+ case ESCKEY: /* cancel */
+ case RIGHTMOUSE:
+ pose_slide_exit(C, op);
+ return OPERATOR_CANCELLED;
+
+ case MOUSEMOVE: /* calculate new position */
+ {
+ /* calculate percentage based on position of mouse (we only use x-axis for now.
+ * since this is more conveninent for users to do), and store new percentage value
+ */
+ pso->percentage= (evt->x - pso->ar->winrct.xmin) / ((float)pso->ar->winx);
+ RNA_float_set(op->ptr, "percentage", pso->percentage);
+
+ /* apply... */
+ pose_slide_apply(C, op, pso);
+ }
+ break;
+ }
- /* temp static operator code... */
- pose_slide_apply(C, op, pso);
- pose_slide_exit(C, op);
- return OPERATOR_FINISHED;
+ /* still running... */
+ return OPERATOR_RUNNING_MODAL;
}
-// TODO: common modal + cancel
-
+/* common code for cancel() */
+static int pose_slide_cancel (bContext *C, wmOperator *op)
+{
+ /* cleanup and done */
+ pose_slide_exit(C, op);
+ return OPERATOR_CANCELLED;
+}
/* common code for exec() methods */
static int pose_slide_exec_common (bContext *C, wmOperator *op, tPoseSlideOp *pso)
@@ -708,12 +776,12 @@ void POSE_OT_breakdown (wmOperatorType *ot)
/* callbacks */
ot->exec= pose_slide_breakdown_exec;
ot->invoke= pose_slide_breakdown_invoke;
- //ot->modal= pose_slide_modal;
- //ot->cancel= pose_slide_cancel;
+ ot->modal= pose_slide_modal;
+ ot->cancel= pose_slide_cancel;
ot->poll= ED_operator_posemode;
/* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;//|OPTYPE_BLOCKING;
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
/* Properties */
pose_slide_opdef_properties(ot);