Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/constraint.c
| Show First 20 Lines • Show All 886 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| bChildOfConstraint *data = con->data; | bChildOfConstraint *data = con->data; | ||||
| bConstraintTarget *ct = targets->first; | bConstraintTarget *ct = targets->first; | ||||
| /* only evaluate if there is a target */ | /* only evaluate if there is a target */ | ||||
| if (VALID_CONS_TARGET(ct)) { | if (VALID_CONS_TARGET(ct)) { | ||||
| float parmat[4][4]; | float parmat[4][4]; | ||||
| /* Compute the inverse matrix if requested. */ | |||||
| if (data->flag & CHILDOF_SET_INVERSE) { | |||||
| /* TODO: handle the channel flag mess below - but this is no worse than before. */ | |||||
| float iparmat[4][4], iobmat[4][4]; | |||||
| invert_m4_m4(iparmat, ct->matrix); | |||||
| invert_m4_m4(iobmat, cob->matrix); | |||||
| mul_m4_series(data->invmat, iparmat, cob->prevmat, iobmat); | |||||
| data->flag &= ~CHILDOF_SET_INVERSE; | |||||
| /* Write the computed matrix back to the master copy if in COW evaluation. */ | |||||
| bConstraint *orig_con = constraint_find_original_for_update(cob, con); | |||||
| if (orig_con != NULL) { | |||||
| bChildOfConstraint *orig_data = orig_con->data; | |||||
| copy_m4_m4(orig_data->invmat, data->invmat); | |||||
| orig_data->flag &= ~CHILDOF_SET_INVERSE; | |||||
| } | |||||
| } | |||||
| /* simple matrix parenting */ | /* simple matrix parenting */ | ||||
| if (data->flag == CHILDOF_ALL) { | if ((data->flag & CHILDOF_ALL) == CHILDOF_ALL) { | ||||
| /* multiply target (parent matrix) by offset (parent inverse) to get | /* multiply target (parent matrix) by offset (parent inverse) to get | ||||
| * the effect of the parent that will be exerted on the owner | * the effect of the parent that will be exerted on the owner | ||||
| */ | */ | ||||
| mul_m4_m4m4(parmat, ct->matrix, data->invmat); | mul_m4_m4m4(parmat, ct->matrix, data->invmat); | ||||
| /* now multiply the parent matrix by the owner matrix to get the | /* now multiply the parent matrix by the owner matrix to get the | ||||
| * the effect of this constraint (i.e. owner is 'parented' to parent) | * the effect of this constraint (i.e. owner is 'parented' to parent) | ||||
| ▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | else { | ||||
| cob->matrix[3][1] = tempmat[3][1]; | cob->matrix[3][1] = tempmat[3][1]; | ||||
| } | } | ||||
| if (!(data->flag & CHILDOF_LOCZ)) { | if (!(data->flag & CHILDOF_LOCZ)) { | ||||
| cob->matrix[3][2] = tempmat[3][2]; | cob->matrix[3][2] = tempmat[3][2]; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* XXX note, con->flag should be CONSTRAINT_SPACEONCE for bone-childof, patched in readfile.c */ | /* XXX note, con->flag should be CONSTRAINT_SPACEONCE for bone-childof, patched in readfile.c */ | ||||
sybren: The space that should be between "matrixto" sneakily made its way to become a double space… | |||||
| static bConstraintTypeInfo CTI_CHILDOF = { | static bConstraintTypeInfo CTI_CHILDOF = { | ||||
| CONSTRAINT_TYPE_CHILDOF, /* type */ | CONSTRAINT_TYPE_CHILDOF, /* type */ | ||||
| sizeof(bChildOfConstraint), /* size */ | sizeof(bChildOfConstraint), /* size */ | ||||
| "Child Of", /* name */ | "Child Of", /* name */ | ||||
| "bChildOfConstraint", /* struct name */ | "bChildOfConstraint", /* struct name */ | ||||
| NULL, /* free data */ | NULL, /* free data */ | ||||
| childof_id_looper, /* id looper */ | childof_id_looper, /* id looper */ | ||||
| NULL, /* copy data */ | NULL, /* copy data */ | ||||
| ▲ Show 20 Lines • Show All 3,935 Lines • ▼ Show 20 Lines | static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets)) | ||||
| if (clip) { | if (clip) { | ||||
| MovieTracking *tracking = &clip->tracking; | MovieTracking *tracking = &clip->tracking; | ||||
| MovieTrackingObject *object; | MovieTrackingObject *object; | ||||
| object = BKE_tracking_object_get_named(tracking, data->object); | object = BKE_tracking_object_get_named(tracking, data->object); | ||||
| if (object) { | if (object) { | ||||
| float mat[4][4], obmat[4][4], imat[4][4], cammat[4][4], camimat[4][4], parmat[4][4]; | float mat[4][4], obmat[4][4], imat[4][4], parmat[4][4]; | ||||
| float ctime = DEG_get_ctime(depsgraph); | float ctime = DEG_get_ctime(depsgraph); | ||||
| float framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, ctime); | float framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, ctime); | ||||
| BKE_object_where_is_calc_mat4(camob, cammat); | |||||
| BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, framenr, mat); | BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, framenr, mat); | ||||
| invert_m4_m4(camimat, cammat); | invert_m4_m4(imat, mat); | ||||
| mul_m4_m4m4(parmat, cammat, data->invmat); | mul_m4_m4m4(parmat, camob->obmat, imat); | ||||
| copy_m4_m4(cammat, camob->obmat); | |||||
| copy_m4_m4(obmat, cob->matrix); | copy_m4_m4(obmat, cob->matrix); | ||||
| invert_m4_m4(imat, mat); | /* Recalculate the inverse matrix if requested. */ | ||||
| if (data->flag & OBJECTSOLVER_SET_INVERSE) { | |||||
| float iparmat[4][4], iobmat[4][4]; | |||||
| invert_m4_m4(iparmat, parmat); | |||||
| invert_m4_m4(iobmat, obmat); | |||||
| mul_m4_series(data->invmat, iparmat, cob->prevmat, iobmat); | |||||
| data->flag &= ~OBJECTSOLVER_SET_INVERSE; | |||||
| mul_m4_series(cob->matrix, cammat, imat, camimat, parmat, obmat); | /* Write the computed matrix back to the master copy if in COW evaluation. */ | ||||
| bConstraint *orig_con = constraint_find_original_for_update(cob, con); | |||||
| if (orig_con != NULL) { | |||||
| bObjectSolverConstraint *orig_data = orig_con->data; | |||||
| copy_m4_m4(orig_data->invmat, data->invmat); | |||||
| orig_data->flag &= ~OBJECTSOLVER_SET_INVERSE; | |||||
| } | |||||
| } | |||||
| mul_m4_series(cob->matrix, parmat, data->invmat, obmat); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static bConstraintTypeInfo CTI_OBJECTSOLVER = { | static bConstraintTypeInfo CTI_OBJECTSOLVER = { | ||||
| CONSTRAINT_TYPE_OBJECTSOLVER, /* type */ | CONSTRAINT_TYPE_OBJECTSOLVER, /* type */ | ||||
| sizeof(bObjectSolverConstraint), /* size */ | sizeof(bObjectSolverConstraint), /* size */ | ||||
| "Object Solver", /* name */ | "Object Solver", /* name */ | ||||
| ▲ Show 20 Lines • Show All 828 Lines • ▼ Show 20 Lines | |||||
| * after running this function, to sort out cob | * after running this function, to sort out cob | ||||
| */ | */ | ||||
| void BKE_constraints_solve(struct Depsgraph *depsgraph, | void BKE_constraints_solve(struct Depsgraph *depsgraph, | ||||
| ListBase *conlist, | ListBase *conlist, | ||||
| bConstraintOb *cob, | bConstraintOb *cob, | ||||
| float ctime) | float ctime) | ||||
| { | { | ||||
| bConstraint *con; | bConstraint *con; | ||||
| float oldmat[4][4]; | |||||
| float enf; | float enf; | ||||
| /* check that there is a valid constraint object to evaluate */ | /* check that there is a valid constraint object to evaluate */ | ||||
| if (cob == NULL) { | if (cob == NULL) { | ||||
| return; | return; | ||||
| } | } | ||||
| /* loop over available constraints, solving and blending them */ | /* loop over available constraints, solving and blending them */ | ||||
| Show All 18 Lines | for (con = conlist->first; con; con = con->next) { | ||||
| } | } | ||||
| /* influence of constraint | /* influence of constraint | ||||
| * - value should have been set from animation data already | * - value should have been set from animation data already | ||||
| */ | */ | ||||
| enf = con->enforce; | enf = con->enforce; | ||||
| /* make copy of worldspace matrix pre-constraint for use with blending later */ | /* make copy of worldspace matrix pre-constraint for use with blending later */ | ||||
| copy_m4_m4(oldmat, cob->matrix); | copy_m4_m4(cob->prevmat, cob->matrix); | ||||
| /* restore the matrix from the start of the stack if requested */ | |||||
| if (con->flag & CONSTRAINT_START_MATRIX) { | |||||
| copy_m4_m4(cob->matrix, cob->startmat); | |||||
| } | |||||
| /* move owner matrix into right space */ | /* move owner matrix into right space */ | ||||
| BKE_constraint_mat_convertspace( | BKE_constraint_mat_convertspace( | ||||
| cob->ob, cob->pchan, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace, false); | cob->ob, cob->pchan, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace, false); | ||||
| /* prepare targets for constraint solving */ | /* prepare targets for constraint solving */ | ||||
| BKE_constraint_targets_for_solving_get(depsgraph, con, cob, &targets, ctime); | BKE_constraint_targets_for_solving_get(depsgraph, con, cob, &targets, ctime); | ||||
| Show All 19 Lines | for (con = conlist->first; con; con = con->next) { | ||||
| * (T26014 and T25725), since some constraints may not convert the solution back to the input | * (T26014 and T25725), since some constraints may not convert the solution back to the input | ||||
| * space before blending but all are guaranteed to end up in good "worldspace" result. | * space before blending but all are guaranteed to end up in good "worldspace" result. | ||||
| */ | */ | ||||
| /* Note: all kind of stuff here before (caused trouble), much easier to just interpolate, | /* Note: all kind of stuff here before (caused trouble), much easier to just interpolate, | ||||
| * or did I miss something? -jahka (r.32105) */ | * or did I miss something? -jahka (r.32105) */ | ||||
| if (enf < 1.0f) { | if (enf < 1.0f) { | ||||
| float solution[4][4]; | float solution[4][4]; | ||||
| copy_m4_m4(solution, cob->matrix); | copy_m4_m4(solution, cob->matrix); | ||||
| interp_m4_m4m4(cob->matrix, oldmat, solution, enf); | interp_m4_m4m4(cob->matrix, cob->prevmat, solution, enf); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
The space that should be between "matrixto" sneakily made its way to become a double space between "i.e. owner".