diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 2b6a84519b6..2486aa9f346 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -531,7 +531,8 @@ void *new_constraint_data (short type) { bActionConstraint *data; data = MEM_callocN(sizeof(bActionConstraint), "actionConstraint"); - + data->local= 1; + result = data; } break; @@ -717,23 +718,29 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own if(data->subtarget[0]) { pchan = get_pose_channel(data->tar->pose, data->subtarget); if (pchan) { - float diff_mat[3][3], arm_mat[3][3], pose_mat[3][3], par_mat[3][3], ipar_mat[3][3]; - /* we need the local rotation = current rotation - (parent rotation + restpos) */ - - Mat3CpyMat4(arm_mat, pchan->bone->arm_mat); - - if (pchan->parent) { - Mat3CpyMat4(par_mat, pchan->parent->pose_mat); - Mat3MulMat3(diff_mat, par_mat, arm_mat); + /* new; true local rotation constraint */ + if(data->local) { + float diff_mat[3][3], arm_mat[3][3], pose_mat[3][3], par_mat[3][3], ipar_mat[3][3]; + /* we need the local rotation = current rotation - (parent rotation + restpos) */ - Mat3Inv(ipar_mat, diff_mat); + Mat3CpyMat4(arm_mat, pchan->bone->arm_mat); + + if (pchan->parent) { + Mat3CpyMat4(par_mat, pchan->parent->pose_mat); + Mat3MulMat3(diff_mat, par_mat, arm_mat); + + Mat3Inv(ipar_mat, diff_mat); + } + else { + Mat3Inv(ipar_mat, arm_mat); + } + + Mat3CpyMat4(pose_mat, pchan->pose_mat); + Mat3MulMat3(tempmat3, ipar_mat, pose_mat); } - else { - Mat3Inv(ipar_mat, arm_mat); + else { /* we use the global rotation, mainly backwards compatibility */ + Mat3CpyMat4(tempmat3, pchan->pose_mat); } - - Mat3CpyMat4(pose_mat, pchan->pose_mat); - Mat3MulMat3(tempmat3, ipar_mat, pose_mat); } else Mat3One(tempmat3); } @@ -746,10 +753,12 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own } Mat3ToEul(tempmat3, eul); - eul[0]*=(float)(180.0/M_PI); eul[1]*=(float)(180.0/M_PI); eul[2]*=(float)(180.0/M_PI); + + if(data->local==0) // backwards compatible negative values... + VecMulf(eul, -1.0f); /* Target defines the animation */ s = (eul[data->type]-data->min)/(data->max-data->min); diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index d7e4e97dce1..2646f803bf9 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -99,7 +99,8 @@ typedef struct bLocateLikeConstraint{ typedef struct bActionConstraint{ Object *tar; - int type; + short type; + short local; short start; short end; float min; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index ae19cd4f684..c8256ee03f1 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -445,17 +445,18 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s uiBlockEndAlign(block); /* Draw action button */ - uiDefIDPoinBut(block, test_actionpoin_but, B_CONSTRAINT_CHANGETARGET, "AC:", *xco+((width/2)-117), *yco-64, 78, 18, &data->act, "Action containing the keyed motion for this bone"); - uiDefButI(block, MENU, B_CONSTRAINT_REDRAW, "Key on%t|X Rot%x0|Y Rot%x1|Z Rot%x2", *xco+((width/2)-117), *yco-84, 78, 18, &data->type, 0, 24, 0, 0, "Specify which transformation channel from the target is used to key the action"); + uiBlockBeginAlign(block); + uiDefButS(block, TOG, B_CONSTRAINT_TEST, "Local", *xco+((width/2)-117), *yco-46, 78, 18, &data->local, 0, 0, 0, 0, "Use true local rotation difference"); + uiDefIDPoinBut(block, test_actionpoin_but, B_CONSTRAINT_TEST, "AC:", *xco+((width/2)-117), *yco-64, 78, 18, &data->act, "Action containing the keyed motion for this bone"); + uiDefButS(block, MENU, B_CONSTRAINT_TEST, "Key on%t|X Rot%x0|Y Rot%x1|Z Rot%x2", *xco+((width/2)-117), *yco-84, 78, 18, &data->type, 0, 24, 0, 0, "Specify which transformation channel from the target is used to key the action"); uiBlockBeginAlign(block); - uiDefButS(block, NUM, B_CONSTRAINT_CHANGETARGET, "Start:", *xco+((width/2)-36), *yco-64, 78, 18, &data->start, 1, MAXFRAME, 0.0, 0.0, "Starting frame of the keyed motion"); - uiDefButS(block, NUM, B_CONSTRAINT_CHANGETARGET, "End:", *xco+((width/2)-36), *yco-84, 78, 18, &data->end, 1, MAXFRAME, 0.0, 0.0, "Ending frame of the keyed motion"); - uiBlockEndAlign(block); + uiDefButS(block, NUM, B_CONSTRAINT_TEST, "Start:", *xco+((width/2)-36), *yco-64, 78, 18, &data->start, 1, MAXFRAME, 0.0, 0.0, "Starting frame of the keyed motion"); + uiDefButS(block, NUM, B_CONSTRAINT_TEST, "End:", *xco+((width/2)-36), *yco-84, 78, 18, &data->end, 1, MAXFRAME, 0.0, 0.0, "Ending frame of the keyed motion"); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Min:", *xco+((width/2)+45), *yco-64, 78, 18, &data->min, -180, 180, 0, 0, "Minimum value for target channel range"); - uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Max:", *xco+((width/2)+45), *yco-84, 78, 18, &data->max, -180, 180, 0, 0, "Maximum value for target channel range"); + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Min:", *xco+((width/2)+45), *yco-64, 78, 18, &data->min, -180, 180, 0, 0, "Minimum value for target channel range"); + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Max:", *xco+((width/2)+45), *yco-84, 78, 18, &data->max, -180, 180, 0, 0, "Maximum value for target channel range"); uiBlockEndAlign(block); } break;