diff options
author | Campbell Barton <ideasman42@gmail.com> | 2011-12-31 07:07:14 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2011-12-31 07:07:14 +0400 |
commit | 81f5c9ed9b8193864f1c6160aed9eef9338f0d27 (patch) | |
tree | de71a52d3ed2c5a1fd47a846af5d68e1c571e606 /source/blender/blenkernel/intern/constraint.c | |
parent | 50ca81154e5ead104723ba137942e92cb860ace8 (diff) | |
parent | 792452a7e53aa92361145e415491943bc91d8a6e (diff) |
svn merge ^/trunk/blender -r42991:43009
Diffstat (limited to 'source/blender/blenkernel/intern/constraint.c')
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 298 |
1 files changed, 205 insertions, 93 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 6e2a17aada6..99b2d96ba10 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -827,7 +827,7 @@ static void childof_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta { bChildOfConstraint *data= con->data; bConstraintTarget *ct= targets->first; - + /* only evaluate if there is a target */ if (VALID_CONS_TARGET(ct)) { float parmat[4][4]; @@ -1257,6 +1257,7 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr float quat[4]; if ((data->followflag & FOLLOWPATH_STATIC) == 0) { /* animated position along curve depending on time */ + Nurb *nu = cu->nurb.first; curvetime= cu->ctime - data->offset; /* ctime is now a proper var setting of Curve which gets set by Animato like any other var that's animated, @@ -1266,7 +1267,18 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr * factor, which then gets clamped to lie within 0.0 - 1.0 range */ curvetime /= cu->pathlen; - CLAMP(curvetime, 0.0f, 1.0f); + + if (nu && nu->flagu & CU_NURB_CYCLIC) { + /* If the curve is cyclic, enable looping around if the time is + * outside the bounds 0..1 */ + if ((curvetime < 0.0f) || (curvetime > 1.0f)) { + curvetime -= floor(curvetime); + } + } + else { + /* The curve is not cyclic, so clamp to the begin/end points. */ + CLAMP(curvetime, 0.0f, 1.0f); + } } else { /* fixed position along curve */ @@ -3939,6 +3951,7 @@ static void followtrack_id_looper (bConstraint *con, ConstraintIDFunc func, void bFollowTrackConstraint *data= con->data; func(con, (ID**)&data->clip, userdata); + func(con, (ID**)&data->camera, userdata); } static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets)) @@ -3946,105 +3959,126 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase Scene *scene= cob->scene; bFollowTrackConstraint *data= con->data; MovieClip *clip= data->clip; + MovieTracking *tracking; MovieTrackingTrack *track; - + MovieTrackingObject *tracking_object; + Object *camob= data->camera ? data->camera : scene->camera; + if (data->flag & FOLLOWTRACK_ACTIVECLIP) clip= scene->clip; - - if (!clip || !data->track[0]) + + if (!clip || !data->track[0] || !camob) return; - - track= BKE_tracking_named_track(&clip->tracking, data->track); - + + tracking= &clip->tracking; + + if(data->object[0]) + tracking_object= BKE_tracking_named_object(tracking, data->object); + else + tracking_object= BKE_tracking_get_camera_object(tracking); + + if(!tracking_object) + return; + + track= BKE_tracking_named_track(tracking, tracking_object, data->track); + if (!track) return; - + if (data->flag & FOLLOWTRACK_USE_3D_POSITION) { if (track->flag & TRACK_HAS_BUNDLE) { - float pos[3], mat[4][4], obmat[4][4]; - + MovieTracking *tracking= &clip->tracking; + float obmat[4][4], mat[4][4]; + copy_m4_m4(obmat, cob->matrix); - - BKE_get_tracking_mat(cob->scene, NULL, mat); - mul_v3_m4v3(pos, mat, track->bundle_pos); - - cob->matrix[3][0] += pos[0]; - cob->matrix[3][1] += pos[1]; - cob->matrix[3][2] += pos[2]; + + if((tracking_object->flag&TRACKING_OBJECT_CAMERA)==0) { + float imat[4][4]; + + copy_m4_m4(mat, camob->obmat); + + BKE_tracking_get_interpolated_camera(tracking, tracking_object, scene->r.cfra, imat); + invert_m4(imat); + + mul_serie_m4(cob->matrix, obmat, mat, imat, NULL, NULL, NULL, NULL, NULL); + translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]); + } + else { + BKE_get_tracking_mat(cob->scene, camob, mat); + + mult_m4_m4m4(cob->matrix, obmat, mat); + translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]); + } } } else { - Object *camob= cob->scene->camera; - - if (camob) { - MovieClipUser user; - MovieTrackingMarker *marker; - float vec[3], disp[3], axis[3], mat[4][4]; - float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp); - float len, d; - - where_is_object_mat(scene, camob, mat); - - /* camera axis */ - vec[0]= 0.0f; - vec[1]= 0.0f; - vec[2]= 1.0f; - mul_v3_m4v3(axis, mat, vec); - - /* distance to projection plane */ - copy_v3_v3(vec, cob->matrix[3]); - sub_v3_v3(vec, mat[3]); - project_v3_v3v3(disp, vec, axis); - - len= len_v3(disp); - - if (len > FLT_EPSILON) { - CameraParams params; - float pos[2], rmat[4][4]; - - user.framenr= scene->r.cfra; - marker= BKE_tracking_get_marker(track, user.framenr); - - add_v2_v2v2(pos, marker->pos, track->offset); - - camera_params_init(¶ms); - camera_params_from_object(¶ms, camob); + MovieClipUser user; + MovieTrackingMarker *marker; + float vec[3], disp[3], axis[3], mat[4][4]; + float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp); + float len, d; - if (params.is_ortho) { - vec[0]= params.ortho_scale * (pos[0]-0.5f+params.shiftx); - vec[1]= params.ortho_scale * (pos[1]-0.5f+params.shifty); - vec[2]= -len; - - if (aspect > 1.0f) vec[1] /= aspect; - else vec[0] *= aspect; - - mul_v3_m4v3(disp, camob->obmat, vec); - - copy_m4_m4(rmat, camob->obmat); - zero_v3(rmat[3]); - mult_m4_m4m4(cob->matrix, cob->matrix, rmat); - - copy_v3_v3(cob->matrix[3], disp); - } - else { - d= (len*params.sensor_x) / (2.0f*params.lens); - - vec[0]= d*(2.0f*(pos[0]+params.shiftx)-1.0f); - vec[1]= d*(2.0f*(pos[1]+params.shifty)-1.0f); - vec[2]= -len; - - if (aspect > 1.0f) vec[1] /= aspect; - else vec[0] *= aspect; - - mul_v3_m4v3(disp, camob->obmat, vec); - - /* apply camera rotation so Z-axis would be co-linear */ - copy_m4_m4(rmat, camob->obmat); - zero_v3(rmat[3]); - mult_m4_m4m4(cob->matrix, cob->matrix, rmat); - - copy_v3_v3(cob->matrix[3], disp); - } + where_is_object_mat(scene, camob, mat); + + /* camera axis */ + vec[0]= 0.0f; + vec[1]= 0.0f; + vec[2]= 1.0f; + mul_v3_m4v3(axis, mat, vec); + + /* distance to projection plane */ + copy_v3_v3(vec, cob->matrix[3]); + sub_v3_v3(vec, mat[3]); + project_v3_v3v3(disp, vec, axis); + + len= len_v3(disp); + + if (len > FLT_EPSILON) { + CameraParams params; + float pos[2], rmat[4][4]; + + user.framenr= scene->r.cfra; + marker= BKE_tracking_get_marker(track, user.framenr); + + add_v2_v2v2(pos, marker->pos, track->offset); + + camera_params_init(¶ms); + camera_params_from_object(¶ms, camob); + + if (params.is_ortho) { + vec[0]= params.ortho_scale * (pos[0]-0.5f+params.shiftx); + vec[1]= params.ortho_scale * (pos[1]-0.5f+params.shifty); + vec[2]= -len; + + if (aspect > 1.0f) vec[1] /= aspect; + else vec[0] *= aspect; + + mul_v3_m4v3(disp, camob->obmat, vec); + + copy_m4_m4(rmat, camob->obmat); + zero_v3(rmat[3]); + mult_m4_m4m4(cob->matrix, cob->matrix, rmat); + + copy_v3_v3(cob->matrix[3], disp); + } + else { + d= (len*params.sensor_x) / (2.0f*params.lens); + + vec[0]= d*(2.0f*(pos[0]+params.shiftx)-1.0f); + vec[1]= d*(2.0f*(pos[1]+params.shifty)-1.0f); + vec[2]= -len; + + if (aspect > 1.0f) vec[1] /= aspect; + else vec[0] *= aspect; + + mul_v3_m4v3(disp, camob->obmat, vec); + + /* apply camera rotation so Z-axis would be co-linear */ + copy_m4_m4(rmat, camob->obmat); + zero_v3(rmat[3]); + mult_m4_m4m4(cob->matrix, cob->matrix, rmat); + + copy_v3_v3(cob->matrix[3], disp); } } } @@ -4088,16 +4122,19 @@ static void camerasolver_evaluate (bConstraint *con, bConstraintOb *cob, ListBas Scene *scene= cob->scene; bCameraSolverConstraint *data= con->data; MovieClip *clip= data->clip; - + if (data->flag & CAMERASOLVER_ACTIVECLIP) clip= scene->clip; - + if (clip) { float mat[4][4], obmat[4][4]; - - BKE_tracking_get_interpolated_camera(&clip->tracking, scene->r.cfra, mat); - + MovieTracking *tracking= &clip->tracking; + MovieTrackingObject *object= BKE_tracking_get_camera_object(tracking); + + BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, mat); + copy_m4_m4(obmat, cob->matrix); + mult_m4_m4m4(cob->matrix, obmat, mat); } } @@ -4118,6 +4155,80 @@ static bConstraintTypeInfo CTI_CAMERASOLVER = { camerasolver_evaluate /* evaluate */ }; +/* ----------- Object Solver ------------- */ + +static void objectsolver_new_data (void *cdata) +{ + bObjectSolverConstraint *data= (bObjectSolverConstraint *)cdata; + + data->clip = NULL; + data->flag |= OBJECTSOLVER_ACTIVECLIP; + unit_m4(data->invmat); +} + +static void objectsolver_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata) +{ + bObjectSolverConstraint *data= con->data; + + func(con, (ID**)&data->clip, userdata); + func(con, (ID**)&data->camera, userdata); +} + +static void objectsolver_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets)) +{ + Scene *scene= cob->scene; + bObjectSolverConstraint *data= con->data; + MovieClip *clip= data->clip; + Object *camob= data->camera ? data->camera : scene->camera; + + if (data->flag & OBJECTSOLVER_ACTIVECLIP) + clip= scene->clip; + + if(!camob || !clip) + return; + + if (clip) { + MovieTracking *tracking= &clip->tracking; + MovieTrackingObject *object; + + object= BKE_tracking_named_object(tracking, data->object); + + if(object) { + float mat[4][4], obmat[4][4], imat[4][4], cammat[4][4], camimat[4][4], parmat[4][4]; + + where_is_object_mat(scene, camob, cammat); + + BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, mat); + + invert_m4_m4(camimat, cammat); + mult_m4_m4m4(parmat, cammat, data->invmat); + + copy_m4_m4(cammat, camob->obmat); + copy_m4_m4(obmat, cob->matrix); + + invert_m4_m4(imat, mat); + + mul_serie_m4(cob->matrix, cammat, imat, camimat, parmat, obmat, NULL, NULL, NULL); + } + } +} + +static bConstraintTypeInfo CTI_OBJECTSOLVER = { + CONSTRAINT_TYPE_OBJECTSOLVER, /* type */ + sizeof(bObjectSolverConstraint), /* size */ + "Object Solver", /* name */ + "bObjectSolverConstraint", /* struct name */ + NULL, /* free data */ + NULL, /* relink data */ + objectsolver_id_looper, /* id looper */ + NULL, /* copy data */ + objectsolver_new_data, /* new data */ + NULL, /* get constraint targets */ + NULL, /* flush constraint targets */ + NULL, /* get target matrix */ + objectsolver_evaluate /* evaluate */ +}; + /* ************************* Constraints Type-Info *************************** */ /* All of the constraints api functions use bConstraintTypeInfo structs to carry out * and operations that involve constraint specific code. @@ -4158,6 +4269,7 @@ static void constraints_init_typeinfo (void) constraintsTypeInfo[25]= &CTI_PIVOT; /* Pivot Constraint */ constraintsTypeInfo[26]= &CTI_FOLLOWTRACK; /* Follow Track Constraint */ constraintsTypeInfo[27]= &CTI_CAMERASOLVER; /* Camera Solver Constraint */ + constraintsTypeInfo[28]= &CTI_OBJECTSOLVER; /* Object Solver Constraint */ } /* This function should be used for getting the appropriate type-info when only |