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>2013-05-12 20:04:08 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2013-05-12 20:04:08 +0400
commitbeb73831f6c66d7f01c50c6c8b37f23cc67b9914 (patch)
tree59eed0ffff789d58a828f52bd8565979852f8d31
parentbbd533d4acc9ddd9942a338a59888fcbb1a73aa4 (diff)
Documentation for functions inside tracking.c
Additional changes: - Cleaned up sources to reduce mess in some big functions. - Removed unused function from libmv c-api. - Made functions naming more consistent. - Use bool for internal stuff in tracking.c. Shall be no functional changes :)
-rw-r--r--extern/libmv/libmv-capi.cpp23
-rw-r--r--extern/libmv/libmv-capi.h6
-rw-r--r--source/blender/blenkernel/intern/tracking.c470
3 files changed, 370 insertions, 129 deletions
diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp
index 0f2ebc50384..8bb89b8e1ae 100644
--- a/extern/libmv/libmv-capi.cpp
+++ b/extern/libmv/libmv-capi.cpp
@@ -419,23 +419,6 @@ protected:
void *callback_customdata_;
};
-int libmv_refineParametersAreValid(int parameters) {
- return (parameters == (LIBMV_REFINE_FOCAL_LENGTH)) ||
- (parameters == (LIBMV_REFINE_FOCAL_LENGTH |
- LIBMV_REFINE_PRINCIPAL_POINT)) ||
- (parameters == (LIBMV_REFINE_FOCAL_LENGTH |
- LIBMV_REFINE_PRINCIPAL_POINT |
- LIBMV_REFINE_RADIAL_DISTORTION_K1 |
- LIBMV_REFINE_RADIAL_DISTORTION_K2)) ||
- (parameters == (LIBMV_REFINE_FOCAL_LENGTH |
- LIBMV_REFINE_RADIAL_DISTORTION_K1 |
- LIBMV_REFINE_RADIAL_DISTORTION_K2)) ||
- (parameters == (LIBMV_REFINE_FOCAL_LENGTH |
- LIBMV_REFINE_RADIAL_DISTORTION_K1)) ||
- (parameters == (LIBMV_REFINE_RADIAL_DISTORTION_K1 |
- LIBMV_REFINE_RADIAL_DISTORTION_K2));
-}
-
static void libmv_solveRefineIntrinsics(libmv::Tracks *tracks, libmv::CameraIntrinsics *intrinsics,
libmv::EuclideanReconstruction *reconstruction, int refine_intrinsics,
reconstruct_progress_update_cb progress_update_callback, void *callback_customdata,
@@ -952,7 +935,7 @@ void libmv_CameraIntrinsicsDistortFloat(struct libmv_CameraIntrinsics *libmvIntr
/* ************ utils ************ */
-void libmv_applyCameraIntrinsics(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options,
+void libmv_ApplyCameraIntrinsics(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options,
double x, double y, double *x1, double *y1)
{
libmv::CameraIntrinsics camera_intrinsics;
@@ -966,8 +949,8 @@ void libmv_applyCameraIntrinsics(libmv_cameraIntrinsicsOptions *libmv_camera_int
}
}
-void libmv_InvertIntrinsics(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options,
- double x, double y, double *x1, double *y1)
+void libmv_InvertCameraIntrinsics(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options,
+ double x, double y, double *x1, double *y1)
{
libmv::CameraIntrinsics camera_intrinsics;
diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h
index c3debe45fd1..bf09fbd5005 100644
--- a/extern/libmv/libmv-capi.h
+++ b/extern/libmv/libmv-capi.h
@@ -101,8 +101,6 @@ typedef struct libmv_reconstructionOptions {
typedef void (*reconstruct_progress_update_cb) (void *customdata, double progress, const char *message);
-int libmv_refineParametersAreValid(int parameters);
-
struct libmv_Reconstruction *libmv_solveReconstruction(struct libmv_Tracks *libmv_tracks,
libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options,
libmv_reconstructionOptions *libmv_reconstruction_options,
@@ -161,9 +159,9 @@ void libmv_CameraIntrinsicsDistortFloat(struct libmv_CameraIntrinsics *libmv_int
float *src, float *dst, int width, int height, float overscan, int channels);
/* utils */
-void libmv_applyCameraIntrinsics(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options,
+void libmv_ApplyCameraIntrinsics(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options,
double x, double y, double *x1, double *y1);
-void libmv_InvertIntrinsics(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options,
+void libmv_InvertCameraIntrinsics(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options,
double x, double y, double *x1, double *y1);
#ifdef __cplusplus
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index 37979326215..3e9206bc4d0 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -78,13 +78,14 @@ static struct {
ListBase tracks;
} tracking_clipboard;
-/*********************** Common functions *************************/
+/*********************** Common functions *************************/
+/* Duplicate the specified track, result will no belong to any list. */
static MovieTrackingTrack *tracking_track_duplicate(MovieTrackingTrack *track)
{
MovieTrackingTrack *new_track;
- new_track = MEM_callocN(sizeof(MovieTrackingTrack), "tracksMapMerge new_track");
+ new_track = MEM_callocN(sizeof(MovieTrackingTrack), "tracking_track_duplicate new_track");
*new_track = *track;
new_track->next = new_track->prev = NULL;
@@ -94,6 +95,7 @@ static MovieTrackingTrack *tracking_track_duplicate(MovieTrackingTrack *track)
return new_track;
}
+/* Free the whole list of tracks, list's head and tail are set to NULL. */
static void tracking_tracks_free(ListBase *tracks)
{
MovieTrackingTrack *track;
@@ -105,32 +107,49 @@ static void tracking_tracks_free(ListBase *tracks)
BLI_freelistN(tracks);
}
+/* Free reconstruction structures, only frees contents of a structure,
+ * (if structure is allocated in heap, it shall be handled outside).
+ *
+ * All the pointers inside structure becomes invalid after this call.
+ */
static void tracking_reconstruction_free(MovieTrackingReconstruction *reconstruction)
{
if (reconstruction->cameras)
MEM_freeN(reconstruction->cameras);
}
+/* Free memory used by tracking object, only frees contents of the structure,
+ * (if structure is allocated in heap, it shall be handled outside).
+ *
+ * All the pointers inside structure becomes invalid after this call.
+ */
static void tracking_object_free(MovieTrackingObject *object)
{
tracking_tracks_free(&object->tracks);
tracking_reconstruction_free(&object->reconstruction);
}
+/* Free list of tracking objects, list's head and tail is set to NULL. */
static void tracking_objects_free(ListBase *objects)
{
MovieTrackingObject *object;
+ /* Free objects contents. */
for (object = objects->first; object; object = object->next)
tracking_object_free(object);
+ /* Free objects themselves. */
BLI_freelistN(objects);
}
+/* Free memory used by a dopesheet, only frees dopesheet contents.
+ * leaving dopesheet crystal clean for further usage.
+ */
static void tracking_dopesheet_free(MovieTrackingDopesheet *dopesheet)
{
MovieTrackingDopesheetChannel *channel;
+ /* Free channel's sergments. */
channel = dopesheet->channels.first;
while (channel) {
if (channel->segments) {
@@ -140,14 +159,21 @@ static void tracking_dopesheet_free(MovieTrackingDopesheet *dopesheet)
channel = channel->next;
}
+ /* Free lists themselves. */
BLI_freelistN(&dopesheet->channels);
BLI_freelistN(&dopesheet->coverage_segments);
+ /* Ensure lists are clean. */
dopesheet->channels.first = dopesheet->channels.last = NULL;
dopesheet->coverage_segments.first = dopesheet->coverage_segments.last = NULL;
dopesheet->tot_channel = 0;
}
+/* Free tracking structure, only frees structure contents
+ * (if structure is allocated in heap, it shall be handled outside).
+ *
+ * All the pointers inside structure becomes invalid after this call.
+ */
void BKE_tracking_free(MovieTracking *tracking)
{
tracking_tracks_free(&tracking->tracks);
@@ -160,6 +186,9 @@ void BKE_tracking_free(MovieTracking *tracking)
tracking_dopesheet_free(&tracking->dopesheet);
}
+/* Initialize motion tracking settings to default values,
+ * used when new movie clip datablock is creating.
+ */
void BKE_tracking_settings_init(MovieTracking *tracking)
{
tracking->camera.sensor_width = 35.0f;
@@ -184,6 +213,7 @@ void BKE_tracking_settings_init(MovieTracking *tracking)
BKE_tracking_object_add(tracking, "Camera");
}
+/* Get list base of active object's tracks. */
ListBase *BKE_tracking_get_active_tracks(MovieTracking *tracking)
{
MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
@@ -195,6 +225,7 @@ ListBase *BKE_tracking_get_active_tracks(MovieTracking *tracking)
return &tracking->tracks;
}
+/* Get reconstruction data of active object. */
MovieTrackingReconstruction *BKE_tracking_get_active_reconstruction(MovieTracking *tracking)
{
MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
@@ -202,6 +233,9 @@ MovieTrackingReconstruction *BKE_tracking_get_active_reconstruction(MovieTrackin
return BKE_tracking_object_get_reconstruction(tracking, object);
}
+/* Get transformation matrix for a given object which is used
+ * for parenting motion tracker reconstruction to 3D world.
+ */
void BKE_tracking_get_camera_object_matrix(Scene *scene, Object *ob, float mat[4][4])
{
if (!ob) {
@@ -217,6 +251,11 @@ void BKE_tracking_get_camera_object_matrix(Scene *scene, Object *ob, float mat[4
unit_m4(mat);
}
+/* Get projection matrix for camera specified by given tracking object
+ * and frame number.
+ *
+ * NOTE: frame number should be in clip space, not scene space
+ */
void BKE_tracking_get_projection_matrix(MovieTracking *tracking, MovieTrackingObject *object,
int framenr, int winx, int winy, float mat[4][4])
{
@@ -264,7 +303,7 @@ void BKE_tracking_get_projection_matrix(MovieTracking *tracking, MovieTrackingOb
}
}
-/* **** space transformation functions **** */
+/* **** space transformation functions **** */
/* Three coordinate frames: Frame, Search, and Marker
* Two units: Pixels, Unified
@@ -403,6 +442,7 @@ static void set_marker_coords_from_tracking(int frame_width, int frame_height, M
/*********************** clipboard *************************/
+/* Free clipboard by freeing memory used by all tracks in it. */
void BKE_tracking_clipboard_free(void)
{
MovieTrackingTrack *track = tracking_clipboard.tracks.first, *next_track;
@@ -419,13 +459,16 @@ void BKE_tracking_clipboard_free(void)
tracking_clipboard.tracks.first = tracking_clipboard.tracks.last = NULL;
}
+/* Copy selected tracks from specified object to the clipboard. */
void BKE_tracking_clipboard_copy_tracks(MovieTracking *tracking, MovieTrackingObject *object)
{
ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
MovieTrackingTrack *track = tracksbase->first;
+ /* First drop all tracks from current clipboard. */
BKE_tracking_clipboard_free();
+ /* Then copy all selected visible tracks to it. */
while (track) {
if (TRACK_SELECTED(track) && (track->flag & TRACK_HIDDEN) == 0) {
MovieTrackingTrack *new_track = tracking_track_duplicate(track);
@@ -437,11 +480,17 @@ void BKE_tracking_clipboard_copy_tracks(MovieTracking *tracking, MovieTrackingOb
}
}
+/* Check whether there're any tracks in the clipboard. */
int BKE_tracking_clipboard_has_tracks(void)
{
return tracking_clipboard.tracks.first != NULL;
}
+/* Paste tracks from clipboard to specified object.
+ *
+ * Names of new tracks in object are guaranteed to
+ * be unique here.
+ */
void BKE_tracking_clipboard_paste_tracks(MovieTracking *tracking, MovieTrackingObject *object)
{
ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
@@ -457,10 +506,19 @@ void BKE_tracking_clipboard_paste_tracks(MovieTracking *tracking, MovieTrackingO
}
}
-/*********************** Tracks *************************/
+/*********************** Tracks *************************/
+/* Place a disabled marker before or after specified ref_marker.
+ *
+ * If before is truth, disabled marker is placed before reference
+ * one, and it's placed after it otherwise.
+ *
+ * If there's already a marker at the frame where disabled one
+ * is expected to be placed, nothing will happen if overwrite
+ * is false.
+ */
static void tracking_marker_insert_disabled(MovieTrackingTrack *track, const MovieTrackingMarker *ref_marker,
- int before, int overwrite)
+ bool before, bool overwrite)
{
MovieTrackingMarker marker_new;
@@ -477,6 +535,14 @@ static void tracking_marker_insert_disabled(MovieTrackingTrack *track, const Mov
BKE_tracking_marker_insert(track, &marker_new);
}
+/* Add new track to a specified tracks base.
+ *
+ * Coordinates are expected to be in normalized 0..1 space,
+ * frame number is expected to be in clip space.
+ *
+ * Width and height are clip's dimension used to scale track's
+ * pattern and search regions.
+ */
MovieTrackingTrack *BKE_tracking_track_add(MovieTracking *tracking, ListBase *tracksbase, float x, float y,
int framenr, int width, int height)
{
@@ -531,18 +597,32 @@ MovieTrackingTrack *BKE_tracking_track_add(MovieTracking *tracking, ListBase *tr
return track;
}
+/* Ensure specified track has got unique name,
+ * if it's not name of specified track will be changed
+ * keeping names of all other tracks unchanged.
+ */
void BKE_tracking_track_unique_name(ListBase *tracksbase, MovieTrackingTrack *track)
{
BLI_uniquename(tracksbase, track, CTX_DATA_(BLF_I18NCONTEXT_ID_MOVIECLIP, "Track"), '.',
offsetof(MovieTrackingTrack, name), sizeof(track->name));
}
+/* Free specified track, only frees contents of a structure
+ * (if track is allocated in heap, it shall be handled outside).
+ *
+ * All the pointers inside track becomes invalid after this call.
+ */
void BKE_tracking_track_free(MovieTrackingTrack *track)
{
if (track->markers)
MEM_freeN(track->markers);
}
+/* Set flag for all specified track's areas.
+ *
+ * area - which part of marker should be selected. see TRACK_AREA_* constants.
+ * flag - flag to be set for areas.
+ */
void BKE_tracking_track_flag_set(MovieTrackingTrack *track, int area, int flag)
{
if (area == TRACK_AREA_NONE)
@@ -556,6 +636,11 @@ void BKE_tracking_track_flag_set(MovieTrackingTrack *track, int area, int flag)
track->search_flag |= flag;
}
+/* Clear flag from all specified track's areas.
+ *
+ * area - which part of marker should be selected. see TRACK_AREA_* constants.
+ * flag - flag to be cleared for areas.
+ */
void BKE_tracking_track_flag_clear(MovieTrackingTrack *track, int area, int flag)
{
if (area == TRACK_AREA_NONE)
@@ -569,11 +654,19 @@ void BKE_tracking_track_flag_clear(MovieTrackingTrack *track, int area, int flag
track->search_flag &= ~flag;
}
+/* Check whether track has got marker at specified frame.
+ *
+ * NOTE: frame number should be in clip space, not scene space.
+ */
int BKE_tracking_track_has_marker_at_frame(MovieTrackingTrack *track, int framenr)
{
return BKE_tracking_marker_get_exact(track, framenr) != 0;
}
+/* Check whether track has got enabled marker at specified frame.
+ *
+ * NOTE: frame number should be in clip space, not scene space.
+ */
int BKE_tracking_track_has_enabled_marker_at_frame(MovieTrackingTrack *track, int framenr)
{
MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, framenr);
@@ -581,6 +674,18 @@ int BKE_tracking_track_has_enabled_marker_at_frame(MovieTrackingTrack *track, in
return marker && (marker->flag & MARKER_DISABLED) == 0;
}
+/* Clear track's path:
+ *
+ * - If action is TRACK_CLEAR_REMAINED path from ref_frame+1 up to
+ * end will be clear.
+ *
+ * - If action is TRACK_CLEAR_UPTO path from the beginning up to
+ * ref_frame-1 will be clear.
+ *
+ * - If action is TRACK_CLEAR_ALL only mareker at frame ref_frame will remain.
+ *
+ * NOTE: frame number should be in clip space, not scene space
+ */
void BKE_tracking_track_path_clear(MovieTrackingTrack *track, int ref_frame, int action)
{
int a;
@@ -600,7 +705,7 @@ void BKE_tracking_track_path_clear(MovieTrackingTrack *track, int ref_frame, int
}
if (track->markersnr)
- tracking_marker_insert_disabled(track, &track->markers[track->markersnr - 1], FALSE, TRUE);
+ tracking_marker_insert_disabled(track, &track->markers[track->markersnr - 1], false, true);
}
else if (action == TRACK_CLEAR_UPTO) {
a = track->markersnr - 1;
@@ -619,7 +724,7 @@ void BKE_tracking_track_path_clear(MovieTrackingTrack *track, int ref_frame, int
}
if (track->markersnr)
- tracking_marker_insert_disabled(track, &track->markers[0], TRUE, TRUE);
+ tracking_marker_insert_disabled(track, &track->markers[0], true, true);
}
else if (action == TRACK_CLEAR_ALL) {
MovieTrackingMarker *marker, marker_new;
@@ -633,8 +738,8 @@ void BKE_tracking_track_path_clear(MovieTrackingTrack *track, int ref_frame, int
BKE_tracking_marker_insert(track, &marker_new);
- tracking_marker_insert_disabled(track, &marker_new, TRUE, TRUE);
- tracking_marker_insert_disabled(track, &marker_new, FALSE, TRUE);
+ tracking_marker_insert_disabled(track, &marker_new, true, true);
+ tracking_marker_insert_disabled(track, &marker_new, false, true);
}
}
@@ -819,11 +924,12 @@ static bGPDlayer *track_mask_gpencil_layer_get(MovieTrackingTrack *track)
while (layer) {
if (layer->flag & GP_LAYER_ACTIVE) {
bGPDframe *frame = layer->frames.first;
- int ok = FALSE;
+ bool ok = false;
while (frame) {
if (frame->strokes.first) {
- ok = TRUE;
+ ok = true;
+ break;
}
frame = frame->next;
@@ -1291,7 +1397,7 @@ MovieTrackingReconstruction *BKE_tracking_object_get_reconstruction(MovieTrackin
/*********************** Camera *************************/
-static int reconstructed_camera_index_get(MovieTrackingReconstruction *reconstruction, int framenr, int nearest)
+static int reconstructed_camera_index_get(MovieTrackingReconstruction *reconstruction, int framenr, bool nearest)
{
MovieReconstructedCamera *cameras = reconstruction->cameras;
int a = 0, d = 1;
@@ -1395,7 +1501,7 @@ MovieReconstructedCamera *BKE_tracking_camera_get_reconstructed(MovieTracking *t
int a;
reconstruction = BKE_tracking_object_get_reconstruction(tracking, object);
- a = reconstructed_camera_index_get(reconstruction, framenr, FALSE);
+ a = reconstructed_camera_index_get(reconstruction, framenr, false);
if (a == -1)
return NULL;
@@ -1412,7 +1518,7 @@ void BKE_tracking_camera_get_reconstructed_interpolate(MovieTracking *tracking,
reconstruction = BKE_tracking_object_get_reconstruction(tracking, object);
cameras = reconstruction->cameras;
- a = reconstructed_camera_index_get(reconstruction, framenr, 1);
+ a = reconstructed_camera_index_get(reconstruction, framenr, true);
if (a == -1) {
unit_m4(mat);
@@ -1583,7 +1689,7 @@ void BKE_tracking_distort_v2(MovieTracking *tracking, const float co[2], float r
x = (co[0] - camera->principal[0]) / camera->focal;
y = (co[1] - camera->principal[1] * aspy) / camera->focal;
- libmv_applyCameraIntrinsics(&camera_intrinsics_options, x, y, &x, &y);
+ libmv_ApplyCameraIntrinsics(&camera_intrinsics_options, x, y, &x, &y);
/* result is in image coords already */
r_co[0] = x;
@@ -1606,7 +1712,7 @@ void BKE_tracking_undistort_v2(MovieTracking *tracking, const float co[2], float
cameraIntrinscisOptionsFromTracking(&camera_intrinsics_options, tracking, 0, 0);
- libmv_InvertIntrinsics(&camera_intrinsics_options, x, y, &x, &y);
+ libmv_InvertCameraIntrinsics(&camera_intrinsics_options, x, y, &x, &y);
r_co[0] = (float)x * camera->focal + camera->principal[0];
r_co[1] = (float)y * camera->focal + camera->principal[1] * aspy;
@@ -2147,7 +2253,8 @@ typedef struct MovieTrackingContext {
MovieClip *clip;
int clip_flag;
- int first_time, frames;
+ int frames;
+ bool first_time;
MovieTrackingSettings settings;
TracksMap *tracks_map;
@@ -2172,6 +2279,10 @@ static void track_context_free(void *customdata)
#endif
}
+/* Create context for motion 2D tracking, copies all data needed
+ * for thread-safe tracking, allowing clip modifications during
+ * tracking.
+ */
MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *user, short backwards, short sequence)
{
MovieTrackingContext *context = MEM_callocN(sizeof(MovieTrackingContext), "trackingContext");
@@ -2186,7 +2297,7 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u
context->settings = *settings;
context->backwards = backwards;
context->sync_frame = user->framenr;
- context->first_time = TRUE;
+ context->first_time = true;
context->sequence = sequence;
/* count */
@@ -2251,6 +2362,7 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u
return context;
}
+/* Free context used for tracking. */
void BKE_tracking_context_free(MovieTrackingContext *context)
{
if (!context->sequence)
@@ -2261,6 +2373,10 @@ void BKE_tracking_context_free(MovieTrackingContext *context)
MEM_freeN(context);
}
+/* Synchronize tracks between clip editor and tracking context,
+ * by merging them together so all new created tracks and tracked
+ * ones presents in the movie clip.
+ */
void BKE_tracking_context_sync(MovieTrackingContext *context)
{
MovieTracking *tracking = &context->clip->tracking;
@@ -2278,6 +2394,9 @@ void BKE_tracking_context_sync(MovieTrackingContext *context)
BKE_tracking_dopesheet_tag_update(tracking);
}
+/* Synchronize clip user's frame number with a frame number from tracking context,
+ * used to update current frame displayed in the clip editor while tracking.
+ */
void BKE_tracking_context_sync_user(const MovieTrackingContext *context, MovieClipUser *user)
{
user->framenr = context->sync_frame;
@@ -2311,6 +2430,7 @@ static void uint8_rgba_to_float_gray(const unsigned char *rgba, float *gray, int
}
}
+/* Get grayscale float search buffer for given marker and frame. */
static float *track_get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
int *width_r, int *height_r)
{
@@ -2348,6 +2468,10 @@ static float *track_get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track,
return gray_pixels;
}
+/* Get image boffer for a given frame
+ *
+ * Frame is in clip space.
+ */
static ImBuf *tracking_context_get_frame_ibuf(MovieTrackingContext *context, int framenr)
{
ImBuf *ibuf;
@@ -2360,6 +2484,7 @@ static ImBuf *tracking_context_get_frame_ibuf(MovieTrackingContext *context, int
return ibuf;
}
+/* Get previous keyframed marker. */
static MovieTrackingMarker *tracking_context_get_keyframed_marker(MovieTrackingContext *context, MovieTrackingTrack *track,
MovieTrackingMarker *marker)
{
@@ -2368,7 +2493,7 @@ static MovieTrackingMarker *tracking_context_get_keyframed_marker(MovieTrackingC
while (a >= 0 && a < track->markersnr) {
int next = (context->backwards) ? a + 1 : a - 1;
- int is_keyframed = FALSE;
+ bool is_keyframed = false;
MovieTrackingMarker *cur_marker = &track->markers[a];
MovieTrackingMarker *next_marker = NULL;
@@ -2377,7 +2502,7 @@ static MovieTrackingMarker *tracking_context_get_keyframed_marker(MovieTrackingC
/* if next mrker is disabled, stop searching keyframe and use current frame as keyframe */
if (next_marker && next_marker->flag & MARKER_DISABLED)
- is_keyframed = TRUE;
+ is_keyframed = true;
is_keyframed |= (cur_marker->flag & MARKER_TRACKED) == 0;
@@ -2393,6 +2518,7 @@ static MovieTrackingMarker *tracking_context_get_keyframed_marker(MovieTrackingC
return marker_keyed;
}
+/* Get image buffer for previous marker's keyframe. */
static ImBuf *tracking_context_get_keyframed_ibuf(MovieTrackingContext *context, MovieTrackingTrack *track,
MovieTrackingMarker *marker, MovieTrackingMarker **marker_keyed_r)
{
@@ -2407,6 +2533,7 @@ static ImBuf *tracking_context_get_keyframed_ibuf(MovieTrackingContext *context,
return tracking_context_get_frame_ibuf(context, keyed_framenr);
}
+/* Get image buffer which si used as referece for track. */
static ImBuf *tracking_context_get_reference_ibuf(MovieTrackingContext *context, MovieTrackingTrack *track,
MovieTrackingMarker *marker, int curfra,
MovieTrackingMarker **marker_keyed)
@@ -2426,9 +2553,13 @@ static ImBuf *tracking_context_get_reference_ibuf(MovieTrackingContext *context,
return ibuf;
}
-static int track_context_update_reference(MovieTrackingContext *context, TrackContext *track_context,
- MovieTrackingTrack *track, MovieTrackingMarker *marker, int curfra,
- int frame_width, int frame_height)
+/* Update track's reference patch (patch from which track is tracking from)
+ *
+ * Returns false if reference image buffer failed to load.
+ */
+static bool track_context_update_reference(MovieTrackingContext *context, TrackContext *track_context,
+ MovieTrackingTrack *track, MovieTrackingMarker *marker, int curfra,
+ int frame_width, int frame_height)
{
MovieTrackingMarker *marker_keyed = NULL;
ImBuf *reference_ibuf = NULL;
@@ -2438,7 +2569,7 @@ static int track_context_update_reference(MovieTrackingContext *context, TrackCo
reference_ibuf = tracking_context_get_reference_ibuf(context, track, marker, curfra, &marker_keyed);
if (!reference_ibuf)
- return FALSE;
+ return false;
track_context->marker = *marker_keyed;
@@ -2459,9 +2590,12 @@ static int track_context_update_reference(MovieTrackingContext *context, TrackCo
IMB_freeImBuf(reference_ibuf);
- return TRUE;
+ return true;
}
+/* Fill in libmv tracker options structure from a tracking context
+ * with settings need to be used to perform track.
+ */
static void tracking_configure_tracker(TrackContext *track_context, MovieTrackingTrack *track,
struct libmv_trackRegionOptions *options)
{
@@ -2479,9 +2613,9 @@ static void tracking_configure_tracker(TrackContext *track_context, MovieTrackin
options->image1_mask = track_context->mask;
}
-/* returns FALSE if marker crossed margin area from frame bounds */
-static int tracking_check_marker_margin(MovieTrackingTrack *track, MovieTrackingMarker *marker,
- int frame_width, int frame_height)
+/* returns false if marker crossed margin area from frame bounds */
+static bool tracking_check_marker_margin(MovieTrackingTrack *track, MovieTrackingMarker *marker,
+ int frame_width, int frame_height)
{
float pat_min[2], pat_max[2], dim[2], margin[2];
@@ -2497,12 +2631,17 @@ static int tracking_check_marker_margin(MovieTrackingTrack *track, MovieTracking
if (marker->pos[0] < margin[0] || marker->pos[0] > 1.0f - margin[0] ||
marker->pos[1] < margin[1] || marker->pos[1] > 1.0f - margin[1])
{
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
+/* Scale search area of marker based on scale changes of pattern area,
+ *
+ * TODO(sergey): currently based on pattern bounding box scale change,
+ * smarter approach here is welcome.
+ */
static void tracking_scale_marker_search(const MovieTrackingMarker *old_marker, MovieTrackingMarker *new_marker)
{
float old_pat_min[2], old_pat_max[2];
@@ -2522,8 +2661,11 @@ static void tracking_scale_marker_search(const MovieTrackingMarker *old_marker,
new_marker->search_max[1] *= scale_y;
}
+/* Insert new marker which was tracked from old_marker to a new image,
+ * will also ensure tracked segment is surrounded by disabled markers.
+ */
static void tracking_insert_new_marker(MovieTrackingContext *context, MovieTrackingTrack *track,
- const MovieTrackingMarker *old_marker, int curfra, int tracked,
+ const MovieTrackingMarker *old_marker, int curfra, bool tracked,
int frame_width, int frame_height,
double dst_pixel_x[5], double dst_pixel_y[5])
{
@@ -2545,14 +2687,14 @@ static void tracking_insert_new_marker(MovieTrackingContext *context, MovieTrack
* if so -- create disabled marker before currently tracking "segment"
*/
- tracking_marker_insert_disabled(track, old_marker, !context->backwards, FALSE);
+ tracking_marker_insert_disabled(track, old_marker, !context->backwards, false);
}
/* insert currently tracked marker */
BKE_tracking_marker_insert(track, &new_marker);
/* make currently tracked segment be finished with disabled marker */
- tracking_marker_insert_disabled(track, &new_marker, context->backwards, FALSE);
+ tracking_marker_insert_disabled(track, &new_marker, context->backwards, false);
}
else {
new_marker.framenr = nextfra;
@@ -2561,25 +2703,28 @@ static void tracking_insert_new_marker(MovieTrackingContext *context, MovieTrack
BKE_tracking_marker_insert(track, &new_marker);
}
}
-
#endif
+/* Track all the tracks from context one more frame,
+ * returns FALSe if nothing was tracked.
+ */
int BKE_tracking_context_step(MovieTrackingContext *context)
{
ImBuf *destination_ibuf;
int frame_delta = context->backwards ? -1 : 1;
int curfra = BKE_movieclip_remap_scene_to_clip_frame(context->clip, context->user.framenr);
- /* int nextfra; */ /* UNUSED */
- int a, ok = FALSE, map_size;
+ int a, map_size;
+ bool ok = false;
int frame_width, frame_height;
map_size = tracks_map_get_size(context->tracks_map);
- /* nothing to track, avoid unneeded frames reading to save time and memory */
+ /* Nothing to track, avoid unneeded frames reading to save time and memory. */
if (!map_size)
return FALSE;
+ /* Get an image buffer for frame we're tracking to. */
context->user.framenr += frame_delta;
destination_ibuf = BKE_movieclip_get_ibuf_flag(context->clip, &context->user,
@@ -2587,8 +2732,6 @@ int BKE_tracking_context_step(MovieTrackingContext *context)
if (!destination_ibuf)
return FALSE;
- /* nextfra = curfra + frame_delta; */ /* UNUSED */
-
frame_width = destination_ibuf->x;
frame_height = destination_ibuf->y;
@@ -2604,13 +2747,14 @@ int BKE_tracking_context_step(MovieTrackingContext *context)
if (marker && (marker->flag & MARKER_DISABLED) == 0) {
#ifdef WITH_LIBMV
- int width, height, tracked = FALSE, need_readjust;
+ int width, height;
+ bool tracked = false, need_readjust;
double dst_pixel_x[5], dst_pixel_y[5];
if (track->pattern_match == TRACK_MATCH_KEYFRAME)
need_readjust = context->first_time;
else
- need_readjust = TRUE;
+ need_readjust = true;
/* do not track markers which are too close to boundary */
if (tracking_check_marker_margin(track, marker, frame_width, frame_height)) {
@@ -2625,7 +2769,7 @@ int BKE_tracking_context_step(MovieTrackingContext *context)
if (need_readjust) {
if (track_context_update_reference(context, track_context, track, marker,
- curfra, frame_width, frame_height) == FALSE)
+ curfra, frame_width, frame_height) == false)
{
/* happens when reference frame fails to be loaded */
continue;
@@ -2666,7 +2810,7 @@ int BKE_tracking_context_step(MovieTrackingContext *context)
frame_width, frame_height, dst_pixel_x, dst_pixel_y);
}
- ok = TRUE;
+ ok = true;
#else
(void)frame_height;
(void)frame_width;
@@ -2676,7 +2820,7 @@ int BKE_tracking_context_step(MovieTrackingContext *context)
IMB_freeImBuf(destination_ibuf);
- context->first_time = FALSE;
+ context->first_time = false;
context->frames++;
return ok;
@@ -2721,6 +2865,7 @@ typedef struct ReconstructProgressData {
} ReconstructProgressData;
#ifdef WITH_LIBMV
+/* Create mew libmv Tracks structure from blender's tracks list. */
static struct libmv_Tracks *libmv_tracks_new(ListBase *tracksbase, int width, int height)
{
int tracknr = 0;
@@ -2748,6 +2893,7 @@ static struct libmv_Tracks *libmv_tracks_new(ListBase *tracksbase, int width, in
return tracks;
}
+/* Retrieve refined camera intrinsics from libmv to blender. */
static void reconstruct_retrieve_libmv_intrinscis(MovieReconstructContext *context, MovieTracking *tracking)
{
struct libmv_Reconstruction *libmv_reconstruction = context->reconstruction;
@@ -2771,6 +2917,10 @@ static void reconstruct_retrieve_libmv_intrinscis(MovieReconstructContext *conte
tracking->camera.k3 = k3;
}
+/* Retrieve reconstructed tracks from libmv to blender.
+ * Actually, this also copies reconstructed cameras
+ * from libmv to movie clip datablock.
+ */
static int reconstruct_retrieve_libmv_tracks(MovieReconstructContext *context, MovieTracking *tracking)
{
struct libmv_Reconstruction *libmv_reconstruction = context->reconstruction;
@@ -2778,7 +2928,9 @@ static int reconstruct_retrieve_libmv_tracks(MovieReconstructContext *context, M
MovieReconstructedCamera *reconstructed;
MovieTrackingTrack *track;
ListBase *tracksbase = NULL;
- int ok = TRUE, tracknr = 0, a, origin_set = FALSE;
+ int tracknr = 0, a;
+ bool ok = true;
+ bool origin_set = false;
int sfra = context->sfra, efra = context->efra;
float imat[4][4];
@@ -2809,7 +2961,7 @@ static int reconstruct_retrieve_libmv_tracks(MovieReconstructContext *context, M
}
else {
track->flag &= ~TRACK_HAS_BUNDLE;
- ok = FALSE;
+ ok = false;
printf("No bundle for track #%d '%s'\n", tracknr, track->name);
}
@@ -2850,9 +3002,9 @@ static int reconstruct_retrieve_libmv_tracks(MovieReconstructContext *context, M
* aligned correct or not.
*/
if (!origin_set) {
- invert_m4_m4(imat, mat);
- unit_m4(mat);
- origin_set = TRUE;
+ copy_m4_m4(imat, mat);
+ invert_m4(imat);
+ origin_set = true;
}
else {
mult_m4_m4m4(mat, imat, mat);
@@ -2864,7 +3016,7 @@ static int reconstruct_retrieve_libmv_tracks(MovieReconstructContext *context, M
reconstruction->camnr++;
}
else {
- ok = FALSE;
+ ok = false;
printf("No camera for frame %d\n", a);
}
}
@@ -2890,6 +3042,7 @@ static int reconstruct_retrieve_libmv_tracks(MovieReconstructContext *context, M
return ok;
}
+/* Retrieve all the libmv data from context to blender's side data blocks. */
static int reconstruct_retrieve_libmv(MovieReconstructContext *context, MovieTracking *tracking)
{
/* take the intrinscis back from libmv */
@@ -2898,6 +3051,7 @@ static int reconstruct_retrieve_libmv(MovieReconstructContext *context, MovieTra
return reconstruct_retrieve_libmv_tracks(context, tracking);
}
+/* Convert blender's refinement flags to libmv's. */
static int reconstruct_refine_intrinsics_get_flags(MovieTracking *tracking, MovieTrackingObject *object)
{
int refine = tracking->settings.refine_camera_intrinsics;
@@ -2921,6 +3075,7 @@ static int reconstruct_refine_intrinsics_get_flags(MovieTracking *tracking, Movi
return flags;
}
+/* Count tracks which has markers at both of keyframes. */
static int reconstruct_count_tracks_on_both_keyframes(MovieTracking *tracking, MovieTrackingObject *object)
{
ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
@@ -2943,7 +3098,9 @@ static int reconstruct_count_tracks_on_both_keyframes(MovieTracking *tracking, M
}
#endif
-int BKE_tracking_reconstruction_check(MovieTracking *tracking, MovieTrackingObject *object, char *error_msg, int error_size)
+/* Perform early check on whether everything is fine to start reconstruction. */
+int BKE_tracking_reconstruction_check(MovieTracking *tracking, MovieTrackingObject *object,
+ char *error_msg, int error_size)
{
#ifdef WITH_LIBMV
if (tracking->settings.motion_flag & TRACKING_MOTION_MODAL) {
@@ -2951,7 +3108,8 @@ int BKE_tracking_reconstruction_check(MovieTracking *tracking, MovieTrackingObje
return TRUE;
}
else if (reconstruct_count_tracks_on_both_keyframes(tracking, object) < 8) {
- BLI_strncpy(error_msg, N_("At least 8 common tracks on both of keyframes are needed for reconstruction"),
+ BLI_strncpy(error_msg,
+ N_("At least 8 common tracks on both of keyframes are needed for reconstruction"),
error_size);
return FALSE;
@@ -2968,6 +3126,11 @@ int BKE_tracking_reconstruction_check(MovieTracking *tracking, MovieTrackingObje
#endif
}
+/* Create context for camera/object motion reconstruction.
+ * Copies all data needed for reconstruction from movie
+ * clip datablock, so editing this clip is safe during
+ * reconstruction job is in progress.
+ */
MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieTracking *tracking, MovieTrackingObject *object,
int keyframe1, int keyframe2, int width, int height)
{
@@ -3046,6 +3209,7 @@ MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieTracking *
return context;
}
+/* Free memory used by a reconstruction process. */
void BKE_tracking_reconstruction_context_free(MovieReconstructContext *context)
{
#ifdef WITH_LIBMV
@@ -3061,6 +3225,7 @@ void BKE_tracking_reconstruction_context_free(MovieReconstructContext *context)
}
#ifdef WITH_LIBMV
+/* Callback which is called from libmv side to update progress in the interface. */
static void reconstruct_update_solve_cb(void *customdata, double progress, const char *message)
{
ReconstructProgressData *progressdata = customdata;
@@ -3073,6 +3238,7 @@ static void reconstruct_update_solve_cb(void *customdata, double progress, const
BLI_snprintf(progressdata->stats_message, progressdata->message_size, "Solving camera | %s", message);
}
+/* FIll in camera intrinsics structure from reconstruction context. */
static void camraIntrincicsOptionsFromContext(libmv_cameraIntrinsicsOptions *camera_intrinsics_options,
MovieReconstructContext *context)
{
@@ -3089,6 +3255,7 @@ static void camraIntrincicsOptionsFromContext(libmv_cameraIntrinsicsOptions *cam
camera_intrinsics_options->image_height = context->height;
}
+/* Fill in reconstruction options structure from reconstruction context. */
static void reconstructionOptionsFromContext(libmv_reconstructionOptions *reconstruction_options,
MovieReconstructContext *context)
{
@@ -3102,6 +3269,15 @@ static void reconstructionOptionsFromContext(libmv_reconstructionOptions *recons
}
#endif
+/* Solve camera/object motion and reconstruct 3D markers position
+ * from a prepared reconstruction context.
+ *
+ * stop is not actually used at this moment, so reconstruction
+ * job could not be stopped.
+ *
+ * do_update, progress and stat_message are set by reconstruction
+ * callback in libmv side and passing to an interface.
+ */
void BKE_tracking_reconstruction_solve(MovieReconstructContext *context, short *stop, short *do_update,
float *progress, char *stats_message, int message_size)
{
@@ -3148,6 +3324,9 @@ void BKE_tracking_reconstruction_solve(MovieReconstructContext *context, short *
#endif
}
+/* Finish reconstruction process by copying reconstructed data
+ * to an actual movie clip datablock.
+ */
int BKE_tracking_reconstruction_finish(MovieReconstructContext *context, MovieTracking *tracking)
{
MovieTrackingReconstruction *reconstruction;
@@ -3179,12 +3358,21 @@ int BKE_tracking_reconstruction_finish(MovieReconstructContext *context, MovieTr
/*********************** Feature detection *************************/
#ifdef WITH_LIBMV
-static int check_point_in_stroke(bGPDstroke *stroke, float x, float y)
+/* Check whether point is inside grease pencil stroke. */
+static bool check_point_in_stroke(bGPDstroke *stroke, float x, float y)
{
int i, prev;
int count = 0;
bGPDspoint *points = stroke->points;
+ /* Count intersections of horizontal ray coming from the point.
+ * Point will be inside layer if and only if number of intersection
+ * is uneven.
+ *
+ * Well, if layer has got self-intersections, this logic wouldn't
+ * work, but such situation is crappy anyway.
+ */
+
prev = stroke->totpoints - 1;
for (i = 0; i < stroke->totpoints; i++) {
@@ -3198,10 +3386,11 @@ static int check_point_in_stroke(bGPDstroke *stroke, float x, float y)
prev = i;
}
- return count % 2;
+ return count % 2 ? true : false;
}
-static int check_point_in_layer(bGPDlayer *layer, float x, float y)
+/* Check whether point is inside any stroke of grease pencil layer. */
+static bool check_point_in_layer(bGPDlayer *layer, float x, float y)
{
bGPDframe *frame = layer->frames.first;
@@ -3210,19 +3399,20 @@ static int check_point_in_layer(bGPDlayer *layer, float x, float y)
while (stroke) {
if (check_point_in_stroke(stroke, x, y))
- return TRUE;
+ return true;
stroke = stroke->next;
}
frame = frame->next;
}
- return FALSE;
+ return false;
}
+/* Get features detected by libmv and create tracks on the clip for them. */
static void detect_retrieve_libmv_features(MovieTracking *tracking, ListBase *tracksbase,
struct libmv_Features *features, int framenr, int width, int height,
- bGPDlayer *layer, int place_outside_layer)
+ bGPDlayer *layer, bool place_outside_layer)
{
int a;
@@ -3230,7 +3420,7 @@ static void detect_retrieve_libmv_features(MovieTracking *tracking, ListBase *tr
while (a--) {
MovieTrackingTrack *track;
double x, y, size, score;
- int ok = TRUE;
+ bool ok = true;
float xu, yu;
libmv_getFeature(features, a, &x, &y, &score, &size);
@@ -3250,6 +3440,9 @@ static void detect_retrieve_libmv_features(MovieTracking *tracking, ListBase *tr
}
}
+/* Get a gray-scale unsigned char buffer from given image buffer
+ * wich will be used for feature detection.
+ */
static unsigned char *detect_get_frame_ucharbuf(ImBuf *ibuf)
{
int x, y;
@@ -3280,6 +3473,7 @@ static unsigned char *detect_get_frame_ucharbuf(ImBuf *ibuf)
}
#endif
+/* Detect features using FAST detector */
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)
@@ -3293,8 +3487,9 @@ void BKE_tracking_detect_fast(MovieTracking *tracking, ListBase *tracksbase, ImB
MEM_freeN(pixels);
- detect_retrieve_libmv_features(tracking, tracksbase, features, framenr,
- ibuf->x, ibuf->y, layer, place_outside_layer);
+ detect_retrieve_libmv_features(tracking, tracksbase, features,
+ framenr, ibuf->x, ibuf->y, layer,
+ place_outside_layer ? true : false);
libmv_destroyFeatures(features);
#else
@@ -3312,9 +3507,14 @@ void BKE_tracking_detect_fast(MovieTracking *tracking, ListBase *tracksbase, ImB
/*********************** 2D stabilization *************************/
-static int stabilization_median_point_get(MovieTracking *tracking, int framenr, float median[2])
+/* Claculate median point of markers of tracks marked as used for
+ * 2D stabilization.
+ *
+ * NOTE: frame number should be in clip space, not scene space
+ */
+static bool stabilization_median_point_get(MovieTracking *tracking, int framenr, float median[2])
{
- int ok = FALSE;
+ bool ok = false;
float min[2], max[2];
MovieTrackingTrack *track;
@@ -3327,7 +3527,7 @@ static int stabilization_median_point_get(MovieTracking *tracking, int framenr,
minmax_v2v2_v2(min, max, marker->pos);
- ok = TRUE;
+ ok = true;
}
track = track->next;
@@ -3339,6 +3539,12 @@ static int stabilization_median_point_get(MovieTracking *tracking, int framenr,
return ok;
}
+/* Calculate stabilization data (translation, scale and rotation) from
+ * given median of first and current frame medians, tracking data and
+ * frame number.
+ *
+ * NOTE: frame number should be in clip space, not scene space
+ */
static void stabilization_calculate_data(MovieTracking *tracking, int framenr, float width, float height,
float firstmedian[2], float median[2], float loc[2],
float *scale, float *angle)
@@ -3378,15 +3584,20 @@ static void stabilization_calculate_data(MovieTracking *tracking, int framenr, f
}
}
+/* Calculate factor of a scale, which will eliminate black areas
+ * appearing on the frame caused by frame translation.
+ */
static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, int width, int height)
{
float firstmedian[2];
MovieTrackingStabilization *stab = &tracking->stabilization;
float aspect = tracking->camera.pixel_aspect;
+ /* Early output if stabilization data is already up-to-date. */
if (stab->ok)
return stab->scale;
+ /* See comment in BKE_tracking_stabilization_data_get about first frame. */
if (stabilization_median_point_get(tracking, 1, firstmedian)) {
int sfra = INT_MAX, efra = INT_MIN, cfra;
float scale = 1.0f;
@@ -3394,6 +3605,7 @@ static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, i
stab->scale = 1.0f;
+ /* Calculate frame range of tracks used for stabilization. */
track = tracking->tracks.first;
while (track) {
if (track->flag & TRACK_USE_2D_STAB ||
@@ -3406,6 +3618,9 @@ static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, i
track = track->next;
}
+ /* For every frame we calculate scale factor needed to eliminate black
+ * aread and choose largest scale factor as final one.
+ */
for (cfra = sfra; cfra <= efra; cfra++) {
float median[2];
float loc[2], angle, tmp_scale;
@@ -3496,13 +3711,17 @@ static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, i
return stab->scale;
}
-/* NOTE: frame number should be in clip space, not scene space */
+/* Get stabilization data (translation, scaling and angle) for a given frame.
+ *
+ * NOTE: frame number should be in clip space, not scene space
+ */
void BKE_tracking_stabilization_data_get(MovieTracking *tracking, int framenr, int width, int height,
float loc[2], float *scale, float *angle)
{
float firstmedian[2], median[2];
MovieTrackingStabilization *stab = &tracking->stabilization;
+ /* Early output if stabilization is disabled. */
if ((stab->flag & TRACKING_2D_STABILIZATION) == 0) {
zero_v2(loc);
*scale = 1.0f;
@@ -3511,6 +3730,13 @@ void BKE_tracking_stabilization_data_get(MovieTracking *tracking, int framenr, i
return;
}
+ /* Even if tracks does not start at frame 1, their position will
+ * be estimated at this frame, which will give reasonable result
+ * in most of cases.
+ *
+ * However, it's still better to replace this with real first
+ * frame number at which tracks are appearing.
+ */
if (stabilization_median_point_get(tracking, 1, firstmedian)) {
stabilization_median_point_get(tracking, framenr, median);
@@ -3536,7 +3762,11 @@ void BKE_tracking_stabilization_data_get(MovieTracking *tracking, int framenr, i
}
}
-/* NOTE: frame number should be in clip space, not scene space */
+/* Stabilize given image buffer using stabilization data for
+ * a specified frame number.
+ *
+ * NOTE: frame number should be in clip space, not scene space
+ */
ImBuf *BKE_tracking_stabilize_frame(MovieTracking *tracking, int framenr, ImBuf *ibuf,
float loc[2], float *scale, float *angle)
{
@@ -3613,9 +3843,6 @@ ImBuf *BKE_tracking_stabilize_frame(MovieTracking *tracking, int framenr, ImBuf
}
}
- /* TODO(sergey): we've got no mipmaps actually? */
- tmpibuf->userflags |= IB_MIPMAP_INVALID;
-
if (tmpibuf->rect_float)
tmpibuf->userflags |= IB_RECT_INVALID;
@@ -3631,6 +3858,13 @@ ImBuf *BKE_tracking_stabilize_frame(MovieTracking *tracking, int framenr, ImBuf
return tmpibuf;
}
+/* Get 4x4 transformation matrix which corresponds to
+ * stabilization data and used for easy coordinate
+ * transformation.
+ *
+ * NOTE: The reaosn it is 4x4 matrix is because it's
+ * used for OpenGL drawing directly.
+ */
void BKE_tracking_stabilization_data_to_mat4(int width, int height, float aspect, float loc[2],
float scale, float angle, float mat[4][4])
{
@@ -3662,6 +3896,8 @@ void BKE_tracking_stabilization_data_to_mat4(int width, int height, float aspect
/*********************** Dopesheet functions *************************/
+/* ** Channels sort comparators ** */
+
static int channels_alpha_sort(void *a, void *b)
{
MovieTrackingDopesheetChannel *channel_a = a;
@@ -3741,7 +3977,8 @@ static int channels_average_error_inverse_sort(void *a, void *b)
return 0;
}
-static void channels_segments_calc(MovieTrackingDopesheetChannel *channel)
+/* Calculate frames segments at which track is tracked continuously. */
+static void tracking_dopesheet_channels_segments_calc(MovieTrackingDopesheetChannel *channel)
{
MovieTrackingTrack *track = channel->track;
int i, segment;
@@ -3750,6 +3987,10 @@ static void channels_segments_calc(MovieTrackingDopesheetChannel *channel)
channel->max_segment = 0;
channel->total_frames = 0;
+ /* TODO(sergey): looks a bit code-duplicated, need to look into
+ * logic de-duplication here.
+ */
+
/* count */
i = 0;
while (i < track->markersnr) {
@@ -3819,7 +4060,49 @@ static void channels_segments_calc(MovieTrackingDopesheetChannel *channel)
}
}
-static void tracking_dopesheet_sort(MovieTracking *tracking, int sort_method, int inverse)
+/* Create channels for tracks and calculate tracked segments for them. */
+static void tracking_dopesheet_channels_calc(MovieTracking *tracking)
+{
+ MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
+ MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
+ MovieTrackingTrack *track;
+ MovieTrackingReconstruction *reconstruction =
+ BKE_tracking_object_get_reconstruction(tracking, object);
+ ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
+
+ short sel_only = dopesheet->flag & TRACKING_DOPE_SELECTED_ONLY;
+ short show_hidden = dopesheet->flag & TRACKING_DOPE_SHOW_HIDDEN;
+
+ for (track = tracksbase->first; track; track = track->next) {
+ MovieTrackingDopesheetChannel *channel;
+
+ if (!show_hidden && (track->flag & TRACK_HIDDEN) != 0)
+ continue;
+
+ if (sel_only && !TRACK_SELECTED(track))
+ continue;
+
+ channel = MEM_callocN(sizeof(MovieTrackingDopesheetChannel), "tracking dopesheet channel");
+ channel->track = track;
+
+ if (reconstruction->flag & TRACKING_RECONSTRUCTED) {
+ BLI_snprintf(channel->name, sizeof(channel->name), "%s (%.4f)", track->name, track->error);
+ }
+ else {
+ BLI_strncpy(channel->name, track->name, sizeof(channel->name));
+ }
+
+ tracking_dopesheet_channels_segments_calc(channel);
+
+ BLI_addtail(&dopesheet->channels, channel);
+ dopesheet->tot_channel++;
+ }
+}
+
+/* Sot dopesheet channels using given method (name, average error, total coverage,
+ * longest tracked segment) and could also inverse the list if it's enabled.
+ */
+static void tracking_dopesheet_channels_sort(MovieTracking *tracking, int sort_method, int inverse)
{
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
@@ -3855,6 +4138,7 @@ static void tracking_dopesheet_sort(MovieTracking *tracking, int sort_method, in
static int coverage_from_count(int count)
{
+ /* Values are actually arbitrary here, probably need to be tweaked. */
if (count < 8)
return TRACKING_COVERAGE_BAD;
else if (count < 16)
@@ -3862,6 +4146,10 @@ static int coverage_from_count(int count)
return TRACKING_COVERAGE_OK;
}
+/* Calculate coverage of frames with tracks, this information
+ * is used to highlight dopesheet background depending on how
+ * many tracks exists on the frame.
+ */
static void tracking_dopesheet_calc_coverage(MovieTracking *tracking)
{
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
@@ -3935,6 +4223,9 @@ static void tracking_dopesheet_calc_coverage(MovieTracking *tracking)
MEM_freeN(per_frame_counter);
}
+/* Tag dopesheet for update, actual update will happen later
+ * when it'll be actually needed.
+ */
void BKE_tracking_dopesheet_tag_update(MovieTracking *tracking)
{
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
@@ -3942,53 +4233,22 @@ void BKE_tracking_dopesheet_tag_update(MovieTracking *tracking)
dopesheet->ok = FALSE;
}
+/* Do dopesheet update, if update is not needed nothing will happen. */
void BKE_tracking_dopesheet_update(MovieTracking *tracking)
{
- MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
- MovieTrackingTrack *track;
- MovieTrackingReconstruction *reconstruction;
- ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
short sort_method = dopesheet->sort_method;
short inverse = dopesheet->flag & TRACKING_DOPE_SORT_INVERSE;
- short sel_only = dopesheet->flag & TRACKING_DOPE_SELECTED_ONLY;
- short show_hidden = dopesheet->flag & TRACKING_DOPE_SHOW_HIDDEN;
if (dopesheet->ok)
return;
tracking_dopesheet_free(dopesheet);
- reconstruction = BKE_tracking_object_get_reconstruction(tracking, object);
-
/* channels */
- for (track = tracksbase->first; track; track = track->next) {
- MovieTrackingDopesheetChannel *channel;
-
- if (!show_hidden && (track->flag & TRACK_HIDDEN) != 0)
- continue;
-
- if (sel_only && !TRACK_SELECTED(track))
- continue;
-
- channel = MEM_callocN(sizeof(MovieTrackingDopesheetChannel), "tracking dopesheet channel");
- channel->track = track;
-
- if (reconstruction->flag & TRACKING_RECONSTRUCTED) {
- BLI_snprintf(channel->name, sizeof(channel->name), "%s (%.4f)", track->name, track->error);
- }
- else {
- BLI_strncpy(channel->name, track->name, sizeof(channel->name));
- }
-
- channels_segments_calc(channel);
-
- BLI_addtail(&dopesheet->channels, channel);
- dopesheet->tot_channel++;
- }
-
- tracking_dopesheet_sort(tracking, sort_method, inverse);
+ tracking_dopesheet_channels_calc(tracking);
+ tracking_dopesheet_channels_sort(tracking, sort_method, inverse);
/* frame coverage */
tracking_dopesheet_calc_coverage(tracking);