Merging r42648 through r42722 from trunk into soc-2011-tomato
[blender.git] / source / blender / blenkernel / intern / constraint.c
index 927a98c174fabd4e51261b4ed77b103ce2c0f3df..820f6b9ef5a03c98209aea12c406bbed08aa5c63 100644 (file)
@@ -825,7 +825,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];
@@ -3937,6 +3937,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))
@@ -3944,105 +3945,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(&params);
-                               camera_params_from_object(&params, 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(&params);
+                       camera_params_from_object(&params, 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);
                        }
                }
        }
@@ -4086,16 +4108,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);
        }
 }
@@ -4116,6 +4141,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.
@@ -4156,6 +4255,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