Blender V4.3
tracking_plane_tracker.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11#include "MEM_guardedalloc.h"
12
13#include "DNA_movieclip_types.h"
14
15#include "BLI_math_matrix.h"
16#include "BLI_math_vector.h"
17#include "BLI_utildefines.h"
18
19#include "BKE_tracking.h"
20
21#include "libmv-capi.h"
22
23typedef double Vec2[2];
24
26 MovieTrackingPlaneTrack *plane_track, int frame1, int frame2, Vec2 **r_x1, Vec2 **r_x2)
27{
28 Vec2 *x1, *x2;
29
30 *r_x1 = x1 = MEM_cnew_array<Vec2>(plane_track->point_tracksnr, "point correspondences x1");
31 *r_x2 = x2 = MEM_cnew_array<Vec2>(plane_track->point_tracksnr, "point correspondences x2");
32
33 int correspondence_index = 0;
34 for (int i = 0; i < plane_track->point_tracksnr; i++) {
35 MovieTrackingTrack *point_track = plane_track->point_tracks[i];
36 MovieTrackingMarker *point_marker1, *point_marker2;
37
38 point_marker1 = BKE_tracking_marker_get_exact(point_track, frame1);
39 point_marker2 = BKE_tracking_marker_get_exact(point_track, frame2);
40
41 if (point_marker1 != nullptr && point_marker2 != nullptr) {
42 /* Here conversion from float to double happens. */
43 x1[correspondence_index][0] = point_marker1->pos[0];
44 x1[correspondence_index][1] = point_marker1->pos[1];
45
46 x2[correspondence_index][0] = point_marker2->pos[0];
47 x2[correspondence_index][1] = point_marker2->pos[1];
48
49 correspondence_index++;
50 }
51 }
52
53 return correspondence_index;
54}
55
56/* NOTE: frame number should be in clip space, not scene space */
58 int start_frame,
59 int direction,
60 bool retrack)
61{
62 MovieTrackingPlaneMarker *start_plane_marker = BKE_tracking_plane_marker_get(plane_track,
63 start_frame);
64 MovieTrackingPlaneMarker *keyframe_plane_marker = nullptr;
65 MovieTrackingPlaneMarker new_plane_marker;
66 int frame_delta = direction > 0 ? 1 : -1;
67
68 if (plane_track->flag & PLANE_TRACK_AUTOKEY) {
69 /* Find a keyframe in given direction. */
70 for (int current_frame = start_frame;; current_frame += frame_delta) {
72 plane_track, current_frame + frame_delta);
73
74 if (next_plane_marker == nullptr) {
75 break;
76 }
77
78 if ((next_plane_marker->flag & PLANE_MARKER_TRACKED) == 0) {
79 keyframe_plane_marker = next_plane_marker;
80 break;
81 }
82 }
83 }
84 else {
85 start_plane_marker->flag |= PLANE_MARKER_TRACKED;
86 }
87
88 new_plane_marker = *start_plane_marker;
89 new_plane_marker.flag |= PLANE_MARKER_TRACKED;
90
91 for (int current_frame = start_frame;; current_frame += frame_delta) {
93 plane_track, current_frame + frame_delta);
94 Vec2 *x1, *x2;
95 double H_double[3][3];
96 float H[3][3];
97
98 /* As soon as we meet keyframed plane, we stop updating the sequence. */
99 if (next_plane_marker && (next_plane_marker->flag & PLANE_MARKER_TRACKED) == 0) {
100 /* Don't override keyframes if track is in auto-keyframe mode */
101 if (plane_track->flag & PLANE_TRACK_AUTOKEY) {
102 break;
103 }
104 }
105
106 const int num_correspondences = point_markers_correspondences_on_both_image(
107 plane_track, current_frame, current_frame + frame_delta, &x1, &x2);
108 if (num_correspondences < 4) {
109 MEM_freeN(x1);
110 MEM_freeN(x2);
111 break;
112 }
113
114 libmv_homography2DFromCorrespondencesEuc(x1, x2, num_correspondences, H_double);
115
116 copy_m3_m3d(H, H_double);
117
118 for (int i = 0; i < 4; i++) {
119 float vec[3] = {0.0f, 0.0f, 1.0f}, vec2[3];
120 copy_v2_v2(vec, new_plane_marker.corners[i]);
121
122 /* Apply homography */
123 mul_v3_m3v3(vec2, H, vec);
124
125 /* Normalize. */
126 vec2[0] /= vec2[2];
127 vec2[1] /= vec2[2];
128
129 copy_v2_v2(new_plane_marker.corners[i], vec2);
130 }
131
132 new_plane_marker.framenr = current_frame + frame_delta;
133
134 if (!retrack && keyframe_plane_marker && next_plane_marker &&
135 (plane_track->flag & PLANE_TRACK_AUTOKEY))
136 {
137 float fac = (float(next_plane_marker->framenr) - start_plane_marker->framenr) /
138 (float(keyframe_plane_marker->framenr) - start_plane_marker->framenr);
139
140 fac = 3 * fac * fac - 2 * fac * fac * fac;
141
142 for (int i = 0; i < 4; i++) {
143 interp_v2_v2v2(new_plane_marker.corners[i],
144 new_plane_marker.corners[i],
145 next_plane_marker->corners[i],
146 fac);
147 }
148 }
149
150 BKE_tracking_plane_marker_insert(plane_track, &new_plane_marker);
151
152 MEM_freeN(x1);
153 MEM_freeN(x2);
154 }
155}
156
158 int start_frame)
159{
160 track_plane_from_existing_motion(plane_track, start_frame, 1, false);
161 track_plane_from_existing_motion(plane_track, start_frame, -1, false);
162}
163
165 int start_frame,
166 int direction)
167{
168 MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, start_frame);
169 int index = plane_marker - plane_track->markers;
170 int frame_delta = direction > 0 ? 1 : -1;
171
172 while (index >= 0 && index < plane_track->markersnr) {
173 if ((plane_marker->flag & PLANE_MARKER_TRACKED) == 0) {
174 return plane_marker;
175 }
176 plane_marker += frame_delta;
177 }
178
179 return nullptr;
180}
181
183 MovieTrackingPlaneTrack *plane_track, int start_frame)
184{
185 MovieTrackingPlaneMarker *prev_plane_keyframe, *next_plane_keyframe;
186
187 prev_plane_keyframe = find_plane_keyframe(plane_track, start_frame, -1);
188 next_plane_keyframe = find_plane_keyframe(plane_track, start_frame, 1);
189
190 if (prev_plane_keyframe != nullptr && next_plane_keyframe != nullptr) {
191 /* First we track from left keyframe to the right one without any blending. */
192 track_plane_from_existing_motion(plane_track, prev_plane_keyframe->framenr, 1, true);
193
194 /* And then we track from the right keyframe to the left one, so shape blends in nicely */
195 track_plane_from_existing_motion(plane_track, next_plane_keyframe->framenr, -1, false);
196 }
197 else if (prev_plane_keyframe != nullptr) {
198 track_plane_from_existing_motion(plane_track, prev_plane_keyframe->framenr, 1, true);
199 }
200 else if (next_plane_keyframe != nullptr) {
201 track_plane_from_existing_motion(plane_track, next_plane_keyframe->framenr, -1, true);
202 }
203}
204
205BLI_INLINE void float_corners_to_double(/*const*/ float corners[4][2], double double_corners[4][2])
206{
207 copy_v2db_v2fl(double_corners[0], corners[0]);
208 copy_v2db_v2fl(double_corners[1], corners[1]);
209 copy_v2db_v2fl(double_corners[2], corners[2]);
210 copy_v2db_v2fl(double_corners[3], corners[3]);
211}
212
213void BKE_tracking_homography_between_two_quads(/*const*/ float reference_corners[4][2],
214 /*const*/ float corners[4][2],
215 float H[3][3])
216{
217 Vec2 x1[4], x2[4];
218 double H_double[3][3];
219
220 float_corners_to_double(reference_corners, x1);
221 float_corners_to_double(corners, x2);
222
223 libmv_homography2DFromCorrespondencesEuc(x1, x2, 4, H_double);
224
225 copy_m3_m3d(H, H_double);
226}
struct MovieTrackingPlaneMarker * BKE_tracking_plane_marker_insert(struct MovieTrackingPlaneTrack *plane_track, struct MovieTrackingPlaneMarker *plane_marker)
Definition tracking.cc:1719
struct MovieTrackingPlaneMarker * BKE_tracking_plane_marker_get_exact(struct MovieTrackingPlaneTrack *plane_track, int framenr)
Definition tracking.cc:1837
struct MovieTrackingMarker * BKE_tracking_marker_get_exact(struct MovieTrackingTrack *track, int framenr)
Definition tracking.cc:1391
struct MovieTrackingPlaneMarker * BKE_tracking_plane_marker_get(struct MovieTrackingPlaneTrack *plane_track, int framenr)
Definition tracking.cc:1791
#define BLI_INLINE
void copy_m3_m3d(float m1[3][3], const double m2[3][3])
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
MINLINE void copy_v2db_v2fl(double r[2], const float a[2])
void interp_v2_v2v2(float r[2], const float a[2], const float b[2], float t)
Definition math_vector.c:21
MINLINE void copy_v2_v2(float r[2], const float a[2])
@ PLANE_MARKER_TRACKED
@ PLANE_TRACK_AUTOKEY
Read Guarded memory(de)allocation.
draw_view in_light_buf[] float
void libmv_homography2DFromCorrespondencesEuc(double(*x1)[2], double(*x2)[2], int num_points, double H[3][3])
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
#define H(x, y, z)
MovieTrackingTrack ** point_tracks
MovieTrackingPlaneMarker * markers
static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_track, int start_frame, int direction, bool retrack)
static int point_markers_correspondences_on_both_image(MovieTrackingPlaneTrack *plane_track, int frame1, int frame2, Vec2 **r_x1, Vec2 **r_x2)
BLI_INLINE void float_corners_to_double(float corners[4][2], double double_corners[4][2])
void BKE_tracking_retrack_plane_from_existing_motion_at_segment(MovieTrackingPlaneTrack *plane_track, int start_frame)
static MovieTrackingPlaneMarker * find_plane_keyframe(MovieTrackingPlaneTrack *plane_track, int start_frame, int direction)
void BKE_tracking_track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_track, int start_frame)
void BKE_tracking_homography_between_two_quads(float reference_corners[4][2], float corners[4][2], float H[3][3])