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-08-16 13:46:30 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2013-08-16 13:46:30 +0400
commit24ce60cfe4511534e57a2dea3f24579c74bbdd29 (patch)
tree57df16e6d5f41545e1379f8a51e0e10fe6b2eef1 /source/blender/editors
parentcab2aef71ab44bc7d85cf4e2c1de607d02e0df7d (diff)
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker in tomato branch. Movie clip editor changes: - Artist might create a plane track out of multiple point tracks which belongs to the same track (minimum amount of point tracks is 4, maximum is not actually limited). When new plane track is added, it's getting "tracked" across all point tracks, which makes it stick to the same plane point tracks belong to. - After plane track was added, it need to be manually adjusted in a way it covers feature one might to mask/replace. General transform tools (G, R, S) or sliding corners with a mouse could be sued for this. Plane corner which corresponds to left bottom image corner has got X/Y axis on it (red is for X axis, green for Y). - Re-adjusting plane corners makes plane to be "re-tracked" for the frames sequence between current frame and next and previous keyframes. - Kayframes might be removed from the plane, using Shit-X (Marker Delete) operator. However, currently manual re-adjustment or "re-track" trigger is needed. Compositor changes: - Added new node called Plane Track Deform. - User selects which plane track to use (for this he need to select movie clip datablock, object and track names). - Node gets an image input, which need to be warped into the plane. - Node outputs: * Input image warped into the plane. * Plane, rasterized to a mask. Masking changes: - Mask points might be parented to a plane track, which makes this point deforming in a way as if it belongs to the tracked plane. Some video tutorials are available: - Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4 - Artist video: https://vimeo.com/71727578 This is mine and Keir's holiday code project :)
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/mask/mask_relationships.c55
-rw-r--r--source/blender/editors/mask/mask_shapekey.c1
-rw-r--r--source/blender/editors/space_clip/clip_draw.c232
-rw-r--r--source/blender/editors/space_clip/clip_graph_ops.c6
-rw-r--r--source/blender/editors/space_clip/clip_intern.h7
-rw-r--r--source/blender/editors/space_clip/clip_utils.c56
-rw-r--r--source/blender/editors/space_clip/space_clip.c7
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c403
-rw-r--r--source/blender/editors/space_clip/tracking_select.c257
-rw-r--r--source/blender/editors/space_node/drawnode.c36
-rw-r--r--source/blender/editors/transform/transform.c7
-rw-r--r--source/blender/editors/transform/transform.h2
-rw-r--r--source/blender/editors/transform/transform_conversions.c159
-rw-r--r--source/blender/editors/transform/transform_generics.c11
14 files changed, 1139 insertions, 100 deletions
diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c
index 2a1bdee32f7..6ced2423074 100644
--- a/source/blender/editors/mask/mask_relationships.c
+++ b/source/blender/editors/mask/mask_relationships.c
@@ -102,32 +102,53 @@ static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op))
MaskLayer *masklay;
/* parent info */
- SpaceClip *sc;
- MovieClip *clip;
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+ MovieTracking *tracking;
MovieTrackingTrack *track;
- MovieTrackingMarker *marker;
+ MovieTrackingPlaneTrack *plane_track;
MovieTrackingObject *tracking_object;
/* done */
- int framenr;
+ int framenr, parent_type;
+ float parmask_pos[2], orig_corners[4][2];
+ char *sub_parent_name;
- float marker_pos_ofs[2];
- float parmask_pos[2];
-
- if ((NULL == (sc = CTX_wm_space_clip(C))) ||
- (NULL == (clip = sc->clip)) ||
- (NULL == (track = clip->tracking.act_track)) ||
- (NULL == (tracking_object = BKE_tracking_object_get_active(&clip->tracking))))
- {
+ if (ELEM(NULL, sc, clip)) {
return OPERATOR_CANCELLED;
}
framenr = ED_space_clip_get_clip_frame_number(sc);
- marker = BKE_tracking_marker_get(track, framenr);
- add_v2_v2v2(marker_pos_ofs, marker->pos, track->offset);
+ tracking = &clip->tracking;
+ tracking_object = BKE_tracking_object_get_active(&clip->tracking);
+
+ if (tracking_object == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ if ((track = BKE_tracking_track_get_active(tracking)) != NULL) {
+ MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
+ float marker_pos_ofs[2];
+
+ add_v2_v2v2(marker_pos_ofs, marker->pos, track->offset);
- BKE_mask_coord_from_movieclip(clip, &sc->user, parmask_pos, marker_pos_ofs);
+ BKE_mask_coord_from_movieclip(clip, &sc->user, parmask_pos, marker_pos_ofs);
+
+ sub_parent_name = track->name;
+ parent_type = MASK_PARENT_POINT_TRACK;
+ }
+ else if ((plane_track = BKE_tracking_plane_track_get_active(tracking)) != NULL) {
+ MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);
+
+ zero_v2(parmask_pos);
+ sub_parent_name = plane_track->name;
+ parent_type = MASK_PARENT_PLANE_TRACK;
+ memcpy(orig_corners, plane_marker->corners, sizeof(orig_corners));
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
MaskSpline *spline;
@@ -144,10 +165,12 @@ static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op))
if (MASKPOINT_ISSEL_ANY(point)) {
point->parent.id_type = ID_MC;
point->parent.id = &clip->id;
+ point->parent.type = parent_type;
BLI_strncpy(point->parent.parent, tracking_object->name, sizeof(point->parent.parent));
- BLI_strncpy(point->parent.sub_parent, track->name, sizeof(point->parent.sub_parent));
+ BLI_strncpy(point->parent.sub_parent, sub_parent_name, sizeof(point->parent.sub_parent));
copy_v2_v2(point->parent.parent_orig, parmask_pos);
+ memcpy(point->parent.parent_corners_orig, orig_corners, sizeof(point->parent.parent_corners_orig));
}
}
}
diff --git a/source/blender/editors/mask/mask_shapekey.c b/source/blender/editors/mask/mask_shapekey.c
index 93bdca93096..d5fbdca5b0a 100644
--- a/source/blender/editors/mask/mask_shapekey.c
+++ b/source/blender/editors/mask/mask_shapekey.c
@@ -38,6 +38,7 @@
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_mask.h"
+#include "BKE_report.h"
#include "DNA_object_types.h"
#include "DNA_mask_types.h"
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index d1fd5093974..eb58bdc7696 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -111,6 +111,57 @@ static void draw_keyframe(int frame, int cfra, int sfra, float framelen, int wid
}
}
+static int generic_track_get_markersnr(MovieTrackingTrack *track, MovieTrackingPlaneTrack *plane_track)
+{
+ if (track) {
+ return track->markersnr;
+ }
+ else if (plane_track) {
+ return plane_track->markersnr;
+ }
+
+ return 0;
+}
+
+static int generic_track_get_marker_framenr(MovieTrackingTrack *track, MovieTrackingPlaneTrack *plane_track,
+ int marker_index)
+{
+ if (track) {
+ return track->markers[marker_index].framenr;
+ }
+ else if (plane_track) {
+ return plane_track->markers[marker_index].framenr;
+ }
+
+ return 0;
+}
+
+static bool generic_track_is_marker_enabled(MovieTrackingTrack *track, MovieTrackingPlaneTrack *plane_track,
+ int marker_index)
+{
+ if (track) {
+ return (track->markers[marker_index].flag & MARKER_DISABLED) == 0;
+ }
+ else if (plane_track) {
+ return true;
+ }
+
+ return false;
+}
+
+static bool generic_track_is_marker_keyframed(MovieTrackingTrack *track, MovieTrackingPlaneTrack *plane_track,
+ int marker_index)
+{
+ if (track) {
+ return (track->markers[marker_index].flag & MARKER_TRACKED) == 0;
+ }
+ else if (plane_track) {
+ return (plane_track->markers[marker_index].flag & PLANE_MARKER_TRACKED) == 0;
+ }
+
+ return false;
+}
+
static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Scene *scene)
{
float x;
@@ -119,6 +170,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
MovieTracking *tracking = &clip->tracking;
MovieTrackingObject *act_object = BKE_tracking_object_get_active(tracking);
MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking);
+ MovieTrackingPlaneTrack *act_plane_track = BKE_tracking_plane_track_get_active(&clip->tracking);
MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking);
glEnable(GL_BLEND);
@@ -143,34 +195,29 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
}
/* track */
- if (act_track) {
- MovieTrackingTrack *track = act_track;
-
+ if (act_track || act_plane_track) {
for (i = sfra - clip->start_frame + 1, a = 0; i <= efra - clip->start_frame + 1; i++) {
int framenr;
- MovieTrackingMarker *marker;
+ int markersnr = generic_track_get_markersnr(act_track, act_plane_track);
- while (a < track->markersnr) {
- if (track->markers[a].framenr >= i)
+ while (a < markersnr) {
+ int marker_framenr = generic_track_get_marker_framenr(act_track, act_plane_track, a);
+
+ if (marker_framenr >= i)
break;
- if (a < track->markersnr - 1 && track->markers[a + 1].framenr > i)
+ if (a < markersnr - 1 && generic_track_get_marker_framenr(act_track, act_plane_track, a + 1) > i)
break;
a++;
}
- if (a < track->markersnr)
- marker = &track->markers[a];
- else
- marker = &track->markers[track->markersnr - 1];
-
- if ((marker->flag & MARKER_DISABLED) == 0) {
- framenr = marker->framenr;
+ if (generic_track_is_marker_enabled(act_track, act_plane_track, a)) {
+ framenr = generic_track_get_marker_framenr(act_track, act_plane_track, a);
if (framenr != i)
glColor4ub(128, 128, 0, 96);
- else if ((marker->flag & MARKER_TRACKED) == 0)
+ else if (generic_track_is_marker_keyframed(act_track, act_plane_track, a))
glColor4ub(255, 255, 0, 196);
else
glColor4ub(255, 255, 0, 96);
@@ -961,13 +1008,159 @@ static void view2d_to_region_float(View2D *v2d, float x, float y, float *regionx
*regiony = v2d->mask.ymin + y * BLI_rcti_size_y(&v2d->mask);
}
+static void plane_track_colors(bool is_active, float color[3], float selected_color[3])
+{
+ UI_GetThemeColor3fv(TH_MARKER, color);
+
+ if (is_active)
+ UI_GetThemeColor3fv(TH_ACT_MARKER, selected_color);
+ else
+ UI_GetThemeColor3fv(TH_SEL_MARKER, selected_color);
+}
+
+static void getArrowEndPoint(const int width, const int height, const float zoom,
+ const float start_corner[2], const float end_corner[2],
+ float end_point[2])
+{
+ float direction[2];
+ float max_length;
+
+ sub_v2_v2v2(direction, end_corner, start_corner);
+
+ direction[0] *= width;
+ direction[1] *= height;
+ max_length = len_v2(direction);
+ normalize_v2(direction);
+ mul_v2_fl(direction, min_ff(32.0f / zoom, max_length));
+ direction[0] /= width;
+ direction[1] /= height;
+
+ add_v2_v2v2(end_point, start_corner, direction);
+}
+
+static void draw_plane_marker_ex(SpaceClip *sc, MovieTrackingPlaneTrack *plane_track,
+ MovieTrackingPlaneMarker *plane_marker, bool is_active_track,
+ bool draw_outline, int width, int height)
+{
+ bool tiny = (sc->flag & SC_SHOW_TINY_MARKER) != 0;
+ bool is_selected_track = plane_track->flag & SELECT;
+ float px[2];
+
+ if (draw_outline) {
+ UI_ThemeColor(TH_MARKER_OUTLINE);
+ }
+ else {
+ float color[3], selected_color[3];
+ plane_track_colors(is_active_track, color, selected_color);
+ if (is_selected_track) {
+ glColor3fv(selected_color);
+ }
+ else {
+ glColor3fv(color);
+ }
+ }
+
+ px[0] = 1.0f / width / sc->zoom;
+ px[1] = 1.0f / height / sc->zoom;
+
+ if (draw_outline) {
+ if (!tiny) {
+ glLineWidth(3.0f);
+ }
+ }
+ else if (tiny) {
+ glLineStipple(3, 0xaaaa);
+ glEnable(GL_LINE_STIPPLE);
+ glEnable(GL_COLOR_LOGIC_OP);
+ glLogicOp(GL_NOR);
+ }
+
+ /* Draw rectangle itself. */
+ glBegin(GL_LINE_LOOP);
+ glVertex2fv(plane_marker->corners[0]);
+ glVertex2fv(plane_marker->corners[1]);
+ glVertex2fv(plane_marker->corners[2]);
+ glVertex2fv(plane_marker->corners[3]);
+ glEnd();
+
+ /* Draw axis. */
+ if (!draw_outline) {
+ float end_point[2];
+ glPushAttrib(GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT);
+
+ getArrowEndPoint(width, height, sc->zoom, plane_marker->corners[0], plane_marker->corners[1], end_point);
+ glColor3f(1.0, 0.0, 0.0f);
+ glBegin(GL_LINES);
+ glVertex2fv(plane_marker->corners[0]);
+ glVertex2fv(end_point);
+ glEnd();
+
+ getArrowEndPoint(width, height, sc->zoom, plane_marker->corners[0], plane_marker->corners[3], end_point);
+ glColor3f(0.0, 1.0, 0.0f);
+ glBegin(GL_LINES);
+ glVertex2fv(plane_marker->corners[0]);
+ glVertex2fv(end_point);
+ glEnd();
+
+ glPopAttrib();
+ }
+
+ /* Draw sliders. */
+ if (is_selected_track) {
+ int i;
+ for (i = 0; i < 4; i++) {
+ draw_marker_slide_square(plane_marker->corners[i][0], plane_marker->corners[i][1],
+ 3.0f * px[0], 3.0f * px[1], draw_outline, px);
+ }
+ }
+
+ if (draw_outline) {
+ if (!tiny) {
+ glLineWidth(1.0f);
+ }
+ }
+ else if (tiny) {
+ glDisable(GL_COLOR_LOGIC_OP);
+ glDisable(GL_LINE_STIPPLE);
+ glLineStipple(3, 0xaaaa);
+ glEnable(GL_LINE_STIPPLE);
+ }
+}
+
+static void draw_plane_marker_outline(SpaceClip *sc, MovieTrackingPlaneTrack *plane_track,
+ MovieTrackingPlaneMarker *plane_marker, int width, int height)
+{
+ draw_plane_marker_ex(sc, plane_track, plane_marker, false, true, width, height);
+}
+
+static void draw_plane_marker(SpaceClip *sc, MovieTrackingPlaneTrack *plane_track,
+ MovieTrackingPlaneMarker *plane_marker, bool is_active_track,
+ int width, int height)
+{
+ draw_plane_marker_ex(sc, plane_track, plane_marker, is_active_track, false, width, height);
+}
+
+static void draw_plane_track(SpaceClip *sc, MovieTrackingPlaneTrack *plane_track,
+ int framenr, bool is_active_track, int width, int height)
+{
+ MovieTrackingPlaneMarker *plane_marker;
+
+ plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);
+
+ draw_plane_marker_outline(sc, plane_track, plane_marker, width, height);
+ draw_plane_marker(sc, plane_track, plane_marker, is_active_track, width, height);
+}
+
+/* Draw all kind of tracks. */
static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
int width, int height, float zoomx, float zoomy)
{
float x, y;
MovieTracking *tracking = &clip->tracking;
ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+ ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
MovieTrackingTrack *track, *act_track;
+ MovieTrackingPlaneTrack *plane_track, *active_plane_track;
MovieTrackingMarker *marker;
int framenr = ED_space_clip_get_clip_frame_number(sc);
int undistort = sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT;
@@ -1160,6 +1353,15 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
glDisable(GL_POINT_SMOOTH);
}
+ /* Draw plane tracks */
+ active_plane_track = BKE_tracking_plane_track_get_active(tracking);
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = plane_track->next)
+ {
+ draw_plane_track(sc, plane_track, framenr, plane_track == active_plane_track, width, height);
+ }
+
glPopMatrix();
if (sc->flag & SC_SHOW_NAMES) {
diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c
index edc6ac1ecf7..cdb0fdadebd 100644
--- a/source/blender/editors/space_clip/clip_graph_ops.c
+++ b/source/blender/editors/space_clip/clip_graph_ops.c
@@ -466,11 +466,10 @@ static int delete_curve_exec(bContext *C, wmOperator *UNUSED(op))
SpaceClip *sc = CTX_wm_space_clip(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
- ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
if (act_track)
- clip_delete_track(C, clip, tracksbase, act_track);
+ clip_delete_track(C, clip, act_track);
return OPERATOR_FINISHED;
}
@@ -498,7 +497,6 @@ static int delete_knot_exec(bContext *C, wmOperator *UNUSED(op))
SpaceClip *sc = CTX_wm_space_clip(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
- ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
if (act_track) {
@@ -508,7 +506,7 @@ static int delete_knot_exec(bContext *C, wmOperator *UNUSED(op))
MovieTrackingMarker *marker = &act_track->markers[a];
if (marker->flag & MARKER_GRAPH_SEL)
- clip_delete_marker(C, clip, tracksbase, act_track, marker);
+ clip_delete_marker(C, clip, act_track, marker);
else
a++;
}
diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h
index 51cb83eecad..8d112b7413c 100644
--- a/source/blender/editors/space_clip/clip_intern.h
+++ b/source/blender/editors/space_clip/clip_intern.h
@@ -132,8 +132,8 @@ void clip_graph_tracking_values_iterate(struct SpaceClip *sc, int selected_only,
void clip_graph_tracking_iterate(struct SpaceClip *sc, int selected_only, int include_hidden, void *userdata,
void (*func)(void *userdata, struct MovieTrackingMarker *marker));
-void clip_delete_track(struct bContext *C, struct MovieClip *clip, struct ListBase *tracksbase, struct MovieTrackingTrack *track);
-void clip_delete_marker(struct bContext *C, struct MovieClip *clip, struct ListBase *tracksbase, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker);
+void clip_delete_track(struct bContext *C, struct MovieClip *clip, struct MovieTrackingTrack *track);
+void clip_delete_marker(struct bContext *C, struct MovieClip *clip, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker);
void clip_view_center_to_point(SpaceClip *sc, float x, float y);
@@ -193,6 +193,9 @@ void CLIP_OT_tracking_object_remove(struct wmOperatorType *ot);
void CLIP_OT_copy_tracks(struct wmOperatorType *ot);
void CLIP_OT_paste_tracks(struct wmOperatorType *ot);
+void CLIP_OT_create_plane_track(struct wmOperatorType *ot);
+void CLIP_OT_slide_plane_marker(struct wmOperatorType *ot);
+
/* tracking_select.c */
void CLIP_OT_select(struct wmOperatorType *ot);
void CLIP_OT_select_all(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c
index d7a9b1c0cb6..72a3cb98a6a 100644
--- a/source/blender/editors/space_clip/clip_utils.c
+++ b/source/blender/editors/space_clip/clip_utils.c
@@ -175,11 +175,14 @@ void clip_graph_tracking_iterate(SpaceClip *sc, int selected_only, int include_h
}
}
-void clip_delete_track(bContext *C, MovieClip *clip, ListBase *tracksbase, MovieTrackingTrack *track)
+void clip_delete_track(bContext *C, MovieClip *clip, MovieTrackingTrack *track)
{
MovieTracking *tracking = &clip->tracking;
MovieTrackingStabilization *stab = &tracking->stabilization;
MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
+ MovieTrackingPlaneTrack *plane_track, *next_plane_track;
+ ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+ ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
int has_bundle = FALSE, update_stab = FALSE;
@@ -196,6 +199,51 @@ void clip_delete_track(bContext *C, MovieClip *clip, ListBase *tracksbase, Movie
if (track->flag & TRACK_HAS_BUNDLE)
has_bundle = TRUE;
+ /* Make sure no plane will use freed track */
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = next_plane_track)
+ {
+ bool found = false;
+ int i;
+
+ next_plane_track = plane_track->next;
+
+ for (i = 0; i < plane_track->point_tracksnr; i++) {
+ if (plane_track->point_tracks[i] == track) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ continue;
+ }
+
+ if (plane_track->point_tracksnr > 4) {
+ int track_index;
+ MovieTrackingTrack **new_point_tracks;
+
+ new_point_tracks = MEM_mallocN(sizeof(*new_point_tracks) * plane_track->point_tracksnr,
+ "new point tracks array");
+
+ for (i = 0, track_index = 0; i < plane_track->point_tracksnr; i++) {
+ if (plane_track->point_tracks[i] != track) {
+ new_point_tracks[track_index++] = plane_track->point_tracks[i];
+ }
+ }
+
+ MEM_freeN(plane_track->point_tracks);
+ plane_track->point_tracks = new_point_tracks;
+ plane_track->point_tracksnr--;
+ }
+ else {
+ /* Delete planes with less than 3 point tracks in it. */
+ BKE_tracking_plane_track_free(plane_track);
+ BLI_freelinkN(plane_tracks_base, plane_track);
+ }
+ }
+
BKE_tracking_track_free(track);
BLI_freelinkN(tracksbase, track);
@@ -212,11 +260,11 @@ void clip_delete_track(bContext *C, MovieClip *clip, ListBase *tracksbase, Movie
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
}
-void clip_delete_marker(bContext *C, MovieClip *clip, ListBase *tracksbase,
- MovieTrackingTrack *track, MovieTrackingMarker *marker)
+void clip_delete_marker(bContext *C, MovieClip *clip, MovieTrackingTrack *track,
+ MovieTrackingMarker *marker)
{
if (track->markersnr == 1) {
- clip_delete_track(C, clip, tracksbase, track);
+ clip_delete_track(C, clip, track);
}
else {
BKE_tracking_marker_delete(track, marker->framenr);
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 562a8584560..8213853c937 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -517,6 +517,10 @@ static void clip_operatortypes(void)
WM_operatortype_append(CLIP_OT_copy_tracks);
WM_operatortype_append(CLIP_OT_paste_tracks);
+ /* Plane tracker */
+ WM_operatortype_append(CLIP_OT_create_plane_track);
+ WM_operatortype_append(CLIP_OT_slide_plane_marker);
+
/* ** clip_graph_ops.c ** */
/* graph editing */
@@ -685,6 +689,9 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks_clear", HKEY, KM_PRESS, KM_ALT, 0);
+ /* plane tracks */
+ WM_keymap_add_item(keymap, "CLIP_OT_slide_plane_marker", LEFTMOUSE, KM_PRESS, 0, 0);
+
/* clean-up */
WM_keymap_add_item(keymap, "CLIP_OT_join_tracks", JKEY, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index f3d070452a5..e14fc8ad399 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -34,6 +34,7 @@
#include "DNA_camera_types.h"
#include "DNA_constraint_types.h"
#include "DNA_gpencil_types.h"
+#include "DNA_mask_types.h"
#include "DNA_movieclip_types.h"
#include "DNA_object_types.h" /* SELECT */
#include "DNA_scene_types.h"
@@ -55,6 +56,8 @@
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_library.h"
+#include "BKE_mask.h"
+#include "BKE_node.h"
#include "BKE_sound.h"
#include "WM_api.h"
@@ -88,6 +91,7 @@ static bool add_marker(const bContext *C, float x, float y)
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+ ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
MovieTrackingTrack *track;
int width, height;
int framenr = ED_space_clip_get_clip_frame_number(sc);
@@ -101,8 +105,10 @@ static bool add_marker(const bContext *C, float x, float y)
track = BKE_tracking_track_add(tracking, tracksbase, x, y, framenr, width, height);
BKE_tracking_track_select(tracksbase, track, TRACK_AREA_ALL, 0);
+ BKE_tracking_plane_tracks_deselect_all(plane_tracks_base);
clip->tracking.act_track = track;
+ clip->tracking.act_plane_track = NULL;
return true;
}
@@ -234,13 +240,31 @@ static int delete_track_exec(bContext *C, wmOperator *UNUSED(op))
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+ ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
MovieTrackingTrack *track = tracksbase->first, *next;
+ MovieTrackingPlaneTrack *plane_track, *next_plane_track;
+ bool modified = false;
+
+ /* Delete selected plane tracks. */
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = next_plane_track)
+ {
+ next_plane_track = plane_track->next;
+
+ if (plane_track->flag & SELECT) {
+ BKE_tracking_plane_track_free(plane_track);
+ BLI_freelinkN(plane_tracks_base, plane_track);
+ modified = true;
+ }
+ }
+ /* Remove selected point tracks (they'll also be removed from planes which uses them). */
while (track) {
next = track->next;
if (TRACK_VIEW_SELECTED(sc, track))
- clip_delete_track(C, clip, tracksbase, track);
+ clip_delete_track(C, clip, track);
track = next;
}
@@ -248,6 +272,10 @@ static int delete_track_exec(bContext *C, wmOperator *UNUSED(op))
/* nothing selected now, unlock view so it can be scrolled nice again */
sc->flag &= ~SC_LOCK_SELECTION;
+ if (modified) {
+ WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
+ }
+
return OPERATOR_FINISHED;
}
@@ -274,7 +302,9 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op))
SpaceClip *sc = CTX_wm_space_clip(C);
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 = tracksbase->first, *next;
+ MovieTrackingPlaneTrack *plane_track, *plane_track_next;
int framenr = ED_space_clip_get_clip_frame_number(sc);
int has_selection = 0;
@@ -287,13 +317,34 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op))
if (marker) {
has_selection |= track->markersnr > 1;
- clip_delete_marker(C, clip, tracksbase, track, marker);
+ clip_delete_marker(C, clip, track, marker);
}
}
track = next;
}
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = plane_track_next)
+ {
+ plane_track_next = plane_track->next;
+
+ if (plane_track->flag & SELECT) {
+ MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get_exact(plane_track, framenr);
+
+ if (plane_marker) {
+ if (plane_track->markersnr == 1) {
+ BKE_tracking_plane_track_free(plane_track);
+ BLI_freelinkN(plane_tracks_base, plane_track);
+ }
+ else {
+ BKE_tracking_plane_marker_delete(plane_track, framenr);
+ }
+ }
+ }
+ }
+
if (!has_selection) {
/* nothing selected now, unlock view so it can be scrolled nice again */
sc->flag &= ~SC_LOCK_SELECTION;
@@ -727,6 +778,7 @@ static int slide_marker_invoke(bContext *C, wmOperator *op, const wmEvent *event
MovieTracking *tracking = &clip->tracking;
tracking->act_track = slidedata->track;
+ tracking->act_plane_track = NULL;
op->customdata = slidedata;
@@ -3670,3 +3722,350 @@ void CLIP_OT_paste_tracks(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+
+/********************** Create plane track operator *********************/
+
+static int create_plane_track_tracks_exec(bContext *C, wmOperator *op)
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+ MovieTracking *tracking = &clip->tracking;
+ MovieTrackingPlaneTrack *plane_track;
+ ListBase *tracks_base = BKE_tracking_get_active_tracks(tracking);
+ ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
+ int framenr = ED_space_clip_get_clip_frame_number(sc);
+
+ plane_track = BKE_tracking_plane_track_add(tracking, plane_tracks_base, tracks_base, framenr);
+
+ if (plane_track == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Need at least 4 selected point tracks to create a plane");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ BKE_tracking_tracks_deselect_all(tracks_base);
+
+ plane_track->flag |= SELECT;
+ clip->tracking.act_track = NULL;
+ clip->tracking.act_plane_track = plane_track;
+
+ /* Copute homoraphies and apply them on marker's corner, so we've got
+ * quite nice motion from the very beginning.
+ */
+ BKE_tracking_track_plane_from_existing_motion(plane_track, framenr);
+ }
+
+ WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_create_plane_track(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Create Plane Track";
+ ot->description = "Create new plane track out of selected point tracks";
+ ot->idname = "CLIP_OT_create_plane_track";
+
+ /* api callbacks */
+ ot->exec = create_plane_track_tracks_exec;
+ ot->poll = ED_space_clip_tracking_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/********************** Slide plane marker corner operator *********************/
+
+typedef struct SlidePlaneMarkerData {
+ MovieTrackingPlaneTrack *plane_track;
+ MovieTrackingPlaneMarker *plane_marker;
+ int width, height;
+ int corner_index;
+ float *corner;
+ int previous_mval[2];
+ float previous_corner[2];
+ float old_corner[2];
+ bool accurate;
+} SlidePlaneMarkerData;
+
+static bool mouse_on_plane_slide_zone(SpaceClip *sc, float co[2], float slide_zone[2], int width, int height)
+{
+ const float size = 12.0f;
+ float dx, dy;
+
+ dx = size / width / sc->zoom;
+ dy = size / height / sc->zoom;
+
+ return IN_RANGE_INCL(co[0], slide_zone[0] - dx, slide_zone[0] + dx) &&
+ IN_RANGE_INCL(co[1], slide_zone[1] - dy, slide_zone[1] + dy);
+}
+
+static MovieTrackingPlaneTrack *tracking_plane_marker_check_slide(bContext *C, const wmEvent *event, int *corner_r)
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ ARegion *ar = CTX_wm_region(C);
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+ MovieTrackingPlaneTrack *plane_track;
+ int width, height;
+ float co[2];
+ ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking);
+ int framenr = ED_space_clip_get_clip_frame_number(sc);
+
+ ED_space_clip_get_size(sc, &width, &height);
+
+ if (width == 0 || height == 0) {
+ return NULL;
+ }
+
+ ED_clip_mouse_pos(sc, ar, event->mval, co);
+
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = plane_track->next)
+ {
+ if (plane_track->flag & SELECT) {
+ MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);
+ bool ok = false;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (mouse_on_plane_slide_zone(sc, co, plane_marker->corners[i], width, height)) {
+ if (corner_r) {
+ *corner_r = i;
+ }
+ ok = true;
+ break;
+ }
+ }
+
+ if (ok) {
+ return plane_track;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+static void *slide_plane_marker_customdata(bContext *C, const wmEvent *event)
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ ARegion *ar = CTX_wm_region(C);
+ MovieTrackingPlaneTrack *plane_track;
+ int width, height;
+ float co[2];
+ SlidePlaneMarkerData *customdata = NULL;
+ int framenr = ED_space_clip_get_clip_frame_number(sc);
+ int corner;
+
+ ED_space_clip_get_size(sc, &width, &height);
+
+ if (width == 0 || height == 0) {
+ return NULL;
+ }
+
+ ED_clip_mouse_pos(sc, ar, event->mval, co);
+
+ plane_track = tracking_plane_marker_check_slide(C, event, &corner);
+ if (plane_track) {
+ MovieTrackingPlaneMarker *plane_marker;
+
+ customdata = MEM_callocN(sizeof(SlidePlaneMarkerData), "slide plane marker data");
+
+ plane_marker = BKE_tracking_plane_marker_ensure(plane_track, framenr);
+
+ customdata->plane_track = plane_track;
+ customdata->plane_marker = plane_marker;
+ customdata->width = width;
+ customdata->height = height;
+
+ customdata->previous_mval[0] = event->mval[0];
+ customdata->previous_mval[1] = event->mval[1];
+
+ customdata->corner_index = corner;
+ customdata->corner = plane_marker->corners[corner];
+
+ copy_v2_v2(customdata->previous_corner, customdata->corner);
+ copy_v2_v2(customdata->old_corner, customdata->corner);
+ }
+
+ return customdata;
+}
+
+static int slide_plane_marker_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ SlidePlaneMarkerData *slidedata = slide_plane_marker_customdata(C, event);
+
+ if (slidedata) {
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+ MovieTracking *tracking = &clip->tracking;
+
+ tracking->act_plane_track = slidedata->plane_track;
+ tracking->act_track = NULL;
+
+ op->customdata = slidedata;
+
+ hide_cursor(C);
+ WM_event_add_modal_handler(C, op);
+
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL);
+
+ return OPERATOR_RUNNING_MODAL;
+ }
+
+ return OPERATOR_PASS_THROUGH;
+}
+
+static void cancel_mouse_slide_plane_marker(SlidePlaneMarkerData *data)
+{
+ copy_v2_v2(data->corner, data->old_corner);
+}
+
+static void free_slide_plane_marker_data(SlidePlaneMarkerData *data)
+{
+ MEM_freeN(data);
+}
+
+static void slide_plane_marker_update_homographies(SpaceClip *sc, SlidePlaneMarkerData *data)
+{
+ int framenr = ED_space_clip_get_clip_frame_number(sc);
+
+ BKE_tracking_track_plane_from_existing_motion(data->plane_track, framenr);
+}
+
+static int slide_plane_marker_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+ SlidePlaneMarkerData *data = (SlidePlaneMarkerData *) op->customdata;
+ float dx, dy, mdelta[2];
+ int next_corner_index, prev_corner_index, diag_corner_index;
+ float *next_corner, *prev_corner, *diag_corner;
+ float next_edge[2], prev_edge[2], next_diag_edge[2], prev_diag_edge[2];
+
+ switch (event->type) {
+ case LEFTCTRLKEY:
+ case RIGHTCTRLKEY:
+ case LEFTSHIFTKEY:
+ case RIGHTSHIFTKEY:
+ if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY))
+ data->accurate = event->val == KM_PRESS;
+
+ /* fall-through */
+ case MOUSEMOVE:
+ mdelta[0] = event->mval[0] - data->previous_mval[0];
+ mdelta[1] = event->mval[1] - data->previous_mval[1];
+
+ dx = mdelta[0] / data->width / sc->zoom;
+ dy = mdelta[1] / data->height / sc->zoom;
+
+ if (data->accurate) {
+ dx /= 5.0f;
+ dy /= 5.0f;
+ }
+
+ data->corner[0] = data->previous_corner[0] + dx;
+ data->corner[1] = data->previous_corner[1] + dy;
+
+
+ /*
+ prev_edge
+ (Corner 3, current) <----------------------- (Corner 2, previous)
+ | ^
+ | |
+ | |
+ | |
+ next_edge | | next_diag_edge
+ | |
+ | |
+ | |
+ v |
+ (Corner 0, next) -----------------------> (Corner 1, diagonal)
+ prev_diag_edge
+ */
+
+ next_corner_index = (data->corner_index + 1) % 4;
+ prev_corner_index = (data->corner_index + 3) % 4;
+ diag_corner_index = (data->corner_index + 2) % 4;
+
+ next_corner = data->plane_marker->corners[next_corner_index];
+ prev_corner = data->plane_marker->corners[prev_corner_index];
+ diag_corner = data->plane_marker->corners[diag_corner_index];
+
+ sub_v2_v2v2(next_edge, next_corner, data->corner);
+ sub_v2_v2v2(prev_edge, data->corner, prev_corner);
+ sub_v2_v2v2(next_diag_edge, prev_corner, diag_corner);
+ sub_v2_v2v2(prev_diag_edge, diag_corner, next_corner);
+
+ if (cross_v2v2(prev_edge, next_edge) < 0.0f) {
+ closest_to_line_v2(data->corner, data->corner, prev_corner, next_corner);
+ }
+
+ if (cross_v2v2(next_diag_edge, prev_edge) < 0.0f) {
+ closest_to_line_v2(data->corner, data->corner, prev_corner, diag_corner);
+ }
+
+ if (cross_v2v2(next_edge, prev_diag_edge) < 0.0f) {
+ closest_to_line_v2(data->corner, data->corner, next_corner, diag_corner);
+ }
+
+ data->previous_mval[0] = event->mval[0];
+ data->previous_mval[1] = event->mval[1];
+ copy_v2_v2(data->previous_corner, data->corner);
+
+ DAG_id_tag_update(&sc->clip->id, 0);
+
+ WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, NULL);
+
+ break;
+
+ case LEFTMOUSE:
+ if (event->val == KM_RELEASE) {
+ /* Marker is now keyframed. */
+ data->plane_marker->flag &= ~PLANE_MARKER_TRACKED;
+
+ slide_plane_marker_update_homographies(sc, data);
+
+ free_slide_plane_marker_data(op->customdata);
+
+ show_cursor(C);
+
+ DAG_id_tag_update(&sc->clip->id, 0);
+ WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
+
+ return OPERATOR_FINISHED;
+ }
+
+ break;
+
+ case ESCKEY:
+ cancel_mouse_slide_plane_marker(op->customdata);
+
+ free_slide_plane_marker_data(op->customdata);
+
+ show_cursor(C);
+
+ WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
+
+ return OPERATOR_CANCELLED;
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+void CLIP_OT_slide_plane_marker(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Slide Plane Marker";
+ ot->description = "Slide plane marker areas";
+ ot->idname = "CLIP_OT_slide_plane_marker";
+
+ /* api callbacks */
+ ot->poll = ED_space_clip_tracking_poll;
+ ot->invoke = slide_plane_marker_invoke;
+ ot->modal = slide_plane_marker_modal;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_GRAB_POINTER | OPTYPE_BLOCKING;
+}
diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c
index b03209173d8..6e4d10173fb 100644
--- a/source/blender/editors/space_clip/tracking_select.c
+++ b/source/blender/editors/space_clip/tracking_select.c
@@ -169,6 +169,7 @@ static float dist_to_rect(float co[2], float pos[2], float min[2], float max[2])
return sqrtf(min_ffff(d1, d2, d3, d4));
}
+/* Distance to quad defined by it's corners, corners are relative to pos */
static float dist_to_crns(float co[2], float pos[2], float crns[4][2])
{
float d1, d2, d3, d4;
@@ -184,7 +185,22 @@ static float dist_to_crns(float co[2], float pos[2], float crns[4][2])
return sqrtf(min_ffff(d1, d2, d3, d4));
}
-static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbase, float co[2])
+/* Same as above, but all the coordinates are absolute */
+static float dist_to_crns_abs(float co[2], float corners[4][2])
+{
+ float d1, d2, d3, d4;
+ float *v1 = corners[0], *v2 = corners[1];
+ float *v3 = corners[2], *v4 = corners[3];
+
+ d1 = dist_squared_to_line_segment_v2(co, v1, v2);
+ d2 = dist_squared_to_line_segment_v2(co, v2, v3);
+ d3 = dist_squared_to_line_segment_v2(co, v3, v4);
+ d4 = dist_squared_to_line_segment_v2(co, v4, v1);
+
+ return sqrtf(min_ffff(d1, d2, d3, d4));
+}
+
+static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbase, float co[2], float *distance_r)
{
MovieTrackingTrack *track = NULL, *cur;
float mindist = 0.0f;
@@ -221,19 +237,88 @@ static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbas
cur = cur->next;
}
+ *distance_r = mindist;
+
return track;
}
+static MovieTrackingPlaneTrack *find_nearest_plane_track(SpaceClip *sc, ListBase *plane_tracks_base,
+ float co[2], float *distance_r)
+{
+ MovieTrackingPlaneTrack *plane_track = NULL, *current_plane_track;
+ float min_distance = 0.0f;
+ int framenr = ED_space_clip_get_clip_frame_number(sc);
+
+ for (current_plane_track = plane_tracks_base->first;
+ current_plane_track;
+ current_plane_track = current_plane_track->next)
+ {
+ MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(current_plane_track, framenr);
+
+ if ((current_plane_track->flag & TRACK_HIDDEN) == 0) {
+ float distance = dist_to_crns_abs(co, plane_marker->corners);
+ if (plane_track == NULL || distance < min_distance) {
+ plane_track = current_plane_track;
+ min_distance = distance;
+ }
+ }
+ }
+
+ *distance_r = min_distance;
+
+ return plane_track;
+}
+
+static void delect_all_tracks(ListBase *tracks_base)
+{
+ MovieTrackingTrack *track;
+ for (track = tracks_base->first;
+ track;
+ track = track->next)
+ {
+ BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT);
+ }
+}
+
+static void delect_all_plane_tracks(ListBase *plane_tracks_base)
+{
+ MovieTrackingPlaneTrack *plane_track;
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = plane_track->next)
+ {
+ plane_track->flag &= ~SELECT;
+ }
+}
+
static int mouse_select(bContext *C, float co[2], int extend)
{
SpaceClip *sc = CTX_wm_space_clip(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+ ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
- MovieTrackingTrack *track = NULL; /* selected marker */
+ MovieTrackingTrack *track;
+ MovieTrackingPlaneTrack *plane_track;
+ float distance_to_track, distance_to_plane_track;
+
+ track = find_nearest_track(sc, tracksbase, co, &distance_to_track);
+ plane_track = find_nearest_plane_track(sc, plane_tracks_base, co, &distance_to_plane_track);
+
+ /* Between track and plane we choose closest to the mouse for selection here. */
+ if (track && plane_track) {
+ if (distance_to_track < distance_to_plane_track) {
+ plane_track = NULL;
+ }
+ else {
+ track = NULL;
+ }
+ }
- track = find_nearest_track(sc, tracksbase, co);
+ if (!extend) {
+ delect_all_plane_tracks(plane_tracks_base);
+ }
if (track) {
int area = track_mouse_area(C, co, track);
@@ -242,10 +327,13 @@ static int mouse_select(bContext *C, float co[2], int extend)
area = TRACK_AREA_ALL;
if (extend && TRACK_AREA_SELECTED(track, area)) {
- if (track == act_track)
+ if (track == act_track) {
BKE_tracking_track_deselect(track, area);
- else
+ }
+ else {
clip->tracking.act_track = track;
+ clip->tracking.act_plane_track = NULL;
+ }
}
else {
if (area == TRACK_AREA_POINT)
@@ -253,7 +341,25 @@ static int mouse_select(bContext *C, float co[2], int extend)
BKE_tracking_track_select(tracksbase, track, area, extend);
clip->tracking.act_track = track;
+ clip->tracking.act_plane_track = NULL;
+ }
+ }
+ else if (plane_track) {
+ if (!extend) {
+ delect_all_tracks(tracksbase);
+ }
+
+ if (plane_track->flag & SELECT) {
+ if (extend) {
+ plane_track->flag &= ~SELECT;
+ }
+ }
+ else {
+ plane_track->flag |= SELECT;
}
+
+ clip->tracking.act_track = NULL;
+ clip->tracking.act_plane_track = plane_track;
}
if (!extend) {
@@ -350,7 +456,9 @@ static int border_select_exec(bContext *C, wmOperator *op)
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
MovieTrackingTrack *track;
+ MovieTrackingPlaneTrack *plane_track;
ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+ ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
rcti rect;
rctf rectf;
int change = FALSE, mode, extend;
@@ -389,6 +497,33 @@ static int border_select_exec(bContext *C, wmOperator *op)
track = track->next;
}
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = plane_track->next)
+ {
+ if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) {
+ MovieTrackingPlaneMarker *plane_marker =
+ BKE_tracking_plane_marker_get(plane_track, framenr);
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (BLI_rctf_isect_pt_v(&rectf, plane_marker->corners[i])) {
+ if (mode == GESTURE_MODAL_SELECT) {
+ plane_track->flag |= SELECT;
+ }
+ else {
+ plane_track->flag &= ~SELECT;
+ }
+ }
+ else if (!extend) {
+ plane_track->flag &= ~SELECT;
+ }
+ }
+
+ change = TRUE;
+ }
+ }
+
if (change) {
BKE_tracking_dopesheet_tag_update(tracking);
@@ -430,7 +565,9 @@ static int do_lasso_select_marker(bContext *C, const int mcords[][2], const shor
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
MovieTrackingTrack *track;
+ MovieTrackingPlaneTrack *plane_track;
ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+ ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
rcti rect;
int change = FALSE;
int framenr = ED_space_clip_get_clip_frame_number(sc);
@@ -466,6 +603,37 @@ static int do_lasso_select_marker(bContext *C, const int mcords[][2], const shor
track = track->next;
}
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = plane_track->next)
+ {
+ if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) {
+ MovieTrackingPlaneMarker *plane_marker =
+ BKE_tracking_plane_marker_get(plane_track, framenr);
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ float screen_co[2];
+
+ /* marker in screen coords */
+ ED_clip_point_stable_pos__reverse(sc, ar, plane_marker->corners[i], screen_co);
+
+ if (BLI_rcti_isect_pt(&rect, screen_co[0], screen_co[1]) &&
+ BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], V2D_IS_CLIPPED))
+ {
+ if (select) {
+ plane_track->flag |= SELECT;
+ }
+ else {
+ plane_track->flag &= ~SELECT;
+ }
+ }
+ }
+
+ change = TRUE;
+ }
+ }
+
if (change) {
BKE_tracking_dopesheet_tag_update(tracking);
@@ -518,17 +686,22 @@ void CLIP_OT_select_lasso(wmOperatorType *ot)
/********************** circle select operator *********************/
-static int marker_inside_ellipse(MovieTrackingMarker *marker, float offset[2], float ellipse[2])
+static int point_inside_ellipse(float point[2], float offset[2], float ellipse[2])
{
/* normalized ellipse: ell[0] = scaleX, ell[1] = scaleY */
float x, y;
- x = (marker->pos[0] - offset[0]) * ellipse[0];
- y = (marker->pos[1] - offset[1]) * ellipse[1];
+ x = (point[0] - offset[0]) * ellipse[0];
+ y = (point[1] - offset[1]) * ellipse[1];
return x * x + y * y < 1.0f;
}
+static int marker_inside_ellipse(MovieTrackingMarker *marker, float offset[2], float ellipse[2])
+{
+ return point_inside_ellipse(marker->pos, offset, ellipse);
+}
+
static int circle_select_exec(bContext *C, wmOperator *op)
{
SpaceClip *sc = CTX_wm_space_clip(C);
@@ -537,7 +710,9 @@ static int circle_select_exec(bContext *C, wmOperator *op)
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
MovieTrackingTrack *track;
+ MovieTrackingPlaneTrack *plane_track;
ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+ ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
int x, y, radius, width, height, mode, change = FALSE;
float zoomx, zoomy, offset[2], ellipse[2];
int framenr = ED_space_clip_get_clip_frame_number(sc);
@@ -577,6 +752,30 @@ static int circle_select_exec(bContext *C, wmOperator *op)
track = track->next;
}
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = plane_track->next)
+ {
+ if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) {
+ MovieTrackingPlaneMarker *plane_marker =
+ BKE_tracking_plane_marker_get(plane_track, framenr);
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (point_inside_ellipse(plane_marker->corners[i], offset, ellipse)) {
+ if (mode == GESTURE_MODAL_SELECT) {
+ plane_track->flag |= SELECT;
+ }
+ else {
+ plane_track->flag &= ~SELECT;
+ }
+ }
+ }
+
+ change = TRUE;
+ }
+ }
+
if (change) {
BKE_tracking_dopesheet_tag_update(tracking);
@@ -619,16 +818,18 @@ static int select_all_exec(bContext *C, wmOperator *op)
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
MovieTrackingTrack *track = NULL; /* selected track */
+ MovieTrackingPlaneTrack *plane_track = NULL; /* selected plane track */
MovieTrackingMarker *marker;
ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+ ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
int action = RNA_enum_get(op->ptr, "action");
int framenr = ED_space_clip_get_clip_frame_number(sc);
int has_selection = FALSE;
if (action == SEL_TOGGLE) {
action = SEL_SELECT;
- track = tracksbase->first;
- while (track) {
+
+ for (track = tracksbase->first; track; track = track->next) {
if (TRACK_VIEW_SELECTED(sc, track)) {
marker = BKE_tracking_marker_get(track, framenr);
@@ -637,13 +838,20 @@ static int select_all_exec(bContext *C, wmOperator *op)
break;
}
}
+ }
- track = track->next;
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = plane_track->next)
+ {
+ if (plane_track->flag & SELECT) {
+ action = SEL_DESELECT;
+ break;
+ }
}
}
- track = tracksbase->first;
- while (track) {
+ for (track = tracksbase->first; track; track = track->next) {
if ((track->flag & TRACK_HIDDEN) == 0) {
marker = BKE_tracking_marker_get(track, framenr);
@@ -670,8 +878,29 @@ static int select_all_exec(bContext *C, wmOperator *op)
if (TRACK_VIEW_SELECTED(sc, track))
has_selection = TRUE;
+ }
- track = track->next;
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = plane_track->next)
+ {
+ if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) {
+ switch (action) {
+ case SEL_SELECT:
+ plane_track->flag |= SELECT;
+ break;
+ case SEL_DESELECT:
+ plane_track->flag &= ~SELECT;
+ break;
+ case SEL_INVERT:
+ plane_track->flag ^= SELECT;
+ break;
+ }
+ }
+
+ if (plane_track->flag & SELECT) {
+ has_selection = TRUE;
+ }
}
if (!has_selection)
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index cf3c0454e6b..5cc22b25f72 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -2225,6 +2225,39 @@ static void node_composit_buts_trackpos(uiLayout *layout, bContext *C, PointerRN
}
}
+static void node_composit_buts_planetrackdeform(uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+ bNode *node = ptr->data;
+
+ uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL);
+
+ if (node->id) {
+ MovieClip *clip = (MovieClip *) node->id;
+ MovieTracking *tracking = &clip->tracking;
+ MovieTrackingObject *object;
+ uiLayout *col;
+ PointerRNA tracking_ptr;
+ NodeTrackPosData *data = node->storage;
+
+ RNA_pointer_create(&clip->id, &RNA_MovieTracking, tracking, &tracking_ptr);
+
+ col = uiLayoutColumn(layout, FALSE);
+ uiItemPointerR(col, ptr, "tracking_object", &tracking_ptr, "objects", "", ICON_OBJECT_DATA);
+
+ object = BKE_tracking_object_get_named(tracking, data->tracking_object);
+ if (object) {
+ PointerRNA object_ptr;
+
+ RNA_pointer_create(&clip->id, &RNA_MovieTrackingObject, object, &object_ptr);
+
+ uiItemPointerR(col, ptr, "plane_track_name", &object_ptr, "plane_tracks", "", ICON_ANIM_DATA);
+ }
+ else {
+ uiItemR(layout, ptr, "plane_track_name", 0, "", ICON_ANIM_DATA);
+ }
+ }
+}
+
/* only once called */
static void node_composit_set_butfunc(bNodeType *ntype)
{
@@ -2444,6 +2477,9 @@ static void node_composit_set_butfunc(bNodeType *ntype)
case CMP_NODE_TRACKPOS:
ntype->uifunc = node_composit_buts_trackpos;
break;
+ case CMP_NODE_PLANETRACKDEFORM:
+ ntype->uifunc = node_composit_buts_planetrackdeform;
+ break;
}
}
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index d5a9d0f9f93..6d801b86685 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -3005,7 +3005,12 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3])
copy_v3_v3(center, td->center);
}
else if (t->options & CTX_MOVIECLIP) {
- copy_v3_v3(center, td->center);
+ if (td->flag & TD_INDIVIDUAL_SCALE) {
+ copy_v3_v3(center, td->center);
+ }
+ else {
+ copy_v3_v3(center, t->center);
+ }
}
else {
copy_v3_v3(center, t->center);
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 4a1c4203a43..4954f861934 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -455,7 +455,7 @@ typedef struct TransInfo {
#define TD_USEQUAT (1 << 3)
#define TD_NOTCONNECTED (1 << 4)
#define TD_SINGLESIZE (1 << 5) /* used for scaling of MetaElem->rad */
-/*#define TD_TIMEONLY (1 << 8) */ /*UNUSED*/
+#define TD_INDIVIDUAL_SCALE (1 << 8) /* Scale relative to individual element center */
#define TD_NOCENTER (1 << 9)
#define TD_NO_EXT (1 << 10) /* ext abused for particle key timing */
#define TD_SKIP (1 << 11) /* don't transform this data */
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 95ec20a0c2b..01605003d7b 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -5959,7 +5959,8 @@ static void createTransNodeData(bContext *UNUSED(C), TransInfo *t)
enum transDataTracking_Mode {
transDataTracking_ModeTracks = 0,
- transDataTracking_ModeCurves = 1
+ transDataTracking_ModeCurves = 1,
+ transDataTracking_ModePlaneTracks = 2,
};
typedef struct TransDataTracking {
@@ -5978,6 +5979,9 @@ typedef struct TransDataTracking {
/* marker transformation from curves editor */
float *prev_pos, scale;
short coord;
+
+ MovieTrackingTrack *track;
+ MovieTrackingPlaneTrack *plane_track;
} TransDataTracking;
static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTracking *tdt,
@@ -6008,6 +6012,7 @@ static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTra
tdt->markersnr = track->markersnr;
tdt->markers = track->markers;
+ tdt->track = track;
if (rel) {
if (!anchor) {
@@ -6026,6 +6031,7 @@ static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTra
copy_v3_v3(td->iloc, td->loc);
//copy_v3_v3(td->center, td->loc);
+ td->flag |= TD_INDIVIDUAL_SCALE;
td->center[0] = marker->pos[0] * aspx;
td->center[1] = marker->pos[1] * aspy;
@@ -6076,6 +6082,52 @@ static void trackToTransData(const int framenr, TransData *td, TransData2D *td2d
}
}
+static void planeMarkerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTracking *tdt,
+ MovieTrackingPlaneTrack *plane_track, float corner[2],
+ float aspx, float aspy)
+{
+ tdt->mode = transDataTracking_ModePlaneTracks;
+ tdt->plane_track = plane_track;
+
+ td2d->loc[0] = corner[0] * aspx; /* hold original location */
+ td2d->loc[1] = corner[1] * aspy;
+
+ td2d->loc2d = corner; /* current location */
+ td2d->loc[2] = 0.0f;
+
+ td->flag = 0;
+ td->loc = td2d->loc;
+ copy_v3_v3(td->iloc, td->loc);
+ copy_v3_v3(td->center, td->loc);
+
+ memset(td->axismtx, 0, sizeof(td->axismtx));
+ td->axismtx[2][2] = 1.0f;
+
+ td->ext = NULL;
+ td->val = NULL;
+
+ td->flag |= TD_SELECTED;
+ td->dist = 0.0;
+
+ unit_m3(td->mtx);
+ unit_m3(td->smtx);
+}
+
+static void planeTrackToTransData(const int framenr, TransData *td, TransData2D *td2d,
+ TransDataTracking *tdt, MovieTrackingPlaneTrack *plane_track,
+ float aspx, float aspy)
+{
+ MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_ensure(plane_track, framenr);
+ int i;
+
+ tdt->flag = plane_marker->flag;
+ plane_marker->flag &= ~PLANE_MARKER_TRACKED;
+
+ for (i = 0; i < 4; i++) {
+ planeMarkerToTransDataInit(td++, td2d++, tdt++, plane_track, plane_marker->corners[i], aspx, aspy);
+ }
+}
+
static void transDataTrackingFree(TransInfo *t)
{
TransDataTracking *tdt = t->customData;
@@ -6096,7 +6148,9 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t)
SpaceClip *sc = CTX_wm_space_clip(C);
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;
TransDataTracking *tdt;
int framenr = ED_space_clip_get_clip_frame_number(sc);
float aspx, aspy;
@@ -6122,6 +6176,15 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t)
track = track->next;
}
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = plane_track->next)
+ {
+ if (plane_track->flag & SELECT) {
+ t->total += 4;
+ }
+ }
+
if (t->total == 0)
return;
@@ -6165,11 +6228,23 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t)
track = track->next;
}
+
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = plane_track->next)
+ {
+ if (plane_track->flag & SELECT) {
+ planeTrackToTransData(framenr, td, td2d, tdt, plane_track, aspx, aspy);
+ td += 4;
+ td2d += 4;
+ tdt += 4;
+ }
+ }
}
static void markerToTransCurveDataInit(TransData *td, TransData2D *td2d, TransDataTracking *tdt,
- MovieTrackingMarker *marker, MovieTrackingMarker *prev_marker,
- short coord, float size)
+ MovieTrackingTrack *track, MovieTrackingMarker *marker,
+ MovieTrackingMarker *prev_marker, short coord, float size)
{
float frames_delta = (marker->framenr - prev_marker->framenr);
@@ -6180,6 +6255,7 @@ static void markerToTransCurveDataInit(TransData *td, TransData2D *td2d, TransDa
tdt->coord = coord;
tdt->scale = 1.0f / size * frames_delta;
tdt->prev_pos = prev_marker->pos;
+ tdt->track = track;
/* calculate values depending on marker's speed */
td2d->loc[0] = marker->framenr;
@@ -6265,14 +6341,14 @@ static void createTransTrackingCurvesData(bContext *C, TransInfo *t)
continue;
if (marker->flag & MARKER_GRAPH_SEL_X) {
- markerToTransCurveDataInit(td, td2d, tdt, marker, &track->markers[i - 1], 0, width);
+ markerToTransCurveDataInit(td, td2d, tdt, track, marker, &track->markers[i - 1], 0, width);
td += 1;
td2d += 1;
tdt += 1;
}
if (marker->flag & MARKER_GRAPH_SEL_Y) {
- markerToTransCurveDataInit(td, td2d, tdt, marker, &track->markers[i - 1], 1, height);
+ markerToTransCurveDataInit(td, td2d, tdt, track, marker, &track->markers[i - 1], 1, height);
td += 1;
td2d += 1;
@@ -6313,57 +6389,54 @@ static void createTransTrackingData(bContext *C, TransInfo *t)
static void cancelTransTracking(TransInfo *t)
{
- TransDataTracking *tdt = t->customData;
SpaceClip *sc = t->sa->spacedata.first;
- MovieClip *clip = ED_space_clip_get_clip(sc);
- ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
- MovieTrackingTrack *track;
- MovieTrackingMarker *marker;
- int a, framenr = ED_space_clip_get_clip_frame_number(sc);
+ int i, framenr = ED_space_clip_get_clip_frame_number(sc);
- if (tdt->mode == transDataTracking_ModeTracks) {
- track = tracksbase->first;
- while (track) {
- if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
- marker = BKE_tracking_marker_get(track, framenr);
- marker->flag = tdt->flag;
+ i = 0;
+ while (i < t->total) {
+ TransDataTracking *tdt = (TransDataTracking *) t->customData + i;
- tdt++;
+ if (tdt->mode == transDataTracking_ModeTracks) {
+ MovieTrackingTrack *track = tdt->track;
+ MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
- if (track->flag & SELECT)
- tdt++;
+ marker->flag = tdt->flag;
- if (track->pat_flag & SELECT)
- tdt += 2;
+ if (track->flag & SELECT)
+ i++;
- if (track->search_flag & SELECT)
- tdt += 2;
- }
+ if (track->pat_flag & SELECT)
+ i += 4;
- track = track->next;
+ if (track->search_flag & SELECT)
+ i += 2;
}
- }
- else if (tdt->mode == transDataTracking_ModeCurves) {
- MovieTrackingMarker *prev_marker;
+ else if (tdt->mode == transDataTracking_ModeCurves) {
+ MovieTrackingTrack *track = tdt->track;
+ MovieTrackingMarker *marker, *prev_marker;
+ int a;
- track = tracksbase->first;
- while (track) {
- if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
- for (a = 1; a < track->markersnr; a++) {
- marker = &track->markers[a];
- prev_marker = &track->markers[a - 1];
+ for (a = 1; a < track->markersnr; a++) {
+ marker = &track->markers[a];
+ prev_marker = &track->markers[a - 1];
- if ((marker->flag & MARKER_DISABLED) || (prev_marker->flag & MARKER_DISABLED))
- continue;
+ if ((marker->flag & MARKER_DISABLED) || (prev_marker->flag & MARKER_DISABLED))
+ continue;
- if (marker->flag & (MARKER_GRAPH_SEL_X | MARKER_GRAPH_SEL_Y)) {
- marker->flag = tdt->flag;
- }
+ if (marker->flag & (MARKER_GRAPH_SEL_X | MARKER_GRAPH_SEL_Y)) {
+ marker->flag = tdt->flag;
}
}
+ }
+ else if (tdt->mode == transDataTracking_ModePlaneTracks) {
+ MovieTrackingPlaneTrack *plane_track = tdt->plane_track;
+ MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);
- track = track->next;
+ plane_marker->flag = tdt->flag;
+ i += 3;
}
+
+ i++;
}
}
@@ -6432,6 +6505,10 @@ void flushTransTracking(TransInfo *t)
else if (tdt->mode == transDataTracking_ModeCurves) {
td2d->loc2d[tdt->coord] = tdt->prev_pos[tdt->coord] + td2d->loc[1] * tdt->scale;
}
+ else if (tdt->mode == transDataTracking_ModePlaneTracks) {
+ td2d->loc2d[0] = td2d->loc[0] / aspx;
+ td2d->loc2d[1] = td2d->loc[1] / aspy;
+ }
}
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index cb0a0530036..4c7ac4193b3 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -659,7 +659,9 @@ 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);
@@ -690,6 +692,15 @@ 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) {