15#include "RNA_prototypes.hh"
118 if (val !=
nullptr) {
128 &clip->tracking.stabilization,
129 &RNA_MovieTrackingStabilization,
137 return id_data_find_fcurve(&clip->id, track, &RNA_MovieTrackingTrack,
"weight_stab", 0,
nullptr);
149 return default_value;
196 if (ctx !=
nullptr) {
206 StabContext *ctx = MEM_cnew<StabContext>(
"2D stabilization animation runtime data");
209 ctx->
stab = &clip->tracking.stabilization;
232 if (ctx !=
nullptr) {
260 return marker - track->
markers;
275 if (i < end &&
markers[i].framenr < *next_higher) {
277 *next_higher =
markers[i].framenr;
291 if (0 <= i &&
markers[i].framenr > *next_lower) {
293 *next_lower =
markers[i].framenr;
330 if ((next_higher - ref_frame) < (ref_frame - next_lower)) {
397 float result_offset[2])
442 const float pivot[2],
480 const float pivot[2],
481 float result_translation[2])
483 const float origin[2] = {0.5f * aspect *
size, 0.5f * size};
484 float intended_pivot[2], rotated_pivot[2];
485 float rotation_mat[2][2];
494 add_v2_v2(result_translation, intended_pivot);
495 sub_v2_v2(result_translation, rotated_pivot);
513 float r_translation[2],
527 *r_scale_step = 0.0f;
546 weight_sum += weight;
548 r_translation[0] += weight * offset[0];
549 r_translation[1] += weight * offset[1];
550 ref_pos[0] += weight * marker->
pos[0];
551 ref_pos[1] += weight * marker->
pos[1];
560 ref_pos[0] /= weight_sum;
561 ref_pos[1] /= weight_sum;
562 r_translation[0] /= weight_sum;
563 r_translation[1] /= weight_sum;
583 float rotation, scale, quality;
585 stabilization_base, marker, aspect, r_pivot, &rotation, &scale);
586 const float quality_weight = weight * quality;
587 weight_sum += quality_weight;
588 *r_angle += rotation * quality_weight;
590 *r_scale_step +=
logf(scale) * quality_weight;
603 *r_scale_step /= weight_sum;
604 *r_angle /= weight_sum;
610 *r_scale_step = 0.0f;
636 weight_sum += weight;
637 r_ref_pos[0] += weight * marker->
pos[0];
638 r_ref_pos[1] += weight * marker->
pos[1];
644 r_ref_pos[0] /= weight_sum;
645 r_ref_pos[1] /= weight_sum;
690 float r_translation[2],
696 float trans_a[2], trans_b[2];
697 float angle_a, angle_b;
698 float scale_a, scale_b;
699 float pivot_a[2], pivot_b[2];
700 bool success =
false;
706 t = (
float(framenr) - frame_a) / (frame_b - frame_a);
710 ctx, frame_a, aspect, trans_a, pivot_a, &angle_a, &scale_a);
715 ctx, frame_b, aspect, trans_b, pivot_b, &angle_b, &scale_b);
722 *r_scale_step = s * scale_a + t * scale_b;
723 *r_angle = s * angle_a + t * angle_b;
747 int anchor_frame = tracking->stabilization.anchor_frame;
751 order[tracknr].data = track;
754 order[tracknr].sort_value =
abs(marker->
framenr - anchor_frame);
755 order[tracknr].reference_frame = marker->
framenr;
821 const float average_translation[2],
822 const float pivot[2],
823 const float average_angle,
824 const float average_scale_step)
854 size_t track_len = 0;
863 int reference_frame = tracking->stabilization.anchor_frame;
864 float average_angle = 0, average_scale_step = 0;
865 float average_translation[2], average_pos[2], pivot[2];
873 local_data = MEM_cnew<TrackStabilizationBase>(
"2D stabilization per track baseline data");
886 order = MEM_cnew_array<TrackInitOrder>(track_len,
"stabilization track order");
892 if (track_len == 0) {
900 for (
int i = 0; i < track_len; i++) {
902 if (reference_frame != order[i].reference_frame) {
903 reference_frame = order[i].reference_frame;
910 &average_scale_step);
941 float r_translation[2],
946 bool success =
false;
951 *r_scale_step = 0.0f;
957 ctx, framenr, aspect, r_translation, r_pivot, r_angle, r_scale_step);
983 ctx, next_higher, aspect, r_translation, r_pivot, r_angle, r_scale_step);
988 ctx, next_lower, aspect, r_translation, r_pivot, r_angle, r_scale_step);
1012 float r_translation[2],
1017 float target_pos[2], target_scale;
1021 *r_scale =
expf(scale_step * scaleinf);
1038 if (target_scale != 0.0f) {
1039 *r_scale /= target_scale;
1044 r_translation[0] *=
float(size) * aspect;
1045 r_translation[1] *=
float(size);
1046 r_pivot[0] *=
float(size) * aspect;
1047 r_pivot[1] *=
float(size);
1052 if (do_compensate) {
1055 if (*r_scale != 0.0f) {
1056 *r_scale = 1.0f / *r_scale;
1062 const float pivot[2],
1063 const float translation[2],
1068 float translation_mat[4][4], rotation_mat[4][4], scale_mat[4][4], pivot_mat[4][4],
1069 inv_pivot_mat[4][4], aspect_mat[4][4], inv_aspect_mat[4][4];
1070 const float scale_vector[3] = {scale, scale, 1.0f};
1080 aspect_mat[0][0] /= pixel_aspect;
1087 add_v2_v2(translation_mat[3], translation);
1114 int height =
size, width = aspect *
size;
1116 int sfra = INT_MAX, efra = INT_MIN;
1117 float scale = 1.0f, scale_step = 0.0f;
1124 int first_frame = track->markers[0].framenr;
1125 int last_frame = track->markers[track->markersnr - 1].framenr;
1126 sfra =
min_ii(sfra, first_frame);
1127 efra =
max_ii(efra, last_frame);
1132 for (
int cfra = sfra; cfra <= efra; cfra++) {
1133 float translation[2], pivot[2],
angle, tmp_scale;
1135 const float points[4][2] = {
1137 const bool do_compensate =
true;
1140 ctx, cfra, aspect, translation, pivot, &angle, &scale_step);
1160 for (
int edge_index = 0; edge_index < 4; edge_index++) {
1165 float stable_edge_p1[3], stable_edge_p2[3];
1166 copy_v2_v2(stable_edge_p1, points[edge_index]);
1167 copy_v2_v2(stable_edge_p2, points[(edge_index + 1) % 4]);
1168 stable_edge_p1[2] = stable_edge_p2[2] = 0.0f;
1175 for (
int point_index = 0; point_index < 4; point_index++) {
1176 const float point[3] = {points[point_index][0], points[point_index][1], 0.0f};
1180 float stable_edge_vec[3];
1181 sub_v3_v3v3(stable_edge_vec, stable_edge_p2, stable_edge_p1);
1185 float point_to_edge_start_vec[3];
1186 sub_v3_v3v3(point_to_edge_start_vec, point, stable_edge_p1);
1192 if (
cross_v2v2(stable_edge_vec, point_to_edge_start_vec) >= 0.0f) {
1194 float scale_pivot[2];
1210 float real_dist =
dist_to_line_v2(scale_pivot, stable_edge_p1, stable_edge_p2);
1212 const float S = required_dist / real_dist;
1213 scale =
max_ff(scale, S);
1254 float translation[2],
1262 bool do_compensate =
true;
1263 float scale_step = 0.0f;
1265 float aspect =
float(width) * pixel_aspect / height;
1274 ctx, framenr, aspect, translation, pivot, angle, &scale_step))
1277 ctx, framenr, size, aspect, do_compensate, scale_step, translation, pivot, scale, angle);
1303 ImBuf *ibuf = data->ibuf;
1304 ImBuf *tmpibuf = data->tmpibuf;
1305 float(*mat)[4] = data->mat;
1307 float vec[3] = {0.0f,
float(y), 0.0f};
1314 for (
int x = 0; x < tmpibuf->
x; x++, dst++) {
1317 *dst = imbuf::interpolate_bilinear_border_fl(ibuf, rvec[0], rvec[1]);
1321 for (
int x = 0; x < tmpibuf->
x; x++, dst++) {
1324 *dst = imbuf::interpolate_cubic_bspline_fl(ibuf, rvec[0], rvec[1]);
1329 for (
int x = 0; x < tmpibuf->
x; x++, dst++) {
1332 *dst = imbuf::interpolate_nearest_border_fl(ibuf, rvec[0], rvec[1]);
1340 for (
int x = 0; x < tmpibuf->
x; x++, dst++) {
1343 *dst = imbuf::interpolate_bilinear_border_byte(ibuf, rvec[0], rvec[1]);
1347 for (
int x = 0; x < tmpibuf->
x; x++, dst++) {
1350 *dst = imbuf::interpolate_cubic_bspline_byte(ibuf, rvec[0], rvec[1]);
1355 for (
int x = 0; x < tmpibuf->
x; x++, dst++) {
1358 *dst = imbuf::interpolate_nearest_border_byte(ibuf, rvec[0], rvec[1]);
1365 MovieClip *clip,
int framenr,
ImBuf *ibuf,
float translation[2],
float *scale,
float *angle)
1367 float tloc[2], tscale, tangle;
1371 int width = ibuf->
x, height = ibuf->
y;
1372 float pixel_aspect = tracking->camera.pixel_aspect;
1416 ibuf->
x, ibuf->
y, pixel_aspect, tloc, tscale, tangle, mat);
1425 data.tmpibuf = tmpibuf;
1427 data.tracking_filter = tracking->stabilization.filter;
1431 settings.use_threading = (tmpibuf->
y > 128);
1457 float translation[2],
1474 pivot[0] = 0.5f * pixel_aspect * buffer_width;
1475 pivot[1] = 0.5f * buffer_height;
float evaluate_fcurve(const FCurve *fcu, float evaltime)
FCurve * id_data_find_fcurve(ID *id, void *data, StructRNA *type, const char *prop_name, int index, bool *r_driven)
float BKE_movieclip_remap_clip_to_scene_frame(const struct MovieClip *clip, float framenr)
struct MovieTrackingObject * BKE_tracking_object_get_camera(const struct MovieTracking *tracking)
struct MovieTrackingMarker * BKE_tracking_marker_get(struct MovieTrackingTrack *track, int framenr)
struct MovieTrackingMarker * BKE_tracking_marker_get_exact(struct MovieTrackingTrack *track, int framenr)
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
void BLI_ghash_insert(GHash *gh, void *key, void *val)
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
#define LISTBASE_FOREACH(type, var, list)
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
float dist_to_line_v2(const float p[2], const float l1[2], const float l2[2])
void unit_m4(float m[4][4])
void size_to_mat4(float R[4][4], const float size[3])
void mul_m4_v3(const float M[4][4], float r[3])
#define mul_m4_series(...)
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void rotate_m4(float mat[4][4], char axis, float angle)
bool invert_m4(float mat[4][4])
void mul_m2_v2(const float mat[2][2], float vec[2])
void angle_to_mat2(float R[2][2], float angle)
MINLINE float len_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v2_v2(float r[2], const float a[2])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v2_fl(float r[2], float f)
void interp_v2_v2v2(float r[2], const float a[2], const float b[2], float t)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void add_v2_v2(float r[2], const float a[2])
MINLINE float cross_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE void zero_v2(float r[2])
int BLI_sortutil_cmp_int(const void *a_, const void *b_)
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
@ TRACKING_FILTER_BICUBIC
@ TRACKING_FILTER_BILINEAR
@ TRACKING_STABILIZE_SCALE
@ TRACKING_STABILIZE_ROTATION
@ TRACKING_2D_STABILIZATION
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
void IMB_colormanagegent_copy_settings(ImBuf *ibuf_src, ImBuf *ibuf_dst)
Contains defines and structs used throughout the imbuf module.
Read Guarded memory(de)allocation.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
draw_view in_light_buf[] float
struct ImBuf * IMB_allocImBuf(unsigned int, unsigned int, unsigned char, unsigned int)
const vector< Marker > & markers
void MEM_freeN(void *vmemh)
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
MovieTrackingMarker * markers
MovieTrackingCamera camera
MovieTrackingStabilization * stab
GHash * private_track_data
MovieTrackingTrack * data
FCurve * track_weight_curve
float stabilization_offset_base[2]
bool is_init_for_stabilization
float stabilization_scale_base
float stabilization_rotation_base[2][2]
void BKE_tracking_stabilization_data_to_mat4(int buffer_width, int buffer_height, float pixel_aspect, float translation[2], float scale, float angle, float r_mat[4][4])
static void retrieve_next_lower_usable_frame(StabContext *ctx, MovieTrackingTrack *track, int i, int ref_frame, int *next_lower)
static void average_marker_positions(StabContext *ctx, int framenr, float r_ref_pos[2])
static void discard_stabilization_baseline_data(void *val)
static int establish_track_initialization_order(StabContext *ctx, TrackInitOrder *order)
static MovieTrackingMarker * get_closest_marker(StabContext *ctx, MovieTrackingTrack *track, int ref_frame)
static float get_animated_target_scale(StabContext *ctx, int framenr)
void BKE_tracking_stabilization_data_get(MovieClip *clip, int framenr, int width, int height, float translation[2], float *scale, float *angle)
static float get_animated_target_rot(StabContext *ctx, int framenr)
static float get_animated_rotinf(StabContext *ctx, int framenr)
static bool average_track_contributions(StabContext *ctx, int framenr, float aspect, float r_translation[2], float r_pivot[2], float *r_angle, float *r_scale_step)
static float fetch_from_fcurve(const FCurve *animationCurve, int framenr, StabContext *ctx, float default_value)
static void stabilization_calculate_data(StabContext *ctx, int framenr, int size, float aspect, bool do_compensate, float scale_step, float r_translation[2], float r_pivot[2], float *r_scale, float *r_angle)
static FCurve * retrieve_track_weight_animation(MovieClip *clip, MovieTrackingTrack *track)
static bool stabilization_determine_offset_for_frame(StabContext *ctx, int framenr, float aspect, float r_translation[2], float r_pivot[2], float *r_angle, float *r_scale_step)
static bool is_init_for_stabilization(StabContext *ctx, MovieTrackingTrack *track)
static bool is_usable_for_stabilization(StabContext *ctx, MovieTrackingTrack *track)
static bool is_effectively_disabled(StabContext *ctx, MovieTrackingTrack *track, MovieTrackingMarker *marker)
static void use_values_from_fcurves(StabContext *ctx, bool toggle)
static bool interpolate_averaged_track_contributions(StabContext *ctx, int framenr, int frame_a, int frame_b, const float aspect, float r_translation[2], float r_pivot[2], float *r_angle, float *r_scale_step)
static void get_animated_target_pos(StabContext *ctx, int framenr, float target_pos[2])
static float get_animated_locinf(StabContext *ctx, int framenr)
static void init_all_tracks(StabContext *ctx, float aspect)
static float get_animated_scaleinf(StabContext *ctx, int framenr)
static float get_animated_weight(StabContext *ctx, MovieTrackingTrack *track, int framenr)
static float SCALE_ERROR_LIMIT_BIAS
static int search_closest_marker_index(MovieTrackingTrack *track, int ref_frame)
static void find_next_working_frames(StabContext *ctx, int framenr, int *next_lower, int *next_higher)
static void attach_stabilization_baseline_data(StabContext *ctx, MovieTrackingTrack *track, TrackStabilizationBase *private_data)
static StabContext * init_stabilization_working_context(MovieClip *clip)
static void setup_pivot(const float ref_pos[2], float r_pivot[2])
static TrackStabilizationBase * access_stabilization_baseline_data(StabContext *ctx, MovieTrackingTrack *track)
static float calculate_autoscale_factor(StabContext *ctx, int size, float aspect)
static float EPSILON_WEIGHT
static void stabilization_data_to_mat4(float pixel_aspect, const float pivot[2], const float translation[2], float scale, float angle, float r_mat[4][4])
ImBuf * BKE_tracking_stabilize_frame(MovieClip *clip, int framenr, ImBuf *ibuf, float translation[2], float *scale, float *angle)
static void retrieve_next_higher_usable_frame(StabContext *ctx, MovieTrackingTrack *track, int i, int ref_frame, int *next_higher)
static StabContext * init_stabilizer(MovieClip *clip, int size, float aspect)
static MovieTrackingMarker * get_tracking_data_point(StabContext *ctx, MovieTrackingTrack *track, int framenr, float *r_weight)
static float rotation_contribution(TrackStabilizationBase *track_ref, MovieTrackingMarker *marker, const float aspect, const float pivot[2], float *result_angle, float *result_scale)
static void compensate_rotation_center(const int size, float aspect, const float angle, const float scale, const float pivot[2], float result_translation[2])
static FCurve * retrieve_stab_animation(MovieClip *clip, const char *data_path, int idx)
static void discard_stabilization_working_context(StabContext *ctx)
static void init_track_for_stabilization(StabContext *ctx, MovieTrackingTrack *track, int reference_frame, float aspect, const float average_translation[2], const float pivot[2], const float average_angle, const float average_scale_step)
static void tracking_stabilize_frame_interpolation_cb(void *__restrict userdata, const int y, const TaskParallelTLS *__restrict)
static void translation_contribution(TrackStabilizationBase *track_ref, MovieTrackingMarker *marker, float result_offset[2])
ccl_device_inline int abs(int x)