diff options
Diffstat (limited to 'source/blender/blenkernel/intern/constraint.c')
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 8b5cf3bd196..f904d6e66df 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -44,6 +44,7 @@ #include "BLI_utildefines.h" #include "DNA_armature_types.h" +#include "DNA_camera_types.h" #include "DNA_constraint_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" @@ -51,15 +52,19 @@ #include "DNA_curve_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" + #include "DNA_lattice_types.h" #include "DNA_scene_types.h" #include "DNA_text_types.h" +#include "DNA_tracking_types.h" +#include "DNA_movieclip_types.h" #include "BKE_action.h" #include "BKE_anim.h" /* for the curve calculation part */ #include "BKE_armature.h" #include "BKE_blender.h" +#include "BKE_camera.h" #include "BKE_constraint.h" #include "BKE_displist.h" #include "BKE_deform.h" @@ -72,6 +77,8 @@ #include "BKE_idprop.h" #include "BKE_shrinkwrap.h" #include "BKE_mesh.h" +#include "BKE_tracking.h" +#include "BKE_movieclip.h" #ifdef WITH_PYTHON #include "BPY_extern.h" @@ -3924,6 +3931,203 @@ static bConstraintTypeInfo CTI_PIVOT = { pivotcon_evaluate /* evaluate */ }; +/* ----------- Follow Track ------------- */ + +static void followtrack_new_data (void *cdata) +{ + bFollowTrackConstraint *data= (bFollowTrackConstraint *)cdata; + + data->clip= NULL; + data->flag|= FOLLOWTRACK_ACTIVECLIP; + data->reference= FOLLOWTRACK_TRACK; +} + +static void followtrack_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata) +{ + bFollowTrackConstraint *data= con->data; + + func(con, (ID**)&data->clip, userdata); +} + +static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets)) +{ + Scene *scene= cob->scene; + bFollowTrackConstraint *data= con->data; + MovieClip *clip= data->clip; + MovieTrackingTrack *track; + + if(data->flag&FOLLOWTRACK_ACTIVECLIP) + clip= scene->clip; + + if(!clip || !data->track[0]) + return; + + track= BKE_tracking_named_track(&clip->tracking, data->track); + + if(!track) + return; + + if(data->reference==FOLLOWTRACK_BUNDLE) { + if(track->flag&TRACK_HAS_BUNDLE) { + float pos[3], mat[4][4], obmat[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]; + } + } 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 sensor_x, sensor_y, lens, len, d, ortho_scale= 1.f; + + where_is_object_mat(scene, camob, mat); + + /* camera axis */ + vec[0]= 0.f; + vec[1]= 0.f; + vec[2]= 1.f; + 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) { + float pos[2], rmat[4][4], shiftx= 0.0f, shifty= 0.0f, clipsta= 0.0f, clipend= 0.0f; + short is_ortho= 0, sensor_fit= CAMERA_SENSOR_FIT_AUTO; + Camera *cam= NULL; + + user.framenr= scene->r.cfra; + marker= BKE_tracking_get_marker(track, user.framenr); + + add_v2_v2v2(pos, marker->pos, track->offset); + + object_camera_intrinsics(camob, &cam, &is_ortho, &shiftx, &shifty, &clipsta, &clipend, &lens, &sensor_x, &sensor_y, &sensor_fit); + + if(is_ortho) { + if(cam) + ortho_scale= cam->ortho_scale; + + vec[0]= ortho_scale * (pos[0]-0.5f+shiftx); + vec[1]= ortho_scale * (pos[1]-0.5f+shifty); + vec[2]= -len; + + if(aspect>1.f) vec[1]/= aspect; + else vec[0]*= aspect; + + mul_v3_m4v3(disp, camob->obmat, vec); + + copy_m4_m4(rmat, camob->obmat); + zero_v3(rmat[3]); + mul_m4_m4m4(cob->matrix, rmat, cob->matrix); + + copy_v3_v3(cob->matrix[3], disp); + } + else { + d= (len*sensor_x) / (2.f*lens); + + vec[0]= d*(2.f*(pos[0]+shiftx)-1.f); + vec[1]= d*(2.f*(pos[1]+shifty)-1.f); + vec[2]= -len; + + if(aspect>1.f) 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]); + mul_m4_m4m4(cob->matrix, rmat, cob->matrix); + + copy_v3_v3(cob->matrix[3], disp); + } + } + } + } +} + +static bConstraintTypeInfo CTI_FOLLOWTRACK = { + CONSTRAINT_TYPE_FOLLOWTRACK, /* type */ + sizeof(bFollowTrackConstraint), /* size */ + "Follow Track", /* name */ + "bFollowTrackConstraint", /* struct name */ + NULL, /* free data */ + NULL, /* relink data */ + followtrack_id_looper, /* id looper */ + NULL, /* copy data */ + followtrack_new_data, /* new data */ + NULL, /* get constraint targets */ + NULL, /* flush constraint targets */ + NULL, /* get target matrix */ + followtrack_evaluate /* evaluate */ +}; + +/* ----------- Camre Solver ------------- */ + +static void camerasolver_new_data (void *cdata) +{ + bCameraSolverConstraint *data= (bCameraSolverConstraint *)cdata; + + data->clip= NULL; + data->flag|= CAMERASOLVER_ACTIVECLIP; +} + +static void camerasolver_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata) +{ + bCameraSolverConstraint *data= con->data; + + func(con, (ID**)&data->clip, userdata); +} + +static void camerasolver_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets)) +{ + 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); + + copy_m4_m4(obmat, cob->matrix); + mul_m4_m4m4(cob->matrix, mat, obmat); + } +} + +static bConstraintTypeInfo CTI_CAMERASOLVER = { + CONSTRAINT_TYPE_CAMERASOLVER, /* type */ + sizeof(bCameraSolverConstraint), /* size */ + "Camera Solver", /* name */ + "bCameraSolverConstraint", /* struct name */ + NULL, /* free data */ + NULL, /* relink data */ + camerasolver_id_looper, /* id looper */ + NULL, /* copy data */ + camerasolver_new_data, /* new data */ + NULL, /* get constraint targets */ + NULL, /* flush constraint targets */ + NULL, /* get target matrix */ + camerasolver_evaluate /* evaluate */ +}; + /* ************************* Constraints Type-Info *************************** */ /* All of the constraints api functions use bConstraintTypeInfo structs to carry out * and operations that involve constraint specific code. @@ -3962,6 +4166,8 @@ static void constraints_init_typeinfo (void) constraintsTypeInfo[23]= &CTI_TRANSLIKE; /* Copy Transforms Constraint */ constraintsTypeInfo[24]= &CTI_SAMEVOL; /* Maintain Volume Constraint */ constraintsTypeInfo[25]= &CTI_PIVOT; /* Pivot Constraint */ + constraintsTypeInfo[26]= &CTI_FOLLOWTRACK; /* Follow Track Constraint */ + constraintsTypeInfo[27]= &CTI_CAMERASOLVER; /* Camera Solver Constraint */ } /* This function should be used for getting the appropriate type-info when only |