Object tracking: configurable scale for object solution
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 19 Dec 2011 15:12:33 +0000 (15:12 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 19 Dec 2011 15:12:33 +0000 (15:12 +0000)
Added slider to define scale of object solution which is used to define
"depth" of object relative to camera position. This slider effects on all
"users" of object solution such as bundles display, constrained objects and so.

Added new operator called "Set Solution Scale" to set real scale for object
solution based on real distance between two bundles reconstructed for this object.

New slider and operator can be found on "Object" panel in toolbox when in
reconstruction mode and active tracking object isn't a camera.

release/scripts/startup/bl_ui/space_clip.py
source/blender/blenkernel/intern/tracking.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/space_clip/clip_intern.h
source/blender/editors/space_clip/space_clip.c
source/blender/editors/space_clip/tracking_ops.c
source/blender/makesdna/DNA_tracking_types.h
source/blender/makesrna/intern/rna_tracking.c

index 5aec9a8e58c26017f616f5e4cb85715dee125fff..5234ffbcc328a140b5585caeaa9b120b190eb82b 100644 (file)
@@ -302,6 +302,39 @@ class CLIP_PT_tools_orientation(Panel):
         col.prop(settings, "distance")
 
 
+class CLIP_PT_tools_object(Panel):
+    bl_space_type = 'CLIP_EDITOR'
+    bl_region_type = 'TOOLS'
+    bl_label = "Object"
+
+    @classmethod
+    def poll(cls, context):
+        sc = context.space_data
+        clip = sc.clip
+
+        if clip and sc.mode == 'RECONSTRUCTION':
+            tracking_object = clip.tracking.objects.active
+            return not tracking_object.is_camera
+
+        return False
+
+    def draw(self, context):
+        sc = context.space_data
+        clip = sc.clip
+        layout = self.layout
+        tracking_object = clip.tracking.objects.active
+        settings = sc.clip.tracking.settings
+
+        col = layout.column()
+
+        col.prop(tracking_object, "scale")
+
+        col.separator()
+
+        col.operator("clip.set_solution_scale", text="Set Scale")
+        col.prop(settings, "object_distance")
+
+
 class CLIP_PT_tools_grease_pencil(Panel):
     bl_space_type = 'CLIP_EDITOR'
     bl_region_type = 'TOOLS'
index 06680dc9da40a4e623b52142261226a5242e761d..0b58d1562fa88db7979a0a7e0b3759d3a37d0a6d 100644 (file)
@@ -86,6 +86,7 @@ void BKE_tracking_init_settings(MovieTracking *tracking)
        tracking->settings.keyframe1= 1;
        tracking->settings.keyframe2= 30;
        tracking->settings.dist= 1;
+       tracking->settings.object_distance= 1;
 
        tracking->stabilization.scaleinf= 1.0f;
        tracking->stabilization.locinf= 1.0f;
@@ -1920,6 +1921,16 @@ static int reconstruction_camera_index(MovieTrackingReconstruction *reconstructi
        return -1;
 }
 
+static void scale_reconstructed_camera(MovieTrackingObject *object, float mat[4][4])
+{
+       if((object->flag&TRACKING_OBJECT_CAMERA)==0) {
+               float smat[4][4];
+
+               scale_m4_fl(smat, 1.0f/object->scale);
+               mult_m4_m4m4(mat, mat, smat);
+       }
+}
+
 MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(MovieTracking *tracking,
                        MovieTrackingObject *object, int framenr)
 {
@@ -1958,6 +1969,8 @@ void BKE_tracking_get_interpolated_camera(MovieTracking *tracking, MovieTracking
        } else {
                copy_m4_m4(mat, cameras[a].mat);
        }
+
+       scale_reconstructed_camera(object, mat);
 }
 
 void BKE_get_tracking_mat(Scene *scene, Object *ob, float mat[4][4])
index dbc8439e50db724e324bf85caafc54e72ee430d3..ab362fba14310c7b89ad9abaf0bc09e22d6306bd 100644 (file)
@@ -12693,9 +12693,20 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
                for (clip= main->movieclip.first; clip; clip= clip->id.next) {
                        MovieTracking *tracking= &clip->tracking;
+                       MovieTrackingObject *tracking_object= tracking->objects.first;
+
+                       if(!tracking->settings.object_distance)
+                               tracking->settings.object_distance= 1.0f;
 
                        if(tracking->objects.first == NULL)
                                BKE_tracking_new_object(tracking, "Camera");
+
+                       while(tracking_object) {
+                               if(!tracking_object->scale)
+                                       tracking_object->scale= 1.0f;
+
+                               tracking_object= tracking_object->next;
+                       }
                }
 
                for (ob= main->object.first; ob; ob= ob->id.next) {
index 38da4dd86ff7e413b68c917890b3823b447cb497..64881499a31ba14fda98b3544f0a38fb32aace13 100644 (file)
@@ -124,6 +124,7 @@ void CLIP_OT_set_origin(struct wmOperatorType *ot);
 void CLIP_OT_set_floor(struct wmOperatorType *ot);
 void CLIP_OT_set_axis(struct wmOperatorType *ot);
 void CLIP_OT_set_scale(struct wmOperatorType *ot);
+void CLIP_OT_set_solution_scale(struct wmOperatorType *ot);
 
 void CLIP_OT_set_center_principal(struct wmOperatorType *ot);
 
index 01779a806b9818d397e4b65ded64a659ea1119e0..5291121571cab37ef289e003456c448a6874c571 100644 (file)
@@ -351,6 +351,7 @@ static void clip_operatortypes(void)
        WM_operatortype_append(CLIP_OT_set_floor);
        WM_operatortype_append(CLIP_OT_set_axis);
        WM_operatortype_append(CLIP_OT_set_scale);
+       WM_operatortype_append(CLIP_OT_set_solution_scale);
 
        /* detect */
        WM_operatortype_append(CLIP_OT_detect_features);
index c37113e924cc97cc47a539753b0919b39b0c4c4e..ff970a9db30f034538b73739b06d255e4456f6e0 100644 (file)
@@ -2344,7 +2344,7 @@ void CLIP_OT_set_axis(wmOperatorType *ot)
 
 /********************** set scale operator *********************/
 
-static int set_scale_exec(bContext *C, wmOperator *op)
+static int do_set_scale(bContext *C, wmOperator *op, int scale_solution)
 {
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
@@ -2352,24 +2352,26 @@ static int set_scale_exec(bContext *C, wmOperator *op)
        MovieTrackingObject *tracking_object= BKE_tracking_active_object(tracking);
        MovieTrackingTrack *track;
        Scene *scene= CTX_data_scene(C);
-       Object *object;
+       Object *object= NULL;
        ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
        int tot= 0;
        float vec[2][3], mat[4][4], scale;
        float dist= RNA_float_get(op->ptr, "distance");
 
        if(count_selected_bundles(C)!=2) {
-               BKE_report(op->reports, RPT_ERROR, "Two tracks with bundles should be selected to scale scene");
+               BKE_report(op->reports, RPT_ERROR, "Two tracks with bundles should be selected to set scale");
 
                return OPERATOR_CANCELLED;
        }
 
-       if(tracking_object->flag&TRACKING_OBJECT_CAMERA)
+       if(tracking_object->flag&TRACKING_OBJECT_CAMERA) {
                object= scene->camera;
-       else
+       }
+       else if(!scale_solution) {
                object= OBACT;
+       }
 
-       if(object->parent)
+       if(object && object->parent)
                object= object->parent;
 
        BKE_get_tracking_mat(scene, NULL, mat);
@@ -2392,7 +2394,8 @@ static int set_scale_exec(bContext *C, wmOperator *op)
                if(tracking_object->flag&TRACKING_OBJECT_CAMERA) {
                        mul_v3_fl(object->size, scale);
                        mul_v3_fl(object->loc, scale);
-               } else {
+               } else
+               if(!scale_solution){
                        object->size[0]= object->size[1]= object->size[2]= 1.0f/scale;
 
                        if(scene->camera) {
@@ -2401,9 +2404,14 @@ static int set_scale_exec(bContext *C, wmOperator *op)
                                object->size[2]/= scene->camera->size[2];
                        }
                }
+               else {
+                       tracking_object->scale= scale;
+               }
 
                DAG_id_tag_update(&clip->id, 0);
-               DAG_id_tag_update(&object->id, OB_RECALC_OB);
+
+               if(object)
+                       DAG_id_tag_update(&object->id, OB_RECALC_OB);
 
                WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip);
                WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
@@ -2412,6 +2420,11 @@ static int set_scale_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
+static int set_scale_exec(bContext *C, wmOperator *op)
+{
+       return do_set_scale(C, op, 0);
+}
+
 static int set_scale_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
 {
        SpaceClip *sc= CTX_wm_space_clip(C);
@@ -2444,6 +2457,60 @@ void CLIP_OT_set_scale(wmOperatorType *ot)
                "Distance", "Distance between selected tracks", -100.0f, 100.0f);
 }
 
+/********************** set solution scale operator *********************/
+
+static int set_solution_scale_poll(bContext *C)
+{
+       if(space_clip_frame_poll(C)) {
+               Scene *scene= CTX_data_scene(C);
+               SpaceClip *sc= CTX_wm_space_clip(C);
+               MovieClip *clip= ED_space_clip(sc);
+               MovieTracking *tracking= &clip->tracking;
+               MovieTrackingObject *tracking_object= BKE_tracking_active_object(tracking);
+
+               return (tracking_object->flag&TRACKING_OBJECT_CAMERA) == 0;
+       }
+
+       return 0;
+}
+
+static int set_solution_scale_exec(bContext *C, wmOperator *op)
+{
+       return do_set_scale(C, op, 1);
+}
+
+static int set_solution_scale_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+{
+       SpaceClip *sc= CTX_wm_space_clip(C);
+       MovieClip *clip= ED_space_clip(sc);
+       float dist= RNA_float_get(op->ptr, "distance");
+
+       if(dist==0.0f)
+               RNA_float_set(op->ptr, "distance", clip->tracking.settings.object_distance);
+
+       return set_solution_scale_exec(C, op);
+}
+
+void CLIP_OT_set_solution_scale(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Set Solution Scale";
+       ot->description= "Set object solution scale using distance between two selected tracks";
+       ot->idname= "CLIP_OT_set_solution_scale";
+
+       /* api callbacks */
+       ot->exec= set_solution_scale_exec;
+       ot->invoke= set_solution_scale_invoke;
+       ot->poll= set_solution_scale_poll;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       /* properties */
+       RNA_def_float(ot->srna, "distance", 0.0f, -FLT_MAX, FLT_MAX,
+               "Distance", "Distance between selected tracks", -100.0f, 100.0f);
+}
+
 /********************** set principal center operator *********************/
 
 static int set_center_principal_exec(bContext *C, wmOperator *UNUSED(op))
index fd0e281b60fe267ae1f5f19eca0b16616e74561a..25ae75dcb0338831eb38ec76b49aa0ad27f983bc 100644 (file)
@@ -142,7 +142,10 @@ typedef struct MovieTrackingSettings {
 
        /* cleanup */
        int clean_frames, clean_action;
-       float clean_error, pad;
+       float clean_error;
+
+       /* set object scale */
+       float object_distance;          /* distance between two bundles used for object scaling */
 } MovieTrackingSettings;
 
 typedef struct MovieTrackingStabilization {
@@ -176,7 +179,9 @@ typedef struct MovieTrackingObject {
        struct MovieTrackingObject *next, *prev;
 
        char name[24];                  /* Name of tracking object */
-       int flag, pad;
+       int flag;
+       float scale;                    /* scale of object solution in amera space */
+
        ListBase tracks;                /* list of tracks use to tracking this object */
        MovieTrackingReconstruction reconstruction;     /* reconstruction data for this object */
 } MovieTrackingObject;
index bf3806e5de4ca5b7ce0e0c64aa8de8393d1bff49..bbec6484c5f144c03ce8c421ee755dd42c7a6401 100644 (file)
@@ -336,6 +336,14 @@ void rna_trackingObject_name_set(PointerRNA *ptr, const char *value)
        BKE_tracking_object_unique_name(&clip->tracking, object);
 }
 
+static void rna_trackingObject_flushUpdate(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
+{
+       MovieClip *clip= (MovieClip*)ptr->id.data;
+
+       WM_main_add_notifier(NC_OBJECT|ND_TRANSFORM, NULL);
+       DAG_id_tag_update(&clip->id, 0);
+}
+
 /* API */
 
 static void add_tracks_to_base(MovieClip *clip, MovieTracking *tracking, ListBase *tracksbase, int frame, int number)
@@ -572,6 +580,14 @@ static void rna_def_trackingSettings(BlenderRNA *brna)
        RNA_def_property_range(prop, 5, 1000);
        RNA_def_property_update(prop, 0, "rna_tracking_defaultSettings_searchUpdate");
        RNA_def_property_ui_text(prop, "Search Size", "Size of search area for newly created tracks");
+
+       /* object distance */
+       prop= RNA_def_property(srna, "object_distance", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_float_sdna(prop, NULL, "object_distance");
+       RNA_def_property_ui_text(prop, "Distance", "Distance between two bundles used for object scaling");
+       RNA_def_property_range(prop, 0.001, 10000);
+       RNA_def_property_ui_range(prop, 0.001, 10000.0, 1, 3);
 }
 
 static void rna_def_trackingCamera(BlenderRNA *brna)
@@ -1100,6 +1116,15 @@ static void rna_def_trackingObject(BlenderRNA *brna)
        /* reconstruction */
        prop= RNA_def_property(srna, "reconstruction", PROP_POINTER, PROP_NONE);
        RNA_def_property_struct_type(prop, "MovieTrackingReconstruction");
+
+       /* scale */
+       prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_float_sdna(prop, NULL, "scale");
+       RNA_def_property_range(prop, 0.0001f, 10000.0f);
+       RNA_def_property_ui_range(prop, 0.0001f, 10000.0, 1, 4);
+       RNA_def_property_ui_text(prop, "Scale", "Scale of object solution in camera space");
+       RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_trackingObject_flushUpdate");
 }
 
 static void rna_def_trackingObjects(BlenderRNA *brna, PropertyRNA *cprop)