Frame matching methods for follow track constraint
authorSergey Sharybin <sergey.vfx@gmail.com>
Thu, 9 Aug 2012 16:57:02 +0000 (16:57 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Thu, 9 Aug 2012 16:57:02 +0000 (16:57 +0000)
This is needed in cases when using blender camera with different
resolution than original footage. Behaves in the same way as
background picture framing.

release/scripts/startup/bl_ui/properties_object_constraint.py
source/blender/blenkernel/intern/constraint.c
source/blender/makesdna/DNA_constraint_types.h
source/blender/makesrna/intern/rna_constraint.c

index e4da581ab8345ba741a7868ae5064d5e50b6cfc6..3c53a829fa2143587dea190be5d93f6216e6c9ba 100644 (file)
@@ -773,16 +773,21 @@ class ConstraintButtonsPanel():
         row.prop(con, "use_active_clip")
         row.prop(con, "use_3d_position")
 
+        col = layout.column()
+
         if not con.use_active_clip:
-            layout.prop(con, "clip")
+            col.prop(con, "clip")
+
+        row = col.row()
+        row.prop(con, "frame_method", expand=True)
 
         if clip:
-            layout.prop_search(con, "object", clip.tracking, "objects", icon='OBJECT_DATA')
-            layout.prop_search(con, "track", clip.tracking, "tracks", icon='ANIM_DATA')
+            col.prop_search(con, "object", clip.tracking, "objects", icon='OBJECT_DATA')
+            col.prop_search(con, "track", clip.tracking, "tracks", icon='ANIM_DATA')
 
-        layout.prop(con, "camera")
+        col.prop(con, "camera")
 
-        row = layout.row()
+        row = col.row()
         row.active = not con.use_3d_position
         row.prop(con, "depth_object")
 
index e08c9e9d39ec6fb02a44f67b52023976bd8e2efa..16edbc3f0a98658d90b4d7bb3ccd91c963aa3a63 100644 (file)
@@ -82,8 +82,6 @@
 #include "BKE_tessmesh.h"
 #include "BKE_tracking.h"
 #include "BKE_movieclip.h"
-#include "BKE_tracking.h"
-#include "BKE_movieclip.h"
 
 #ifdef WITH_PYTHON
 #include "BPY_extern.h"
@@ -3985,6 +3983,41 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
 
                        add_v2_v2v2(pos, marker->pos, track->offset);
 
+                       /* aspect correction */
+                       if (data->frame_method != FOLLOWTRACK_FRAME_STRETCH) {
+                               int width, height;
+                               float w_src, h_src, w_dst, h_dst, asp_src, asp_dst;
+
+                               BKE_movieclip_get_size(clip, NULL, &width, &height);
+
+                               /* apply clip display aspect */
+                               w_src = width * clip->aspx;
+                               h_src = height * clip->aspy;
+
+                               w_dst = scene->r.xsch * scene->r.xasp;
+                               h_dst = scene->r.ysch * scene->r.yasp;
+
+                               asp_src = w_src / h_src;
+                               asp_dst = w_dst / h_dst;
+
+                               if (fabsf(asp_src - asp_dst) >= FLT_EPSILON) {
+                                       if ((asp_src > asp_dst) == (data->frame_method == FOLLOWTRACK_FRAME_CROP)) {
+                                               /* fit X */
+                                               float div = asp_src / asp_dst;
+                                               float cent = (float) width / 2.0f;
+
+                                               pos[0] = (((pos[0] * width - cent) * div) + cent) / width;
+                                       }
+                                       else {
+                                               /* fit Y */
+                                               float div = asp_dst / asp_src;
+                                               float cent = (float) height / 2.0f;
+
+                                               pos[1] = (((pos[1] * height - cent) * div) + cent) / height;
+                                       }
+                               }
+                       }
+
                        BKE_camera_params_init(&params);
                        BKE_camera_params_from_object(&params, camob);
 
index b603684040133345dddb386a7878812c8dc65c46..8d953079bdb69a95f8eac96949611b44788e2dee 100644 (file)
@@ -415,7 +415,8 @@ typedef struct bShrinkwrapConstraint {
 typedef struct bFollowTrackConstraint {
        struct MovieClip        *clip;
        char    track[64];      /* MAX_NAME */
-       int             flag, pad;
+       int             flag;
+       int             frame_method;
        char            object[64];     /* MAX_NAME */
        struct Object *camera;
        struct Object *depth_ob;
@@ -780,6 +781,12 @@ typedef enum eFollowTrack_Flags {
        FOLLOWTRACK_USE_3D_POSITION     = (1<<1)
 } eFollowTrack_Flags;
 
+typedef enum eFollowTrack_FrameMethod {
+       FOLLOWTRACK_FRAME_STRETCH = 0,
+       FOLLOWTRACK_FRAME_FIT = 1,
+       FOLLOWTRACK_FRAME_CROP = 2
+} eFollowTrack_FrameMethod;
+
 /* CameraSolver Constraint -> flag */
 typedef enum eCameraSolver_Flags {
        CAMERASOLVER_ACTIVECLIP = (1<<0)
index 8d718715e5b09f76c4e95048bcb1a98314b5f014..770bdb68e389884a4de9f051bfa230ffad4f408d 100644 (file)
@@ -2207,6 +2207,13 @@ static void rna_def_constraint_follow_track(BlenderRNA *brna)
        StructRNA *srna;
        PropertyRNA *prop;
 
+       static const EnumPropertyItem frame_method_items[] = {
+               {FOLLOWTRACK_FRAME_STRETCH, "STRETCH", 0, "Stretch", ""},
+               {FOLLOWTRACK_FRAME_FIT, "FIT", 0, "Fit", ""},
+               {FOLLOWTRACK_FRAME_CROP, "CROP", 0, "Crop", ""},
+               {0, NULL, 0, NULL, NULL}
+       };
+
        srna = RNA_def_struct(brna, "FollowTrackConstraint", "Constraint");
        RNA_def_struct_ui_text(srna, "Follow Track Constraint", "Lock motion to the target motion track");
        RNA_def_struct_sdna_from(srna, "bFollowTrackConstraint", "data");
@@ -2261,6 +2268,13 @@ static void rna_def_constraint_follow_track(BlenderRNA *brna)
        RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
        RNA_def_property_pointer_funcs(prop, NULL, "rna_Constraint_followTrack_depthObject_set", NULL,
                                       "rna_Constraint_followTrack_depthObject_poll");
+
+       /* frame method */
+       prop = RNA_def_property(srna, "frame_method", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_bitflag_sdna(prop, NULL, "frame_method");
+       RNA_def_property_enum_items(prop, frame_method_items);
+       RNA_def_property_ui_text(prop, "Frame Method", "How the footage fits in the camera frame");
+       RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
 }
 
 static void rna_def_constraint_camera_solver(BlenderRNA *brna)