Re-track the plane after clearing the keyframe

From the math point of view there're two cases:

- Clearing the keyframe between two other ones.

  In this case tracker will first track plane from
  left keyframe to right one without doing any kind
  of blending. This will make plane stick to the
  actual plane motion, but lead to possible jump
  at the right keyframe.

  Second step is to track from the right keyframe
  to the left one with blending. This gives nice
  transition at the point of second keyframe and
  this mimics situation when you've been setting
  keyframes from left to right.

- Clearing left-most/right-most keyframe.

  In this case it's enough to only re-track the
  plane without blending from the neighbor keyframe
  without blending.
This commit is contained in:
2013-09-17 08:54:10 +00:00
parent bf5bbda187
commit b9be47e91c
3 changed files with 55 additions and 6 deletions

View File

@@ -218,6 +218,7 @@ void BKE_tracking_refine_marker(struct MovieClip *clip, struct MovieTrackingTrac
/* **** Plane tracking **** */
void BKE_tracking_track_plane_from_existing_motion(struct MovieTrackingPlaneTrack *plane_track, int start_frame);
void BKE_tracking_retrack_plane_from_existing_motion_at_segment(struct MovieTrackingPlaneTrack *plane_track, int start_frame);
void BKE_tracking_homography_between_two_quads(/*const*/ float reference_corners[4][2], /*const*/ float corners[4][2], float H[3][3]);
/* **** Camera solving **** */

View File

@@ -3282,7 +3282,8 @@ BLI_INLINE void mat3f_from_mat3d(float mat_float[3][3], double mat_double[3][3])
}
/* NOTE: frame number should be in clip space, not scene space */
static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_track, int start_frame, int direction)
static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_track, int start_frame,
int direction, bool retrack)
{
MovieTrackingPlaneMarker *start_plane_marker = BKE_tracking_plane_marker_get(plane_track, start_frame);
MovieTrackingPlaneMarker *keyframe_plane_marker = NULL;
@@ -3359,7 +3360,7 @@ static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_trac
new_plane_marker.framenr = current_frame + frame_delta;
if (keyframe_plane_marker &&
if (!retrack && keyframe_plane_marker &&
next_plane_marker &&
(plane_track->flag & PLANE_TRACK_AUTOKEY))
{
@@ -3384,8 +3385,47 @@ static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_trac
/* NOTE: frame number should be in clip space, not scene space */
void BKE_tracking_track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_track, int start_frame)
{
track_plane_from_existing_motion(plane_track, start_frame, 1);
track_plane_from_existing_motion(plane_track, start_frame, -1);
track_plane_from_existing_motion(plane_track, start_frame, 1, false);
track_plane_from_existing_motion(plane_track, start_frame, -1, false);
}
static MovieTrackingPlaneMarker *find_plane_keyframe(MovieTrackingPlaneTrack *plane_track,
int start_frame, int direction)
{
MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, start_frame);
int index = plane_marker - plane_track->markers;
int frame_delta = direction > 0 ? 1 : -1;
while (index >= 0 && index < plane_track->markersnr) {
if ((plane_marker->flag & PLANE_MARKER_TRACKED) == 0) {
return plane_marker;
}
plane_marker += frame_delta;
}
return NULL;
}
void BKE_tracking_retrack_plane_from_existing_motion_at_segment(MovieTrackingPlaneTrack *plane_track, int start_frame)
{
MovieTrackingPlaneMarker *prev_plane_keyframe, *next_plane_keyframe;
prev_plane_keyframe = find_plane_keyframe(plane_track, start_frame, -1);
next_plane_keyframe = find_plane_keyframe(plane_track, start_frame, 1);
if (prev_plane_keyframe != NULL && next_plane_keyframe != NULL) {
/* First we track from left keyframe to the right one without any blending. */
track_plane_from_existing_motion(plane_track, prev_plane_keyframe->framenr, 1, true);
/* And then we track from the right keyframe to the left one, so shape blends in nicely */
track_plane_from_existing_motion(plane_track, next_plane_keyframe->framenr, -1, false);
}
else if (prev_plane_keyframe != NULL) {
track_plane_from_existing_motion(plane_track, prev_plane_keyframe->framenr, 1, true);
}
else if (next_plane_keyframe != NULL) {
track_plane_from_existing_motion(plane_track, next_plane_keyframe->framenr, -1, true);
}
}
BLI_INLINE void float_corners_to_double(/*const*/ float corners[4][2], double double_corners[4][2])

View File

@@ -4135,14 +4135,22 @@ static void keyframe_set_flag(bContext *C, bool set)
MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get_exact(plane_track, framenr);
if (plane_marker) {
if (set) {
plane_marker->flag &= ~PLANE_MARKER_TRACKED;
if (plane_marker->flag & PLANE_MARKER_TRACKED) {
plane_marker->flag &= ~PLANE_MARKER_TRACKED;
BKE_tracking_track_plane_from_existing_motion(plane_track, plane_marker->framenr);
}
}
else {
plane_marker->flag |= PLANE_MARKER_TRACKED;
if ((plane_marker->flag & PLANE_MARKER_TRACKED) == 0) {
plane_marker->flag |= PLANE_MARKER_TRACKED;
BKE_tracking_retrack_plane_from_existing_motion_at_segment(plane_track, plane_marker->framenr);
}
}
}
}
}
WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
}
static int keyframe_insert_exec(bContext *C, wmOperator *UNUSED(op))