Commit: 59b586b3376eef39b1079af945f1d6fa29eba3eb
Author: Sergey Sharybin
Date:   Mon Dec 28 17:28:28 2020 +0100
Branches: tracking_average
https://developer.blender.org/rB59b586b3376eef39b1079af945f1d6fa29eba3eb

Tracking: Add interpolated accessor for markers

Allows to get marker position interpolated through out a gap.

Currently unused, but is covered with test. Aimed to be used for
track average operator.

===================================================================

M       source/blender/blenkernel/BKE_tracking.h
M       source/blender/blenkernel/intern/tracking.c
M       source/blender/blenkernel/intern/tracking_test.cc

===================================================================

diff --git a/source/blender/blenkernel/BKE_tracking.h 
b/source/blender/blenkernel/BKE_tracking.h
index 4dbc22ae18f..5da8d969f1e 100644
--- a/source/blender/blenkernel/BKE_tracking.h
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -139,6 +139,17 @@ struct MovieTrackingMarker 
*BKE_tracking_marker_get_exact(struct MovieTrackingTr
 struct MovieTrackingMarker *BKE_tracking_marker_ensure(struct 
MovieTrackingTrack *track,
                                                        int framenr);
 
+/* Get marker position, possibly interpolating interpolating gap between 
keyframed/tracked markers.
+ *
+ * The result marker frame number is set to the requested frame number. Its 
flags are 0 if the
+ * marker is interpolated, and is set to original marker flag if there were no 
interpolation
+ * involved.
+ *
+ * Returns truth if the result is usable. */
+bool BKE_tracking_marker_get_interpolated(struct MovieTrackingTrack *track,
+                                          const int framenr,
+                                          struct MovieTrackingMarker 
*r_marker);
+
 void BKE_tracking_marker_pattern_minmax(const struct MovieTrackingMarker 
*marker,
                                         float min[2],
                                         float max[2]);
diff --git a/source/blender/blenkernel/intern/tracking.c 
b/source/blender/blenkernel/intern/tracking.c
index e5f9d59270e..bc892c7dd88 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -1389,6 +1389,80 @@ MovieTrackingMarker 
*BKE_tracking_marker_ensure(MovieTrackingTrack *track, int f
   return marker;
 }
 
+static const MovieTrackingMarker *get_usable_marker_for_interpolation(
+    struct MovieTrackingTrack *track,
+    const MovieTrackingMarker *anchor_marker,
+    const int direction)
+{
+  BLI_assert(direction == -1 || direction == 1);
+
+  const MovieTrackingMarker *last_marker = track->markers + track->markersnr - 
1;
+  const MovieTrackingMarker *current_marker = anchor_marker;
+
+  while (current_marker >= track->markers && current_marker <= last_marker) {
+    if ((current_marker->flag & MARKER_DISABLED) == 0) {
+      return current_marker;
+    }
+    current_marker += direction;
+  }
+
+  return NULL;
+}
+
+bool BKE_tracking_marker_get_interpolated(struct MovieTrackingTrack *track,
+                                          const int framenr,
+                                          struct MovieTrackingMarker *r_marker)
+{
+  const MovieTrackingMarker *closest_marker = BKE_tracking_marker_get(track, 
framenr);
+  if (closest_marker == NULL) {
+    return false;
+  }
+
+  const MovieTrackingMarker *left_marker = get_usable_marker_for_interpolation(
+      track, closest_marker, -1);
+  if (left_marker == NULL) {
+    return false;
+  }
+
+  const MovieTrackingMarker *right_marker = 
get_usable_marker_for_interpolation(
+      track, closest_marker + 1, 1);
+  if (right_marker == NULL) {
+    return false;
+  }
+
+  if (left_marker == right_marker) {
+    *r_marker = *left_marker;
+    return true;
+  }
+
+  const float factor = (float)(framenr - left_marker->framenr) /
+                       (right_marker->framenr - left_marker->framenr);
+
+  interp_v2_v2v2(r_marker->pos, left_marker->pos, right_marker->pos, factor);
+
+  for (int i = 0; i < 4; i++) {
+    interp_v2_v2v2(r_marker->pattern_corners[i],
+                   left_marker->pattern_corners[i],
+                   right_marker->pattern_corners[i],
+                   factor);
+  }
+
+  interp_v2_v2v2(r_marker->search_min, left_marker->search_min, 
right_marker->search_min, factor);
+  interp_v2_v2v2(r_marker->search_max, left_marker->search_max, 
right_marker->search_max, factor);
+
+  r_marker->framenr = framenr;
+  r_marker->flag = 0;
+
+  if (framenr == left_marker->framenr) {
+    r_marker->flag = left_marker->flag;
+  }
+  else if (framenr == right_marker->framenr) {
+    r_marker->flag = right_marker->flag;
+  }
+
+  return true;
+}
+
 void BKE_tracking_marker_pattern_minmax(const MovieTrackingMarker *marker,
                                         float min[2],
                                         float max[2])
diff --git a/source/blender/blenkernel/intern/tracking_test.cc 
b/source/blender/blenkernel/intern/tracking_test.cc
index 6afcf6872eb..d3ce3ff82fc 100644
--- a/source/blender/blenkernel/intern/tracking_test.cc
+++ b/source/blender/blenkernel/intern/tracking_test.cc
@@ -5,15 +5,23 @@
 #include "DNA_tracking_types.h"
 
 #include "BKE_tracking.h"
+#include "BLI_float2.hh"
+
+namespace blender {
 
 namespace {
 
 class TrackingTest : public ::testing::Test {
  protected:
-  MovieTrackingMarker *addMarkerToTrack(MovieTrackingTrack *track, int 
frame_number)
+  MovieTrackingMarker *addMarkerToTrack(MovieTrackingTrack *track,
+                                        int frame_number,
+                                        const float2 &position = float2(0.0f, 
0.0f),
+                                        int flag = 0)
   {
     MovieTrackingMarker marker = {{0.0f}};
+    copy_v2_v2(marker.pos, position);
     marker.framenr = frame_number;
+    marker.flag = flag;
     return BKE_tracking_marker_insert(track, &marker);
   }
 };
@@ -62,3 +70,100 @@ TEST_F(TrackingTest, BKE_tracking_marker_get_exact)
 
   BKE_tracking_track_free(&track);
 }
+
+TEST_F(TrackingTest, BKE_tracking_marker_get_interpolated)
+{
+  /* Simple case, no disabled markers in a way. */
+  {
+    MovieTrackingTrack track = {nullptr};
+
+    addMarkerToTrack(&track, 1, float2(1.0f, 5.0f));
+    addMarkerToTrack(&track, 10, float2(2.0f, 1.0f));
+
+    {
+      MovieTrackingMarker interpolated_marker;
+      EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 1, 
&interpolated_marker));
+      EXPECT_EQ(interpolated_marker.framenr, 1);
+      EXPECT_V2_NEAR(interpolated_marker.pos, float2(1.0f, 5.0f), 1e-6f);
+    }
+
+    {
+      MovieTrackingMarker interpolated_marker;
+      EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 10, 
&interpolated_marker));
+      EXPECT_EQ(interpolated_marker.framenr, 10);
+      EXPECT_V2_NEAR(interpolated_marker.pos, float2(2.0f, 1.0f), 1e-6f);
+    }
+
+    {
+      MovieTrackingMarker interpolated_marker;
+      EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 4, 
&interpolated_marker));
+      EXPECT_EQ(interpolated_marker.framenr, 4);
+      EXPECT_V2_NEAR(interpolated_marker.pos, float2(1.3333333f, 3.6666666f), 
1e-6f);
+    }
+
+    BKE_tracking_track_free(&track);
+  }
+
+  /* More comprehensive test, which resembles real life trackign scenario 
better. */
+  {
+    MovieTrackingTrack track = {nullptr};
+
+    addMarkerToTrack(&track, 1, float2(1.0f, 5.0f));
+    addMarkerToTrack(&track, 2, float2(0.0f, 0.0f), MARKER_DISABLED);
+    addMarkerToTrack(&track, 9, float2(0.0f, 0.0f), MARKER_DISABLED);
+    addMarkerToTrack(&track, 10, float2(2.0f, 1.0f));
+
+    {
+      MovieTrackingMarker interpolated_marker;
+      EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 1, 
&interpolated_marker));
+      EXPECT_EQ(interpolated_marker.framenr, 1);
+      EXPECT_V2_NEAR(interpolated_marker.pos, float2(1.0f, 5.0f), 1e-6f);
+    }
+
+    {
+      MovieTrackingMarker interpolated_marker;
+      EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 10, 
&interpolated_marker));
+      EXPECT_EQ(interpolated_marker.framenr, 10);
+      EXPECT_V2_NEAR(interpolated_marker.pos, float2(2.0f, 1.0f), 1e-6f);
+    }
+
+    {
+      MovieTrackingMarker interpolated_marker;
+      EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 4, 
&interpolated_marker));
+      EXPECT_EQ(interpolated_marker.framenr, 4);
+      EXPECT_V2_NEAR(interpolated_marker.pos, float2(1.3333333f, 3.6666666f), 
1e-6f);
+    }
+
+    BKE_tracking_track_free(&track);
+  }
+
+  /* Tracked/keyframed flag check. */
+  {
+    MovieTrackingTrack track = {nullptr};
+
+    addMarkerToTrack(&track, 1, float2(1.0f, 5.0f), MARKER_TRACKED);
+    addMarkerToTrack(&track, 10, float2(2.0f, 1.0f), MARKER_TRACKED);
+
+    {
+      MovieTrackingMarker interpolated_marker;
+      EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 1, 
&interpolated_marker));
+      EXPECT_EQ(interpolated_marker.flag, MARKER_TRACKED);
+    }
+
+    {
+      MovieTrackingMarker interpolated_marker;
+      EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 10, 
&interpolated_marker));
+      EXPECT_EQ(interpolated_marker.flag, MARKER_TRACKED);
+    }
+
+    {
+      MovieTrackingMarker interpolated_marker;
+      EXPECT_TRUE(BKE_tracking_marker_get_interpolated(&track, 4, 
&interpolated_marker));
+      EXPECT_EQ(interpolated_marker.flag, 0);
+    }
+
+    BKE_tracking_track_free(&track);
+  }
+}
+
+}  // namespace blender

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to