Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2011-12-05 22:57:17 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2011-12-05 22:57:17 +0400
commit9355cc5c399a9d7cd49815c68eeeac788022ba1a (patch)
treec4b9c3c19e31b7a06f98486fcbb85008dc51ca5c /source/blender/blenkernel
parentf55f9e95db44838130a18f80b33bd77f58e8a987 (diff)
Object tracking; initial commit
This commit implements basis stuff needed for object tracking, use case isn't perfect now, interface also should be cleaned a bit. - Added list of objects to be tracked. Default there's only one object called "Camera" which is used for solving camera motion. Other objects can be added and each of them will have it;s own list of tracks. Only one object can be used for camera solving at this moment. - Added new constraint called "Object Tracking" which makes oriented object be moving in the save way as solved object motion. - Scene orientation tools can be used for orienting object to bundles. - All tools which works with list of tracks or reconstruction data now gets that lists from active editing object. - All objects and their tracking data are available via python api.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_tracking.h44
-rw-r--r--source/blender/blenkernel/intern/constraint.c180
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c21
-rw-r--r--source/blender/blenkernel/intern/movieclip.c9
-rw-r--r--source/blender/blenkernel/intern/tracking.c363
5 files changed, 499 insertions, 118 deletions
diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h
index e55d40ebfe5..6c43493d1d4 100644
--- a/source/blender/blenkernel/BKE_tracking.h
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -34,11 +34,13 @@
struct bGPDlayer;
struct ImBuf;
+struct ListBase;
struct MovieReconstructContext;
struct MovieTrackingTrack;
struct MovieTrackingMarker;
struct MovieTracking;
struct MovieTrackingContext;
+struct MovieTrackingObject;
struct MovieClipUser;
struct MovieDistortion;
struct Camera;
@@ -49,8 +51,8 @@ void BKE_tracking_init_settings(struct MovieTracking *tracking);
void BKE_tracking_clamp_track(struct MovieTrackingTrack *track, int event);
void BKE_tracking_track_flag(struct MovieTrackingTrack *track, int area, int flag, int clear);
-struct MovieTrackingTrack *BKE_tracking_add_track(struct MovieTracking *tracking, float x, float y,
- int framenr, int width, int height);
+struct MovieTrackingTrack *BKE_tracking_add_track(struct MovieTracking *tracking, struct ListBase *tracksbase,
+ float x, float y, int framenr, int width, int height);
void BKE_tracking_insert_marker(struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker);
void BKE_tracking_delete_marker(struct MovieTrackingTrack *track, int framenr);
@@ -72,16 +74,27 @@ struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTra
struct ImBuf *BKE_tracking_get_search_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track,
struct MovieTrackingMarker *marker, int margin, int anchored, float pos[2], int origin[2]);
-void BKE_track_unique_name(struct MovieTracking *tracking, struct MovieTrackingTrack *track);
+void BKE_track_unique_name(struct ListBase *tracksbase, struct MovieTrackingTrack *track);
-struct MovieTrackingTrack *BKE_tracking_named_track(struct MovieTracking *tracking, const char *name);
+struct MovieTrackingTrack *BKE_tracking_named_track(struct MovieTracking *tracking, struct MovieTrackingObject *object, const char *name);
struct MovieTrackingTrack *BKE_tracking_indexed_track(struct MovieTracking *tracking, int tracknr);
void BKE_tracking_camera_shift(struct MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty);
void BKE_tracking_camera_to_blender(struct MovieTracking *tracking, struct Scene *scene, struct Camera *camera, int width, int height);
void BKE_get_tracking_mat(struct Scene *scene, struct Object *ob, float mat[4][4]);
-void BKE_tracking_projection_matrix(struct MovieTracking *tracking, int framenr, int winx, int winy, float mat[4][4]);
+void BKE_tracking_projection_matrix(struct MovieTracking *tracking, struct MovieTrackingObject *object,
+ int framenr, int winx, int winy, float mat[4][4]);
+
+struct ListBase *BKE_tracking_get_tracks(struct MovieTracking *tracking);
+struct MovieTrackingReconstruction *BKE_tracking_get_reconstruction(struct MovieTracking *tracking);
+
+struct MovieTrackingTrack *BKE_tracking_active_track(struct MovieTracking *tracking);
+struct MovieTrackingObject *BKE_tracking_active_object(struct MovieTracking *tracking);
+struct MovieTrackingObject *BKE_tracking_get_camera_object(struct MovieTracking *tracking);
+struct ListBase *BKE_tracking_object_tracks(struct MovieTracking *tracking, struct MovieTrackingObject *object);
+struct MovieTrackingReconstruction *BKE_tracking_object_reconstruction(struct MovieTracking *tracking,
+ struct MovieTrackingObject *object);
/* 2D tracking */
struct MovieTrackingContext *BKE_tracking_context_new(struct MovieClip *clip, struct MovieClipUser *user,
@@ -92,20 +105,23 @@ void BKE_tracking_sync_user(struct MovieClipUser *user, struct MovieTrackingCont
int BKE_tracking_next(struct MovieTrackingContext *context);
/* Camera solving */
-int BKE_tracking_can_reconstruct(struct MovieTracking *tracking, char *error_msg, int error_size);
+int BKE_tracking_can_reconstruct(struct MovieTracking *tracking, struct MovieTrackingObject *object,
+ char *error_msg, int error_size);
struct MovieReconstructContext* BKE_tracking_reconstruction_context_new(struct MovieTracking *tracking,
- int keyframe1, int keyframe2, int width, int height);
+ struct MovieTrackingObject *object, int keyframe1, int keyframe2, int width, int height);
void BKE_tracking_reconstruction_context_free(struct MovieReconstructContext *context);
void BKE_tracking_solve_reconstruction(struct MovieReconstructContext *context,
short *stop, short *do_update, float *progress, char *stats_message, int message_size);
int BKE_tracking_finish_reconstruction(struct MovieReconstructContext *context, struct MovieTracking *tracking);
-struct MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(struct MovieTracking *tracking, int framenr);
-void BKE_tracking_get_interpolated_camera(struct MovieTracking *tracking, int framenr, float mat[4][4]);
+struct MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(struct MovieTracking *tracking,
+ struct MovieTrackingObject *object, int framenr);
+void BKE_tracking_get_interpolated_camera(struct MovieTracking *tracking,
+ struct MovieTrackingObject *object, int framenr, float mat[4][4]);
/* Feature detection */
-void BKE_tracking_detect_fast(struct MovieTracking *tracking, struct ImBuf *imbuf,
+void BKE_tracking_detect_fast(struct MovieTracking *tracking, struct ListBase *tracksbase, struct ImBuf *imbuf,
int framenr, int margin, int min_trackness, int min_distance, struct bGPDlayer *layer,
int place_outside_layer);
@@ -127,8 +143,14 @@ void BKE_tracking_distortion_destroy(struct MovieDistortion *distortion);
struct ImBuf *BKE_tracking_undistort(struct MovieTracking *tracking, struct ImBuf *ibuf, int width, int height, float overscan);
struct ImBuf *BKE_tracking_distort(struct MovieTracking *tracking, struct ImBuf *ibuf, int width, int height, float overscan);
+/* Object tracking */
+struct MovieTrackingObject *BKE_tracking_new_object(struct MovieTracking *tracking, const char *name);
+void BKE_tracking_remove_object(struct MovieTracking *tracking, struct MovieTrackingObject *object);
+void BKE_tracking_object_unique_name(struct MovieTracking *tracking, struct MovieTrackingObject *object);
+struct MovieTrackingObject *BKE_tracking_named_object(struct MovieTracking *tracking, const char *name);
+
/* Select */
-void BKE_tracking_select_track(struct MovieTracking *tracking, struct MovieTrackingTrack *track, int area, int extend);
+void BKE_tracking_select_track(struct ListBase *tracksbase, struct MovieTrackingTrack *track, int area, int extend);
void BKE_tracking_deselect_track(struct MovieTrackingTrack *track, int area);
#define TRACK_SELECTED(track) ((((track)->flag&TRACK_HIDDEN)==0) && ((track)->flag&SELECT || (track)->pat_flag&SELECT || (track)->search_flag&SELECT))
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 6f29594f811..9d8aae3bb52 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -3953,67 +3953,95 @@ 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;
+
if (data->flag & FOLLOWTRACK_ACTIVECLIP)
clip= scene->clip;
-
+
if (!clip || !data->track[0])
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];
-
- copy_m4_m4(obmat, cob->matrix);
-
- BKE_get_tracking_mat(cob->scene, NULL, mat);
+ MovieTracking *tracking= &clip->tracking;
+ float pos[3], mat[4][4];
+
+ if((tracking_object->flag&TRACKING_OBJECT_CAMERA)==0) {
+ Object *camob= scene->camera;
+ float obmat[4][4], imat[4][4];
+
+ if(!camob)
+ return;
+
+ copy_m4_m4(mat, camob->obmat);
+
+ BKE_tracking_get_interpolated_camera(tracking, tracking_object, scene->r.cfra, obmat);
+
+ invert_m4_m4(imat, obmat);
+ mul_m4_m4m4(mat, imat, mat);
+ }
+ else {
+ 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];
+
+ cob->matrix[3][0] = pos[0];
+ cob->matrix[3][1] = pos[1];
+ cob->matrix[3][2] = pos[2];
}
}
else {
- Object *camob= cob->scene->camera;
-
+ Object *camob= 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);
@@ -4021,35 +4049,35 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase
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]);
mul_m4_m4m4(cob->matrix, rmat, cob->matrix);
-
+
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]);
mul_m4_m4m4(cob->matrix, rmat, cob->matrix);
-
+
copy_v3_v3(cob->matrix[3], disp);
}
}
@@ -4095,16 +4123,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);
+
mul_m4_m4m4(cob->matrix, mat, obmat);
}
}
@@ -4125,6 +4156,76 @@ 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;
+}
+
+static void objectsolver_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
+{
+ bObjectSolverConstraint *data= con->data;
+
+ func(con, (ID**)&data->clip, userdata);
+}
+
+static void objectsolver_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
+{
+ Scene *scene= cob->scene;
+ bObjectSolverConstraint *data= con->data;
+ MovieClip *clip= data->clip;
+
+ if (data->flag & OBJECTSOLVER_ACTIVECLIP)
+ clip= scene->clip;
+
+ if(!scene->camera)
+ 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];
+
+ where_is_object_mat(scene, scene->camera, cammat);
+
+ BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, mat);
+
+ invert_m4_m4(camimat, cammat);
+
+ copy_m4_m4(cammat, scene->camera->obmat);
+ copy_m4_m4(obmat, cob->matrix);
+
+ invert_m4_m4(imat, mat);
+
+ mul_serie_m4(cob->matrix, cammat, imat, camimat, obmat, NULL, 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.
@@ -4165,6 +4266,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
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 4eaf49dc679..b0776a0b51b 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -647,16 +647,21 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
continue;
/* special case for camera tracking -- it doesn't use targets to define relations */
- if(ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER)) {
+ if(ELEM3(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER, CONSTRAINT_TYPE_OBJECTSOLVER)) {
+ int depends_on_camera= 0;
+
if(cti->type==CONSTRAINT_TYPE_FOLLOWTRACK) {
bFollowTrackConstraint *data= (bFollowTrackConstraint *)con->data;
- if((data->clip || data->flag&FOLLOWTRACK_ACTIVECLIP) && data->track[0]) {
- if(scene->camera) {
- node2 = dag_get_node(dag, scene->camera);
- dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB, cti->name);
- }
- }
+ if((data->clip || data->flag&FOLLOWTRACK_ACTIVECLIP) && data->track[0])
+ depends_on_camera= 1;
+ }
+ else if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER)
+ depends_on_camera= 1;
+
+ if(depends_on_camera && scene->camera) {
+ node2 = dag_get_node(dag, scene->camera);
+ dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB, cti->name);
}
dag_add_relation(dag,scenenode,node,DAG_RL_SCENE, "Scene Relation");
@@ -2160,7 +2165,7 @@ static void dag_object_time_update_flags(Object *ob)
if (cti) {
/* special case for camera tracking -- it doesn't use targets to define relations */
- if(ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER)) {
+ if(ELEM3(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER, CONSTRAINT_TYPE_OBJECTSOLVER)) {
ob->recalc |= OB_RECALC_OB;
}
else if (cti->get_constraint_targets) {
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index 75d8ec584e8..04686e6a897 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -813,7 +813,8 @@ void BKE_movieclip_reload(MovieClip *clip)
void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClipScopes *scopes)
{
- if(scopes->ok) return;
+ if(scopes->ok)
+ return;
if(scopes->track_preview) {
IMB_freeImBuf(scopes->track_preview);
@@ -824,8 +825,10 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
scopes->track= NULL;
if(clip) {
- if(clip->tracking.act_track) {
- MovieTrackingTrack *track= clip->tracking.act_track;
+ MovieTrackingTrack *act_track= BKE_tracking_active_track(&clip->tracking);
+
+ if(act_track) {
+ MovieTrackingTrack *track= act_track;
MovieTrackingMarker *marker= BKE_tracking_get_marker(track, user->framenr);
if(marker->flag&MARKER_DISABLED) {
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index 0786abba67d..5d20445b53f 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -54,6 +54,7 @@
#include "BKE_movieclip.h"
#include "BKE_object.h"
#include "BKE_scene.h"
+#include "BKE_main.h" // XXX: ...
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -89,6 +90,8 @@ void BKE_tracking_init_settings(MovieTracking *tracking)
tracking->stabilization.locinf= 1.0f;
tracking->stabilization.rotinf= 1.0f;
tracking->stabilization.maxscale= 2.0f;
+
+ BKE_tracking_new_object(tracking, "Camera");
}
void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event)
@@ -207,7 +210,7 @@ void BKE_tracking_track_flag(MovieTrackingTrack *track, int area, int flag, int
}
}
-MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, float x, float y,
+MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, ListBase *tracksbase, float x, float y,
int framenr, int width, int height)
{
MovieTrackingTrack *track;
@@ -250,8 +253,8 @@ MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, float x, flo
if(track->tracker == TRACKER_KLT)
BKE_tracking_clamp_track(track, CLAMP_PYRAMID_LEVELS);
- BLI_addtail(&tracking->tracks, track);
- BKE_track_unique_name(tracking, track);
+ BLI_addtail(tracksbase, track);
+ BKE_track_unique_name(tracksbase, track);
return track;
}
@@ -523,18 +526,44 @@ void BKE_tracking_join_tracks(MovieTrackingTrack *dst_track, MovieTrackingTrack
dst_track->markersnr= tot;
}
-void BKE_tracking_free(MovieTracking *tracking)
+static void tracking_tracks_free(ListBase *tracks)
{
MovieTrackingTrack *track;
- for(track= tracking->tracks.first; track; track= track->next) {
+ for(track= tracks->first; track; track= track->next) {
BKE_tracking_free_track(track);
}
- BLI_freelistN(&tracking->tracks);
+ BLI_freelistN(tracks);
+}
+
+static void tracking_reconstruction_free(MovieTrackingReconstruction *reconstruction)
+{
+ if(reconstruction->cameras)
+ MEM_freeN(reconstruction->cameras);
+}
+
+static void tracking_object_free(MovieTrackingObject *object)
+{
+ tracking_tracks_free(&object->tracks);
+ tracking_reconstruction_free(&object->reconstruction);
+}
+
+static void tracking_objects_free(ListBase *objects)
+{
+ MovieTrackingObject *object;
+
+ for(object= objects->first; object; object= object->next)
+ tracking_object_free(object);
- if(tracking->reconstruction.cameras)
- MEM_freeN(tracking->reconstruction.cameras);
+ BLI_freelistN(objects);
+}
+
+void BKE_tracking_free(MovieTracking *tracking)
+{
+ tracking_tracks_free(&tracking->tracks);
+ tracking_reconstruction_free(&tracking->reconstruction);
+ tracking_objects_free(&tracking->objects);
if(tracking->stabilization.scaleibuf)
IMB_freeImBuf(tracking->stabilization.scaleibuf);
@@ -546,6 +575,9 @@ void BKE_tracking_free(MovieTracking *tracking)
/*********************** tracks map *************************/
typedef struct TracksMap {
+ char object_name[32];
+ int is_camera;
+
int num_tracks;
int customdata_size;
@@ -557,10 +589,13 @@ typedef struct TracksMap {
int ptr;
} TracksMap;
-static TracksMap *tracks_map_new(int num_tracks, int customdata_size)
+static TracksMap *tracks_map_new(const char *object_name, int is_camera, int num_tracks, int customdata_size)
{
TracksMap *map= MEM_callocN(sizeof(TracksMap), "TrackingsMap");
+ strcpy(map->object_name, object_name);
+ map->is_camera= is_camera;
+
map->num_tracks= num_tracks;
map->customdata_size= customdata_size;
@@ -606,10 +641,24 @@ static void tracks_map_insert(TracksMap *map, MovieTrackingTrack *track, void *c
static void tracks_map_merge(TracksMap *map, MovieTracking *tracking)
{
MovieTrackingTrack *track;
+ MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking);
ListBase tracks= {NULL, NULL}, new_tracks= {NULL, NULL};
- ListBase *old_tracks= &tracking->tracks;
+ ListBase *old_tracks;
int a;
+ if(map->is_camera) {
+ old_tracks= &tracking->tracks;
+ } else {
+ MovieTrackingObject *object= BKE_tracking_named_object(tracking, map->object_name);
+
+ if(!object) {
+ /* object was deleted by user, create new one */
+ object= BKE_tracking_new_object(tracking, map->object_name);
+ }
+
+ old_tracks= &object->tracks;
+ }
+
/* duplicate currently operating tracks to temporary list.
this is needed to keep names in unique state and it's faster to change names
of currently operating tracks (if needed) */
@@ -633,7 +682,7 @@ static void tracks_map_merge(TracksMap *map, MovieTracking *tracking)
/* original track was found, re-use flags and remove this track */
if(cur) {
- if(cur==tracking->act_track)
+ if(act_track)
replace_sel= 1;
track->flag= cur->flag;
@@ -684,7 +733,7 @@ static void tracks_map_merge(TracksMap *map, MovieTracking *tracking)
track= next;
}
- tracking->tracks= new_tracks;
+ *old_tracks= new_tracks;
}
static void tracks_map_free(TracksMap *map, void (*customdata_free) (void *customdata))
@@ -744,7 +793,9 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u
MovieTrackingContext *context= MEM_callocN(sizeof(MovieTrackingContext), "trackingContext");
MovieTracking *tracking= &clip->tracking;
MovieTrackingSettings *settings= &tracking->settings;
+ ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
MovieTrackingTrack *track;
+ MovieTrackingObject *object= BKE_tracking_active_object(tracking);
int num_tracks= 0;
context->settings= *settings;
@@ -754,7 +805,7 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u
context->first_time= 1;
/* count */
- track= tracking->tracks.first;
+ track= tracksbase->first;
while(track) {
if(TRACK_SELECTED(track) && (track->flag&TRACK_LOCKED)==0) {
MovieTrackingMarker *marker= BKE_tracking_get_marker(track, user->framenr);
@@ -769,12 +820,13 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u
if(num_tracks) {
int width, height;
- context->tracks_map= tracks_map_new(num_tracks, sizeof(TrackContext));
+ context->tracks_map= tracks_map_new(object->name, object->flag & TRACKING_OBJECT_CAMERA,
+ num_tracks, sizeof(TrackContext));
BKE_movieclip_get_size(clip, user, &width, &height);
/* create tracking data */
- track= tracking->tracks.first;
+ track= tracksbase->first;
while(track) {
if(TRACK_SELECTED(track) && (track->flag&TRACK_LOCKED)==0) {
MovieTrackingMarker *marker= BKE_tracking_get_marker(track, user->framenr);
@@ -1370,6 +1422,8 @@ typedef struct MovieReconstructContext {
struct libmv_Reconstruction *reconstruction;
#endif
+ char object_name[32];
+ int is_camera;
float focal_length;
float principal_point[2];
@@ -1391,13 +1445,13 @@ typedef struct ReconstructProgressData {
} ReconstructProgressData;
#if WITH_LIBMV
-static struct libmv_Tracks *create_libmv_tracks(MovieTracking *tracking, int width, int height)
+static struct libmv_Tracks *create_libmv_tracks(ListBase *tracksbase, int width, int height)
{
int tracknr= 0;
MovieTrackingTrack *track;
struct libmv_Tracks *tracks= libmv_tracksNew();
- track= tracking->tracks.first;
+ track= tracksbase->first;
while(track) {
int a= 0;
@@ -1441,16 +1495,28 @@ static void retrieve_libmv_reconstruct_intrinscis(MovieReconstructContext *conte
static int retrieve_libmv_reconstruct_tracks(MovieReconstructContext *context, MovieTracking *tracking)
{
struct libmv_Reconstruction *libmv_reconstruction= context->reconstruction;
- MovieTrackingReconstruction *reconstruction= &tracking->reconstruction;
+ MovieTrackingReconstruction *reconstruction= NULL;
MovieReconstructedCamera *reconstructed;
MovieTrackingTrack *track;
+ ListBase *tracksbase= NULL;
int ok= 1, tracknr= 0, a, origin_set= 0;
int sfra= context->sfra, efra= context->efra;
float imat[4][4];
+ if(context->is_camera) {
+ tracksbase= &tracking->tracks;
+ reconstruction= &tracking->reconstruction;
+ }
+ else {
+ MovieTrackingObject *object= BKE_tracking_named_object(tracking, context->object_name);
+
+ tracksbase= &object->tracks;
+ reconstruction= &object->reconstruction;
+ }
+
unit_m4(imat);
- track= tracking->tracks.first;
+ track= tracksbase->first;
while(track) {
double pos[3];
@@ -1516,7 +1582,7 @@ static int retrieve_libmv_reconstruct_tracks(MovieReconstructContext *context, M
}
if(origin_set) {
- track= tracking->tracks.first;
+ track= tracksbase->first;
while(track) {
if(track->flag&TRACK_HAS_BUNDLE)
mul_v3_m4v3(track->bundle_pos, imat, track->bundle_pos);
@@ -1532,8 +1598,6 @@ static int retrieve_libmv_reconstruct_tracks(MovieReconstructContext *context, M
static int retrieve_libmv_reconstruct(MovieReconstructContext *context, MovieTracking *tracking)
{
- tracks_map_merge(context->tracks_map, tracking);
-
/* take the intrinscis back from libmv */
retrieve_libmv_reconstruct_intrinscis(context, tracking);
@@ -1560,13 +1624,13 @@ static int get_refine_intrinsics_flags(MovieTracking *tracking)
return flags;
}
-static int count_tracks_on_both_keyframes(MovieTracking *tracking)
+static int count_tracks_on_both_keyframes(MovieTracking *tracking, ListBase *tracksbase)
{
int tot= 0;
int frame1= tracking->settings.keyframe1, frame2= tracking->settings.keyframe2;
MovieTrackingTrack *track;
- track= tracking->tracks.first;
+ track= tracksbase->first;
while(track) {
if(BKE_tracking_has_marker(track, frame1))
if(BKE_tracking_has_marker(track, frame2))
@@ -1579,10 +1643,12 @@ static int count_tracks_on_both_keyframes(MovieTracking *tracking)
}
#endif
-int BKE_tracking_can_reconstruct(MovieTracking *tracking, char *error_msg, int error_size)
+int BKE_tracking_can_reconstruct(MovieTracking *tracking, MovieTrackingObject *object, char *error_msg, int error_size)
{
#if WITH_LIBMV
- if(count_tracks_on_both_keyframes(tracking)<8) {
+ ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object);
+
+ if(count_tracks_on_both_keyframes(tracking, tracksbase)<8) {
BLI_strncpy(error_msg, "At least 8 tracks on both of keyframes are needed for reconstruction", error_size);
return 0;
}
@@ -1597,17 +1663,22 @@ int BKE_tracking_can_reconstruct(MovieTracking *tracking, char *error_msg, int e
}
MovieReconstructContext* BKE_tracking_reconstruction_context_new(MovieTracking *tracking,
- int keyframe1, int keyframe2, int width, int height)
+ MovieTrackingObject *object, int keyframe1, int keyframe2, int width, int height)
{
MovieReconstructContext *context= MEM_callocN(sizeof(MovieReconstructContext), "MovieReconstructContext data");
MovieTrackingCamera *camera= &tracking->camera;
+ ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object);
float aspy= 1.0f/tracking->camera.pixel_aspect;
- int num_tracks= BLI_countlist(&tracking->tracks);
+ int num_tracks= BLI_countlist(tracksbase);
int sfra= INT_MAX, efra= INT_MIN;
MovieTrackingTrack *track;
- context->tracks_map= tracks_map_new(num_tracks, 0);
- track= tracking->tracks.first;
+ strcpy(context->object_name, object->name);
+ context->is_camera = object->flag&TRACKING_OBJECT_CAMERA;
+
+ context->tracks_map= tracks_map_new(context->object_name, context->is_camera, num_tracks, 0);
+
+ track= tracksbase->first;
while(track) {
int first= 0, last= track->markersnr;
MovieTrackingMarker *first_marker= &track->markers[0];
@@ -1640,7 +1711,7 @@ MovieReconstructContext* BKE_tracking_reconstruction_context_new(MovieTracking *
context->efra= efra;
#ifdef WITH_LIBMV
- context->tracks= create_libmv_tracks(tracking, width, height*aspy);
+ context->tracks= create_libmv_tracks(tracksbase, width, height*aspy);
context->keyframe1= keyframe1;
context->keyframe2= keyframe2;
context->refine_flags= get_refine_intrinsics_flags(tracking);
@@ -1740,8 +1811,22 @@ void BKE_tracking_solve_reconstruction(MovieReconstructContext *context, short *
int BKE_tracking_finish_reconstruction(MovieReconstructContext *context, MovieTracking *tracking)
{
- tracking->reconstruction.error= context->reprojection_error;
- tracking->reconstruction.flag|= TRACKING_RECONSTRUCTED;
+ MovieTrackingReconstruction *reconstruction;
+
+ tracks_map_merge(context->tracks_map, tracking);
+
+ if(context->is_camera) {
+ reconstruction= &tracking->reconstruction;
+ }
+ else {
+ MovieTrackingObject *object;
+
+ object= BKE_tracking_named_object(tracking, context->object_name);
+ reconstruction= &object->reconstruction;
+ }
+
+ reconstruction->error= context->reprojection_error;
+ reconstruction->flag|= TRACKING_RECONSTRUCTED;
#ifdef WITH_LIBMV
if(!retrieve_libmv_reconstruct(context, tracking))
@@ -1751,14 +1836,15 @@ int BKE_tracking_finish_reconstruction(MovieReconstructContext *context, MovieTr
return 1;
}
-void BKE_track_unique_name(MovieTracking *tracking, MovieTrackingTrack *track)
+void BKE_track_unique_name(ListBase *tracksbase, MovieTrackingTrack *track)
{
- BLI_uniquename(&tracking->tracks, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name));
+ BLI_uniquename(tracksbase, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name));
}
-MovieTrackingTrack *BKE_tracking_named_track(MovieTracking *tracking, const char *name)
+MovieTrackingTrack *BKE_tracking_named_track(MovieTracking *tracking, MovieTrackingObject *object, const char *name)
{
- MovieTrackingTrack *track= tracking->tracks.first;
+ ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object);
+ MovieTrackingTrack *track= tracksbase->first;
while(track) {
if(!strcmp(track->name, name))
@@ -1770,9 +1856,8 @@ MovieTrackingTrack *BKE_tracking_named_track(MovieTracking *tracking, const char
return NULL;
}
-static int reconstruction_camera_index(MovieTracking *tracking, int framenr, int nearest)
+static int reconstruction_camera_index(MovieTrackingReconstruction *reconstruction, int framenr, int nearest)
{
- MovieTrackingReconstruction *reconstruction= &tracking->reconstruction;
MovieReconstructedCamera *cameras= reconstruction->cameras;
int a= 0, d= 1;
@@ -1824,21 +1909,31 @@ static int reconstruction_camera_index(MovieTracking *tracking, int framenr, int
return -1;
}
-MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(MovieTracking *tracking, int framenr)
+MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(MovieTracking *tracking,
+ MovieTrackingObject *object, int framenr)
{
- int a= reconstruction_camera_index(tracking, framenr, 0);
+ MovieTrackingReconstruction *reconstruction;
+ int a;
+
+ reconstruction= BKE_tracking_object_reconstruction(tracking, object);
+ a= reconstruction_camera_index(reconstruction, framenr, 0);
if(a==-1)
return NULL;
- return &tracking->reconstruction.cameras[a];
+ return &reconstruction->cameras[a];
}
-void BKE_tracking_get_interpolated_camera(MovieTracking *tracking, int framenr, float mat[4][4])
+void BKE_tracking_get_interpolated_camera(MovieTracking *tracking, MovieTrackingObject *object,
+ int framenr, float mat[4][4])
{
- MovieTrackingReconstruction *reconstruction= &tracking->reconstruction;
- MovieReconstructedCamera *cameras= reconstruction->cameras;
- int a= reconstruction_camera_index(tracking, framenr, 1);
+ MovieTrackingReconstruction *reconstruction;
+ MovieReconstructedCamera *cameras;
+ int a;
+
+ reconstruction= BKE_tracking_object_reconstruction(tracking, object);
+ cameras= reconstruction->cameras;
+ a= reconstruction_camera_index(reconstruction, framenr, 1);
if(a==-1) {
unit_m4(mat);
@@ -1890,7 +1985,8 @@ void BKE_tracking_camera_to_blender(MovieTracking *tracking, Scene *scene, Camer
BKE_tracking_camera_shift(tracking, width, height, &camera->shiftx, &camera->shifty);
}
-void BKE_tracking_projection_matrix(MovieTracking *tracking, int framenr, int winx, int winy, float mat[4][4])
+void BKE_tracking_projection_matrix(MovieTracking *tracking, MovieTrackingObject *object,
+ int framenr, int winx, int winy, float mat[4][4])
{
MovieReconstructedCamera *camera;
float lens= tracking->camera.focal*tracking->camera.sensor_width/(float)winx;
@@ -1923,7 +2019,8 @@ void BKE_tracking_projection_matrix(MovieTracking *tracking, int framenr, int wi
perspective_m4(winmat, left, right, bottom, top, clipsta, clipend);
- camera= BKE_tracking_get_reconstructed_camera(tracking, framenr);
+ camera= BKE_tracking_get_reconstructed_camera(tracking, object, framenr);
+
if(camera) {
float imat[4][4];
@@ -1932,6 +2029,77 @@ void BKE_tracking_projection_matrix(MovieTracking *tracking, int framenr, int wi
} else copy_m4_m4(mat, winmat);
}
+ListBase *BKE_tracking_get_tracks(MovieTracking *tracking)
+{
+ MovieTrackingObject *object= BKE_tracking_active_object(tracking);
+
+ if(object && (object->flag & TRACKING_OBJECT_CAMERA) == 0) {
+ return &object->tracks;
+ }
+
+ return &tracking->tracks;
+}
+
+MovieTrackingTrack *BKE_tracking_active_track(MovieTracking *tracking)
+{
+ ListBase *tracksbase;
+
+ if(!tracking->act_track)
+ return NULL;
+
+ tracksbase= BKE_tracking_get_tracks(tracking);
+
+ /* check that active track is in current tracks list */
+ if(BLI_findindex(tracksbase, tracking->act_track) >= 0)
+ return tracking->act_track;
+
+ return NULL;
+}
+
+MovieTrackingObject *BKE_tracking_active_object(MovieTracking *tracking)
+{
+ return BLI_findlink(&tracking->objects, tracking->objectnr);
+}
+
+MovieTrackingObject *BKE_tracking_get_camera_object(MovieTracking *tracking)
+{
+ MovieTrackingObject *object= tracking->objects.first;
+
+ while(object) {
+ if(object->flag & TRACKING_OBJECT_CAMERA)
+ return object;
+
+ object= object->next;
+ }
+
+ return NULL;
+}
+
+ListBase *BKE_tracking_object_tracks(MovieTracking *tracking, MovieTrackingObject *object)
+{
+ if(object->flag & TRACKING_OBJECT_CAMERA) {
+ return &tracking->tracks;
+ }
+
+ return &object->tracks;
+}
+
+MovieTrackingReconstruction *BKE_tracking_object_reconstruction(MovieTracking *tracking, MovieTrackingObject *object)
+{
+ if(object->flag & TRACKING_OBJECT_CAMERA) {
+ return &tracking->reconstruction;
+ }
+
+ return &object->reconstruction;
+}
+
+MovieTrackingReconstruction *BKE_tracking_get_reconstruction(MovieTracking *tracking)
+{
+ MovieTrackingObject *object= BKE_tracking_active_object(tracking);
+
+ return BKE_tracking_object_reconstruction(tracking, object);
+}
+
void BKE_tracking_apply_intrinsics(MovieTracking *tracking, float co[2], float nco[2])
{
MovieTrackingCamera *camera= &tracking->camera;
@@ -2018,8 +2186,9 @@ static int point_in_layer(bGPDlayer *layer, float x, float y)
return 0;
}
-static void retrieve_libmv_features(MovieTracking *tracking, struct libmv_Features *features,
- int framenr, int width, int height, bGPDlayer *layer, int place_outside_layer)
+static void retrieve_libmv_features(MovieTracking *tracking, ListBase *tracksbase,
+ struct libmv_Features *features, int framenr, int width, int height,
+ bGPDlayer *layer, int place_outside_layer)
{
int a;
@@ -2039,7 +2208,7 @@ static void retrieve_libmv_features(MovieTracking *tracking, struct libmv_Featur
ok= point_in_layer(layer, xu, yu)!=place_outside_layer;
if(ok) {
- track= BKE_tracking_add_track(tracking, xu, yu, framenr, width, height);
+ track= BKE_tracking_add_track(tracking, tracksbase, xu, yu, framenr, width, height);
track->flag|= SELECT;
track->pat_flag|= SELECT;
track->search_flag|= SELECT;
@@ -2048,7 +2217,7 @@ static void retrieve_libmv_features(MovieTracking *tracking, struct libmv_Featur
}
#endif
-void BKE_tracking_detect_fast(MovieTracking *tracking, ImBuf *ibuf,
+void BKE_tracking_detect_fast(MovieTracking *tracking, ListBase *tracksbase, ImBuf *ibuf,
int framenr, int margin, int min_trackness, int min_distance, bGPDlayer *layer,
int place_outside_layer)
{
@@ -2056,11 +2225,13 @@ void BKE_tracking_detect_fast(MovieTracking *tracking, ImBuf *ibuf,
struct libmv_Features *features;
unsigned char *pixels= get_ucharbuf(ibuf);
- features= libmv_detectFeaturesFAST(pixels, ibuf->x, ibuf->y, ibuf->x, margin, min_trackness, min_distance);
+ features= libmv_detectFeaturesFAST(pixels, ibuf->x, ibuf->y, ibuf->x,
+ margin, min_trackness, min_distance);
MEM_freeN(pixels);
- retrieve_libmv_features(tracking, features, framenr, ibuf->x, ibuf->y, layer, place_outside_layer);
+ retrieve_libmv_features(tracking, tracksbase, features, framenr,
+ ibuf->x, ibuf->y, layer, place_outside_layer);
libmv_destroyFeatures(features);
#else
@@ -2077,7 +2248,8 @@ void BKE_tracking_detect_fast(MovieTracking *tracking, ImBuf *ibuf,
MovieTrackingTrack *BKE_tracking_indexed_track(MovieTracking *tracking, int tracknr)
{
- MovieTrackingTrack *track= tracking->tracks.first;
+ ListBase *tracksbase= &tracking->tracks; /* XXX: need proper tracks base */
+ MovieTrackingTrack *track= tracksbase->first;
int cur= 1;
while(track) {
@@ -2102,6 +2274,8 @@ static int stabilization_median_point(MovieTracking *tracking, int framenr, floa
INIT_MINMAX2(min, max);
+ (void) tracking;
+
track= tracking->tracks.first;
while(track) {
if(track->flag&TRACK_USE_2D_STAB) {
@@ -2539,12 +2713,12 @@ ImBuf *BKE_tracking_distort(MovieTracking *tracking, ImBuf *ibuf, int width, int
}
/* area - which part of marker should be selected. see TRACK_AREA_* constants */
-void BKE_tracking_select_track(MovieTracking *tracking, MovieTrackingTrack *track, int area, int extend)
+void BKE_tracking_select_track(ListBase *tracksbase, MovieTrackingTrack *track, int area, int extend)
{
if(extend) {
BKE_tracking_track_flag(track, area, SELECT, 0);
} else {
- MovieTrackingTrack *cur= tracking->tracks.first;
+ MovieTrackingTrack *cur= tracksbase->first;
while(cur) {
if(cur==track) {
@@ -2564,3 +2738,78 @@ void BKE_tracking_deselect_track(MovieTrackingTrack *track, int area)
{
BKE_tracking_track_flag(track, area, SELECT, 1);
}
+
+MovieTrackingObject *BKE_tracking_new_object(MovieTracking *tracking, const char *name)
+{
+ MovieTrackingObject *object= MEM_callocN(sizeof(MovieTrackingObject), "tracking object");
+
+ if(tracking->tot_object==0) {
+ /* first object is always camera */
+ BLI_strncpy(object->name, "Camera", sizeof(object->name));
+
+ object->flag|= TRACKING_OBJECT_CAMERA;
+ }
+ else {
+ BLI_strncpy(object->name, name, sizeof(object->name));
+ }
+
+ BLI_addtail(&tracking->objects, object);
+
+ tracking->tot_object++;
+ tracking->objectnr= BLI_countlist(&tracking->objects) - 1;
+
+ BKE_tracking_object_unique_name(tracking, object);
+
+ return object;
+}
+
+void BKE_tracking_remove_object(MovieTracking *tracking, MovieTrackingObject *object)
+{
+ MovieTrackingTrack *track;
+ int index= BLI_findindex(&tracking->objects, object);
+
+ if(index<0)
+ return;
+
+ if(object->flag & TRACKING_OBJECT_CAMERA) {
+ /* object used for camera solving can't be deleted */
+ return;
+ }
+
+ track= object->tracks.first;
+ while(track) {
+ if(track==tracking->act_track)
+ tracking->act_track= NULL;
+
+ track= track->next;
+ }
+
+ tracking_object_free(object);
+ BLI_freelinkN(&tracking->objects, object);
+
+ tracking->tot_object--;
+
+ if(index>0)
+ tracking->objectnr= index-1;
+ else
+ tracking->objectnr= 0;
+}
+
+void BKE_tracking_object_unique_name(MovieTracking *tracking, MovieTrackingObject *object)
+{
+ BLI_uniquename(&tracking->objects, object, "Object", '.', offsetof(MovieTrackingObject, name), sizeof(object->name));
+}
+
+MovieTrackingObject *BKE_tracking_named_object(MovieTracking *tracking, const char *name)
+{
+ MovieTrackingObject *object= tracking->objects.first;
+
+ while(object) {
+ if(!strcmp(object->name, name))
+ return object;
+
+ object= object->next;
+ }
+
+ return NULL;
+}