Camera tracking integration
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 11 Jul 2011 09:04:00 +0000 (09:04 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 11 Jul 2011 09:04:00 +0000 (09:04 +0000)
===========================

- Changed libmv api to use doubles instead of floats.
  No real benefit rather than keeping API uniform.
- Optimized reconstructed camera search. It's optimized for
  playback, not random access.
- Added option to show projection of bundles into footage.
  To see bundles "Show Bundles" from Display panel should
  be enabled. Used very rough limit of 3 px to consider projection
  is fine. Colors are still hard-coded. Not sure it could be useful
  to make them configurable.
- Added option to mute footage. It could be useful to check
  if markers/bundles are moving smoothly.
- Added selector for focal length units.

13 files changed:
extern/libmv/libmv-capi.cpp
extern/libmv/libmv-capi.h
release/scripts/startup/bl_ui/space_clip.py
source/blender/blenkernel/BKE_movieclip.h
source/blender/blenkernel/BKE_tracking.h
source/blender/blenkernel/intern/movieclip.c
source/blender/blenkernel/intern/tracking.c
source/blender/editors/space_clip/clip_draw.c
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/DNA_tracking_types.h
source/blender/makesrna/intern/rna_movieclip.c
source/blender/makesrna/intern/rna_space.c
source/blender/makesrna/intern/rna_tracking.c

index c0393ee99a2b2087f5fd64b7708d51c4cb689abd..e14285be55dfe9dd1c427a852bd1847b14761578 100644 (file)
@@ -331,7 +331,7 @@ int libmv_reporojectionPointForTrack(libmv_Reconstruction *reconstruction, int t
        return 0;
 }
 
-int libmv_reporojectionCameraForImage(libmv_Reconstruction *reconstruction, int image, float mat[4][4])
+int libmv_reporojectionCameraForImage(libmv_Reconstruction *reconstruction, int image, double mat[4][4])
 {
        libmv::Camera *camera = ((libmv::Reconstruction *)reconstruction)->CameraForImage(image);
 
@@ -368,3 +368,20 @@ void libmv_destroyReconstruction(libmv_Reconstruction *reconstruction)
        delete (libmv::Reconstruction *)reconstruction;
 }
 
+/* ************ utils ************ */
+
+void libmv_applyCameraIntrinsics(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+                       double x, double y, double *x1, double *y1)
+{
+       libmv::CameraIntrinsics intrinsics;
+
+       intrinsics.SetFocalLength(focal_length);
+       intrinsics.set_principal_point(principal_x, principal_y);
+       intrinsics.set_radial_distortion(k1, k2, k3);
+
+       if(focal_length) {
+               /* do a lens undistortion if focal length is non-zero only */
+
+               intrinsics.ApplyIntrinsics(x, y, x1, y1);
+       }
+}
index 73bd705813d6093d84b089c00f5c87261bd07922..927a68bc9dd1096656a33b283026fe2ba5182ce2 100644 (file)
@@ -58,9 +58,13 @@ void libmv_tracksDestroy(struct libmv_Tracks *tracks);
 struct libmv_Reconstruction *libmv_solveReconstruction(struct libmv_Tracks *tracks, int keyframe1, int keyframe2,
                        double focal_length, double principal_x, double principal_y, double k1, double k2, double k3);
 int libmv_reporojectionPointForTrack(struct libmv_Reconstruction *reconstruction, int track, double pos[3]);
-int libmv_reporojectionCameraForImage(struct libmv_Reconstruction *reconstruction, int image, float mat[4][4]);
+int libmv_reporojectionCameraForImage(struct libmv_Reconstruction *reconstruction, int image, double mat[4][4]);
 void libmv_destroyReconstruction(struct libmv_Reconstruction *reconstruction);
 
+/* utils */
+void libmv_applyCameraIntrinsics(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+                       double x, double y, double *x1, double *y1);
+
 #ifdef __cplusplus
 }
 #endif
index a2a30130a7ebe6823192829249ac0f42b644c7fd..eb04ecae7aded8f193ddfe302780cfe2d7252523 100644 (file)
@@ -218,7 +218,11 @@ class CLIP_PT_tracking_camera(bpy.types.Panel):
         sc = context.space_data
         clip = sc.clip
 
-        layout.prop(clip.tracking.camera, "focal_length")
+        layout.prop(clip.tracking.camera, "sensor_width")
+
+        row = layout.row()
+        row.prop(clip.tracking.camera, "focal_length")
+        row.prop(clip.tracking.camera, "units", text="")
 
         layout.label(text="Principal Point")
         layout.prop(clip.tracking.camera, "principal", text="")
@@ -249,6 +253,8 @@ class CLIP_PT_display(bpy.types.Panel):
         row.prop(sc, "path_length")
 
         layout.prop(sc, "show_tiny_markers")
+        layout.prop(sc, "show_bundles")
+        layout.prop(sc, "use_mute_footage")
 
 
 class CLIP_PT_test(bpy.types.Panel):
index 975bd4fa07512165113c7b3c1aea6e4075d99769..e51c574b581cf3cff566d73a2eda77a8c84b8d40 100644 (file)
@@ -48,6 +48,7 @@ void BKE_movieclip_reload(struct MovieClip *clip);
 
 struct ImBuf *BKE_movieclip_acquire_ibuf(struct MovieClip *clip, struct MovieClipUser *user);
 void BKE_movieclip_acquire_size(struct MovieClip *clip, struct MovieClipUser *user, int *width, int *height);
+void BKE_movieclip_approx_size(struct MovieClip *clip, int *width, int *height);
 int BKE_movieclip_has_frame(struct MovieClip *clip, struct MovieClipUser *user);
 void BKE_movieclip_user_set_frame(struct MovieClipUser *user, int framenr);
 
index d6a74e9b211f17b3051c46836b7284dc61b82acf..1bd0111a513fef7325934a8a23ed0a0ec13fd99a 100644 (file)
@@ -75,6 +75,8 @@ struct MovieTrackingTrack *BKE_find_track_by_name(struct MovieTracking *tracking
 struct MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(struct MovieTracking *tracking, int framenr);
 
 void BKE_get_tracking_mat(struct Scene *scene, float mat[4][4]);
+void BKE_tracking_projection_matrix(struct MovieTracking *tracking, int framenr, int winx, int winy, float mat[4][4]);
+void BKE_tracking_apply_intrinsics(struct MovieTracking *tracking, float co[2], float width, float height, float nco[2]);
 
 #define TRACK_SELECTED(track) ((track)->flag&SELECT || (track)->pat_flag&SELECT || (track)->search_flag&SELECT)
 #define TRACK_AREA_SELECTED(track, area) ((area)==TRACK_AREA_POINT?(track)->flag&SELECT : ((area)==TRACK_AREA_PAT?(track)->pat_flag&SELECT:(track)->search_flag&SELECT))
index df897be100c6b0ba5c951cc6c5665cc38423079d..034d0f11f4706924d692e37b5698c3aec85e22e0 100644 (file)
@@ -214,6 +214,9 @@ static MovieClip *movieclip_alloc(const char *name)
 
        clip= alloc_libblock(&G.main->movieclip, ID_MC, name);
 
+       clip->tracking.camera.sensor_width= 35.0f;
+       clip->tracking.camera.units= CAMERA_UNITS_MM;
+
        clip->tracking.settings.frames_limit= 20;
        clip->tracking.settings.keyframe1= 1;
        clip->tracking.settings.keyframe2= 30;
@@ -281,7 +284,6 @@ ImBuf *BKE_movieclip_acquire_ibuf(MovieClip *clip, MovieClipUser *user)
        ImBuf *ibuf= NULL;
        int framenr= user?user->framenr:clip->lastframe;
 
-       clip->lastframe= framenr;
        ibuf= get_imbuf_cache(clip, user);
 
        if(!ibuf) {
@@ -294,6 +296,9 @@ ImBuf *BKE_movieclip_acquire_ibuf(MovieClip *clip, MovieClipUser *user)
                        put_imbuf_cache(clip, user, ibuf);
        }
 
+       if(ibuf)
+               clip->lastframe= framenr;
+
        return ibuf;
 }
 
@@ -325,6 +330,29 @@ void BKE_movieclip_acquire_size(MovieClip *clip, MovieClipUser *user, int *width
                IMB_freeImBuf(ibuf);
 }
 
+void BKE_movieclip_approx_size(MovieClip *clip, int *width, int *height)
+{
+       ImBuf *ibuf= BKE_movieclip_acquire_ibuf(clip, NULL);
+
+       if(!ibuf) {
+               MovieClipUser user;
+               user.framenr= 0;
+
+               ibuf= BKE_movieclip_acquire_ibuf(clip, &user);
+       }
+
+       if(ibuf && ibuf->x && ibuf->y) {
+               *width= ibuf->x;
+               *height= ibuf->y;
+       } else {
+               *width= 0;
+               *height= 0;
+       }
+
+       if(ibuf)
+               IMB_freeImBuf(ibuf);
+}
+
 /* get segments of cached frames. useful for debugging cache policies */
 void BKE_movieclip_get_cache_segments(MovieClip *clip, int *totseg_r, int **points_r)
 {
index 6b96d493de4e20c50a5d9c9306ef127fbae5deff..08c600c5d3e11f327871efb0a325e7c8b93d1b7a 100644 (file)
@@ -758,9 +758,16 @@ static void retrive_libmv_reconstruct(MovieClip *clip, struct libmv_Reconstructi
        reconstructed= MEM_callocN((efra-sfra+1)*sizeof(MovieReconstructedCamera), "temp reconstructed camera");
 
        for(a= sfra; a<=efra; a++) {
-               float mat[4][4];
+               double matd[4][4];
+
+               if(libmv_reporojectionCameraForImage(reconstruction, a, matd)) {
+                       int i, j;
+                       float mat[4][4];
+
+                       for(i=0; i<4; i++)
+                               for(j= 0; j<4; j++)
+                                       mat[i][j]= matd[i][j];
 
-               if(libmv_reporojectionCameraForImage(reconstruction, a, mat)) {
                        if(!origin_set) {
                                copy_v3_v3(origin, mat[3]);
                                origin_set= 1;
@@ -838,11 +845,27 @@ MovieTrackingTrack *BKE_find_track_by_name(MovieTracking *tracking, const char *
 
 MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(MovieTracking *tracking, int framenr)
 {
-       int a;
+       MovieTrackingCamera *camera= &tracking->camera;
+       int a= 0, d= 1;
+
+       if(!camera->reconnr)
+               return NULL;
+
+       if(camera->last_camera<camera->reconnr)
+               a= camera->last_camera;
+
+       if(camera->reconstructed[a].framenr>=framenr)
+               d= -1;
+
+       while(a>=0 && a<camera->reconnr) {
+               if(camera->reconstructed[a].framenr==framenr) {
+                       camera->last_camera= a;
+                       return &camera->reconstructed[a];
 
-       for (a= 0; a<tracking->camera.reconnr; a++ ) {
-               if(tracking->camera.reconstructed[a].framenr==framenr)
-                       return &tracking->camera.reconstructed[a];
+                       break;
+               }
+
+               a+= d;
        }
 
        return NULL;
@@ -862,3 +885,56 @@ void BKE_get_tracking_mat(Scene *scene, float mat[4][4])
 
        copy_m4_m4(mat, obmat);
 }
+
+void BKE_tracking_projection_matrix(MovieTracking *tracking, int framenr, int winx, int winy, float mat[4][4])
+{
+       MovieReconstructedCamera *camera;
+       float lens= tracking->camera.focal*32.0f/(float)winx;
+       float viewfac, pixsize, left, right, bottom, top, clipsta, clipend;
+       float winmat[4][4];
+
+       clipsta= 0.1f;
+       clipend= 1000.0f;
+
+       if(winx >= winy)
+               viewfac= (lens*winx)/32.0f;
+       else
+               viewfac= (lens*winy)/32.0f;
+
+       pixsize= clipsta/viewfac;
+
+       left= -0.5f*(float)winx*pixsize;
+       bottom= -0.5f*(float)winy*pixsize;
+       right=  0.5f*(float)winx*pixsize;
+       top=  0.5f*(float)winy*pixsize;
+
+       perspective_m4(winmat, left, right, bottom, top, clipsta, clipend);
+
+       camera= BKE_tracking_get_reconstructed_camera(tracking, framenr);
+       if(camera) {
+               float imat[4][4];
+
+               invert_m4_m4(imat, camera->mat);
+               mul_m4_m4m4(mat, imat, winmat);
+       } else copy_m4_m4(mat, winmat);
+}
+
+void BKE_tracking_apply_intrinsics(MovieTracking *tracking, float co[2], float width, float height, float nco[2])
+{
+       MovieTrackingCamera *camera= &tracking->camera;
+
+#ifdef WITH_LIBMV
+       double x= nco[0], y= nco[1];
+
+       /* normalize coords */
+       x= (co[0]-camera->principal[0]) / camera->focal;
+       y= (co[1]-camera->principal[1]) / camera->focal;
+
+       libmv_applyCameraIntrinsics(camera->focal, camera->principal[0], camera->principal[1],
+                               camera->k1, camera->k2, camera->k3, x, y, &x, &y);
+
+       /* result is in image coords already */
+       nco[0]= x;
+       nco[1]= y;
+#endif
+}
index daab601d45e6386972f3fc4f472023127ce950f2..e004729f88b5bc71541d1717ecd58dd5b8bb3e0b 100644 (file)
@@ -141,7 +141,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
        glRecti(x, 0, x+framelen, 8);
 }
 
-static void draw_movieclip_buffer(ARegion *ar, ImBuf *ibuf, float zoomx, float zoomy)
+static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf, float zoomx, float zoomy)
 {
        int x, y;
 
@@ -151,11 +151,16 @@ static void draw_movieclip_buffer(ARegion *ar, ImBuf *ibuf, float zoomx, float z
        /* find window pixel coordinates of origin */
        UI_view2d_to_region_no_clip(&ar->v2d, 0.f, 0.f, &x, &y);
 
-       if(ibuf->rect_float)
-               IMB_rect_from_float(ibuf);
+       if(sc->flag&SC_MUTE_FOOTAGE) {
+               glColor3f(0.0f, 0.0f, 0.0f);
+               glRectf(x, y, x+ibuf->x*sc->zoom, y+ibuf->y*sc->zoom);
+       } else {
+               if(ibuf->rect_float)
+                       IMB_rect_from_float(ibuf);
 
-       if(ibuf->rect)
-               glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
+               if(ibuf->rect)
+                       glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
+       }
 
        /* reset zoom */
        glPixelZoom(1.f, 1.f);
@@ -482,9 +487,10 @@ static void view2d_to_region_float(View2D *v2d, float x, float y, float *regionx
 static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, float zoomx, float zoomy)
 {
        float x, y;
+       MovieTracking* tracking= &clip->tracking;
        MovieTrackingMarker *marker;
        MovieTrackingTrack *track;
-       int width, height, sel_type;
+       int width, height, sel_type, framenr= sc->user.framenr;
        void *sel;
 
        ED_space_clip_size(sc, &width, &height);
@@ -509,7 +515,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, fl
        BKE_movieclip_last_selection(clip, &sel_type, &sel);
 
        if(sc->flag&SC_SHOW_MARKER_PATH) {
-               track= clip->tracking.tracks.first;
+               track= tracking->tracks.first;
                while(track) {
                        if((track->flag&TRACK_HIDDEN)==0)
                                draw_track_path(sc, clip, track);
@@ -519,10 +525,10 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, fl
        }
 
        /* markers outline and non-selected areas */
-       track= clip->tracking.tracks.first;
+       track= tracking->tracks.first;
        while(track) {
                if((track->flag&TRACK_HIDDEN)==0) {
-                       marker= BKE_tracking_get_marker(track, sc->user.framenr);
+                       marker= BKE_tracking_get_marker(track, framenr);
 
                        draw_marker_outline(sc, track, marker);
                        draw_marker_slide_zones(sc, track, marker, 1, 0, width, height);
@@ -534,13 +540,13 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, fl
 
        /* selected areas only, so selection wouldn't be overlapped by
           non-selected areas */
-       track= clip->tracking.tracks.first;
+       track= tracking->tracks.first;
        while(track) {
                if((track->flag&TRACK_HIDDEN)==0) {
                        int act= sel_type==MCLIP_SEL_TRACK && sel==track;
 
                        if(!act) {
-                               marker= BKE_tracking_get_marker(track, sc->user.framenr);
+                               marker= BKE_tracking_get_marker(track, framenr);
                                draw_marker_areas(sc, track, marker, 0, 1);
                                draw_marker_slide_zones(sc, track, marker, 0, 0, width, height);
                        }
@@ -552,12 +558,54 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, fl
        /* active marker would be displayed on top of everything else */
        if(sel_type==MCLIP_SEL_TRACK) {
                if((((MovieTrackingTrack *)sel)->flag&TRACK_HIDDEN)==0) {
-                       marker= BKE_tracking_get_marker(sel, sc->user.framenr);
+                       marker= BKE_tracking_get_marker(sel, framenr);
                        draw_marker_areas(sc, sel, marker, 1, 1);
                        draw_marker_slide_zones(sc, sel, marker, 0, 1, width, height);
                }
        }
 
+       if(sc->flag&SC_SHOW_BUNDLES) {
+               float pos[4], vec[4], mat[4][4];
+
+               glEnable(GL_POINT_SMOOTH);
+               glPointSize(3.0f);
+
+               BKE_tracking_projection_matrix(tracking, framenr, width, height, mat);
+
+               track= tracking->tracks.first;
+               while(track) {
+                       if(track->flag&TRACK_HAS_BUNDLE) {
+                               marker= BKE_tracking_get_marker(track, framenr);
+
+                               copy_v4_v4(vec, track->bundle_pos);
+                               vec[3]=1;
+
+                               mul_v4_m4v4(pos, mat, vec);
+
+                               pos[0]= (pos[0]/(pos[3]*2.0f)+0.5f)*width;
+                               pos[1]= (pos[1]/(pos[3]*2.0f)+0.5f)*height;
+
+                               BKE_tracking_apply_intrinsics(tracking, pos, width, height, pos);
+
+                               vec[0]= marker->pos[0]*width;
+                               vec[1]= marker->pos[1]*height;
+                               sub_v2_v2(vec, pos);
+
+                               if(len_v2(vec)<3) glColor3f(0.0f, 1.0f, 0.0f);
+                               else glColor3f(1.0f, 0.0f, 0.0f);
+
+                               glBegin(GL_POINTS);
+                                       glVertex3f(pos[0]/width, pos[1]/height, 0);
+                               glEnd();
+                       }
+
+                       track= track->next;
+               }
+
+               glPointSize(1.0f);
+               glDisable(GL_POINT_SMOOTH);
+       }
+
        glPopMatrix();
 }
 
@@ -581,7 +629,7 @@ void draw_clip_main(SpaceClip *sc, ARegion *ar, Scene *scene)
        ibuf= ED_space_clip_acquire_buffer(sc);
 
        if(ibuf) {
-               draw_movieclip_buffer(ar, ibuf, zoomx, zoomy);
+               draw_movieclip_buffer(sc, ar, ibuf, zoomx, zoomy);
                IMB_freeImBuf(ibuf);
 
                draw_tracking(sc, ar, clip, zoomx, zoomy);
index c272dbfde30ef25c2d435d1ea6a933cf05563a5a..6e5e11be4b4bccaf5eef4f301d8567f342020e17 100644 (file)
@@ -965,6 +965,8 @@ enum {
 #define SC_LOCK_SELECTION              (1<<2)
 #define SC_SHOW_TINY_MARKER            (1<<3)
 #define SC_SHOW_MARKER_PATH            (1<<4)
+#define SC_SHOW_BUNDLES                        (1<<5)
+#define SC_MUTE_FOOTAGE                        (1<<6)
 
 
 /* space types, moved from DNA_screen_types.h */
index 962f8d258bab94cd900bfefd5293f2b373c54dfe..2ad11e360c840d5d8c19e79cee591dd7b5627011 100644 (file)
@@ -54,10 +54,13 @@ typedef struct MovieReconstructedCamera {
 } MovieReconstructedCamera;
 
 typedef struct MovieTrackingCamera {
+       float sensor_width;     /* width of CCD sensor */
        float focal;            /* focal length */
+       short units;            /* units of focal length user is working with */
+       short pad;
        float principal[2];     /* principal point */
        float k1, k2, k3;       /* radial distortion */
-       float pad;
+       int last_camera;        /* most recently used camera */
        int reconnr;            /* number of reconstructed cameras */
        struct MovieReconstructedCamera *reconstructed; /* reconstructed cameras */
 } MovieTrackingCamera;
@@ -105,6 +108,12 @@ typedef struct MovieTracking {
        ListBase tracks;
 } MovieTracking;
 
+/* MovieTrackingCamera->units */
+enum {
+       CAMERA_UNITS_PX = 0,
+       CAMERA_UNITS_MM
+};
+
 /* MovieTrackingMarker->flag */
 #define MARKER_DISABLED        1
 
index e4e22922f0dab612aac0d9ec60dee2027dd99b80..d27bcbfe1de9488ab018ccd01a57bdb8414c8642 100644 (file)
@@ -62,19 +62,12 @@ static void rna_MovieClip_reload_update(Main *bmain, Scene *scene, PointerRNA *p
 static void rna_MovieClip_size_get(PointerRNA *ptr, int *values)
 {
        MovieClip *clip= (MovieClip*)ptr->data;
-       ImBuf *ibuf;
+       int width, height;
 
-       ibuf= BKE_movieclip_acquire_ibuf(clip, NULL);
-       if (ibuf) {
-               values[0]= ibuf->x;
-               values[1]= ibuf->y;
+       BKE_movieclip_approx_size(clip, &width, &height);
 
-               IMB_freeImBuf(ibuf);
-       }
-       else {
-               values[0]= 0;
-               values[1]= 0;
-       }
+       values[0]= height;
+       values[1]= width;
 }
 
 static void rna_MovieClip_resolution_get(PointerRNA *ptr, float *values)
index 9ade1bfa708a9b30bb982dddef26894ac7c79e81..4a689f3716ecab29db0f7d312e52539df2e04054 100644 (file)
@@ -2676,6 +2676,18 @@ static void rna_def_space_clip(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Show Tiny Markers", "Show markers tiny");
        RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_TINY_MARKER);
        RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
+
+       /* show bundles */
+       prop= RNA_def_property(srna, "show_bundles", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_ui_text(prop, "Show Bundles", "Show projection of bundles into footage");
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_BUNDLES);
+       RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
+
+       /* mute footage */
+       prop= RNA_def_property(srna, "use_mute_footage", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_ui_text(prop, "Mute Footage", "Mute footage and show black background instead");
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_MUTE_FOOTAGE);
+       RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
 }
 
 void RNA_def_space(BlenderRNA *brna)
index 2c9f747e46a1967ed6e2b9f424d27959bd2440aa..2049524200230d552c097626b4366879d4060372 100644 (file)
@@ -116,6 +116,29 @@ static PointerRNA rna_tracking_active_track_get(PointerRNA *ptr)
        return rna_pointer_inherit_refine(ptr, &RNA_SceneRenderLayer, NULL);
 }
 
+static float rna_trackingCamera_focal_get(PointerRNA *ptr)
+{
+       MovieClip *clip= (MovieClip*)ptr->id.data;
+       MovieTrackingCamera *camera= &clip->tracking.camera;
+       float val= camera->focal;
+
+       if(camera->units==CAMERA_UNITS_MM) {
+               int width, height;
+
+               BKE_movieclip_approx_size(clip, &width, &height);
+
+               if(width)
+                       val= val*camera->sensor_width/(float)width;
+       }
+
+       return val;
+}
+
+static void rna_trackingCamera_focal_set(PointerRNA *ptr, float value)
+{
+       MovieClip *clip= (MovieClip*)ptr->id.data;
+}
+
 #else
 
 static void rna_def_trackingSettings(BlenderRNA *brna)
@@ -124,7 +147,7 @@ static void rna_def_trackingSettings(BlenderRNA *brna)
        PropertyRNA *prop;
 
        static EnumPropertyItem speed_items[] = {
-               {0, "FASTEST", 0, "Fastest", "track as fast as it's possible"},
+               {0, "FASTEST", 0, "Fastest", "Track as fast as it's possible"},
                {TRACKING_SPEED_REALTIME, "REALTIME", 0, "Realtime", "Track with realtime speed"},
                {TRACKING_SPEED_HALF, "HALF", 0, "Half", "Track with half of realtime speed"},
                {TRACKING_SPEED_HALF, "QUARTER", 0, "Quarter", "Track with quarter of realtime speed"},
@@ -170,33 +193,58 @@ static void rna_def_trackingCamera(BlenderRNA *brna)
        StructRNA *srna;
        PropertyRNA *prop;
 
+       static EnumPropertyItem camera_units_items[] = {
+               {CAMERA_UNITS_PX, "PIXELS", 0, "Pixels", "Use pixels for units of focal length"},
+               {CAMERA_UNITS_MM, "MILLIMETERS", 0, "Millimeters", "Use millimeters for units of focal length"},
+               {0, NULL, 0, NULL, NULL}};
+
        srna= RNA_def_struct(brna, "MovieTrackingCamera", NULL);
        RNA_def_struct_ui_text(srna, "Movie tracking camera data", "Match-moving camera data for tracking");
 
+       /* Sensor Wdth */
+       prop= RNA_def_property(srna, "sensor_width", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "sensor_width");
+       RNA_def_property_range(prop, 0.0f, 500.0f);
+       RNA_def_property_ui_text(prop, "Sensor Width", "Width of CCD sensor in millimeters");
+       RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
+
        /* Focal Length */
        prop= RNA_def_property(srna, "focal_length", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "focal");
        RNA_def_property_range(prop, 0.0f, 5000.0f);
        RNA_def_property_ui_text(prop, "Focal Length", "Camera's focal length in pixels");
+       RNA_def_property_float_funcs(prop, "rna_trackingCamera_focal_get", "rna_trackingCamera_focal_set", NULL);
+       RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
+
+       /* Units */
+       prop= RNA_def_property(srna, "units", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "units");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_enum_items(prop, camera_units_items);
+       RNA_def_property_ui_text(prop, "Units", "Units used for camera focal length");
 
        /* Principal Point */
        prop= RNA_def_property(srna, "principal", PROP_FLOAT, PROP_NONE);
        RNA_def_property_array(prop, 2);
        RNA_def_property_float_sdna(prop, NULL, "principal");
        RNA_def_property_ui_text(prop, "Principal Point", "Optical center of lens");
+       RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
 
        /* Radial distortion parameters */
        prop= RNA_def_property(srna, "k1", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "k1");
        RNA_def_property_ui_text(prop, "K1", "");
+       RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
 
        prop= RNA_def_property(srna, "k2", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "k2");
        RNA_def_property_ui_text(prop, "K2", "");
+       RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
 
        prop= RNA_def_property(srna, "k3", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "k3");
        RNA_def_property_ui_text(prop, "K3", "");
+       RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
 }
 
 static void rna_def_trackingMarker(BlenderRNA *brna)