forked from bartvdbraak/blender
Tweaks to plane track
- Do plane re-evaluation only when transform is actually done. Before this re-evaluation happened on every mouse move. - Added a flag "Auto Keyframe" for the plane track, which does: * If Auto Keyframe is enabled, then every manual edit of the plane will create a new keyframe at current frame and update plane motion between current frame and previous/next keyframe. This now also implies blending detected motion with neighbor keyframes, so there's no jump happening. No automatic update on manual point tracks edit will happen. * If auto Keyframe is disabled, then no keyframes are adding to the plane and every plane tweak will re-evaluate in on the whole frame range. In this case manual tweaks to point tracks and re-tracking them implies plane re-evaluation.
This commit is contained in:
parent
97e823488c
commit
e72c6f191f
@ -601,6 +601,7 @@ class CLIP_PT_plane_track(CLIP_PT_tracking_panel, Panel):
|
||||
return
|
||||
|
||||
layout.prop(active_track, "name")
|
||||
layout.prop(active_track, "use_auto_keying")
|
||||
|
||||
|
||||
class CLIP_PT_track_settings(CLIP_PT_tracking_panel, Panel):
|
||||
|
@ -211,6 +211,8 @@ void BKE_tracking_context_free(struct MovieTrackingContext *context);
|
||||
void BKE_tracking_context_sync(struct MovieTrackingContext *context);
|
||||
void BKE_tracking_context_sync_user(const struct MovieTrackingContext *context, struct MovieClipUser *user);
|
||||
bool BKE_tracking_context_step(struct MovieTrackingContext *context);
|
||||
void BKE_tracking_context_finish(struct MovieTrackingContext *context);
|
||||
|
||||
void BKE_tracking_refine_marker(struct MovieClip *clip, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, bool backwards);
|
||||
|
||||
/* **** Plane tracking **** */
|
||||
|
@ -2498,7 +2498,7 @@ typedef struct MovieTrackingContext {
|
||||
MovieClip *clip;
|
||||
int clip_flag;
|
||||
|
||||
int frames;
|
||||
int frames, first_frame;
|
||||
bool first_time;
|
||||
|
||||
MovieTrackingSettings settings;
|
||||
@ -2538,6 +2538,7 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u
|
||||
context->backwards = backwards;
|
||||
context->sync_frame = user->framenr;
|
||||
context->first_time = true;
|
||||
context->first_frame = user->framenr;
|
||||
context->sequence = sequence;
|
||||
|
||||
/* count */
|
||||
@ -3114,6 +3115,44 @@ bool BKE_tracking_context_step(MovieTrackingContext *context)
|
||||
return ok;
|
||||
}
|
||||
|
||||
void BKE_tracking_context_finish(MovieTrackingContext *context)
|
||||
{
|
||||
MovieClip *clip = context->clip;
|
||||
ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking);
|
||||
MovieTrackingPlaneTrack *plane_track;
|
||||
int map_size = tracks_map_get_size(context->tracks_map);
|
||||
|
||||
for (plane_track = plane_tracks_base->first;
|
||||
plane_track;
|
||||
plane_track = plane_track->next)
|
||||
{
|
||||
if ((plane_track->flag & PLANE_TRACK_AUTOKEY) == 0) {
|
||||
int i;
|
||||
for (i = 0; i < map_size; i++) {
|
||||
TrackContext *track_context = NULL;
|
||||
MovieTrackingTrack *track, *old_track;
|
||||
bool do_update = false;
|
||||
int j;
|
||||
|
||||
tracks_map_get_indexed_element(context->tracks_map, i, &track, (void **)&track_context);
|
||||
|
||||
old_track = BLI_ghash_lookup(context->tracks_map->hash, track);
|
||||
for (j = 0; j < plane_track->point_tracksnr; j++) {
|
||||
if (plane_track->point_tracks[j] == old_track) {
|
||||
do_update = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_update) {
|
||||
BKE_tracking_track_plane_from_existing_motion(plane_track, context->first_frame);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Refine marker's position using previously known keyframe.
|
||||
* Direction of searching for a keyframe depends on backwards flag,
|
||||
* which means if backwards is false, previous keyframe will be as
|
||||
@ -3246,9 +3285,30 @@ BLI_INLINE void mat3f_from_mat3d(float mat_float[3][3], double mat_double[3][3])
|
||||
static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_track, int start_frame, int direction)
|
||||
{
|
||||
MovieTrackingPlaneMarker *start_plane_marker = BKE_tracking_plane_marker_get(plane_track, start_frame);
|
||||
MovieTrackingPlaneMarker *keyframe_plane_marker = NULL;
|
||||
MovieTrackingPlaneMarker new_plane_marker;
|
||||
int current_frame, frame_delta = direction > 0 ? 1 : -1;
|
||||
|
||||
if (plane_track->flag & PLANE_TRACK_AUTOKEY) {
|
||||
/* Find a keyframe in given direction. */
|
||||
for (current_frame = start_frame; ; current_frame += frame_delta) {
|
||||
MovieTrackingPlaneMarker *next_plane_marker =
|
||||
BKE_tracking_plane_marker_get_exact(plane_track, current_frame + frame_delta);
|
||||
|
||||
if (next_plane_marker == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((next_plane_marker->flag & PLANE_MARKER_TRACKED) == 0) {
|
||||
keyframe_plane_marker = next_plane_marker;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
start_plane_marker->flag |= PLANE_MARKER_TRACKED;
|
||||
}
|
||||
|
||||
new_plane_marker = *start_plane_marker;
|
||||
new_plane_marker.flag |= PLANE_MARKER_TRACKED;
|
||||
|
||||
@ -3262,7 +3322,10 @@ static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_trac
|
||||
|
||||
/* As soon as we meet keyframed plane, we stop updating the sequence. */
|
||||
if (next_plane_marker && (next_plane_marker->flag & PLANE_MARKER_TRACKED) == 0) {
|
||||
break;
|
||||
/* Don't override keyframes if track is in auto-keyframe mode */
|
||||
if (plane_track->flag & PLANE_TRACK_AUTOKEY) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
num_correspondences =
|
||||
@ -3296,6 +3359,21 @@ static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_trac
|
||||
|
||||
new_plane_marker.framenr = current_frame + frame_delta;
|
||||
|
||||
if (keyframe_plane_marker &&
|
||||
next_plane_marker &&
|
||||
(plane_track->flag & PLANE_TRACK_AUTOKEY))
|
||||
{
|
||||
float fac = ((float) next_plane_marker->framenr - start_plane_marker->framenr)
|
||||
/ ((float) keyframe_plane_marker->framenr - start_plane_marker->framenr);
|
||||
|
||||
fac = 3*fac*fac - 2*fac*fac*fac;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
interp_v2_v2v2(new_plane_marker.corners[i], new_plane_marker.corners[i],
|
||||
next_plane_marker->corners[i], fac);
|
||||
}
|
||||
}
|
||||
|
||||
BKE_tracking_plane_marker_insert(plane_track, &new_plane_marker);
|
||||
|
||||
MEM_freeN(x1);
|
||||
|
@ -812,6 +812,32 @@ static void cancel_mouse_slide(SlideMarkerData *data)
|
||||
}
|
||||
}
|
||||
|
||||
static void apply_mouse_slide(bContext *C, SlideMarkerData *data)
|
||||
{
|
||||
if (data->area == TRACK_AREA_POINT) {
|
||||
SpaceClip *sc = CTX_wm_space_clip(C);
|
||||
MovieClip *clip = ED_space_clip_get_clip(sc);
|
||||
MovieTrackingPlaneTrack *plane_track;
|
||||
ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking);
|
||||
int framenr = ED_space_clip_get_clip_frame_number(sc);
|
||||
|
||||
for (plane_track = plane_tracks_base->first;
|
||||
plane_track;
|
||||
plane_track = plane_track->next)
|
||||
{
|
||||
if ((plane_track->flag & PLANE_TRACK_AUTOKEY) == 0) {
|
||||
int i;
|
||||
for (i = 0; i < plane_track->point_tracksnr; i++) {
|
||||
if (plane_track->point_tracks[i] == data->track) {
|
||||
BKE_tracking_track_plane_from_existing_motion(plane_track, framenr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void free_slide_data(SlideMarkerData *data)
|
||||
{
|
||||
if (data->old_markers)
|
||||
@ -1007,6 +1033,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
|
||||
case LEFTMOUSE:
|
||||
if (event->val == KM_RELEASE) {
|
||||
apply_mouse_slide(C, op->customdata);
|
||||
free_slide_data(op->customdata);
|
||||
|
||||
show_cursor(C);
|
||||
@ -1267,7 +1294,7 @@ static void track_markers_updatejob(void *tmv)
|
||||
BKE_tracking_context_sync(tmj->context);
|
||||
}
|
||||
|
||||
static void track_markers_freejob(void *tmv)
|
||||
static void track_markers_endjob(void *tmv)
|
||||
{
|
||||
TrackMarkersJob *tmj = (TrackMarkersJob *)tmv;
|
||||
|
||||
@ -1276,10 +1303,15 @@ static void track_markers_freejob(void *tmv)
|
||||
ED_update_for_newframe(tmj->main, tmj->scene, 0);
|
||||
|
||||
BKE_tracking_context_sync(tmj->context);
|
||||
BKE_tracking_context_free(tmj->context);
|
||||
BKE_tracking_context_finish(tmj->context);
|
||||
|
||||
WM_main_add_notifier(NC_SCENE | ND_FRAME, tmj->scene);
|
||||
}
|
||||
|
||||
static void track_markers_freejob(void *tmv)
|
||||
{
|
||||
TrackMarkersJob *tmj = (TrackMarkersJob *)tmv;
|
||||
BKE_tracking_context_free(tmj->context);
|
||||
MEM_freeN(tmj);
|
||||
}
|
||||
|
||||
@ -1333,6 +1365,7 @@ static int track_markers_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
|
||||
BKE_tracking_context_sync(context);
|
||||
BKE_tracking_context_finish(context);
|
||||
BKE_tracking_context_free(context);
|
||||
|
||||
/* update scene current frame to the lastes tracked frame */
|
||||
@ -1389,7 +1422,7 @@ static int track_markers_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS
|
||||
else
|
||||
WM_jobs_timer(wm_job, 0.2, NC_MOVIECLIP | NA_EVALUATED, 0);
|
||||
|
||||
WM_jobs_callbacks(wm_job, track_markers_startjob, NULL, track_markers_updatejob, NULL);
|
||||
WM_jobs_callbacks(wm_job, track_markers_startjob, NULL, track_markers_updatejob, track_markers_endjob);
|
||||
|
||||
G.is_break = FALSE;
|
||||
|
||||
|
@ -5250,6 +5250,48 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *o
|
||||
}
|
||||
}
|
||||
|
||||
static void special_aftertrans_update__movieclip(bContext *C, TransInfo *t)
|
||||
{
|
||||
SpaceClip *sc = t->sa->spacedata.first;
|
||||
MovieClip *clip = ED_space_clip_get_clip(sc);
|
||||
MovieTrackingPlaneTrack *plane_track;
|
||||
ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking);
|
||||
int framenr = ED_space_clip_get_clip_frame_number(sc);
|
||||
|
||||
for (plane_track = plane_tracks_base->first;
|
||||
plane_track;
|
||||
plane_track = plane_track->next)
|
||||
{
|
||||
bool do_update = false;
|
||||
|
||||
do_update |= (plane_track->flag & SELECT) != 0;
|
||||
if (do_update == false) {
|
||||
if ((plane_track->flag & PLANE_TRACK_AUTOKEY) == 0) {
|
||||
int i;
|
||||
for (i = 0; i < plane_track->point_tracksnr; i++) {
|
||||
MovieTrackingTrack *track = plane_track->point_tracks[i];
|
||||
|
||||
if (TRACK_VIEW_SELECTED(sc, track)) {
|
||||
do_update = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (do_update) {
|
||||
BKE_tracking_track_plane_from_existing_motion(plane_track, framenr);
|
||||
}
|
||||
}
|
||||
|
||||
if (t->scene->nodetree) {
|
||||
/* tracks can be used for stabilization nodes,
|
||||
* flush update for such nodes */
|
||||
nodeUpdateID(t->scene->nodetree, &clip->id);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_NODES, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void special_aftertrans_update__mask(bContext *C, TransInfo *t)
|
||||
{
|
||||
Mask *mask = NULL;
|
||||
@ -5405,15 +5447,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
|
||||
}
|
||||
else if (t->spacetype == SPACE_CLIP) {
|
||||
if (t->options & CTX_MOVIECLIP) {
|
||||
SpaceClip *sc = t->sa->spacedata.first;
|
||||
MovieClip *clip = ED_space_clip_get_clip(sc);
|
||||
|
||||
if (t->scene->nodetree) {
|
||||
/* tracks can be used for stabilization nodes,
|
||||
* flush update for such nodes */
|
||||
nodeUpdateID(t->scene->nodetree, &clip->id);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_NODES, NULL);
|
||||
}
|
||||
special_aftertrans_update__movieclip(C, t);
|
||||
}
|
||||
else if (t->options & CTX_MASK) {
|
||||
special_aftertrans_update__mask(C, t);
|
||||
|
@ -659,9 +659,7 @@ static void recalcData_spaceclip(TransInfo *t)
|
||||
if (ED_space_clip_check_show_trackedit(sc)) {
|
||||
MovieClip *clip = ED_space_clip_get_clip(sc);
|
||||
ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
|
||||
ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking);
|
||||
MovieTrackingTrack *track;
|
||||
MovieTrackingPlaneTrack *plane_track;
|
||||
int framenr = ED_space_clip_get_clip_frame_number(sc);
|
||||
|
||||
flushTransTracking(t);
|
||||
@ -692,15 +690,6 @@ static void recalcData_spaceclip(TransInfo *t)
|
||||
track = track->next;
|
||||
}
|
||||
|
||||
for (plane_track = plane_tracks_base->first;
|
||||
plane_track;
|
||||
plane_track = plane_track->next)
|
||||
{
|
||||
if (plane_track->flag & SELECT) {
|
||||
BKE_tracking_track_plane_from_existing_motion(plane_track, framenr);
|
||||
}
|
||||
}
|
||||
|
||||
DAG_id_tag_update(&clip->id, 0);
|
||||
}
|
||||
else if (t->options & CTX_MASK) {
|
||||
|
@ -481,8 +481,9 @@ enum {
|
||||
|
||||
/* MovieTrackingPlaneTrack->flag */
|
||||
enum {
|
||||
PLANE_TRACK_HIDDEN = (1 << 1),
|
||||
PLANE_TRACK_LOCKED = (1 << 2),
|
||||
PLANE_TRACK_HIDDEN = (1 << 1),
|
||||
PLANE_TRACK_LOCKED = (1 << 2),
|
||||
PLANE_TRACK_AUTOKEY = (1 << 3),
|
||||
};
|
||||
|
||||
#endif /* __DNA_TRACKING_TYPES_H__ */
|
||||
|
@ -1460,6 +1460,12 @@ static void rna_def_trackingPlaneTrack(BlenderRNA *brna)
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT);
|
||||
RNA_def_property_ui_text(prop, "Select", "Plane track is selected");
|
||||
RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
|
||||
|
||||
/* auto keyframing */
|
||||
prop = RNA_def_property(srna, "use_auto_keying", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", PLANE_TRACK_AUTOKEY);
|
||||
RNA_def_property_ui_text(prop, "Auto Keyframe", "Automatic keyframe insertion when moving plane corners");
|
||||
RNA_def_property_ui_icon(prop, ICON_REC, 0);
|
||||
}
|
||||
|
||||
static void rna_def_trackingStabilization(BlenderRNA *brna)
|
||||
|
Loading…
Reference in New Issue
Block a user