svn merge ^/trunk/blender -r42991:43009
authorCampbell Barton <ideasman42@gmail.com>
Sat, 31 Dec 2011 03:07:14 +0000 (03:07 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 31 Dec 2011 03:07:14 +0000 (03:07 +0000)
65 files changed:
release/scripts/modules/bpy/utils.py
release/scripts/presets/tracking_track_color/object.py [new file with mode: 0644]
release/scripts/startup/bl_operators/presets.py
release/scripts/startup/bl_ui/properties_object_constraint.py
release/scripts/startup/bl_ui/properties_render.py
release/scripts/startup/bl_ui/space_clip.py
source/blender/blenkernel/BKE_tracking.h
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/movieclip.c
source/blender/blenkernel/intern/tracking.c
source/blender/blenlib/intern/math_matrix.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/include/BIF_glutil.h
source/blender/editors/interface/interface_draw.c
source/blender/editors/interface/interface_templates.c
source/blender/editors/object/object_constraint.c
source/blender/editors/object/object_intern.h
source/blender/editors/object/object_ops.c
source/blender/editors/render/render_internal.c
source/blender/editors/render/render_preview.c
source/blender/editors/screen/glutil.c
source/blender/editors/sculpt_paint/paint_vertex.c
source/blender/editors/space_clip/clip_draw.c
source/blender/editors/space_clip/clip_editor.c
source/blender/editors/space_clip/clip_graph_draw.c
source/blender/editors/space_clip/clip_graph_ops.c
source/blender/editors/space_clip/clip_intern.h
source/blender/editors/space_clip/clip_utils.c
source/blender/editors/space_clip/space_clip.c
source/blender/editors/space_clip/tracking_ops.c
source/blender/editors/space_image/image_buttons.c
source/blender/editors/space_node/space_node.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_select.c
source/blender/editors/space_view3d/view3d_snap.c
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_generics.c
source/blender/imbuf/IMB_imbuf_types.h
source/blender/imbuf/intern/divers.c
source/blender/makesdna/DNA_constraint_types.h
source/blender/makesdna/DNA_image_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_tracking_types.h
source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/rna_constraint.c
source/blender/makesrna/intern/rna_image.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_tracking.c
source/blender/nodes/composite/node_composite_util.c
source/blender/nodes/composite/nodes/node_composite_image.c
source/blender/render/intern/source/pipeline.c
source/gameengine/Expressions/StringValue.h
source/gameengine/Expressions/Value.h
source/gameengine/Ketsji/BL_Material.cpp
source/gameengine/Ketsji/BL_Texture.cpp
source/gameengine/Ketsji/KX_BlenderMaterial.h
source/gameengine/Ketsji/KX_Dome.cpp
source/gameengine/Ketsji/KX_FontObject.cpp
source/gameengine/Ketsji/KX_FontObject.h
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Ketsji/KX_MeshProxy.cpp
source/gameengine/Ketsji/KX_Scene.h

index cf3e92bdcbfe7834864bc5b7aa821e0fc5798e63..6fd15c146f26d90b20ac864903029ff8241fa4c5 100644 (file)
@@ -349,6 +349,14 @@ def preset_paths(subdir):
             raise Exception("invalid subdir given %r" % subdir)
         elif _os.path.isdir(directory):
             dirs.append(directory)
+
+    # Find addons preset paths
+    import addon_utils
+    for path in addon_utils.paths():
+        directory = _os.path.join(path, "presets", subdir)
+        if _os.path.isdir(directory):
+            dirs.append(directory)
+
     return dirs
 
 
diff --git a/release/scripts/presets/tracking_track_color/object.py b/release/scripts/presets/tracking_track_color/object.py
new file mode 100644 (file)
index 0000000..5cb663d
--- /dev/null
@@ -0,0 +1,5 @@
+import bpy
+track = bpy.context.edit_movieclip.tracking.tracks.active
+
+track.color = (1.0, 0.0, 1.0)
+track.use_custom_color = True
index a5c8c280616469a059c7046aa39547e743d3e497..308c46ca416c41e0b644e85d12ed080f73d1031d 100644 (file)
@@ -76,6 +76,7 @@ class AddPresetBase():
             if hasattr(self, "add"):
                 self.add(context, filepath)
             else:
+                print("Writing Preset: %r" % filepath)
                 file_preset = open(filepath, 'w')
                 file_preset.write("import bpy\n")
 
index 038d7a38fd637acacd9baeec8b56c4663d257322..32ed1c3f1b12f935dbd68d335845c14cfb94eecc 100644 (file)
@@ -755,7 +755,16 @@ class ConstraintButtonsPanel():
         col = layout.column()
         col.prop(con, "rotation_range", text="Pivot When")
 
+    @staticmethod
+    def _getConstraintClip(context, con):
+        if not con.use_active_clip:
+            return con.clip
+        else:
+            return context.scene.active_clip
+
     def FOLLOW_TRACK(self, context, layout, con):
+        clip = self._getConstraintClip(context, con)
+
         row = layout.row()
         row.prop(con, "use_active_clip")
         row.prop(con, "use_3d_position")
@@ -763,7 +772,11 @@ class ConstraintButtonsPanel():
         if not con.use_active_clip:
             layout.prop(con, "clip")
 
-        layout.prop(con, "track")
+        if clip:
+            layout.prop_search(con, "object", clip.tracking, "objects", icon='OBJECT_DATA')
+            layout.prop_search(con, "track", clip.tracking, "tracks", icon='ANIMATION_DATA')
+
+        layout.prop(con, "camera")
 
         layout.operator("clip.constraint_to_fcurve")
 
@@ -775,6 +788,26 @@ class ConstraintButtonsPanel():
 
         layout.operator("clip.constraint_to_fcurve")
 
+    def OBJECT_SOLVER(self, context, layout, con):
+        scene = context.scene
+        clip = self._getConstraintClip(context, con)
+
+        layout.prop(con, "use_active_clip")
+
+        if not con.use_active_clip:
+            layout.prop(con, "clip")
+
+        if clip:
+            layout.prop_search(con, "object", clip.tracking, "objects", icon='OBJECT_DATA')
+
+        layout.prop(con, "camera")
+
+        row = layout.row()
+        row.operator("constraint.objectsolver_set_inverse")
+        row.operator("constraint.objectsolver_clear_inverse")
+
+        layout.operator("clip.constraint_to_fcurve")
+
     def SCRIPT(self, context, layout, con):
         layout.label("Blender 2.5 has no py-constraints")
 
index 6a8439ffaaada054f4ef2bee6743f361b97240d5..7887998b90f460d43b7b3e390b44e4680910ab93 100644 (file)
@@ -316,6 +316,9 @@ class RENDER_PT_shading(RenderButtonsPanel, Panel):
         col = split.column()
         col.prop(rd, "use_raytrace", text="Ray Tracing")
         col.prop(rd, "use_color_management")
+        sub = col.row()
+        sub.active = rd.use_color_management == True
+        sub.prop(rd, "use_color_unpremultiply")
         col.prop(rd, "alpha_mode", text="Alpha")
 
 
index d05c93ccfe10cd720854430ac03c102401337309..5234ffbcc328a140b5585caeaa9b120b190eb82b 100644 (file)
@@ -70,7 +70,13 @@ class CLIP_HT_header(Header):
         row.template_ID(sc, "clip", open='clip.open')
 
         if clip:
-            r = clip.tracking.reconstruction
+            tracking = clip.tracking
+            active = tracking.objects.active
+
+            if active and not active.is_camera:
+                r = active.reconstruction
+            else:
+                r = tracking.reconstruction
 
             if r.is_valid:
                 layout.label(text="Average solve error: %.4f" %
@@ -197,10 +203,18 @@ class CLIP_PT_tools_solve(Panel):
     def draw(self, context):
         layout = self.layout
         clip = context.space_data.clip
-        settings = clip.tracking.settings
+        tracking = clip.tracking
+        settings = tracking.settings
+        tracking_object = tracking.objects.active
 
         col = layout.column(align=True)
-        col.operator("clip.solve_camera", text="Camera Motion")
+
+        if tracking_object.is_camera:
+            solve_text = "Camera Motion"
+        else:
+            solve_text = "Object Motion"
+
+        col.operator("clip.solve_camera", text=solve_text)
         col.operator("clip.clear_solution")
 
         col = layout.column(align=True)
@@ -208,6 +222,7 @@ class CLIP_PT_tools_solve(Panel):
         col.prop(settings, "keyframe_b")
 
         col = layout.column(align=True)
+        col.active = tracking_object.is_camera
         col.label(text="Refine:")
         col.prop(settings, "refine_intrinsics", text="")
 
@@ -287,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'
@@ -316,6 +364,37 @@ class CLIP_PT_tools_grease_pencil(Panel):
         row.prop(context.tool_settings, "use_grease_pencil_sessions")
 
 
+class CLIP_PT_objects(Panel):
+    bl_space_type = 'CLIP_EDITOR'
+    bl_region_type = 'UI'
+    bl_label = "Objects"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    @classmethod
+    def poll(cls, context):
+        sc = context.space_data
+
+        return sc.clip
+
+    def draw(self, context):
+        layout = self.layout
+        sc = context.space_data
+        clip = context.space_data.clip
+        tracking = clip.tracking
+
+        row = layout.row()
+        row.template_list(tracking, "objects", tracking, "active_object_index", rows=3)
+
+        sub = row.column(align=True)
+
+        sub.operator("clip.tracking_object_new", icon='ZOOMIN', text="")
+        sub.operator("clip.tracking_object_remove", icon='ZOOMOUT', text="")
+
+        active = tracking.objects.active
+        if active:
+            layout.prop(active, "name")
+
+
 class CLIP_PT_track(Panel):
     bl_space_type = 'CLIP_EDITOR'
     bl_region_type = 'UI'
@@ -352,9 +431,15 @@ class CLIP_PT_track(Panel):
         layout.template_track(sc, "scopes")
 
         row = layout.row(align=True)
-        row.prop(act_track, "use_red_channel", text="R", toggle=True)
-        row.prop(act_track, "use_green_channel", text="G", toggle=True)
-        row.prop(act_track, "use_blue_channel", text="B", toggle=True)
+        sub = row.row()
+        sub.prop(act_track, "use_red_channel", text="R", toggle=True)
+        sub.prop(act_track, "use_green_channel", text="G", toggle=True)
+        sub.prop(act_track, "use_blue_channel", text="B", toggle=True)
+
+        row.separator()
+
+        sub = row.row()
+        sub.prop(act_track, "use_grayscale_preview", text="B/W", toggle=True)
 
         layout.separator()
 
@@ -422,7 +507,7 @@ class CLIP_PT_tracking_camera(Panel):
         col.operator("clip.set_center_principal", text="Center")
 
         col = layout.column(align=True)
-        col.label(text="Undistortion:")
+        col.label(text="Lens Distortion:")
         col.prop(clip.tracking.camera, "k1")
         col.prop(clip.tracking.camera, "k2")
         col.prop(clip.tracking.camera, "k3")
index 973922d4223383ce3121626575ed6e16978e7ef9..7b3cb3f69bb421e53debc01471532caea8f1aaca 100644 (file)
 
 struct bGPDlayer;
 struct ImBuf;
+struct ListBase;
 struct MovieReconstructContext;
 struct MovieTrackingTrack;
 struct MovieTrackingMarker;
 struct MovieTracking;
 struct MovieTrackingContext;
+struct MovieTrackingObject;
 struct MovieClipUser;
 struct MovieDistortion;
 struct Camera;
@@ -49,8 +51,8 @@ void BKE_tracking_init_settings(struct MovieTracking *tracking);
 void BKE_tracking_clamp_track(struct MovieTrackingTrack *track, int event);
 void BKE_tracking_track_flag(struct MovieTrackingTrack *track, int area, int flag, int clear);
 
-struct MovieTrackingTrack *BKE_tracking_add_track(struct MovieTracking *tracking, float x, float y,
-                       int framenr, int width, int height);
+struct MovieTrackingTrack *BKE_tracking_add_track(struct MovieTracking *tracking, struct ListBase *tracksbase,
+                       float x, float y, int framenr, int width, int height);
 void BKE_tracking_insert_marker(struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker);
 void BKE_tracking_delete_marker(struct MovieTrackingTrack *track, int framenr);
 
@@ -72,40 +74,54 @@ struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTra
 struct ImBuf *BKE_tracking_get_search_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track,
                        struct MovieTrackingMarker *marker, int margin, int anchored, float pos[2], int origin[2]);
 
-void BKE_track_unique_name(struct MovieTracking *tracking, struct MovieTrackingTrack *track);
+void BKE_track_unique_name(struct ListBase *tracksbase, struct MovieTrackingTrack *track);
 
-struct MovieTrackingTrack *BKE_tracking_named_track(struct MovieTracking *tracking, const char *name);
-struct MovieTrackingTrack *BKE_tracking_indexed_track(struct MovieTracking *tracking, int tracknr);
+struct MovieTrackingTrack *BKE_tracking_named_track(struct MovieTracking *tracking, struct MovieTrackingObject *object, const char *name);
+struct MovieTrackingTrack *BKE_tracking_indexed_track(struct MovieTracking *tracking, int tracknr, struct ListBase **tracksbase_r);
 
 void BKE_tracking_camera_shift(struct MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty);
 void BKE_tracking_camera_to_blender(struct MovieTracking *tracking, struct Scene *scene, struct Camera *camera, int width, int height);
 
 void BKE_get_tracking_mat(struct Scene *scene, struct Object *ob, 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_projection_matrix(struct MovieTracking *tracking, struct MovieTrackingObject *object,
+                       int framenr, int winx, int winy, float mat[4][4]);
+
+struct ListBase *BKE_tracking_get_tracks(struct MovieTracking *tracking);
+struct MovieTrackingReconstruction *BKE_tracking_get_reconstruction(struct MovieTracking *tracking);
+
+struct MovieTrackingTrack *BKE_tracking_active_track(struct MovieTracking *tracking);
+struct MovieTrackingObject *BKE_tracking_active_object(struct MovieTracking *tracking);
+struct MovieTrackingObject *BKE_tracking_get_camera_object(struct MovieTracking *tracking);
+struct ListBase *BKE_tracking_object_tracks(struct MovieTracking *tracking, struct MovieTrackingObject *object);
+struct MovieTrackingReconstruction *BKE_tracking_object_reconstruction(struct MovieTracking *tracking,
+                       struct MovieTrackingObject *object);
 
 /* 2D tracking */
 struct MovieTrackingContext *BKE_tracking_context_new(struct MovieClip *clip, struct MovieClipUser *user,
-                       short backwards, short disable_failed, short sequence);
+                       short backwards, short sequence);
 void BKE_tracking_context_free(struct MovieTrackingContext *context);
 void BKE_tracking_sync(struct MovieTrackingContext *context);
 void BKE_tracking_sync_user(struct MovieClipUser *user, struct MovieTrackingContext *context);
 int BKE_tracking_next(struct MovieTrackingContext *context);
 
 /* Camera solving */
-int BKE_tracking_can_reconstruct(struct MovieTracking *tracking, char *error_msg, int error_size);
+int BKE_tracking_can_reconstruct(struct MovieTracking *tracking, struct MovieTrackingObject *object,
+                       char *error_msg, int error_size);
 
 struct MovieReconstructContext* BKE_tracking_reconstruction_context_new(struct MovieTracking *tracking,
-                       int keyframe1, int keyframe2, int width, int height);
+                       struct MovieTrackingObject *object, int keyframe1, int keyframe2, int width, int height);
 void BKE_tracking_reconstruction_context_free(struct MovieReconstructContext *context);
 void BKE_tracking_solve_reconstruction(struct MovieReconstructContext *context,
                        short *stop, short *do_update, float *progress, char *stats_message, int message_size);
 int BKE_tracking_finish_reconstruction(struct MovieReconstructContext *context, struct MovieTracking *tracking);
 
-struct MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(struct MovieTracking *tracking, int framenr);
-void BKE_tracking_get_interpolated_camera(struct MovieTracking *tracking, int framenr, float mat[4][4]);
+struct MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(struct MovieTracking *tracking,
+                       struct MovieTrackingObject *object, int framenr);
+void BKE_tracking_get_interpolated_camera(struct MovieTracking *tracking,
+                       struct MovieTrackingObject *object, int framenr, float mat[4][4]);
 
 /* Feature detection */
-void BKE_tracking_detect_fast(struct MovieTracking *tracking, struct ImBuf *imbuf,
+void BKE_tracking_detect_fast(struct MovieTracking *tracking, struct ListBase *tracksbase, struct ImBuf *imbuf,
                        int framenr, int margin, int min_trackness, int min_distance, struct bGPDlayer *layer,
                        int place_outside_layer);
 
@@ -127,8 +143,14 @@ void BKE_tracking_distortion_destroy(struct MovieDistortion *distortion);
 struct ImBuf *BKE_tracking_undistort(struct MovieTracking *tracking, struct ImBuf *ibuf, int width, int height, float overscan);
 struct ImBuf *BKE_tracking_distort(struct MovieTracking *tracking, struct ImBuf *ibuf, int width, int height, float overscan);
 
+/* Object tracking */
+struct MovieTrackingObject *BKE_tracking_new_object(struct MovieTracking *tracking, const char *name);
+void BKE_tracking_remove_object(struct MovieTracking *tracking, struct MovieTrackingObject *object);
+void BKE_tracking_object_unique_name(struct MovieTracking *tracking, struct MovieTrackingObject *object);
+struct MovieTrackingObject *BKE_tracking_named_object(struct MovieTracking *tracking, const char *name);
+
 /* Select */
-void BKE_tracking_select_track(struct MovieTracking *tracking, struct MovieTrackingTrack *track, int area, int extend);
+void BKE_tracking_select_track(struct ListBase *tracksbase, struct MovieTrackingTrack *track, int area, int extend);
 void BKE_tracking_deselect_track(struct MovieTrackingTrack *track, int area);
 
 #define TRACK_SELECTED(track)                          ((((track)->flag&TRACK_HIDDEN)==0) && ((track)->flag&SELECT || (track)->pat_flag&SELECT || (track)->search_flag&SELECT))
index 6e2a17aada67718a7e6083284ea994f8b62e7682..99b2d96ba1060fc3fc38b131049fbe7293e65c71 100644 (file)
@@ -827,7 +827,7 @@ static void childof_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
 {
        bChildOfConstraint *data= con->data;
        bConstraintTarget *ct= targets->first;
-       
+
        /* only evaluate if there is a target */
        if (VALID_CONS_TARGET(ct)) {
                float parmat[4][4];
@@ -1257,6 +1257,7 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
                        float quat[4];
                        if ((data->followflag & FOLLOWPATH_STATIC) == 0) {
                                /* animated position along curve depending on time */
+                               Nurb *nu = cu->nurb.first;
                                curvetime= cu->ctime - data->offset;
                                
                                /* ctime is now a proper var setting of Curve which gets set by Animato like any other var that's animated,
@@ -1266,7 +1267,18 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
                                 * factor, which then gets clamped to lie within 0.0 - 1.0 range
                                 */
                                curvetime /= cu->pathlen;
-                               CLAMP(curvetime, 0.0f, 1.0f);
+
+                               if (nu && nu->flagu & CU_NURB_CYCLIC) {
+                                       /* If the curve is cyclic, enable looping around if the time is
+                                        * outside the bounds 0..1 */
+                                       if ((curvetime < 0.0f) || (curvetime > 1.0f)) {
+                                               curvetime -= floor(curvetime);
+                                       }
+                               }
+                               else {
+                                       /* The curve is not cyclic, so clamp to the begin/end points. */
+                                       CLAMP(curvetime, 0.0f, 1.0f);
+                               }
                        }
                        else {
                                /* fixed position along curve */
@@ -3939,6 +3951,7 @@ static void followtrack_id_looper (bConstraint *con, ConstraintIDFunc func, void
        bFollowTrackConstraint *data= con->data;
        
        func(con, (ID**)&data->clip, userdata);
+       func(con, (ID**)&data->camera, userdata);
 }
 
 static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
@@ -3946,105 +3959,126 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase
        Scene *scene= cob->scene;
        bFollowTrackConstraint *data= con->data;
        MovieClip *clip= data->clip;
+       MovieTracking *tracking;
        MovieTrackingTrack *track;
-       
+       MovieTrackingObject *tracking_object;
+       Object *camob= data->camera ? data->camera : scene->camera;
+
        if (data->flag & FOLLOWTRACK_ACTIVECLIP)
                clip= scene->clip;
-       
-       if (!clip || !data->track[0])
+
+       if (!clip || !data->track[0] || !camob)
                return;
-       
-       track= BKE_tracking_named_track(&clip->tracking, data->track);
-       
+
+       tracking= &clip->tracking;
+
+       if(data->object[0])
+               tracking_object= BKE_tracking_named_object(tracking, data->object);
+       else
+               tracking_object= BKE_tracking_get_camera_object(tracking);
+
+       if(!tracking_object)
+               return;
+
+       track= BKE_tracking_named_track(tracking, tracking_object, data->track);
+
        if (!track)
                return;
-       
+
        if (data->flag & FOLLOWTRACK_USE_3D_POSITION) {
                if (track->flag & TRACK_HAS_BUNDLE) {
-                       float pos[3], mat[4][4], obmat[4][4];
-                       
+                       MovieTracking *tracking= &clip->tracking;
+                       float obmat[4][4], mat[4][4];
+
                        copy_m4_m4(obmat, cob->matrix);
-                       
-                       BKE_get_tracking_mat(cob->scene, NULL, mat);
-                       mul_v3_m4v3(pos, mat, track->bundle_pos);
-                       
-                       cob->matrix[3][0] += pos[0];
-                       cob->matrix[3][1] += pos[1];
-                       cob->matrix[3][2] += pos[2];
+
+                       if((tracking_object->flag&TRACKING_OBJECT_CAMERA)==0) {
+                               float imat[4][4];
+
+                               copy_m4_m4(mat, camob->obmat);
+
+                               BKE_tracking_get_interpolated_camera(tracking, tracking_object, scene->r.cfra, imat);
+                               invert_m4(imat);
+
+                               mul_serie_m4(cob->matrix, obmat, mat, imat, NULL, NULL, NULL, NULL, NULL);
+                               translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
+                       }
+                       else {
+                               BKE_get_tracking_mat(cob->scene, camob, mat);
+
+                               mult_m4_m4m4(cob->matrix, obmat, mat);
+                               translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
+                       }
                }
        } 
        else {
-               Object *camob= cob->scene->camera;
-               
-               if (camob) {
-                       MovieClipUser user;
-                       MovieTrackingMarker *marker;
-                       float vec[3], disp[3], axis[3], mat[4][4];
-                       float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp);
-                       float len, d;
-                       
-                       where_is_object_mat(scene, camob, mat);
-                       
-                       /* camera axis */
-                       vec[0]= 0.0f;
-                       vec[1]= 0.0f;
-                       vec[2]= 1.0f;
-                       mul_v3_m4v3(axis, mat, vec);
-                       
-                       /* distance to projection plane */
-                       copy_v3_v3(vec, cob->matrix[3]);
-                       sub_v3_v3(vec, mat[3]);
-                       project_v3_v3v3(disp, vec, axis);
-                       
-                       len= len_v3(disp);
-                       
-                       if (len > FLT_EPSILON) {
-                               CameraParams params;
-                               float pos[2], rmat[4][4];
-                               
-                               user.framenr= scene->r.cfra;
-                               marker= BKE_tracking_get_marker(track, user.framenr);
-                               
-                               add_v2_v2v2(pos, marker->pos, track->offset);
-                               
-                               camera_params_init(&params);
-                               camera_params_from_object(&params, camob);
+               MovieClipUser user;
+               MovieTrackingMarker *marker;
+               float vec[3], disp[3], axis[3], mat[4][4];
+               float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp);
+               float len, d;
 
-                               if (params.is_ortho) {
-                                       vec[0]= params.ortho_scale * (pos[0]-0.5f+params.shiftx);
-                                       vec[1]= params.ortho_scale * (pos[1]-0.5f+params.shifty);
-                                       vec[2]= -len;
-                                       
-                                       if (aspect > 1.0f) vec[1] /= aspect;
-                                       else vec[0] *= aspect;
-                                       
-                                       mul_v3_m4v3(disp, camob->obmat, vec);
-                                       
-                                       copy_m4_m4(rmat, camob->obmat);
-                                       zero_v3(rmat[3]);
-                                       mult_m4_m4m4(cob->matrix, cob->matrix, rmat);
-                                       
-                                       copy_v3_v3(cob->matrix[3], disp);
-                               }
-                               else {
-                                       d= (len*params.sensor_x) / (2.0f*params.lens);
-                                       
-                                       vec[0]= d*(2.0f*(pos[0]+params.shiftx)-1.0f);
-                                       vec[1]= d*(2.0f*(pos[1]+params.shifty)-1.0f);
-                                       vec[2]= -len;
-                                       
-                                       if (aspect > 1.0f) vec[1] /= aspect;
-                                       else vec[0] *= aspect;
-                                       
-                                       mul_v3_m4v3(disp, camob->obmat, vec);
-                                       
-                                       /* apply camera rotation so Z-axis would be co-linear */
-                                       copy_m4_m4(rmat, camob->obmat);
-                                       zero_v3(rmat[3]);
-                                       mult_m4_m4m4(cob->matrix, cob->matrix, rmat);
-                                       
-                                       copy_v3_v3(cob->matrix[3], disp);
-                               }
+               where_is_object_mat(scene, camob, mat);
+
+               /* camera axis */
+               vec[0]= 0.0f;
+               vec[1]= 0.0f;
+               vec[2]= 1.0f;
+               mul_v3_m4v3(axis, mat, vec);
+
+               /* distance to projection plane */
+               copy_v3_v3(vec, cob->matrix[3]);
+               sub_v3_v3(vec, mat[3]);
+               project_v3_v3v3(disp, vec, axis);
+
+               len= len_v3(disp);
+
+               if (len > FLT_EPSILON) {
+                       CameraParams params;
+                       float pos[2], rmat[4][4];
+
+                       user.framenr= scene->r.cfra;
+                       marker= BKE_tracking_get_marker(track, user.framenr);
+
+                       add_v2_v2v2(pos, marker->pos, track->offset);
+
+                       camera_params_init(&params);
+                       camera_params_from_object(&params, camob);
+
+                       if (params.is_ortho) {
+                               vec[0]= params.ortho_scale * (pos[0]-0.5f+params.shiftx);
+                               vec[1]= params.ortho_scale * (pos[1]-0.5f+params.shifty);
+                               vec[2]= -len;
+
+                               if (aspect > 1.0f) vec[1] /= aspect;
+                               else vec[0] *= aspect;
+
+                               mul_v3_m4v3(disp, camob->obmat, vec);
+
+                               copy_m4_m4(rmat, camob->obmat);
+                               zero_v3(rmat[3]);
+                               mult_m4_m4m4(cob->matrix, cob->matrix, rmat);
+
+                               copy_v3_v3(cob->matrix[3], disp);
+                       }
+                       else {
+                               d= (len*params.sensor_x) / (2.0f*params.lens);
+
+                               vec[0]= d*(2.0f*(pos[0]+params.shiftx)-1.0f);
+                               vec[1]= d*(2.0f*(pos[1]+params.shifty)-1.0f);
+                               vec[2]= -len;
+
+                               if (aspect > 1.0f) vec[1] /= aspect;
+                               else vec[0] *= aspect;
+
+                               mul_v3_m4v3(disp, camob->obmat, vec);
+
+                               /* apply camera rotation so Z-axis would be co-linear */
+                               copy_m4_m4(rmat, camob->obmat);
+                               zero_v3(rmat[3]);
+                               mult_m4_m4m4(cob->matrix, cob->matrix, rmat);
+
+                               copy_v3_v3(cob->matrix[3], disp);
                        }
                }
        }
@@ -4088,16 +4122,19 @@ static void camerasolver_evaluate (bConstraint *con, bConstraintOb *cob, ListBas
        Scene *scene= cob->scene;
        bCameraSolverConstraint *data= con->data;
        MovieClip *clip= data->clip;
-       
+
        if (data->flag & CAMERASOLVER_ACTIVECLIP)
                clip= scene->clip;
-       
+
        if (clip) {
                float mat[4][4], obmat[4][4];
-               
-               BKE_tracking_get_interpolated_camera(&clip->tracking, scene->r.cfra, mat);
-               
+               MovieTracking *tracking= &clip->tracking;
+               MovieTrackingObject *object= BKE_tracking_get_camera_object(tracking);
+
+               BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, mat);
+
                copy_m4_m4(obmat, cob->matrix);
+
                mult_m4_m4m4(cob->matrix, obmat, mat);
        }
 }
@@ -4118,6 +4155,80 @@ static bConstraintTypeInfo CTI_CAMERASOLVER = {
        camerasolver_evaluate /* evaluate */
 };
 
+/* ----------- Object Solver ------------- */
+
+static void objectsolver_new_data (void *cdata)
+{
+       bObjectSolverConstraint *data= (bObjectSolverConstraint *)cdata;
+
+       data->clip = NULL;
+       data->flag |= OBJECTSOLVER_ACTIVECLIP;
+       unit_m4(data->invmat);
+}
+
+static void objectsolver_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
+{
+       bObjectSolverConstraint *data= con->data;
+
+       func(con, (ID**)&data->clip, userdata);
+       func(con, (ID**)&data->camera, userdata);
+}
+
+static void objectsolver_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
+{
+       Scene *scene= cob->scene;
+       bObjectSolverConstraint *data= con->data;
+       MovieClip *clip= data->clip;
+       Object *camob= data->camera ? data->camera : scene->camera;
+
+       if (data->flag & OBJECTSOLVER_ACTIVECLIP)
+               clip= scene->clip;
+
+       if(!camob || !clip)
+               return;
+
+       if (clip) {
+               MovieTracking *tracking= &clip->tracking;
+               MovieTrackingObject *object;
+
+               object= BKE_tracking_named_object(tracking, data->object);
+
+               if(object) {
+                       float mat[4][4], obmat[4][4], imat[4][4], cammat[4][4], camimat[4][4], parmat[4][4];
+
+                       where_is_object_mat(scene, camob, cammat);
+
+                       BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, mat);
+
+                       invert_m4_m4(camimat, cammat);
+                       mult_m4_m4m4(parmat, cammat, data->invmat);
+
+                       copy_m4_m4(cammat, camob->obmat);
+                       copy_m4_m4(obmat, cob->matrix);
+
+                       invert_m4_m4(imat, mat);
+
+                       mul_serie_m4(cob->matrix, cammat, imat, camimat, parmat, obmat, NULL, NULL, NULL);
+               }
+       }
+}
+
+static bConstraintTypeInfo CTI_OBJECTSOLVER = {
+       CONSTRAINT_TYPE_OBJECTSOLVER, /* type */
+       sizeof(bObjectSolverConstraint), /* size */
+       "Object Solver", /* name */
+       "bObjectSolverConstraint", /* struct name */
+       NULL, /* free data */
+       NULL, /* relink data */
+       objectsolver_id_looper, /* id looper */
+       NULL, /* copy data */
+       objectsolver_new_data, /* new data */
+       NULL, /* get constraint targets */
+       NULL, /* flush constraint targets */
+       NULL, /* get target matrix */
+       objectsolver_evaluate /* evaluate */
+};
+
 /* ************************* Constraints Type-Info *************************** */
 /* All of the constraints api functions use bConstraintTypeInfo structs to carry out
  * and operations that involve constraint specific code.
@@ -4158,6 +4269,7 @@ static void constraints_init_typeinfo (void)
        constraintsTypeInfo[25]= &CTI_PIVOT;                    /* Pivot Constraint */
        constraintsTypeInfo[26]= &CTI_FOLLOWTRACK;              /* Follow Track Constraint */
        constraintsTypeInfo[27]= &CTI_CAMERASOLVER;             /* Camera Solver Constraint */
+       constraintsTypeInfo[28]= &CTI_OBJECTSOLVER;             /* Object Solver Constraint */
 }
 
 /* This function should be used for getting the appropriate type-info when only
index a76fa8e857935130172ff679d321d77de0c5d96b..e56a8034b2192bd3fcfc086289c69ccd3d68cf8d 100644 (file)
@@ -649,16 +649,21 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
                        continue;
 
                /* special case for camera tracking -- it doesn't use targets to define relations */
-               if(ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER)) {
+               if(ELEM3(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER, CONSTRAINT_TYPE_OBJECTSOLVER)) {
+                       int depends_on_camera= 0;
+
                        if(cti->type==CONSTRAINT_TYPE_FOLLOWTRACK) {
                                bFollowTrackConstraint *data= (bFollowTrackConstraint *)con->data;
 
-                               if((data->clip || data->flag&FOLLOWTRACK_ACTIVECLIP) && data->track[0]) {
-                                       if(scene->camera) {
-                                               node2 = dag_get_node(dag, scene->camera);
-                                               dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB, cti->name);
-                                       }
-                               }
+                               if((data->clip || data->flag&FOLLOWTRACK_ACTIVECLIP) && data->track[0])
+                                       depends_on_camera= 1;
+                       }
+                       else if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER)
+                               depends_on_camera= 1;
+
+                       if(depends_on_camera && scene->camera) {
+                               node2 = dag_get_node(dag, scene->camera);
+                               dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB, cti->name);
                        }
 
                        dag_add_relation(dag,scenenode,node,DAG_RL_SCENE, "Scene Relation");
@@ -2165,7 +2170,7 @@ static void dag_object_time_update_flags(Object *ob)
                        
                        if (cti) {
                                /* special case for camera tracking -- it doesn't use targets to define relations */
-                               if(ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER)) {
+                               if(ELEM3(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER, CONSTRAINT_TYPE_OBJECTSOLVER)) {
                                        ob->recalc |= OB_RECALC_OB;
                                }
                                else if (cti->get_constraint_targets) {
index 354a5265f9091324aabe1cc2f3c30bc1e89b02c8..a5c8f5c905d99950cca5e45793943244eb14a4c9 100644 (file)
@@ -285,6 +285,10 @@ static void image_assign_ibuf(Image *ima, ImBuf *ibuf, int index, int frame)
                                break;
 
                ibuf->index= index;
+               if(ima->flag & IMA_CM_PREDIVIDE)
+                       ibuf->flags |= IB_cm_predivide;
+               else
+                       ibuf->flags &= ~IB_cm_predivide;
 
                /* this function accepts link==NULL */
                BLI_insertlinkbefore(&ima->ibufs, link, ibuf);
@@ -2304,9 +2308,17 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
 
        /* since its possible to access the buffer from the image directly, set the profile [#25073] */
        ibuf->profile= (iuser->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_NONE;
-
        ibuf->dither= dither;
 
+       if(iuser->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE) {
+               ibuf->flags |= IB_cm_predivide;
+               ima->flag |= IMA_CM_PREDIVIDE;
+       }
+       else {
+               ibuf->flags &= ~IB_cm_predivide;
+               ima->flag &= ~IMA_CM_PREDIVIDE;
+       }
+
        ima->ok= IMA_OK_LOADED;
 
        return ibuf;
index 10c060e0aabbb4f880ed9cfa22092f87bdcb16b3..ab963f1e78c158221bc8a9837821a0dec16818b8 100644 (file)
@@ -816,7 +816,8 @@ void BKE_movieclip_reload(MovieClip *clip)
 
 void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClipScopes *scopes)
 {
-       if(scopes->ok) return;
+       if(scopes->ok)
+               return;
 
        if(scopes->track_preview) {
                IMB_freeImBuf(scopes->track_preview);
@@ -827,8 +828,10 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
        scopes->track= NULL;
 
        if(clip) {
-               if(clip->tracking.act_track) {
-                       MovieTrackingTrack *track= clip->tracking.act_track;
+               MovieTrackingTrack *act_track= BKE_tracking_active_track(&clip->tracking);
+
+               if(act_track) {
+                       MovieTrackingTrack *track= act_track;
                        MovieTrackingMarker *marker= BKE_tracking_get_marker(track, user->framenr);
 
                        if(marker->flag&MARKER_DISABLED) {
index 1a0007c5bfe3b94668c3593da8e5e2c09f6f1c2f..6eeae07cb1b86f3a8711817d5c7a1c1966642c21 100644 (file)
@@ -55,6 +55,7 @@
 #include "BKE_movieclip.h"
 #include "BKE_object.h"
 #include "BKE_scene.h"
+#include "BKE_main.h"  // XXX: ...
 
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
@@ -85,11 +86,14 @@ 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;
        tracking->stabilization.rotinf= 1.0f;
        tracking->stabilization.maxscale= 2.0f;
+
+       BKE_tracking_new_object(tracking, "Camera");
 }
 
 void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event)
@@ -208,7 +212,7 @@ void BKE_tracking_track_flag(MovieTrackingTrack *track, int area, int flag, int
        }
 }
 
-MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, float x, float y,
+MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, ListBase *tracksbase, float x, float y,
                        int framenr, int width, int height)
 {
        MovieTrackingTrack *track;
@@ -251,8 +255,8 @@ MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, float x, flo
        if(track->tracker == TRACKER_KLT)
                BKE_tracking_clamp_track(track, CLAMP_PYRAMID_LEVELS);
 
-       BLI_addtail(&tracking->tracks, track);
-       BKE_track_unique_name(tracking, track);
+       BLI_addtail(tracksbase, track);
+       BKE_track_unique_name(tracksbase, track);
 
        return track;
 }
@@ -524,18 +528,44 @@ void BKE_tracking_join_tracks(MovieTrackingTrack *dst_track, MovieTrackingTrack
        dst_track->markersnr= tot;
 }
 
-void BKE_tracking_free(MovieTracking *tracking)
+static void tracking_tracks_free(ListBase *tracks)
 {
        MovieTrackingTrack *track;
 
-       for(track= tracking->tracks.first; track; track= track->next) {
+       for(track= tracks->first; track; track= track->next) {
                BKE_tracking_free_track(track);
        }
 
-       BLI_freelistN(&tracking->tracks);
+       BLI_freelistN(tracks);
+}
+
+static void tracking_reconstruction_free(MovieTrackingReconstruction *reconstruction)
+{
+       if(reconstruction->cameras)
+               MEM_freeN(reconstruction->cameras);
+}
+
+static void tracking_object_free(MovieTrackingObject *object)
+{
+       tracking_tracks_free(&object->tracks);
+       tracking_reconstruction_free(&object->reconstruction);
+}
+
+static void tracking_objects_free(ListBase *objects)
+{
+       MovieTrackingObject *object;
+
+       for(object= objects->first; object; object= object->next)
+               tracking_object_free(object);
 
-       if(tracking->reconstruction.cameras)
-               MEM_freeN(tracking->reconstruction.cameras);
+       BLI_freelistN(objects);
+}
+
+void BKE_tracking_free(MovieTracking *tracking)
+{
+       tracking_tracks_free(&tracking->tracks);
+       tracking_reconstruction_free(&tracking->reconstruction);
+       tracking_objects_free(&tracking->objects);
 
        if(tracking->stabilization.scaleibuf)
                IMB_freeImBuf(tracking->stabilization.scaleibuf);
@@ -547,6 +577,9 @@ void BKE_tracking_free(MovieTracking *tracking)
 /*********************** tracks map *************************/
 
 typedef struct TracksMap {
+       char object_name[32];
+       int is_camera;
+
        int num_tracks;
        int customdata_size;
 
@@ -558,10 +591,13 @@ typedef struct TracksMap {
        int ptr;
 } TracksMap;
 
-static TracksMap *tracks_map_new(int num_tracks, int customdata_size)
+static TracksMap *tracks_map_new(const char *object_name, int is_camera, int num_tracks, int customdata_size)
 {
        TracksMap *map= MEM_callocN(sizeof(TracksMap), "TrackingsMap");
 
+       strcpy(map->object_name, object_name);
+       map->is_camera= is_camera;
+
        map->num_tracks= num_tracks;
        map->customdata_size= customdata_size;
 
@@ -607,10 +643,24 @@ static void tracks_map_insert(TracksMap *map, MovieTrackingTrack *track, void *c
 static void tracks_map_merge(TracksMap *map, MovieTracking *tracking)
 {
        MovieTrackingTrack *track;
+       MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking);
        ListBase tracks= {NULL, NULL}, new_tracks= {NULL, NULL};
-       ListBase *old_tracks= &tracking->tracks;
+       ListBase *old_tracks;
        int a;
 
+       if(map->is_camera) {
+               old_tracks= &tracking->tracks;
+       } else {
+               MovieTrackingObject *object= BKE_tracking_named_object(tracking, map->object_name);
+
+               if(!object) {
+                       /* object was deleted by user, create new one */
+                       object= BKE_tracking_new_object(tracking, map->object_name);
+               }
+
+               old_tracks= &object->tracks;
+       }
+
        /* duplicate currently operating tracks to temporary list.
           this is needed to keep names in unique state and it's faster to change names
           of currently operating tracks (if needed) */
@@ -634,7 +684,7 @@ static void tracks_map_merge(TracksMap *map, MovieTracking *tracking)
 
                        /* original track was found, re-use flags and remove this track */
                        if(cur) {
-                               if(cur==tracking->act_track)
+                               if(act_track)
                                        replace_sel= 1;
 
                                track->flag= cur->flag;
@@ -685,7 +735,7 @@ static void tracks_map_merge(TracksMap *map, MovieTracking *tracking)
                track= next;
        }
 
-       tracking->tracks= new_tracks;
+       *old_tracks= new_tracks;
 }
 
 static void tracks_map_free(TracksMap *map, void (*customdata_free) (void *customdata))
@@ -737,27 +787,28 @@ typedef struct MovieTrackingContext {
        MovieTrackingSettings settings;
        TracksMap *tracks_map;
 
-       short backwards, disable_failed, sequence;
+       short backwards, sequence;
        int sync_frame;
 } MovieTrackingContext;
 
-MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *user, short backwards, short disable_failed, short sequence)
+MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *user, short backwards, short sequence)
 {
        MovieTrackingContext *context= MEM_callocN(sizeof(MovieTrackingContext), "trackingContext");
        MovieTracking *tracking= &clip->tracking;
        MovieTrackingSettings *settings= &tracking->settings;
+       ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
        MovieTrackingTrack *track;
+       MovieTrackingObject *object= BKE_tracking_active_object(tracking);
        int num_tracks= 0;
 
        context->settings= *settings;
        context->backwards= backwards;
-       context->disable_failed= disable_failed;
        context->sync_frame= user->framenr;
        context->first_time= 1;
        context->sequence= sequence;
 
        /* count */
-       track= tracking->tracks.first;
+       track= tracksbase->first;
        while(track) {
                if(TRACK_SELECTED(track) && (track->flag&TRACK_LOCKED)==0) {
                        MovieTrackingMarker *marker= BKE_tracking_get_marker(track, user->framenr);
@@ -772,12 +823,13 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u
        if(num_tracks) {
                int width, height;
 
-               context->tracks_map= tracks_map_new(num_tracks, sizeof(TrackContext));
+               context->tracks_map= tracks_map_new(object->name, object->flag & TRACKING_OBJECT_CAMERA,
+                                       num_tracks, sizeof(TrackContext));
 
                BKE_movieclip_get_size(clip, user, &width, &height);
 
                /* create tracking data */
-               track= tracking->tracks.first;
+               track= tracksbase->first;
                while(track) {
                        if(TRACK_SELECTED(track) && (track->flag&TRACK_LOCKED)==0) {
                                MovieTrackingMarker *marker= BKE_tracking_get_marker(track, user->framenr);
@@ -883,29 +935,53 @@ void BKE_tracking_context_free(MovieTrackingContext *context)
        MEM_freeN(context);
 }
 
-static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track)
+/* zap channels from the imbuf that are disabled by the user. this can lead to
+ * better tracks sometimes. however, instead of simply zeroing the channels
+ * out, do a partial grayscale conversion so the display is better. */
+static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int grayscale)
 {
        int x, y;
+       float scale;
 
-       if((track->flag&(TRACK_DISABLE_RED|TRACK_DISABLE_GREEN|TRACK_DISABLE_BLUE))==0)
+       if((track->flag&(TRACK_DISABLE_RED|TRACK_DISABLE_GREEN|TRACK_DISABLE_BLUE))==0 && !grayscale)
                return;
 
+       /* If only some components are selected, it's important to rescale the result
+        * appropriately so that e.g. if only blue is selected, it's not zeroed out. */
+       scale = ((track->flag&TRACK_DISABLE_RED  ) ? 0.0f : 0.2126f) +
+               ((track->flag&TRACK_DISABLE_GREEN) ? 0.0f : 0.7152f) +
+               ((track->flag&TRACK_DISABLE_BLUE)  ? 0.0f : 0.0722f);
+
        for(y= 0; y<ibuf->y; y++) {
                for (x= 0; x<ibuf->x; x++) {
                        int pixel= ibuf->x*y + x;
 
                        if(ibuf->rect_float) {
                                float *rrgbf= ibuf->rect_float + pixel*4;
-
-                               if(track->flag&TRACK_DISABLE_RED)       rrgbf[0]= 0;
-                               if(track->flag&TRACK_DISABLE_GREEN)     rrgbf[1]= 0;
-                               if(track->flag&TRACK_DISABLE_BLUE)      rrgbf[2]= 0;
+                               float r = (track->flag&TRACK_DISABLE_RED)   ? 0.0f : rrgbf[0];
+                               float g = (track->flag&TRACK_DISABLE_GREEN) ? 0.0f : rrgbf[1];
+                               float b = (track->flag&TRACK_DISABLE_BLUE)  ? 0.0f : rrgbf[2];
+                               if (grayscale) {
+                                       float gray = (0.2126f*r + 0.7152f*g + 0.0722f*b) / scale;
+                                       rrgbf[0] = rrgbf[1] = rrgbf[2] = gray;
+                               } else {
+                                       rrgbf[0] = r;
+                                       rrgbf[1] = g;
+                                       rrgbf[2] = b;
+                               }
                        } else {
                                char *rrgb= (char*)ibuf->rect + pixel*4;
-
-                               if(track->flag&TRACK_DISABLE_RED)       rrgb[0]= 0;
-                               if(track->flag&TRACK_DISABLE_GREEN)     rrgb[1]= 0;
-                               if(track->flag&TRACK_DISABLE_BLUE)      rrgb[2]= 0;
+                               char r = (track->flag&TRACK_DISABLE_RED)   ? 0 : rrgb[0];
+                               char g = (track->flag&TRACK_DISABLE_GREEN) ? 0 : rrgb[1];
+                               char b = (track->flag&TRACK_DISABLE_BLUE)  ? 0 : rrgb[2];
+                               if (grayscale) {
+                                       float gray = (0.2126f*r + 0.7152f*g + 0.0722f*b) / scale;
+                                       rrgb[0] = rrgb[1] = rrgb[2] = gray;
+                               } else {
+                                       rrgb[0] = r;
+                                       rrgb[1] = g;
+                                       rrgb[2] = b;
+                               }
                        }
                }
        }
@@ -947,7 +1023,12 @@ static ImBuf *get_area_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTracki
                origin[1]= y1-margin;
        }
 
-       disable_imbuf_channels(tmpibuf, track);
+       if ((track->flag & TRACK_PREVIEW_GRAYSCALE) ||
+                       (track->flag & TRACK_DISABLE_RED)       ||
+                       (track->flag & TRACK_DISABLE_GREEN)     ||
+                       (track->flag & TRACK_DISABLE_BLUE) ) {
+               disable_imbuf_channels(tmpibuf, track, 1 /* grayscale */);
+       }
 
        return tmpibuf;
 }
@@ -976,7 +1057,7 @@ static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieT
        height= (track->search_max[1]-track->search_min[1])*ibuf->y;
 
        tmpibuf= BKE_tracking_get_search_imbuf(ibuf, track, marker, 0, 0, pos, origin);
-       disable_imbuf_channels(tmpibuf, track);
+       disable_imbuf_channels(tmpibuf, track, 0 /* don't grayscale */);
 
        *width_r= width;
        *height_r= height;
@@ -988,14 +1069,11 @@ static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieT
 
                        if(tmpibuf->rect_float) {
                                float *rrgbf= tmpibuf->rect_float + pixel*4;
-
                                *fp= 0.2126*rrgbf[0] + 0.7152*rrgbf[1] + 0.0722*rrgbf[2];
                        } else {
                                unsigned char *rrgb= (unsigned char*)tmpibuf->rect + pixel*4;
-
                                *fp= (0.2126*rrgb[0] + 0.7152*rrgb[1] + 0.0722*rrgb[2])/255.0f;
                        }
-
                        fp++;
                }
        }
@@ -1017,14 +1095,11 @@ static unsigned char *get_ucharbuf(ImBuf *ibuf)
 
                        if(ibuf->rect_float) {
                                float *rrgbf= ibuf->rect_float + pixel*4;
-
                                *cp= FTOCHAR(0.2126f*rrgbf[0] + 0.7152f*rrgbf[1] + 0.0722f*rrgbf[2]);
                        } else {
                                unsigned char *rrgb= (unsigned char*)ibuf->rect + pixel*4;
-
                                *cp= 0.2126f*rrgb[0] + 0.7152f*rrgb[1] + 0.0722f*rrgb[2];
                        }
-
                        cp++;
                }
        }
@@ -1039,7 +1114,7 @@ static unsigned char *get_search_bytebuf(ImBuf *ibuf, MovieTrackingTrack *track,
        unsigned char *pixels;
 
        tmpibuf= BKE_tracking_get_search_imbuf(ibuf, track, marker, 0, 0, pos, origin);
-       disable_imbuf_channels(tmpibuf, track);
+       disable_imbuf_channels(tmpibuf, track, 0 /* don't grayscale */);
 
        *width_r= tmpibuf->x;
        *height_r= tmpibuf->y;
@@ -1303,7 +1378,7 @@ int BKE_tracking_next(MovieTrackingContext *context)
                        }
 
                        coords_correct= !onbound && !isnan(x2) && !isnan(y2) && finite(x2) && finite(y2);
-                       if(coords_correct && (tracked || !context->disable_failed)) {
+                       if(coords_correct && !onbound && tracked) {
                                if(context->first_time) {
                                        #pragma omp critical
                                        {
@@ -1370,6 +1445,8 @@ typedef struct MovieReconstructContext {
 
        struct libmv_Reconstruction *reconstruction;
 #endif
+       char object_name[32];
+       int is_camera;
 
        float focal_length;
        float principal_point[2];
@@ -1391,13 +1468,13 @@ typedef struct ReconstructProgressData {
 } ReconstructProgressData;
 
 #if WITH_LIBMV
-static struct libmv_Tracks *create_libmv_tracks(MovieTracking *tracking, int width, int height)
+static struct libmv_Tracks *create_libmv_tracks(ListBase *tracksbase, int width, int height)
 {
        int tracknr= 0;
        MovieTrackingTrack *track;
        struct libmv_Tracks *tracks= libmv_tracksNew();
 
-       track= tracking->tracks.first;
+       track= tracksbase->first;
        while(track) {
                int a= 0;
 
@@ -1441,16 +1518,28 @@ static void retrieve_libmv_reconstruct_intrinscis(MovieReconstructContext *conte
 static int retrieve_libmv_reconstruct_tracks(MovieReconstructContext *context, MovieTracking *tracking)
 {
        struct libmv_Reconstruction *libmv_reconstruction= context->reconstruction;
-       MovieTrackingReconstruction *reconstruction= &tracking->reconstruction;
+       MovieTrackingReconstruction *reconstruction= NULL;
        MovieReconstructedCamera *reconstructed;
        MovieTrackingTrack *track;
+       ListBase *tracksbase=  NULL;
        int ok= 1, tracknr= 0, a, origin_set= 0;
        int sfra= context->sfra, efra= context->efra;
        float imat[4][4];
 
+       if(context->is_camera) {
+               tracksbase= &tracking->tracks;
+               reconstruction= &tracking->reconstruction;
+       }
+       else {
+               MovieTrackingObject *object= BKE_tracking_named_object(tracking, context->object_name);
+
+               tracksbase= &object->tracks;
+               reconstruction= &object->reconstruction;
+       }
+
        unit_m4(imat);
 
-       track= tracking->tracks.first;
+       track= tracksbase->first;
        while(track) {
                double pos[3];
 
@@ -1516,7 +1605,7 @@ static int retrieve_libmv_reconstruct_tracks(MovieReconstructContext *context, M
        }
 
        if(origin_set) {
-               track= tracking->tracks.first;
+               track= tracksbase->first;
                while(track) {
                        if(track->flag&TRACK_HAS_BUNDLE)
                                mul_v3_m4v3(track->bundle_pos, imat, track->bundle_pos);
@@ -1532,19 +1621,20 @@ static int retrieve_libmv_reconstruct_tracks(MovieReconstructContext *context, M
 
 static int retrieve_libmv_reconstruct(MovieReconstructContext *context, MovieTracking *tracking)
 {
-       tracks_map_merge(context->tracks_map, tracking);
-
        /* take the intrinscis back from libmv */
        retrieve_libmv_reconstruct_intrinscis(context, tracking);
 
        return retrieve_libmv_reconstruct_tracks(context, tracking);
 }
 
-static int get_refine_intrinsics_flags(MovieTracking *tracking)
+static int get_refine_intrinsics_flags(MovieTracking *tracking, MovieTrackingObject *object)
 {
        int refine= tracking->settings.refine_camera_intrinsics;
        int flags= 0;
 
+       if((object->flag&TRACKING_OBJECT_CAMERA)==0)
+               return 0;
+
        if(refine&REFINE_FOCAL_LENGTH)
                flags|= LIBMV_REFINE_FOCAL_LENGTH;
 
@@ -1560,13 +1650,13 @@ static int get_refine_intrinsics_flags(MovieTracking *tracking)
        return flags;
 }
 
-static int count_tracks_on_both_keyframes(MovieTracking *tracking)
+static int count_tracks_on_both_keyframes(MovieTracking *tracking, ListBase *tracksbase)
 {
        int tot= 0;
        int frame1= tracking->settings.keyframe1, frame2= tracking->settings.keyframe2;
        MovieTrackingTrack *track;
 
-       track= tracking->tracks.first;
+       track= tracksbase->first;
        while(track) {
                if(BKE_tracking_has_marker(track, frame1))
                        if(BKE_tracking_has_marker(track, frame2))
@@ -1579,10 +1669,12 @@ static int count_tracks_on_both_keyframes(MovieTracking *tracking)
 }
 #endif
 
-int BKE_tracking_can_reconstruct(MovieTracking *tracking, char *error_msg, int error_size)
+int BKE_tracking_can_reconstruct(MovieTracking *tracking, MovieTrackingObject *object, char *error_msg, int error_size)
 {
 #if WITH_LIBMV
-       if(count_tracks_on_both_keyframes(tracking)<8) {
+       ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object);
+
+       if(count_tracks_on_both_keyframes(tracking, tracksbase)<8) {
                BLI_strncpy(error_msg, "At least 8 tracks on both of keyframes are needed for reconstruction", error_size);
                return 0;
        }
@@ -1597,24 +1689,29 @@ int BKE_tracking_can_reconstruct(MovieTracking *tracking, char *error_msg, int e
 }
 
 MovieReconstructContext* BKE_tracking_reconstruction_context_new(MovieTracking *tracking,
-                       int keyframe1, int keyframe2, int width, int height)
+                       MovieTrackingObject *object, int keyframe1, int keyframe2, int width, int height)
 {
        MovieReconstructContext *context= MEM_callocN(sizeof(MovieReconstructContext), "MovieReconstructContext data");
        MovieTrackingCamera *camera= &tracking->camera;
+       ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object);
        float aspy= 1.0f/tracking->camera.pixel_aspect;
-       int num_tracks= BLI_countlist(&tracking->tracks);
+       int num_tracks= BLI_countlist(tracksbase);
        int sfra= INT_MAX, efra= INT_MIN;
        MovieTrackingTrack *track;
 
-       context->tracks_map= tracks_map_new(num_tracks, 0);
-       track= tracking->tracks.first;
+       strcpy(context->object_name, object->name);
+       context->is_camera = object->flag&TRACKING_OBJECT_CAMERA;
+
+       context->tracks_map= tracks_map_new(context->object_name, context->is_camera, num_tracks, 0);
+
+       track= tracksbase->first;
        while(track) {
-               int first= 0, last= track->markersnr;
+               int first= 0, last= track->markersnr-1;
                MovieTrackingMarker *first_marker= &track->markers[0];
                MovieTrackingMarker *last_marker= &track->markers[track->markersnr-1];
 
                /* find first not-disabled marker */
-               while(first<track->markersnr-1 && first_marker->flag&MARKER_DISABLED) {
+               while(first<=track->markersnr-1 && first_marker->flag&MARKER_DISABLED) {
                        first++;
                        first_marker++;
                }
@@ -1640,10 +1737,10 @@ MovieReconstructContext* BKE_tracking_reconstruction_context_new(MovieTracking *
        context->efra= efra;
 
 #ifdef WITH_LIBMV
-       context->tracks= create_libmv_tracks(tracking, width, height*aspy);
+       context->tracks= create_libmv_tracks(tracksbase, width, height*aspy);
        context->keyframe1= keyframe1;
        context->keyframe2= keyframe2;
-       context->refine_flags= get_refine_intrinsics_flags(tracking);
+       context->refine_flags= get_refine_intrinsics_flags(tracking, object);
 #else
        (void) width;
        (void) height;
@@ -1740,8 +1837,22 @@ void BKE_tracking_solve_reconstruction(MovieReconstructContext *context, short *
 
 int BKE_tracking_finish_reconstruction(MovieReconstructContext *context, MovieTracking *tracking)
 {
-       tracking->reconstruction.error= context->reprojection_error;
-       tracking->reconstruction.flag|= TRACKING_RECONSTRUCTED;
+       MovieTrackingReconstruction *reconstruction;
+
+       tracks_map_merge(context->tracks_map, tracking);
+
+       if(context->is_camera) {
+               reconstruction= &tracking->reconstruction;
+       }
+       else {
+               MovieTrackingObject *object;
+
+               object= BKE_tracking_named_object(tracking, context->object_name);
+               reconstruction= &object->reconstruction;
+       }
+
+       reconstruction->error= context->reprojection_error;
+       reconstruction->flag|= TRACKING_RECONSTRUCTED;
 
 #ifdef WITH_LIBMV
        if(!retrieve_libmv_reconstruct(context, tracking))
@@ -1751,14 +1862,15 @@ int BKE_tracking_finish_reconstruction(MovieReconstructContext *context, MovieTr
        return 1;
 }
 
-void BKE_track_unique_name(MovieTracking *tracking, MovieTrackingTrack *track)
+void BKE_track_unique_name(ListBase *tracksbase, MovieTrackingTrack *track)
 {
-       BLI_uniquename(&tracking->tracks, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name));
+       BLI_uniquename(tracksbase, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name));
 }
 
-MovieTrackingTrack *BKE_tracking_named_track(MovieTracking *tracking, const char *name)
+MovieTrackingTrack *BKE_tracking_named_track(MovieTracking *tracking, MovieTrackingObject *object, const char *name)
 {
-       MovieTrackingTrack *track= tracking->tracks.first;
+       ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object);
+       MovieTrackingTrack *track= tracksbase->first;
 
        while(track) {
                if(!strcmp(track->name, name))
@@ -1770,9 +1882,8 @@ MovieTrackingTrack *BKE_tracking_named_track(MovieTracking *tracking, const char
        return NULL;
 }
 
-static int reconstruction_camera_index(MovieTracking *tracking, int framenr, int nearest)
+static int reconstruction_camera_index(MovieTrackingReconstruction *reconstruction, int framenr, int nearest)
 {
-       MovieTrackingReconstruction *reconstruction= &tracking->reconstruction;
        MovieReconstructedCamera *cameras= reconstruction->cameras;
        int a= 0, d= 1;
 
@@ -1824,21 +1935,41 @@ static int reconstruction_camera_index(MovieTracking *tracking, int framenr, int
        return -1;
 }
 
-MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(MovieTracking *tracking, int framenr)
+static void scale_reconstructed_camera(MovieTrackingObject *object, float mat[4][4])
 {
-       int a= reconstruction_camera_index(tracking, framenr, 0);
+       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)
+{
+       MovieTrackingReconstruction *reconstruction;
+       int a;
+
+       reconstruction= BKE_tracking_object_reconstruction(tracking, object);
+       a= reconstruction_camera_index(reconstruction, framenr, 0);
 
        if(a==-1)
                return NULL;
 
-       return &tracking->reconstruction.cameras[a];
+       return &reconstruction->cameras[a];
 }
 
-void BKE_tracking_get_interpolated_camera(MovieTracking *tracking, int framenr, float mat[4][4])
+void BKE_tracking_get_interpolated_camera(MovieTracking *tracking, MovieTrackingObject *object,
+                       int framenr, float mat[4][4])
 {
-       MovieTrackingReconstruction *reconstruction= &tracking->reconstruction;
-       MovieReconstructedCamera *cameras= reconstruction->cameras;
-       int a= reconstruction_camera_index(tracking, framenr, 1);
+       MovieTrackingReconstruction *reconstruction;
+       MovieReconstructedCamera *cameras;
+       int a;
+
+       reconstruction= BKE_tracking_object_reconstruction(tracking, object);
+       cameras= reconstruction->cameras;
+       a= reconstruction_camera_index(reconstruction, framenr, 1);
 
        if(a==-1) {
                unit_m4(mat);
@@ -1852,6 +1983,8 @@ void BKE_tracking_get_interpolated_camera(MovieTracking *tracking, int framenr,
        } 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])
@@ -1890,7 +2023,8 @@ void BKE_tracking_camera_to_blender(MovieTracking *tracking, Scene *scene, Camer
        BKE_tracking_camera_shift(tracking, width, height, &camera->shiftx, &camera->shifty);
 }
 
-void BKE_tracking_projection_matrix(MovieTracking *tracking, int framenr, int winx, int winy, float mat[4][4])
+void BKE_tracking_projection_matrix(MovieTracking *tracking, MovieTrackingObject *object,
+                       int framenr, int winx, int winy, float mat[4][4])
 {
        MovieReconstructedCamera *camera;
        float lens= tracking->camera.focal*tracking->camera.sensor_width/(float)winx;
@@ -1923,7 +2057,8 @@ void BKE_tracking_projection_matrix(MovieTracking *tracking, int framenr, int wi
 
        perspective_m4(winmat, left, right, bottom, top, clipsta, clipend);
 
-       camera= BKE_tracking_get_reconstructed_camera(tracking, framenr);
+       camera= BKE_tracking_get_reconstructed_camera(tracking, object, framenr);
+
        if(camera) {
                float imat[4][4];
 
@@ -1932,6 +2067,77 @@ void BKE_tracking_projection_matrix(MovieTracking *tracking, int framenr, int wi
        } else copy_m4_m4(mat, winmat);
 }
 
+ListBase *BKE_tracking_get_tracks(MovieTracking *tracking)
+{
+       MovieTrackingObject *object= BKE_tracking_active_object(tracking);
+
+       if(object && (object->flag & TRACKING_OBJECT_CAMERA) == 0) {
+               return &object->tracks;
+       }
+
+       return &tracking->tracks;
+}
+
+MovieTrackingTrack *BKE_tracking_active_track(MovieTracking *tracking)
+{
+       ListBase *tracksbase;
+
+       if(!tracking->act_track)
+               return NULL;
+
+       tracksbase= BKE_tracking_get_tracks(tracking);
+
+       /* check that active track is in current tracks list */
+       if(BLI_findindex(tracksbase, tracking->act_track) >= 0)
+               return tracking->act_track;
+
+       return NULL;
+}
+
+MovieTrackingObject *BKE_tracking_active_object(MovieTracking *tracking)
+{
+       return BLI_findlink(&tracking->objects, tracking->objectnr);
+}
+
+MovieTrackingObject *BKE_tracking_get_camera_object(MovieTracking *tracking)
+{
+       MovieTrackingObject *object= tracking->objects.first;
+
+       while(object) {
+               if(object->flag & TRACKING_OBJECT_CAMERA)
+                       return object;
+
+               object= object->next;
+       }
+
+       return NULL;
+}
+
+ListBase *BKE_tracking_object_tracks(MovieTracking *tracking, MovieTrackingObject *object)
+{
+       if(object->flag & TRACKING_OBJECT_CAMERA) {
+               return &tracking->tracks;
+       }
+
+       return &object->tracks;
+}
+
+MovieTrackingReconstruction *BKE_tracking_object_reconstruction(MovieTracking *tracking, MovieTrackingObject *object)
+{
+       if(object->flag & TRACKING_OBJECT_CAMERA) {
+               return &tracking->reconstruction;
+       }
+
+       return &object->reconstruction;
+}
+
+MovieTrackingReconstruction *BKE_tracking_get_reconstruction(MovieTracking *tracking)
+{
+       MovieTrackingObject *object= BKE_tracking_active_object(tracking);
+
+       return BKE_tracking_object_reconstruction(tracking, object);
+}
+
 void BKE_tracking_apply_intrinsics(MovieTracking *tracking, float co[2], float nco[2])
 {
        MovieTrackingCamera *camera= &tracking->camera;
@@ -2018,8 +2224,9 @@ static int point_in_layer(bGPDlayer *layer, float x, float y)
        return 0;
 }
 
-static void retrieve_libmv_features(MovieTracking *tracking, struct libmv_Features *features,
-                       int framenr, int width, int height, bGPDlayer *layer, int place_outside_layer)
+static void retrieve_libmv_features(MovieTracking *tracking, ListBase *tracksbase,
+                       struct libmv_Features *features, int framenr, int width, int height,
+                       bGPDlayer *layer, int place_outside_layer)
 {
        int a;
 
@@ -2039,7 +2246,7 @@ static void retrieve_libmv_features(MovieTracking *tracking, struct libmv_Featur
                        ok= point_in_layer(layer, xu, yu)!=place_outside_layer;
 
                if(ok) {
-                       track= BKE_tracking_add_track(tracking, xu, yu, framenr, width, height);
+                       track= BKE_tracking_add_track(tracking, tracksbase, xu, yu, framenr, width, height);
                        track->flag|= SELECT;
                        track->pat_flag|= SELECT;
                        track->search_flag|= SELECT;
@@ -2048,7 +2255,7 @@ static void retrieve_libmv_features(MovieTracking *tracking, struct libmv_Featur
 }
 #endif
 
-void BKE_tracking_detect_fast(MovieTracking *tracking, ImBuf *ibuf,
+void BKE_tracking_detect_fast(MovieTracking *tracking, ListBase *tracksbase, ImBuf *ibuf,
                        int framenr, int margin, int min_trackness, int min_distance, bGPDlayer *layer,
                        int place_outside_layer)
 {
@@ -2056,11 +2263,13 @@ void BKE_tracking_detect_fast(MovieTracking *tracking, ImBuf *ibuf,
        struct libmv_Features *features;
        unsigned char *pixels= get_ucharbuf(ibuf);
 
-       features= libmv_detectFeaturesFAST(pixels, ibuf->x, ibuf->y, ibuf->x, margin, min_trackness, min_distance);
+       features= libmv_detectFeaturesFAST(pixels, ibuf->x, ibuf->y, ibuf->x,
+                       margin, min_trackness, min_distance);
 
        MEM_freeN(pixels);
 
-       retrieve_libmv_features(tracking, features, framenr, ibuf->x, ibuf->y, layer, place_outside_layer);
+       retrieve_libmv_features(tracking, tracksbase, features, framenr,
+                       ibuf->x, ibuf->y, layer, place_outside_layer);
 
        libmv_destroyFeatures(features);
 #else
@@ -2075,22 +2284,34 @@ void BKE_tracking_detect_fast(MovieTracking *tracking, ImBuf *ibuf,
 #endif
 }
 
-MovieTrackingTrack *BKE_tracking_indexed_track(MovieTracking *tracking, int tracknr)
+MovieTrackingTrack *BKE_tracking_indexed_track(MovieTracking *tracking, int tracknr, ListBase **tracksbase_r)
 {
-       MovieTrackingTrack *track= tracking->tracks.first;
+       MovieTrackingObject *object;
        int cur= 1;
 
-       while(track) {
-               if(track->flag&TRACK_HAS_BUNDLE) {
-                       if(cur==tracknr)
-                               return track;
+       object= tracking->objects.first;
+       while(object) {
+               ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object);
+               MovieTrackingTrack *track= tracksbase->first;
+
+               while(track) {
+                       if(track->flag&TRACK_HAS_BUNDLE) {
+                               if(cur==tracknr) {
+                                       *tracksbase_r= tracksbase;
+                                       return track;
+                               }
+
+                               cur++;
+                       }
 
-                       cur++;
+                       track= track->next;
                }
 
-               track= track->next;
+               object= object->next;
        }
 
+       *tracksbase_r= NULL;
+
        return NULL;
 }
 
@@ -2102,6 +2323,8 @@ static int stabilization_median_point(MovieTracking *tracking, int framenr, floa
 
        INIT_MINMAX2(min, max);
 
+       (void) tracking;
+
        track= tracking->tracks.first;
        while(track) {
                if(track->flag&TRACK_USE_2D_STAB) {
@@ -2539,12 +2762,12 @@ ImBuf *BKE_tracking_distort(MovieTracking *tracking, ImBuf *ibuf, int width, int
 }
 
 /* area - which part of marker should be selected. see TRACK_AREA_* constants */
-void BKE_tracking_select_track(MovieTracking *tracking, MovieTrackingTrack *track, int area, int extend)
+void BKE_tracking_select_track(ListBase *tracksbase, MovieTrackingTrack *track, int area, int extend)
 {
        if(extend) {
                BKE_tracking_track_flag(track, area, SELECT, 0);
        } else {
-               MovieTrackingTrack *cur= tracking->tracks.first;
+               MovieTrackingTrack *cur= tracksbase->first;
 
                while(cur) {
                        if(cur==track) {
@@ -2564,3 +2787,78 @@ void BKE_tracking_deselect_track(MovieTrackingTrack *track, int area)
 {
        BKE_tracking_track_flag(track, area, SELECT, 1);
 }
+
+MovieTrackingObject *BKE_tracking_new_object(MovieTracking *tracking, const char *name)
+{
+       MovieTrackingObject *object= MEM_callocN(sizeof(MovieTrackingObject), "tracking object");
+
+       if(tracking->tot_object==0) {
+               /* first object is always camera */
+               BLI_strncpy(object->name, "Camera", sizeof(object->name));
+
+               object->flag|= TRACKING_OBJECT_CAMERA;
+       }
+       else {
+               BLI_strncpy(object->name, name, sizeof(object->name));
+       }
+
+       BLI_addtail(&tracking->objects, object);
+
+       tracking->tot_object++;
+       tracking->objectnr= BLI_countlist(&tracking->objects) - 1;
+
+       BKE_tracking_object_unique_name(tracking, object);
+
+       return object;
+}
+
+void BKE_tracking_remove_object(MovieTracking *tracking, MovieTrackingObject *object)
+{
+       MovieTrackingTrack *track;
+       int index= BLI_findindex(&tracking->objects, object);
+
+       if(index<0)
+               return;
+
+       if(object->flag & TRACKING_OBJECT_CAMERA) {
+               /* object used for camera solving can't be deleted */
+               return;
+       }
+
+       track= object->tracks.first;
+       while(track) {
+               if(track==tracking->act_track)
+                       tracking->act_track= NULL;
+
+               track= track->next;
+       }
+
+       tracking_object_free(object);
+       BLI_freelinkN(&tracking->objects, object);
+
+       tracking->tot_object--;
+
+       if(index>0)
+               tracking->objectnr= index-1;
+       else
+               tracking->objectnr= 0;
+}
+
+void BKE_tracking_object_unique_name(MovieTracking *tracking, MovieTrackingObject *object)
+{
+       BLI_uniquename(&tracking->objects, object, "Object", '.', offsetof(MovieTrackingObject, name), sizeof(object->name));
+}
+
+MovieTrackingObject *BKE_tracking_named_object(MovieTracking *tracking, const char *name)
+{
+       MovieTrackingObject *object= tracking->objects.first;
+
+       while(object) {
+               if(!strcmp(object->name, name))
+                       return object;
+
+               object= object->next;
+       }
+
+       return NULL;
+}
index ee9cbaf1f81242593de187c27fe9bfdd37df5146..cd54c944ba9c84b89d084b761fa007ee0c82220a 100644 (file)
@@ -195,8 +195,14 @@ void mul_m3_m3m3(float m1[][3], float m3_[][3], float m2_[][3])
        m1[2][2]= m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2]; 
 }
 
-void mul_m4_m4m3(float (*m1)[4], float (*m3)[4], float (*m2)[3])
+void mul_m4_m4m3(float (*m1)[4], float (*m3_)[4], float (*m2_)[3])
 {
+       float m2[3][3], m3[4][4];
+
+       /* copy so it works when m1 is the same pointer as m2 or m3 */
+       copy_m3_m3(m2, m2_);
+       copy_m4_m4(m3, m3_);
+
        m1[0][0]= m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0];
        m1[0][1]= m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1];
        m1[0][2]= m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2];
index 8a1240102164a4b816f24ccf18c7fd8b507936e9..122e66160d61a843b05047e92a7860e546a755cc 100644 (file)
@@ -6048,10 +6048,29 @@ static void lib_link_group(FileData *fd, Main *main)
 
 /* ***************** READ MOVIECLIP *************** */
 
+static void direct_link_movieReconstruction(FileData *fd, MovieTrackingReconstruction *reconstruction)
+{
+       reconstruction->cameras= newdataadr(fd, reconstruction->cameras);
+}
+
+static void direct_link_movieTracks(FileData *fd, ListBase *tracksbase)
+{
+       MovieTrackingTrack *track;
+
+       link_list(fd, tracksbase);
+
+       track= tracksbase->first;
+       while(track) {
+               track->markers= newdataadr(fd, track->markers);
+
+               track= track->next;
+       }
+}
+
 static void direct_link_movieclip(FileData *fd, MovieClip *clip)
 {
        MovieTracking *tracking= &clip->tracking;
-       MovieTrackingTrack *track;
+       MovieTrackingObject *object;
 
        if(fd->movieclipmap) clip->cache= newmclipadr(fd, clip->cache);
        else clip->cache= NULL;
@@ -6059,16 +6078,8 @@ static void direct_link_movieclip(FileData *fd, MovieClip *clip)
        if(fd->movieclipmap) clip->tracking.camera.intrinsics= newmclipadr(fd, clip->tracking.camera.intrinsics);
        else clip->tracking.camera.intrinsics= NULL;
 
-       tracking->reconstruction.cameras= newdataadr(fd, tracking->reconstruction.cameras);
-
-       link_list(fd, &tracking->tracks);
-
-       track= tracking->tracks.first;
-       while(track) {
-               track->markers= newdataadr(fd, track->markers);
-
-               track= track->next;
-       }
+       direct_link_movieTracks(fd, &tracking->tracks);
+       direct_link_movieReconstruction(fd, &tracking->reconstruction);
 
        clip->tracking.act_track= newdataadr(fd, clip->tracking.act_track);
 
@@ -6079,6 +6090,16 @@ static void direct_link_movieclip(FileData *fd, MovieClip *clip)
        clip->tracking.stabilization.ok= 0;
        clip->tracking.stabilization.scaleibuf= NULL;
        clip->tracking.stabilization.rot_track= newdataadr(fd, clip->tracking.stabilization.rot_track);
+
+       link_list(fd, &tracking->objects);
+
+       object= tracking->objects.first;
+       while(object) {
+               direct_link_movieTracks(fd, &object->tracks);
+               direct_link_movieReconstruction(fd, &object->reconstruction);
+
+               object= object->next;
+       }
 }
 
 static void lib_link_movieclip(FileData *fd, Main *main)
@@ -12852,8 +12873,43 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
                {
                        MovieClip *clip;
-                       for(clip= main->movieclip.first; clip; clip= clip->id.next) {
+                       Object *ob;
+
+                       for (clip= main->movieclip.first; clip; clip= clip->id.next) {
+                               MovieTracking *tracking= &clip->tracking;
+                               MovieTrackingObject *tracking_object= tracking->objects.first;
+
                                clip->proxy.build_tc_flag|= IMB_TC_RECORD_RUN_NO_GAPS;
+
+                               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) {
+                               bConstraint *con;
+                               for (con= ob->constraints.first; con; con=con->next) {
+                                       bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+
+                                       if(!cti)
+                                               continue;
+
+                                       if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER) {
+                                               bObjectSolverConstraint *data= (bObjectSolverConstraint *)con->data;
+
+                                               if(data->invmat[3][3]==0.0f)
+                                                       unit_m4(data->invmat);
+                                       }
+                               }
                        }
                }
        }
index ac2eef4544273f56cd154f89b3ee3b887a4b275e..ecb655dbaf7535d3852cc93721acdce13b49240b 100644 (file)
@@ -2618,6 +2618,27 @@ static void write_scripts(WriteData *wd, ListBase *idbase)
        }
 }
 
+static void write_movieTracks(WriteData *wd, ListBase *tracks)
+{
+       MovieTrackingTrack *track;
+
+       track= tracks->first;
+       while(track) {
+               writestruct(wd, DATA, "MovieTrackingTrack", 1, track);
+
+               if(track->markers)
+                       writestruct(wd, DATA, "MovieTrackingMarker", track->markersnr, track->markers);
+
+               track= track->next;
+       }
+}
+
+static void write_movieReconstruction(WriteData *wd, MovieTrackingReconstruction *reconstruction)
+{
+       if(reconstruction->camnr)
+               writestruct(wd, DATA, "MovieReconstructedCamera", reconstruction->camnr, reconstruction->cameras);
+}
+
 static void write_movieclips(WriteData *wd, ListBase *idbase)
 {
        MovieClip *clip;
@@ -2626,20 +2647,20 @@ static void write_movieclips(WriteData *wd, ListBase *idbase)
        while(clip) {
                if(clip->id.us>0 || wd->current) {
                        MovieTracking *tracking= &clip->tracking;
-                       MovieTrackingTrack *track;
+                       MovieTrackingObject *object;
                        writestruct(wd, ID_MC, "MovieClip", 1, clip);
 
-                       if(tracking->reconstruction.camnr)
-                               writestruct(wd, DATA, "MovieReconstructedCamera", tracking->reconstruction.camnr, tracking->reconstruction.cameras);
+                       write_movieTracks(wd, &tracking->tracks);
+                       write_movieReconstruction(wd, &tracking->reconstruction);
 
-                       track= tracking->tracks.first;
-                       while(track) {
-                               writestruct(wd, DATA, "MovieTrackingTrack", 1, track);
+                       object= tracking->objects.first;
+                       while(object) {
+                               writestruct(wd, DATA, "MovieTrackingObject", 1, object);
 
-                               if(track->markers)
-                                       writestruct(wd, DATA, "MovieTrackingMarker", track->markersnr, track->markers);
+                               write_movieTracks(wd, &object->tracks);
+                               write_movieReconstruction(wd, &object->reconstruction);
 
-                               track= track->next;
+                               object= object->next;
                        }
                }
 
index cd3d87a89790e66765e3d68eb0d88ecbd1c5060a..33e9192a23e15f1db7ecfeecfb9fd0011533a03a 100644 (file)
@@ -136,13 +136,8 @@ void glaDrawPixelsSafe             (float x, float y, int img_w, int img_h, int row_w, int
         * is expected to be in RGBA byte or float format, and the 
         * modelview and projection matrices are assumed to define a 
         * 1-to-1 mapping to screen space.
-        * @param gamma_correct Optionally gamma correct float sources to sRGB for display
         */
 
-       /* only for float rects, converts to 32 bits and draws */
-void glaDrawPixelsSafe_to32(float fx, float fy, int img_w, int img_h, int row_w, float *rectf, int gamma_correct);
-
-
 void glaDrawPixelsTex          (float x, float y, int img_w, int img_h, int format, void *rect);
 
 void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, void *rect, float scaleX, float scaleY);
index 7dd07db9b30b2d896095c165e5a1c00154152da3..6ebb67af67a9ac174a530cdcd31765b1652fa7aa 100644 (file)
@@ -1465,6 +1465,8 @@ static ImBuf *scale_trackpreview_ibuf(ImBuf *ibuf, float zoomx, float zoomy)
 {
        ImBuf *scaleibuf;
        int x, y, w= ibuf->x*zoomx, h= ibuf->y*zoomy;
+       const float max_x= ibuf->x-1.0f;
+       const float max_y= ibuf->y-1.0f;
        const float scalex= 1.0f/zoomx;
        const float scaley= 1.0f/zoomy;
 
@@ -1472,15 +1474,13 @@ static ImBuf *scale_trackpreview_ibuf(ImBuf *ibuf, float zoomx, float zoomy)
 
        for(y= 0; y<scaleibuf->y; y++) {
                for (x= 0; x<scaleibuf->x; x++) {
-                       int pixel= scaleibuf->x*y + x;
-                       int orig_pixel= ibuf->x*(int)(scaley*(float)y) + (int)(scalex*(float)x);
-                       char *rrgb= (char*)scaleibuf->rect + pixel*4;
-                       char *orig_rrgb= (char*)ibuf->rect + orig_pixel*4;
-
-                       rrgb[0]= orig_rrgb[0];
-                       rrgb[1]= orig_rrgb[1];
-                       rrgb[2]= orig_rrgb[2];
-                       rrgb[3]= orig_rrgb[3];
+                       float src_x= scalex*x;
+                       float src_y= scaley*y;
+
+                       CLAMP(src_x, 0, max_x);
+                       CLAMP(src_y, 0, max_y);
+
+                       bicubic_interpolation(ibuf, scaleibuf, src_x, src_y, x, y);
                }
        }
 
index 63f6309163e4fbb22fa335b1affa10429315b9e3..6b842a6d40906cd4f87a90e209403b2ba74aab3d 100644 (file)
@@ -2201,6 +2201,17 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
                }
                uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "is_active", i, 0, 0, 0, 0,  NULL);
        }
+       else if(itemptr->type == &RNA_MovieTrackingObject) {
+               MovieTrackingObject *tracking_object= (MovieTrackingObject*)itemptr->data;
+
+               split= uiLayoutSplit(sub, 0.75f, 0);
+               if(tracking_object->flag&TRACKING_OBJECT_CAMERA) {
+                       uiItemL(split, name, ICON_CAMERA_DATA);
+               }
+               else {
+                       uiItemL(split, name, ICON_OBJECT_DATA);
+               }
+       }
 
        /* There is a last chance to display custom controls (in addition to the name/label):
         * If the given item property group features a string property named as prop_list,
index 796ca01a6a953748ce29772681991228f42b76e7..8266f3501c5acce73c4a6ed297663885dced0052 100644 (file)
@@ -408,8 +408,21 @@ static void test_constraints (Object *owner, bPoseChannel *pchan)
 
                                if((data->flag&CAMERASOLVER_ACTIVECLIP)==0) {
                                        if(data->clip != NULL && data->track[0]) {
-                                               if (!BKE_tracking_named_track(&data->clip->tracking, data->track))
+                                               MovieTracking *tracking= &data->clip->tracking;
+                                               MovieTrackingObject *tracking_object;
+
+                                               if(data->object[0])
+                                                       tracking_object= BKE_tracking_named_object(tracking, data->object);
+                                               else
+                                                       tracking_object= BKE_tracking_get_camera_object(tracking);
+
+                                               if(!tracking_object) {
                                                        curcon->flag |= CONSTRAINT_DISABLE;
+                                               }
+                                               else {
+                                                       if (!BKE_tracking_named_track(tracking, tracking_object, data->track))
+                                                               curcon->flag |= CONSTRAINT_DISABLE;
+                                               }
                                        }
                                        else curcon->flag |= CONSTRAINT_DISABLE;
                                }
@@ -420,6 +433,12 @@ static void test_constraints (Object *owner, bPoseChannel *pchan)
                                if((data->flag&CAMERASOLVER_ACTIVECLIP)==0 && data->clip == NULL)
                                        curcon->flag |= CONSTRAINT_DISABLE;
                        }
+                       else if (curcon->type == CONSTRAINT_TYPE_OBJECTSOLVER) {
+                               bObjectSolverConstraint *data = curcon->data;
+
+                               if((data->flag&CAMERASOLVER_ACTIVECLIP)==0 && data->clip == NULL)
+                                       curcon->flag |= CONSTRAINT_DISABLE;
+                       }
                        
                        /* Check targets for constraints */
                        if (cti && cti->get_constraint_targets) {
@@ -684,25 +703,13 @@ void CONSTRAINT_OT_limitdistance_reset (wmOperatorType *ot)
 
 /* ------------- Child-Of Constraint ------------------ */
 
-/* ChildOf Constraint - set inverse callback */
-static int childof_set_inverse_exec (bContext *C, wmOperator *op)
+static void child_get_inverse_matrix (Scene *scene, Object *ob, bConstraint *con, float invmat[4][4])
 {
-       Scene *scene= CTX_data_scene(C);
-       Object *ob = ED_object_active_context(C);
-       bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_CHILDOF);
-       bChildOfConstraint *data= (con) ? (bChildOfConstraint *)con->data : NULL;
        bConstraint *lastcon = NULL;
        bPoseChannel *pchan= NULL;
        
-       /* despite 3 layers of checks, we may still not be able to find a constraint */
-       if (data == NULL) {
-               printf("DEBUG: Child-Of Set Inverse - object = '%s'\n", (ob)? ob->id.name+2 : "<None>");
-               BKE_report(op->reports, RPT_ERROR, "Couldn't find constraint data for Child-Of Set Inverse");
-               return OPERATOR_CANCELLED;
-       }
-       
        /* nullify inverse matrix first */
-       unit_m4(data->invmat);
+       unit_m4(invmat);
        
        /* try to find a pose channel - assume that this is the constraint owner */
        // TODO: get from context instead?
@@ -748,7 +755,7 @@ static int childof_set_inverse_exec (bContext *C, wmOperator *op)
                 */
                invert_m4_m4(imat, pchan->pose_mat);
                mult_m4_m4m4(tmat, pmat, imat);
-               invert_m4_m4(data->invmat, tmat);
+               invert_m4_m4(invmat, tmat);
                
                /* 5. restore constraints */
                pchan->constraints.last = lastcon;
@@ -770,9 +777,27 @@ static int childof_set_inverse_exec (bContext *C, wmOperator *op)
                
                /* use what_does_parent to find inverse - just like for normal parenting */
                what_does_parent(scene, ob, &workob);
-               invert_m4_m4(data->invmat, workob.obmat);
+               invert_m4_m4(invmat, workob.obmat);
+       }
+}
+
+/* ChildOf Constraint - set inverse callback */
+static int childof_set_inverse_exec (bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       Object *ob = ED_object_active_context(C);
+       bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_CHILDOF);
+       bChildOfConstraint *data= (con) ? (bChildOfConstraint *)con->data : NULL;
+
+       /* despite 3 layers of checks, we may still not be able to find a constraint */
+       if (data == NULL) {
+               printf("DEBUG: Child-Of Set Inverse - object = '%s'\n", (ob)? ob->id.name+2 : "<None>");
+               BKE_report(op->reports, RPT_ERROR, "Couldn't find constraint data for Child-Of Set Inverse");
+               return OPERATOR_CANCELLED;
        }
        
+       child_get_inverse_matrix(scene, ob, con, data->invmat);
+
        WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
        
        return OPERATOR_FINISHED;
@@ -846,6 +871,96 @@ void CONSTRAINT_OT_childof_clear_inverse (wmOperatorType *ot)
        edit_constraint_properties(ot);
 }
 
+/* ------------- Object Solver Constraint ------------------ */
+
+static int objectsolver_set_inverse_exec (bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       Object *ob = ED_object_active_context(C);
+       bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_OBJECTSOLVER);
+       bObjectSolverConstraint *data= (con) ? (bObjectSolverConstraint *)con->data : NULL;
+
+       /* despite 3 layers of checks, we may still not be able to find a constraint */
+       if (data == NULL) {
+               printf("DEBUG: Child-Of Set Inverse - object = '%s'\n", (ob)? ob->id.name+2 : "<None>");
+               BKE_report(op->reports, RPT_ERROR, "Couldn't find constraint data for Child-Of Set Inverse");
+               return OPERATOR_CANCELLED;
+       }
+
+       child_get_inverse_matrix(scene, ob, con, data->invmat);
+
+       WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
+
+       return OPERATOR_FINISHED;
+}
+
+static int objectsolver_set_inverse_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+{
+       if (edit_constraint_invoke_properties(C, op))
+               return objectsolver_set_inverse_exec(C, op);
+       else
+               return OPERATOR_CANCELLED;
+}
+
+void CONSTRAINT_OT_objectsolver_set_inverse (wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Set Inverse";
+       ot->idname= "CONSTRAINT_OT_objectsolver_set_inverse";
+       ot->description= "Set inverse correction for ObjectSolver constraint";
+
+       ot->exec= objectsolver_set_inverse_exec;
+       ot->invoke= objectsolver_set_inverse_invoke;
+       ot->poll= edit_constraint_poll;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       edit_constraint_properties(ot);
+}
+
+static int objectsolver_clear_inverse_exec (bContext *C, wmOperator *op)
+{
+       Object *ob = ED_object_active_context(C);
+       bConstraint *con = edit_constraint_property_get(op, ob, CONSTRAINT_TYPE_OBJECTSOLVER);
+       bObjectSolverConstraint *data= (con) ? (bObjectSolverConstraint *)con->data : NULL;
+
+       if(data==NULL) {
+               BKE_report(op->reports, RPT_ERROR, "Childof constraint not found");
+               return OPERATOR_CANCELLED;
+       }
+
+       /* simply clear the matrix */
+       unit_m4(data->invmat);
+
+       WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
+
+       return OPERATOR_FINISHED;
+}
+
+static int objectsolver_clear_inverse_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+{
+       if (edit_constraint_invoke_properties(C, op))
+               return objectsolver_clear_inverse_exec(C, op);
+       else
+               return OPERATOR_CANCELLED;
+}
+
+void CONSTRAINT_OT_objectsolver_clear_inverse (wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Clear Inverse";
+       ot->idname= "CONSTRAINT_OT_objectsolver_clear_inverse";
+       ot->description= "Clear inverse correction for ObjectSolver constraint";
+
+       ot->exec= objectsolver_clear_inverse_exec;
+       ot->invoke= objectsolver_clear_inverse_invoke;
+       ot->poll= edit_constraint_poll;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       edit_constraint_properties(ot);
+}
+
 /***************************** BUTTONS ****************************/
 
 void ED_object_constraint_set_active(Object *ob, bConstraint *con)
index 29c6350452ceb586d4e3ea6b2246f042b8dd2f0f..bb7d2e1bc7cc3a54c1996e578dc7b1381db535d4 100644 (file)
@@ -187,6 +187,8 @@ void CONSTRAINT_OT_stretchto_reset(struct wmOperatorType *ot);
 void CONSTRAINT_OT_limitdistance_reset(struct wmOperatorType *ot);
 void CONSTRAINT_OT_childof_set_inverse(struct wmOperatorType *ot);
 void CONSTRAINT_OT_childof_clear_inverse(struct wmOperatorType *ot);
+void CONSTRAINT_OT_objectsolver_set_inverse(struct wmOperatorType *ot);
+void CONSTRAINT_OT_objectsolver_clear_inverse (struct wmOperatorType *ot);
 
 /* object_vgroup.c */
 void OBJECT_OT_vertex_group_add(struct wmOperatorType *ot);
index f6b4656af7ecb655a557abbda8354232fb5e6ca9..054aafe5a99129db9f747001f1abcd358c4ae7b1 100644 (file)
@@ -161,6 +161,8 @@ void ED_operatortypes_object(void)
        WM_operatortype_append(CONSTRAINT_OT_limitdistance_reset);
        WM_operatortype_append(CONSTRAINT_OT_childof_set_inverse);
        WM_operatortype_append(CONSTRAINT_OT_childof_clear_inverse);
+       WM_operatortype_append(CONSTRAINT_OT_objectsolver_set_inverse);
+       WM_operatortype_append(CONSTRAINT_OT_objectsolver_clear_inverse);
 
        WM_operatortype_append(OBJECT_OT_vertex_group_add);
        WM_operatortype_append(OBJECT_OT_vertex_group_remove);
index bff93fea0677c64b44174dd19fcb4234c8f88b44..e4597d6afc38e2384b22ae026607badca6549be4 100644 (file)
@@ -138,11 +138,14 @@ void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volat
        rectf+= 4*(rr->rectx*ymin + xmin);
        rectc= (unsigned char*)(ibuf->rect + ibuf->x*rymin + rxmin);
 
-       if(scene && (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT))
+       if(scene && (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT)) {
                profile_from= IB_PROFILE_LINEAR_RGB;
-       else
+               predivide= (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
+       }
+       else {
                profile_from= IB_PROFILE_SRGB;
-       predivide= 0;
+               predivide= 0;
+       }
 
        IMB_buffer_byte_from_float(rectc, rectf,
                4, ibuf->dither, IB_PROFILE_SRGB, profile_from, predivide,
index feff1e05d6074e77c6205dcf60b58cee2ad7132b..86328ca2a6406d54ba7225da3b0e533fd10701b4 100644 (file)
@@ -460,12 +460,15 @@ static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int
        Render *re;
        RenderResult rres;
        char name[32];
-       int do_gamma_correct=0;
+       int do_gamma_correct=0, do_predivide=0;
        int offx=0, newx= rect->xmax-rect->xmin, newy= rect->ymax-rect->ymin;
 
        if (id && GS(id->name) != ID_TE) {
                /* exception: don't color manage texture previews - show the raw values */
-               if (sce) do_gamma_correct = sce->r.color_mgt_flag & R_COLOR_MANAGEMENT;
+               if (sce) {
+                       do_gamma_correct = sce->r.color_mgt_flag & R_COLOR_MANAGEMENT;
+                       do_predivide = sce->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE;
+               }
        }
 
        if(!split || first) sprintf(name, "Preview %p", (void *)sa);
@@ -488,10 +491,28 @@ static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int
        if(rres.rectf) {
                
                if(ABS(rres.rectx-newx)<2 && ABS(rres.recty-newy)<2) {
+
                        newrect->xmax= MAX2(newrect->xmax, rect->xmin + rres.rectx + offx);
                        newrect->ymax= MAX2(newrect->ymax, rect->ymin + rres.recty);
 
-                       glaDrawPixelsSafe_to32(rect->xmin+offx, rect->ymin, rres.rectx, rres.recty, rres.rectx, rres.rectf, do_gamma_correct);
+                       if(rres.rectx && rres.recty) {
+                               /* temporary conversion to byte for drawing */
+                               float fx= rect->xmin + offx;
+                               float fy= rect->ymin;
+                               int profile_from= (do_gamma_correct)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
+                               int dither= 0;
+                               unsigned char *rect_byte;
+
+                               rect_byte= MEM_mallocN(rres.rectx*rres.recty*sizeof(int), "ed_preview_draw_rect");
+
+                               IMB_buffer_byte_from_float(rect_byte, rres.rectf,
+                                       4, dither, IB_PROFILE_SRGB, profile_from, do_predivide, 
+                                       rres.rectx, rres.recty, rres.rectx, rres.rectx);
+
+                               glaDrawPixelsSafe(fx, fy, rres.rectx, rres.recty, rres.rectx, GL_RGBA, GL_UNSIGNED_BYTE, rect_byte);
+
+                               MEM_freeN(rect_byte);
+                       }
 
                        RE_ReleaseResultImage(re);
                        return 1;
index 8f04940efd6541af0c7172a8d6df983bb276b587..0b231ee7b96f5d9ae63ee38597a377b9868be9b1 100644 (file)
@@ -45,9 +45,6 @@
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
 
-#include "IMB_imbuf.h"
-#include "IMB_imbuf_types.h"
-
 #ifndef GL_CLAMP_TO_EDGE
 #define GL_CLAMP_TO_EDGE                        0x812F
 #endif
@@ -562,27 +559,6 @@ void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, void *
        glaDrawPixelsTexScaled(x, y, img_w, img_h, format, rect, 1.0f, 1.0f);
 }
 
-/* row_w is unused but kept for completeness */
-void glaDrawPixelsSafe_to32(float fx, float fy, int img_w, int img_h, int UNUSED(row_w), float *rectf, int do_gamma_correct)
-{
-       unsigned char *rect32;
-       int profile_from= (do_gamma_correct)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
-       int predivide= 0;
-       
-       /* copy imgw-imgh to a temporal 32 bits rect */
-       if(img_w<1 || img_h<1) return;
-       
-       rect32= MEM_mallocN(img_w*img_h*sizeof(int), "temp 32 bits");
-       
-       IMB_buffer_byte_from_float(rect32, rectf,
-               4, 0, IB_PROFILE_SRGB, profile_from, predivide, 
-               img_w, img_h, img_w, img_w);
-       
-       glaDrawPixelsSafe(fx, fy, img_w, img_h, img_w, GL_RGBA, GL_UNSIGNED_BYTE, rect32);
-
-       MEM_freeN(rect32);
-}
-
 void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int format, int type, void *rect)
 {
        float xzoom= glaGetOneFloat(GL_ZOOM_X);
index 860afdb2b50dfd1bf784dbe7dfb9d85efb821434..e827e16f6436e5542e8aee10f499142a68b3e5c5 100644 (file)
@@ -1222,14 +1222,14 @@ static void do_weight_paint_auto_normalize_all_groups(MDeformVert *dvert, const
 See if the current deform vertex has a locked group
 */
 static char has_locked_group(MDeformVert *dvert, const int defbase_tot,
-                             const char *lock_flags)
+                             const char *bone_groups, const char *lock_flags)
 {
        int i;
        MDeformWeight *dw;
 
        for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) {
                if (dw->def_nr < defbase_tot) {
-                       if (lock_flags[dw->def_nr] && dw->weight > 0.0f) {
+                       if (bone_groups[dw->def_nr] && lock_flags[dw->def_nr] && dw->weight > 0.0f) {
                                return TRUE;
                        }
                }
@@ -1406,7 +1406,7 @@ static void enforce_locks(MDeformVert *odv, MDeformVert *ndv,
 
        char *change_status;
 
-       if(!lock_flags || !has_locked_group(ndv, defbase_tot, lock_flags)) {
+       if(!lock_flags || !has_locked_group(ndv, defbase_tot, vgroup_validmap, lock_flags)) {
                return;
        }
        /* record if a group was changed, unlocked and not changed, or locked */
@@ -1679,7 +1679,7 @@ static void do_weight_paint_vertex( /* vars which remain the same for every vert
        /* If there are no locks or multipaint,
         * then there is no need to run the more complicated checks */
        if ( (wpi->do_multipaint == FALSE || wpi->defbase_tot_sel <= 1) &&
-            (wpi->lock_flags == NULL || has_locked_group(dv, wpi->defbase_tot, wpi->lock_flags) == FALSE))
+            (wpi->lock_flags == NULL || has_locked_group(dv, wpi->defbase_tot, wpi->vgroup_validmap, wpi->lock_flags) == FALSE))
        {
                wpaint_blend(wp, dw, uw, alpha, paintweight, wpi->do_flip, FALSE);
 
@@ -1961,12 +1961,13 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *UNUSED
        Object *ob= CTX_data_active_object(C);
        struct WPaintData *wpd;
        Mesh *me;
-
-//     bDeformGroup *dg;
+       bDeformGroup *dg;
 
        float mat[4][4], imat[4][4];
        
-       if(scene->obedit) return OPERATOR_CANCELLED;
+       if(scene->obedit) {
+               return FALSE;
+       }
        
        me= get_mesh(ob);
        if(me==NULL || me->totpoly==0) return OPERATOR_PASS_THROUGH;
@@ -2005,22 +2006,17 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *UNUSED
 
        /* ensure we dont try paint onto an invalid group */
        if (ob->actdef <= 0) {
-               return OPERATOR_PASS_THROUGH;
+               BKE_report(op->reports, RPT_WARNING, "No active vertex group for painting, aborting");
+               return FALSE;
        }
 
-#if 0
        /* check if we are attempting to paint onto a locked vertex group,
         * and other options disallow it from doing anything useful */
        dg = BLI_findlink(&ob->defbase, (ob->actdef-1));
-       if ( (dg->flag & DG_LOCK_WEIGHT) &&
-            (ts->auto_normalize == FALSE) &&
-            (ts->multipaint == FALSE) )
-       {
-               BKE_report(op->reports, RPT_WARNING, "Active group is locked, multi-paint/normalize disabled, aborting");
-
-               return OPERATOR_CANCELLED;
+       if (dg->flag & DG_LOCK_WEIGHT) {
+               BKE_report(op->reports, RPT_WARNING, "Active group is locked, aborting");
+               return FALSE;
        }
-#endif
 
        /* ALLOCATIONS! no return after this line */
        /* make mode data storage */
@@ -2054,7 +2050,7 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *UNUSED
                wpd->vgroup_mirror = wpaint_mirror_vgroup_ensure(ob, wpd->vgroup_active);
        }
        
-       return 1;
+       return TRUE;
 }
 
 static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr)
index 3f9ec3f3c8292692951077a3d0f35a0973e58162..ca2646e9967a03905daa347e93ee167ab29f7010 100644 (file)
@@ -96,6 +96,8 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
        float x;
        int *points, totseg, i, a;
        float sfra= SFRA, efra= EFRA, framelen= ar->winx/(efra-sfra+1);
+       MovieTrackingTrack *act_track= BKE_tracking_active_track(&clip->tracking);
+       MovieTrackingReconstruction *reconstruction= BKE_tracking_get_reconstruction(&clip->tracking);
 
        glEnable(GL_BLEND);
 
@@ -119,8 +121,8 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
        }
 
        /* track */
-       if(clip->tracking.act_track) {
-               MovieTrackingTrack *track= clip->tracking.act_track;
+       if(act_track) {
+               MovieTrackingTrack *track= act_track;
 
                for(i= sfra, a= 0; i <= efra; i++) {
                        int framenr;
@@ -152,9 +154,9 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
        }
 
        /* failed frames */
-       if(clip->tracking.reconstruction.flag&TRACKING_RECONSTRUCTED) {
-               int n= clip->tracking.reconstruction.camnr;
-               MovieReconstructedCamera *cameras= clip->tracking.reconstruction.cameras;
+       if(reconstruction->flag&TRACKING_RECONSTRUCTED) {
+               int n= reconstruction->camnr;
+               MovieReconstructedCamera *cameras= reconstruction->cameras;
 
                glColor4ub(255, 0, 0, 96);
 
@@ -835,8 +837,9 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
 {
        float x, y;
        MovieTracking* tracking= &clip->tracking;
-       MovieTrackingMarker *marker;
+       ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
        MovieTrackingTrack *track, *act_track;
+       MovieTrackingMarker *marker;
        int framenr= sc->user.framenr;
        int undistort= sc->user.render_flag&MCLIP_PROXY_RENDER_UNDISTORT;
        float *marker_pos= NULL, *fp, *active_pos= NULL, cur_pos[2];
@@ -858,13 +861,13 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
        glMultMatrixf(sc->stabmat);
        glScalef(width, height, 0);
 
-       act_track= clip->tracking.act_track;
+       act_track= BKE_tracking_active_track(tracking);
 
        if(sc->user.render_flag&MCLIP_PROXY_RENDER_UNDISTORT) {
                int count= 0;
 
                /* count */
-               track= tracking->tracks.first;
+               track= tracksbase->first;
                while(track) {
                        if((track->flag&TRACK_HIDDEN)==0) {
                                marker= BKE_tracking_get_marker(track, framenr);
@@ -880,7 +883,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
                if(count) {
                        marker_pos= MEM_callocN(2*sizeof(float)*count, "draw_tracking_tracks marker_pos");
 
-                       track= tracking->tracks.first;
+                       track= tracksbase->first;
                        fp= marker_pos;
                        while(track) {
                                if((track->flag&TRACK_HIDDEN)==0) {
@@ -902,7 +905,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
        }
 
        if(sc->flag&SC_SHOW_TRACK_PATH) {
-               track= tracking->tracks.first;
+               track= tracksbase->first;
                while(track) {
                        if((track->flag&TRACK_HIDDEN)==0)
                                draw_track_path(sc, clip, track);
@@ -912,7 +915,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
        }
 
        /* markers outline and non-selected areas */
-       track= tracking->tracks.first;
+       track= tracksbase->first;
        fp= marker_pos;
        while(track) {
                if((track->flag&TRACK_HIDDEN)==0) {
@@ -936,7 +939,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
 
        /* selected areas only, so selection wouldn't be overlapped by
           non-selected areas */
-       track= tracking->tracks.first;
+       track= tracksbase->first;
        fp= marker_pos;
        while(track) {
                if((track->flag&TRACK_HIDDEN)==0) {
@@ -974,15 +977,16 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
        }
 
        if(sc->flag&SC_SHOW_BUNDLES) {
+               MovieTrackingObject *object= BKE_tracking_active_object(tracking);
                float pos[4], vec[4], mat[4][4], aspy;
 
                glEnable(GL_POINT_SMOOTH);
                glPointSize(3.0f);
 
                aspy= 1.0f/clip->tracking.camera.pixel_aspect;
-               BKE_tracking_projection_matrix(tracking, framenr, width, height, mat);
+               BKE_tracking_projection_matrix(tracking, object, framenr, width, height, mat);
 
-               track= tracking->tracks.first;
+               track= tracksbase->first;
                while(track) {
                        if((track->flag&TRACK_HIDDEN)==0 && track->flag&TRACK_HAS_BUNDLE) {
                                marker= BKE_tracking_get_marker(track, framenr);
@@ -1027,7 +1031,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
 
        if(sc->flag&SC_SHOW_NAMES) {
                /* scaling should be cleared before drawing texts, otherwise font would also be scaled */
-               track= tracking->tracks.first;
+               track= tracksbase->first;
                fp= marker_pos;
                while(track) {
                        if((track->flag&TRACK_HIDDEN)==0) {
index c503614579214c902f39bb1433837805efced1a4..d75df0ab51e579ca48f5dde694ebbfdcee6c2630 100644 (file)
@@ -171,12 +171,13 @@ static int selected_boundbox(SpaceClip *sc, float min[2], float max[2])
        MovieClip *clip= ED_space_clip(sc);
        MovieTrackingTrack *track;
        int width, height, ok= 0;
+       ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
 
        INIT_MINMAX2(min, max);
 
        ED_space_clip_size(sc, &width, &height);
 
-       track= clip->tracking.tracks.first;
+       track= tracksbase->first;
        while(track) {
                if(TRACK_VIEW_SELECTED(sc, track)) {
                        MovieTrackingMarker *marker= BKE_tracking_get_marker(track, sc->user.framenr);
index 5a904e0e9b61543b478e4d0e97008d29185bc4aa..9aba6db0c8086fb5cdabdeaaf05392e7c4663efd 100644 (file)
@@ -177,6 +177,7 @@ static void draw_tracks_curves(View2D *v2d, SpaceClip *sc)
 {
        MovieClip *clip= ED_space_clip(sc);
        MovieTracking *tracking= &clip->tracking;
+       MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking);
        int width, height;
        struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } userdata;
 
@@ -188,13 +189,13 @@ static void draw_tracks_curves(View2D *v2d, SpaceClip *sc)
        /* non-selected knot handles */
        userdata.hsize= UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE);
        userdata.sel= 0;
-       userdata.act_track= clip->tracking.act_track;
+       userdata.act_track= act_track;
        UI_view2d_getscale(v2d, &userdata.xscale, &userdata.yscale);
        clip_graph_tracking_values_iterate(sc, &userdata, tracking_segment_knot_cb, NULL, NULL);
 
        /* draw graph lines */
        glEnable(GL_BLEND);
-       clip_graph_tracking_values_iterate(sc, tracking->act_track, tracking_segment_point_cb, tracking_segment_start_cb, tracking_segment_end_cb);
+       clip_graph_tracking_values_iterate(sc, act_track, tracking_segment_point_cb, tracking_segment_start_cb, tracking_segment_end_cb);
        glDisable(GL_BLEND);
 
        /* selected knot handles on top of curves */
@@ -206,7 +207,7 @@ static void draw_frame_curves(SpaceClip *sc)
 {
        MovieClip *clip= ED_space_clip(sc);
        MovieTracking *tracking= &clip->tracking;
-       MovieTrackingReconstruction *reconstruction= &tracking->reconstruction;
+       MovieTrackingReconstruction *reconstruction= BKE_tracking_get_reconstruction(tracking);
        int i, lines= 0, prevfra= 0;
 
        glColor3f(0.0f, 0.0f, 1.0f);
index 56ca1632bae001d780a2167fe713b95d520cb901..08d6bcf47bc80ce9c8e8b0d1ef963914c6d15bc3 100644 (file)
@@ -155,13 +155,14 @@ static int mouse_select_knot(bContext *C, float co[2], int extend)
        ARegion *ar= CTX_wm_region(C);
        View2D *v2d= &ar->v2d;
        MovieTracking *tracking= &clip->tracking;
+       MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking);
        static const int delta= 6;
 
-       if(tracking->act_track) {
+       if(act_track) {
                MouseSelectUserData userdata;
 
                mouse_select_init_data(&userdata, co);
-               clip_graph_tracking_values_iterate_track(sc, tracking->act_track,
+               clip_graph_tracking_values_iterate_track(sc, act_track,
                                        &userdata, find_nearest_tracking_knot_cb, NULL, NULL);
 
                if(userdata.marker) {
@@ -191,6 +192,7 @@ static int mouse_select_curve(bContext *C, float co[2], int extend)
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
        MovieTracking *tracking= &clip->tracking;
+       MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking);
        MouseSelectUserData userdata;
 
        mouse_select_init_data(&userdata, co);
@@ -198,12 +200,12 @@ static int mouse_select_curve(bContext *C, float co[2], int extend)
 
        if(userdata.track) {
                if(extend) {
-                       if(tracking->act_track==userdata.track) {
+                       if(act_track==userdata.track) {
                                /* currently only single curve can be selected (selected curve represents active track) */
-                               tracking->act_track= NULL;
+                               act_track= NULL;
                        }
                }
-               else if(tracking->act_track!=userdata.track) {
+               else if(act_track!=userdata.track) {
                        MovieTrackingMarker *marker;
                        SelectUserData selectdata = {SEL_DESELECT};
 
@@ -292,9 +294,11 @@ static int delete_curve_exec(bContext *C, wmOperator *UNUSED(op))
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
        MovieTracking *tracking= &clip->tracking;
+       ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
+       MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking);
 
-       if(tracking->act_track)
-               clip_delete_track(C, clip, tracking->act_track);
+       if(act_track)
+               clip_delete_track(C, clip, tracksbase, act_track);
 
        return OPERATOR_FINISHED;
 }
@@ -322,16 +326,17 @@ static int delete_knot_exec(bContext *C, wmOperator *UNUSED(op))
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
        MovieTracking *tracking= &clip->tracking;
+       ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
+       MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking);
 
-       if(tracking->act_track) {
+       if(act_track) {
                int a= 0;
-               MovieTrackingTrack *track= tracking->act_track;
 
-               while(a<track->markersnr) {
-                       MovieTrackingMarker *marker= &track->markers[a];
+               while(a<act_track->markersnr) {
+                       MovieTrackingMarker *marker= &act_track->markers[a];
 
                        if(marker->flag&MARKER_GRAPH_SEL)
-                               clip_delete_marker(C, clip, track, marker);
+                               clip_delete_marker(C, clip, tracksbase, act_track, marker);
                        else
                                a++;
                }
index da0b589652edda5bb171a74db55a429bf89e868e..64881499a31ba14fda98b3544f0a38fb32aace13 100644 (file)
@@ -92,8 +92,8 @@ void clip_graph_tracking_values_iterate(struct SpaceClip *sc, void *userdata,
 void clip_graph_tracking_iterate(struct SpaceClip *sc, void *userdata,
                        void (*func) (void *userdata, struct MovieTrackingMarker *marker));
 
-void clip_delete_track(struct bContext *C, struct MovieClip *clip, struct MovieTrackingTrack *track);
-void clip_delete_marker(struct bContext *C, struct MovieClip *clip, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker);
+void clip_delete_track(struct bContext *C, struct MovieClip *clip, struct ListBase *tracksbase, struct MovieTrackingTrack *track);
+void clip_delete_marker(struct bContext *C, struct MovieClip *clip, struct ListBase *tracksbase, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker);
 
 void clip_view_center_to_point(struct SpaceClip *sc, float x, float y);
 
@@ -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);
 
@@ -139,6 +140,9 @@ void CLIP_OT_stabilize_2d_remove(struct wmOperatorType *ot);
 void CLIP_OT_stabilize_2d_select(struct wmOperatorType *ot);
 void CLIP_OT_stabilize_2d_set_rotation(struct wmOperatorType *ot);
 
-void CLIP_OT_clean_tracks(wmOperatorType *ot);
+void CLIP_OT_clean_tracks(struct wmOperatorType *ot);
+
+void CLIP_OT_tracking_object_new(struct wmOperatorType *ot);
+void CLIP_OT_tracking_object_remove(struct wmOperatorType *ot);
 
 #endif /* ED_CLIP_INTERN_H */
index 649b278ab3d9d7b15b5ee27ba6d2a9ab57d85567..3ca8fc35c7fc1d3710ae9876200c3e5dd15bab3f 100644 (file)
@@ -119,9 +119,10 @@ void clip_graph_tracking_values_iterate(SpaceClip *sc, void *userdata,
 {
        MovieClip *clip= ED_space_clip(sc);
        MovieTracking *tracking= &clip->tracking;
+       ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
        MovieTrackingTrack *track;
 
-       track= tracking->tracks.first;
+       track= tracksbase->first;
        while(track) {
                if(TRACK_VIEW_SELECTED(sc, track)) {
                        clip_graph_tracking_values_iterate_track(sc, track, userdata, func, segment_start, segment_end);
@@ -136,9 +137,10 @@ void clip_graph_tracking_iterate(SpaceClip *sc, void *userdata,
 {
        MovieClip *clip= ED_space_clip(sc);
        MovieTracking *tracking= &clip->tracking;
+       ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
        MovieTrackingTrack *track;
 
-       track= tracking->tracks.first;
+       track= tracksbase->first;
        while(track) {
                if(TRACK_VIEW_SELECTED(sc, track)) {
                        int i;
@@ -158,14 +160,15 @@ void clip_graph_tracking_iterate(SpaceClip *sc, void *userdata,
        }
 }
 
-void clip_delete_track(bContext *C, MovieClip *clip, MovieTrackingTrack *track)
+void clip_delete_track(bContext *C, MovieClip *clip, ListBase *tracksbase, MovieTrackingTrack *track)
 {
        MovieTracking *tracking= &clip->tracking;
        MovieTrackingStabilization *stab= &tracking->stabilization;
+       MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking);
 
        int has_bundle= 0, update_stab= 0;
 
-       if(track==tracking->act_track)
+       if(track==act_track)
                tracking->act_track= NULL;
 
        if(track==stab->rot_track) {
@@ -179,7 +182,7 @@ void clip_delete_track(bContext *C, MovieClip *clip, MovieTrackingTrack *track)
                has_bundle= 1;
 
        BKE_tracking_free_track(track);
-       BLI_freelinkN(&tracking->tracks, track);
+       BLI_freelinkN(tracksbase, track);
 
        WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip);
 
@@ -194,10 +197,10 @@ void clip_delete_track(bContext *C, MovieClip *clip, MovieTrackingTrack *track)
                WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, NULL);
 }
 
-void clip_delete_marker(bContext *C, MovieClip *clip, MovieTrackingTrack *track, MovieTrackingMarker *marker)
+void clip_delete_marker(bContext *C, MovieClip *clip, ListBase *tracksbase, MovieTrackingTrack *track, MovieTrackingMarker *marker)
 {
        if(track->markersnr==1) {
-               clip_delete_track(C, clip, track);
+               clip_delete_track(C, clip, tracksbase, track);
        }
        else {
                BKE_tracking_delete_marker(track, marker->framenr);
index c8577f7760ef7168b7544092a51ac3ea9342ec48..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);
@@ -372,6 +373,10 @@ static void clip_operatortypes(void)
        WM_operatortype_append(CLIP_OT_graph_select);
        WM_operatortype_append(CLIP_OT_graph_delete_curve);
        WM_operatortype_append(CLIP_OT_graph_delete_knot);
+
+       /* object tracking */
+       WM_operatortype_append(CLIP_OT_tracking_object_new);
+       WM_operatortype_append(CLIP_OT_tracking_object_remove);
 }
 
 static void clip_keymap(struct wmKeyConfig *keyconf)
index d911e68236b09b4bd9b99de06db2ccb476554c0c..2178d6d9cc64379035ebffc3c89133d15610bba9 100644 (file)
@@ -32,6 +32,7 @@
 #include "MEM_guardedalloc.h"
 
 #include "DNA_camera_types.h"
+#include "DNA_constraint_types.h"
 #include "DNA_gpencil_types.h"
 #include "DNA_movieclip_types.h"
 #include "DNA_object_types.h"  /* SELECT */
@@ -45,6 +46,7 @@
 
 #include "BKE_main.h"
 #include "BKE_context.h"
+#include "BKE_constraint.h"
 #include "BKE_movieclip.h"
 #include "BKE_tracking.h"
 #include "BKE_global.h"
@@ -90,41 +92,21 @@ static int space_clip_frame_poll(bContext *C)
        return 0;
 }
 
-static int space_clip_frame_camera_poll(bContext *C)
-{
-       Scene *scene= CTX_data_scene(C);
-
-       if(space_clip_frame_poll(C)) {
-               return scene->camera != NULL;
-       }
-
-       return 0;
-}
-
-static int space_clip_camera_poll(bContext *C)
-{
-       SpaceClip *sc= CTX_wm_space_clip(C);
-       Scene *scene= CTX_data_scene(C);
-
-       if(sc && sc->clip && scene->camera)
-               return 1;
-
-       return 0;
-}
-
 /********************** add marker operator *********************/
 
 static void add_marker(SpaceClip *sc, float x, float y)
 {
        MovieClip *clip= ED_space_clip(sc);
+       MovieTracking *tracking= &clip->tracking;
+       ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
        MovieTrackingTrack *track;
        int width, height;
        
        ED_space_clip_size(sc, &width, &height);
 
-       track= BKE_tracking_add_track(&clip->tracking, x, y, sc->user.framenr, width, height);
+       track= BKE_tracking_add_track(tracking, tracksbase, x, y, sc->user.framenr, width, height);
 
-       BKE_tracking_select_track(&clip->tracking, track, TRACK_AREA_ALL, 0);
+       BKE_tracking_select_track(tracksbase, track, TRACK_AREA_ALL, 0);
 
        clip->tracking.act_track= track;
 }
@@ -191,13 +173,14 @@ static int delete_track_exec(bContext *C, wmOperator *UNUSED(op))
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
        MovieTracking *tracking= &clip->tracking;
-       MovieTrackingTrack *track= tracking->tracks.first, *next;
+       ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
+       MovieTrackingTrack *track= tracksbase->first, *next;
 
        while(track) {
                next= track->next;
 
                if(TRACK_VIEW_SELECTED(sc, track))
-                       clip_delete_track(C, clip, track);
+                       clip_delete_track(C, clip, tracksbase, track);
 
                track= next;
        }
@@ -230,7 +213,8 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op))
 {
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
-       MovieTrackingTrack *track= clip->tracking.tracks.first, *next;
+       ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
+       MovieTrackingTrack *track= tracksbase->first, *next;
        int framenr= sc->user.framenr;
        int has_selection= 0;
 
@@ -243,7 +227,7 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op))
                        if(marker) {
                                has_selection|= track->markersnr>1;
 
-                               clip_delete_marker(C, clip, track, marker);
+                               clip_delete_marker(C, clip, tracksbase, track, marker);
                        }
                }
 
@@ -429,6 +413,7 @@ static void *slide_marker_customdata(bContext *C, wmEvent *event)
        int width, height;
        float co[2];
        void *customdata= NULL;
+       ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
 
        ED_space_clip_size(sc, &width, &height);
 
@@ -437,7 +422,7 @@ static void *slide_marker_customdata(bContext *C, wmEvent *event)
 
        ED_clip_mouse_pos(C, event, co);
 
-       track= clip->tracking.tracks.first;
+       track= tracksbase->first;
        while(track) {
                if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_LOCKED)==0) {
                        MovieTrackingMarker *marker= BKE_tracking_get_marker(track, sc->user.framenr);
@@ -721,12 +706,12 @@ static float dist_to_rect(float co[2], float pos[2], float min[2], float max[2])
        return MIN4(d1, d2, d3, d4);
 }
 
-static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, MovieClip *clip, float co[2])
+static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbase, float co[2])
 {
        MovieTrackingTrack *track= NULL, *cur;
        float mindist= 0.0f;
 
-       cur= clip->tracking.tracks.first;
+       cur= tracksbase->first;
        while(cur) {
                MovieTrackingMarker *marker= BKE_tracking_get_marker(cur, sc->user.framenr);
 
@@ -764,10 +749,11 @@ static int mouse_select(bContext *C, float co[2], int extend)
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
        MovieTracking *tracking= &clip->tracking;
-       MovieTrackingTrack *act_track= tracking->act_track;
+       ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
+       MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking);
        MovieTrackingTrack *track= NULL;        /* selected marker */
 
-       track= find_nearest_track(sc, clip, co);
+       track= find_nearest_track(sc, tracksbase, co);
 
        if(track) {
                int area= track_mouse_area(sc, co, track);
@@ -784,7 +770,7 @@ static int mouse_select(bContext *C, float co[2], int extend)
                        if(area==TRACK_AREA_POINT)
                                area= TRACK_AREA_ALL;
 
-                       BKE_tracking_select_track(tracking, track, area, extend);
+                       BKE_tracking_select_track(tracksbase, track, area, extend);
                        clip->tracking.act_track= track;
                }
        }
@@ -867,6 +853,7 @@ static int border_select_exec(bContext *C, wmOperator *op)
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
        MovieTrackingTrack *track;
+       ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
        rcti rect;
        rctf rectf;
        int change= 0, mode, extend;
@@ -884,7 +871,7 @@ static int border_select_exec(bContext *C, wmOperator *op)
        extend= RNA_boolean_get(op->ptr, "extend");
 
        /* do actual selection */
-       track= clip->tracking.tracks.first;
+       track= tracksbase->first;
        while(track) {
                if((track->flag&TRACK_HIDDEN)==0) {
                        MovieTrackingMarker *marker= BKE_tracking_get_marker(track, sc->user.framenr);
@@ -952,6 +939,7 @@ static int circle_select_exec(bContext *C, wmOperator *op)
        MovieClip *clip= ED_space_clip(sc);
        ARegion *ar= CTX_wm_region(C);
        MovieTrackingTrack *track;
+       ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
        int x, y, radius, width, height, mode, change= 0;
        float zoomx, zoomy, offset[2], ellipse[2];
 
@@ -972,7 +960,7 @@ static int circle_select_exec(bContext *C, wmOperator *op)
        ED_clip_point_stable_pos(C, x, y, &offset[0], &offset[1]);
 
        /* do selection */
-       track= clip->tracking.tracks.first;
+       track= tracksbase->first;
        while(track) {
                if((track->flag&TRACK_HIDDEN)==0) {
                        MovieTrackingMarker *marker= BKE_tracking_get_marker(track, sc->user.framenr);
@@ -1026,13 +1014,14 @@ static int select_all_exec(bContext *C, wmOperator *op)
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
        MovieTrackingTrack *track= NULL;        /* selected track */
+       ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
        int action= RNA_enum_get(op->ptr, "action");
        int framenr= sc->user.framenr;
        int has_selection= 0;
 
        if(action == SEL_TOGGLE){
                action= SEL_SELECT;
-               track= clip->tracking.tracks.first;
+               track= tracksbase->first;
                while(track) {
                        if(TRACK_VIEW_SELECTED(sc, track)) {
                                action= SEL_DESELECT;
@@ -1043,7 +1032,7 @@ static int select_all_exec(bContext *C, wmOperator *op)
                }
        }
 
-       track= clip->tracking.tracks.first;
+       track= tracksbase->first;
        while(track) {
                if((track->flag&TRACK_HIDDEN)==0) {
                        MovieTrackingMarker *marker= BKE_tracking_get_marker(track, framenr);
@@ -1108,9 +1097,11 @@ static int select_groped_exec(bContext *C, wmOperator *op)
        MovieClip *clip= ED_space_clip(sc);
        MovieTrackingTrack *track;
        MovieTrackingMarker *marker;
+       MovieTracking *tracking= &clip->tracking;
+       ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
        int group= RNA_enum_get(op->ptr, "group");
 
-       track= clip->tracking.tracks.first;
+       track= tracksbase->first;
        while(track) {
                int ok= 0;
 
@@ -1132,11 +1123,13 @@ static int select_groped_exec(bContext *C, wmOperator *op)
                        ok= marker->flag&MARKER_DISABLED;
                }
                else if(group==5) { /* color */
-                       if(clip->tracking.act_track) {
-                               ok= (track->flag&TRACK_CUSTOMCOLOR) == (clip->tracking.act_track->flag&TRACK_CUSTOMCOLOR);
+                       MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking);
+
+                       if(act_track) {
+                               ok= (track->flag&TRACK_CUSTOMCOLOR) == (act_track->flag&TRACK_CUSTOMCOLOR);
 
                                if(ok && track->flag&TRACK_CUSTOMCOLOR)
-                                       ok= equals_v3v3(track->color, clip->tracking.act_track->color);
+                                       ok= equals_v3v3(track->color, act_track->color);
                        }
                }
                else if(group==6) { /* failed */
@@ -1208,10 +1201,11 @@ static int track_markers_testbreak(void)
 static int track_count_markers(SpaceClip *sc, MovieClip *clip)
 {
        int tot= 0;
+       ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
        MovieTrackingTrack *track;
        int framenr= sc->user.framenr;
 
-       track= clip->tracking.tracks.first;
+       track= tracksbase->first;
        while(track) {
                if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_LOCKED)==0) {
                        MovieTrackingMarker *marker= BKE_tracking_exact_marker(track, framenr);
@@ -1228,6 +1222,7 @@ static int track_count_markers(SpaceClip *sc, MovieClip *clip)
 
 static void track_init_markers(SpaceClip *sc, MovieClip *clip, int *frames_limit_r)
 {
+       ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
        MovieTrackingTrack *track;
        int framenr= sc->user.framenr, hidden= 0;
        int frames_limit= 0;
@@ -1235,7 +1230,7 @@ static void track_init_markers(SpaceClip *sc, MovieClip *clip, int *frames_limit
        if((sc->flag&SC_SHOW_MARKER_PATTERN)==0) hidden|= TRACK_AREA_PAT;
        if((sc->flag&SC_SHOW_MARKER_SEARCH)==0) hidden|= TRACK_AREA_SEARCH;
 
-       track= clip->tracking.tracks.first;
+       track= tracksbase->first;
        while(track) {
                if(hidden)
                        BKE_tracking_track_flag(track, hidden, SELECT, 1);
@@ -1302,7 +1297,7 @@ static int track_markers_initjob(bContext *C, TrackMarkersJob *tmj, int backward
                else if(settings->speed==TRACKING_SPEED_DOUBLE) tmj->delay/= 2;
        }
 
-       tmj->context= BKE_tracking_context_new(clip, &sc->user, backwards, 1, 1);
+       tmj->context= BKE_tracking_context_new(clip, &sc->user, backwards, 1);
 
        clip->tracking_context= tmj->context;
 
@@ -1413,7 +1408,7 @@ static int track_markers_exec(bContext *C, wmOperator *op)
                return OPERATOR_CANCELLED;
 
        /* do not disable tracks due to threshold when tracking frame-by-frame */
-       context= BKE_tracking_context_new(clip, &sc->user, backwards, sequence, sequence);
+       context= BKE_tracking_context_new(clip, &sc->user, backwards, sequence);
 
        while(framenr != efra) {
                if(!BKE_tracking_next(context))
@@ -1448,6 +1443,11 @@ static int track_markers_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(eve
        int backwards= RNA_boolean_get(op->ptr, "backwards");
        int sequence= RNA_boolean_get(op->ptr, "sequence");
 
+       if(WM_jobs_test(CTX_wm_manager(C), CTX_wm_area(C))) {
+               /* only one tracking is allowed at a time */
+               return OPERATOR_CANCELLED;
+       }
+
        if(clip->tracking_context)
                return OPERATOR_CANCELLED;
 
@@ -1546,9 +1546,10 @@ static int solve_camera_initjob(bContext *C, SolveCameraJob *scj, wmOperator *op
        Scene *scene= CTX_data_scene(C);
        MovieTracking *tracking= &clip->tracking;
        MovieTrackingSettings *settings= &clip->tracking.settings;
+       MovieTrackingObject *object= BKE_tracking_active_object(tracking);
        int width, height;
 
-       if(!BKE_tracking_can_reconstruct(tracking, error_msg, max_error))
+       if(!BKE_tracking_can_reconstruct(tracking, object, error_msg, max_error))
                return 0;
 
        /* could fail if footage uses images with different sizes */
@@ -1559,7 +1560,7 @@ static int solve_camera_initjob(bContext *C, SolveCameraJob *scj, wmOperator *op
        scj->reports= op->reports;
        scj->user= sc->user;
 
-       scj->context= BKE_tracking_reconstruction_context_new(tracking,
+       scj->context= BKE_tracking_reconstruction_context_new(tracking, object,
                        settings->keyframe1, settings->keyframe2, width, height);
 
        tracking->stats= MEM_callocN(sizeof(MovieTrackingStats), "solve camera stats");
@@ -1670,9 +1671,15 @@ static int solve_camera_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(even
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
        MovieTracking *tracking= &clip->tracking;
+       MovieTrackingReconstruction *reconstruction= BKE_tracking_get_reconstruction(tracking);
        wmJob *steve;
        char error_msg[256]= "\0";
 
+       if(WM_jobs_test(CTX_wm_manager(C), CTX_wm_area(C))) {
+               /* only one solve is allowed at a time */
+               return OPERATOR_CANCELLED;
+       }
+
        scj= MEM_callocN(sizeof(SolveCameraJob), "SolveCameraJob data");
        if(!solve_camera_initjob(C, scj, op, error_msg, sizeof(error_msg))) {
                if(error_msg[0])
@@ -1686,7 +1693,7 @@ static int solve_camera_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(even
        BLI_strncpy(tracking->stats->message, "Solving camera | Preparing solve", sizeof(tracking->stats->message));
 
        /* hide reconstruction statistics from previous solve */
-       clip->tracking.reconstruction.flag&= ~TRACKING_RECONSTRUCTED;
+       reconstruction->flag&= ~TRACKING_RECONSTRUCTED;
        WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip);
 
        /* setup job */
@@ -1746,7 +1753,9 @@ static int clear_solution_exec(bContext *C, wmOperator *UNUSED(op))
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
        MovieTracking *tracking= &clip->tracking;
-       MovieTrackingTrack *track= tracking->tracks.first;
+       ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
+       MovieTrackingReconstruction *reconstruction= BKE_tracking_get_reconstruction(tracking);
+       MovieTrackingTrack *track= tracksbase->first;
 
        while(track) {
                track->flag&= ~TRACK_HAS_BUNDLE;
@@ -1754,13 +1763,13 @@ static int clear_solution_exec(bContext *C, wmOperator *UNUSED(op))
                track= track->next;
        }
 
-       if(tracking->reconstruction.cameras)
-               MEM_freeN(tracking->reconstruction.cameras);
+       if(reconstruction->cameras)
+               MEM_freeN(reconstruction->cameras);
 
-       tracking->reconstruction.cameras= NULL;
-       tracking->reconstruction.camnr= 0;
+       reconstruction->cameras= NULL;
+       reconstruction->camnr= 0;
 
-       tracking->reconstruction.flag&= ~TRACKING_RECONSTRUCTED;
+       reconstruction->flag&= ~TRACKING_RECONSTRUCTED;
 
        DAG_id_tag_update(&clip->id, 0);
 
@@ -1792,9 +1801,10 @@ static int clear_track_path_exec(bContext *C, wmOperator *op)
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
        MovieTrackingTrack *track;
+       ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
        int action= RNA_enum_get(op->ptr, "action");
 
-       track= clip->tracking.tracks.first;
+       track= tracksbase->first;
        while(track) {
                if(TRACK_VIEW_SELECTED(sc, track))
                        BKE_tracking_clear_path(track, sc->user.framenr, action);
@@ -1839,7 +1849,8 @@ static int disable_markers_exec(bContext *C, wmOperator *op)
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
        MovieTracking *tracking= &clip->tracking;
-       MovieTrackingTrack *track= tracking->tracks.first;
+       ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
+       MovieTrackingTrack *track= tracksbase->first;
        int action= RNA_enum_get(op->ptr, "action");
 
        while(track) {
@@ -1888,14 +1899,80 @@ void CLIP_OT_disable_markers(wmOperatorType *ot)
 
 /********************** set origin operator *********************/
 
+static Object *get_camera_with_movieclip(Scene *scene, MovieClip *clip)
+{
+       Object *camera= scene->camera;
+       Base *base;
+
+       if(camera && object_get_movieclip(scene, camera, 0)==clip)
+               return camera;
+
+       base= scene->base.first;
+       while(base) {
+               if(base->object->type == OB_CAMERA) {
+                       if(object_get_movieclip(scene, base->object, 0)==clip) {
+                               camera= base->object;
+                               break;
+                       }
+               }
+
+               base= base->next;
+       }
+
+       return camera;
+}
+
+static Object *get_orientation_object(bContext *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);
+       Object *object= NULL;
+
+       if(tracking_object->flag&TRACKING_OBJECT_CAMERA) {
+               object= get_camera_with_movieclip(scene, clip);
+       }
+       else {
+               object= OBACT;
+       }
+
+       if(object && object->parent)
+               object= object->parent;
+
+       return object;
+}
+
+static int set_orientation_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);
+
+               if(tracking_object->flag&TRACKING_OBJECT_CAMERA) {
+                       return 1;
+               }
+               else {
+                       return OBACT != NULL;
+               }
+       }
+
+       return 0;
+}
+
 static int count_selected_bundles(bContext *C)
 {
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
+       ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
        MovieTrackingTrack *track;
        int tot= 0;
 
-       track= clip->tracking.tracks.first;
+       track= tracksbase->first;
        while(track) {
                if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_HAS_BUNDLE))
                        tot++;
@@ -1906,38 +1983,115 @@ static int count_selected_bundles(bContext *C)
        return tot;
 }
 
+static void object_solver_inverted_matrix(Scene *scene, Object *ob, float invmat[4][4])
+{
+       bConstraint *con;
+       int found= 0;
+
+       for (con= ob->constraints.first; con; con=con->next) {
+               bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+
+               if(!cti)
+                       continue;
+
+               if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER) {
+                       bObjectSolverConstraint *data= (bObjectSolverConstraint *)con->data;
+
+                       if(!found) {
+                               Object *cam= data->camera ? data->camera : scene->camera;
+
+                               where_is_object_mat(scene, cam, invmat);
+                       }
+
+                       mult_m4_m4m4(invmat, invmat, data->invmat);
+
+                       found= 1;
+               }
+       }
+
+       if(found)
+               invert_m4(invmat);
+       else
+               unit_m4(invmat);
+}
+
+static Object *object_solver_camera(Scene *scene, Object *ob)
+{
+       bConstraint *con;
+
+       for (con= ob->constraints.first; con; con=con->next) {
+               bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+
+               if(!cti)
+                       continue;
+
+               if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER) {
+                       bObjectSolverConstraint *data= (bObjectSolverConstraint *)con->data;
+
+                       return data->camera ? data->camera : scene->camera;
+               }
+       }
+
+       return NULL;
+}
+
 static int set_origin_exec(bContext *C, wmOperator *op)
 {
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
+       MovieTracking *tracking= &clip->tracking;
        MovieTrackingTrack *track;
+       MovieTrackingObject *tracking_object;
        Scene *scene= CTX_data_scene(C);
-       Object *parent= scene->camera;
-       float mat[4][4], vec[3];
+       Object *object;
+       Object *camera= get_camera_with_movieclip(scene, clip);
+       ListBase *tracksbase;
+       float mat[4][4], vec[3], median[3];
+       int selected_count= count_selected_bundles(C);
+
+       if(selected_count==0) {
+               BKE_report(op->reports, RPT_ERROR, "At least one track with bundle should be selected to define origin position");
+
+               return OPERATOR_CANCELLED;
+       }
+
+       object= get_orientation_object(C);
+       if(!object) {
+               BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on");
 
-       if(count_selected_bundles(C)!=1) {
-               BKE_report(op->reports, RPT_ERROR, "Track with bundle should be selected to define origin position");
                return OPERATOR_CANCELLED;
        }
 
-       if(scene->camera->parent)
-               parent= scene->camera->parent;
+       tracking_object= BKE_tracking_active_object(tracking);
+
+       tracksbase= BKE_tracking_object_tracks(tracking, tracking_object);
 
-       track= clip->tracking.tracks.first;
+       track= tracksbase->first;
+       zero_v3(median);
        while(track) {
-               if(TRACK_VIEW_SELECTED(sc, track))
-                       break;
+               if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_HAS_BUNDLE)) {
+                       add_v3_v3(median, track->bundle_pos);
+               }
 
                track= track->next;
        }
+       mul_v3_fl(median, 1.0f/selected_count);
 
-       BKE_get_tracking_mat(scene, NULL, mat);
-       mul_v3_m4v3(vec, mat, track->bundle_pos);
+       BKE_get_tracking_mat(scene, camera, mat);
 
-       sub_v3_v3(parent->loc, vec);
+       mul_v3_m4v3(vec, mat, median);
+
+       if(tracking_object->flag&TRACKING_OBJECT_CAMERA) {
+               sub_v3_v3(object->loc, vec);
+       }
+       else {
+               object_solver_inverted_matrix(scene, object, mat);
+               mul_v3_m4v3(vec, mat, vec);
+               copy_v3_v3(object->loc, vec);
+       }
 
        DAG_id_tag_update(&clip->id, 0);
-       DAG_id_tag_update(&parent->id, OB_RECALC_OB);
+       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);
@@ -1954,20 +2108,42 @@ void CLIP_OT_set_origin(wmOperatorType *ot)
 
        /* api callbacks */
        ot->exec= set_origin_exec;
-       ot->poll= space_clip_frame_camera_poll;
+       ot->poll= set_orientation_poll;
 
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       /* properties */
+       RNA_def_boolean(ot->srna, "use_median", 0, "Use Median", "Set origin to median point of selected bundles");
 }
 
 /********************** set floor operator *********************/
 
-static void set_axis(Scene *scene,  Object *ob, MovieTrackingTrack *track, char axis)
+static void set_axis(Scene *scene,  Object *ob, MovieClip *clip, MovieTrackingObject *tracking_object,
+                       MovieTrackingTrack *track, char axis)
 {
-       float mat[4][4], vec[3], obmat[4][4];
+       Object *camera= get_camera_with_movieclip(scene, clip);
+       int is_camera= tracking_object->flag&TRACKING_OBJECT_CAMERA;
+       int  flip= 0;
+       float mat[4][4], vec[3], obmat[4][4], dvec[3];
+
+       object_to_mat4(ob, obmat);
 
-       BKE_get_tracking_mat(scene, NULL, mat);
+       BKE_get_tracking_mat(scene, camera, mat);
        mul_v3_m4v3(vec, mat, track->bundle_pos);
+       copy_v3_v3(dvec, vec);
+
+       if(!is_camera) {
+               float imat[4][4];
+
+               object_solver_inverted_matrix(scene, ob, imat);
+               mul_v3_m4v3(vec, imat, vec);
+
+               invert_m4_m4(imat, obmat);
+               mul_v3_m4v3(dvec, imat, vec);
+
+               sub_v3_v3(vec, obmat[3]);
+       }
 
        if(len_v2(vec) < 1e-3f)
                return;
@@ -1975,26 +2151,48 @@ static void set_axis(Scene *scene,  Object *ob, MovieTrackingTrack *track, char
        unit_m4(mat);
 
        if(axis=='X') {
-               if(fabsf(vec[1])<1e-3f) {
+               if(fabsf(dvec[1])<1e-3f) {
+                       flip= 1;
+
                        mat[0][0]= -1.0f; mat[0][1]= 0.0f; mat[0][2]= 0.0f;
                        mat[1][0]= 0.0f; mat[1][1]= -1.0f; mat[1][2]= 0.0f;
                        mat[2][0]= 0.0f; mat[2][1]= 0.0f; mat[2][2]= 1.0f;
                } else {
                        copy_v3_v3(mat[0], vec);
-                       mat[0][2]= 0.0f;
-                       mat[2][0]= 0.0f; mat[2][1]= 0.0f; mat[2][2]= 1.0f;
-                       cross_v3_v3v3(mat[1], mat[2], mat[0]);
+
+                       if(is_camera || fabsf(vec[2])<1e-3f) {
+                               mat[0][2]= 0.0f;
+                               mat[2][0]= 0.0f; mat[2][1]= 0.0f; mat[2][2]= 1.0f;
+                               cross_v3_v3v3(mat[1], mat[2], mat[0]);
+                       }
+                       else {
+                               vec[2]= 0.0f;
+
+                               cross_v3_v3v3(mat[1], mat[0], vec);
+                               cross_v3_v3v3(mat[2], mat[0], mat[1]);
+                       }
                }
        } else {
-               if(fabsf(vec[0])<1e-3f) {
+               if(fabsf(dvec[0])<1e-3f) {
+                       flip= 1;
+
                        mat[0][0]= -1.0f; mat[0][1]= 0.0f; mat[0][2]= 0.0f;
                        mat[1][0]= 0.0f; mat[1][1]= -1.0f; mat[1][2]= 0.0f;
                        mat[2][0]= 0.0f; mat[2][1]= 0.0f; mat[2][2]= 1.0f;
                } else {
                        copy_v3_v3(mat[1], vec);
-                       mat[1][2]= 0.0f;
-                       mat[2][0]= 0.0f; mat[2][1]= 0.0f; mat[2][2]= 1.0f;
-                       cross_v3_v3v3(mat[0], mat[1], mat[2]);
+
+                       if(is_camera || fabsf(vec[2])<1e-3f) {
+                               mat[1][2]= 0.0f;
+                               mat[2][0]= 0.0f; mat[2][1]= 0.0f; mat[2][2]= 1.0f;
+                               cross_v3_v3v3(mat[0], mat[1], mat[2]);
+                       }
+                       else {
+                               vec[2]= 0.0f;
+
+                               cross_v3_v3v3(mat[0], vec, mat[1]);
+                               cross_v3_v3v3(mat[2], mat[0], mat[1]);
+                       }
                }
        }
 
@@ -2002,10 +2200,30 @@ static void set_axis(Scene *scene,  Object *ob, MovieTrackingTrack *track, char
        normalize_v3(mat[1]);
        normalize_v3(mat[2]);
 
-       invert_m4(mat);
+       if(is_camera) {
+               invert_m4(mat);
+
+               mult_m4_m4m4(mat, mat, obmat);
+       }
+       else {
+               if(!flip) {
+                       float lmat[4][4], ilmat[4][4], rmat[3][3];
+
+                       object_rot_to_mat3(ob, rmat);
+                       invert_m3(rmat);
+                       mul_m4_m4m3(mat, mat, rmat);
+
+                       unit_m4(lmat);
+                       copy_v3_v3(lmat[3], obmat[3]);
+                       invert_m4_m4(ilmat, lmat);
+
+                       mul_serie_m4(mat, lmat, mat, ilmat, obmat, NULL, NULL, NULL, NULL);
+               }
+               else {
+                       mult_m4_m4m4(mat, obmat, mat);
+               }
+       }
 
-       object_to_mat4(ob, obmat);
-       mult_m4_m4m4(mat, mat, obmat);
        object_apply_mat4(ob, mat, 0, 0);
 }
 
@@ -2014,9 +2232,12 @@ static int set_floor_exec(bContext *C, wmOperator *op)
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
        Scene *scene= CTX_data_scene(C);
-       MovieTrackingTrack *track, *axis_track= NULL;
-       Object *camera= scene->camera;
-       Object *parent= camera;
+       MovieTracking *tracking= &clip->tracking;
+       MovieTrackingObject *tracking_object;
+       MovieTrackingTrack *track, *axis_track= NULL, *act_track;
+       ListBase *tracksbase;
+       Object *object;
+       Object *camera= get_camera_with_movieclip(scene, clip);
        int tot= 0;
        float vec[3][3], mat[4][4], obmat[4][4], newmat[4][4], orig[3]= {0.0f, 0.0f, 0.0f};
        float rot[4][4]={{0.0f, 0.0f, -1.0f, 0.0f},
@@ -2026,21 +2247,30 @@ static int set_floor_exec(bContext *C, wmOperator *op)
 
        if(count_selected_bundles(C)!=3) {
                BKE_report(op->reports, RPT_ERROR, "Three tracks with bundles are needed to orient the floor");
+
                return OPERATOR_CANCELLED;
        }
 
-       if(scene->camera->parent)
-               parent= scene->camera->parent;
+       tracking_object= BKE_tracking_active_object(tracking);
+       tracksbase= BKE_tracking_object_tracks(tracking, tracking_object);
+       act_track= BKE_tracking_active_track(tracking);
+
+       object= get_orientation_object(C);
+       if(!object) {
+               BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on");
+
+               return OPERATOR_CANCELLED;
+       }
 
-       BKE_get_tracking_mat(scene, NULL, mat);
+       BKE_get_tracking_mat(scene, camera, mat);
 
        /* get 3 bundles to use as reference */
-       track= clip->tracking.tracks.first;
+       track= tracksbase->first;
        while(track && tot<3) {
                if(track->flag&TRACK_HAS_BUNDLE && TRACK_VIEW_SELECTED(sc, track)) {
                        mul_v3_m4v3(vec[tot], mat, track->bundle_pos);
 
-                       if(tot==0 || track==clip->tracking.act_track)
+                       if(tot==0 || track==act_track)
                                copy_v3_v3(orig, vec[tot]);
                        else
                                axis_track= track;
@@ -2070,25 +2300,30 @@ static int set_floor_exec(bContext *C, wmOperator *op)
        mat[3][1]= orig[1];
        mat[3][2]= orig[2];
 
-       invert_m4(mat);
+       if(tracking_object->flag&TRACKING_OBJECT_CAMERA) {
+               invert_m4(mat);
 
-       object_to_mat4(parent, obmat);
-       mult_m4_m4m4(mat, mat, obmat);
-       mult_m4_m4m4(newmat, rot, mat);
-       object_apply_mat4(parent, newmat, 0, 0);
-
-       /* make camera have positive z-coordinate */
-       if(parent->loc[2]<0) {
-               invert_m4(rot);
+               object_to_mat4(object, obmat);
+               mult_m4_m4m4(mat, mat, obmat);
                mult_m4_m4m4(newmat, rot, mat);
-               object_apply_mat4(parent, newmat, 0, 0);
+               object_apply_mat4(object, newmat, 0, 0);
+
+               /* make camera have positive z-coordinate */
+               if(object->loc[2]<0) {
+                       invert_m4(rot);
+                       mult_m4_m4m4(newmat, rot, mat);
+                       object_apply_mat4(object, newmat, 0, 0);
+               }
+       }
+       else {
+               object_apply_mat4(object, mat, 0, 0);
        }
 
-       where_is_object(scene, parent);
-       set_axis(scene, parent, axis_track, 'X');
+       where_is_object(scene, object);
+       set_axis(scene, object, clip, tracking_object, axis_track, 'X');
 
        DAG_id_tag_update(&clip->id, 0);
-       DAG_id_tag_update(&parent->id, OB_RECALC_OB);
+       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);
@@ -2105,7 +2340,7 @@ void CLIP_OT_set_floor(wmOperatorType *ot)
 
        /* api callbacks */
        ot->exec= set_floor_exec;
-       ot->poll= space_clip_camera_poll;
+       ot->poll= set_orientation_poll;
 
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -2117,9 +2352,12 @@ static int set_axis_exec(bContext *C, wmOperator *op)
 {
        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);
        MovieTrackingTrack *track;
        Scene *scene= CTX_data_scene(C);
-       Object *parent= scene->camera;
+       Object *object;
+       ListBase *tracksbase;
        int axis= RNA_enum_get(op->ptr, "axis");
 
        if(count_selected_bundles(C)!=1) {
@@ -2128,10 +2366,16 @@ static int set_axis_exec(bContext *C, wmOperator *op)
                return OPERATOR_CANCELLED;
        }
 
-       if(scene->camera->parent)
-               parent= scene->camera->parent;
+       object= get_orientation_object(C);
+       if(!object) {
+               BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on");
+
+               return OPERATOR_CANCELLED;
+       }
+
+       tracksbase= BKE_tracking_object_tracks(tracking, tracking_object);
 
-       track= clip->tracking.tracks.first;
+       track=tracksbase->first;
        while(track) {
                if(TRACK_VIEW_SELECTED(sc, track))
                        break;
@@ -2139,10 +2383,10 @@ static int set_axis_exec(bContext *C, wmOperator *op)
                track= track->next;
        }
 
-       set_axis(scene, parent, track, axis==0?'X':'Y');
+       set_axis(scene, object, clip, tracking_object, track, axis==0?'X':'Y');
 
        DAG_id_tag_update(&clip->id, 0);
-       DAG_id_tag_update(&parent->id, OB_RECALC_OB);
+       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);
@@ -2165,7 +2409,7 @@ void CLIP_OT_set_axis(wmOperatorType *ot)
 
        /* api callbacks */
        ot->exec= set_axis_exec;
-       ot->poll= space_clip_frame_camera_poll;
+       ot->poll= set_orientation_poll;
 
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -2176,29 +2420,37 @@ 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);
+       MovieTracking *tracking= &clip->tracking;
+       MovieTrackingObject *tracking_object= BKE_tracking_active_object(tracking);
        MovieTrackingTrack *track;
        Scene *scene= CTX_data_scene(C);
-       Object *parent= scene->camera;
+       Object *object= NULL;
+       Object *camera= get_camera_with_movieclip(scene, clip);
+       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(scene->camera->parent)
-               parent= scene->camera->parent;
+       object= get_orientation_object(C);
+       if(!object) {
+               BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on");
+
+               return OPERATOR_CANCELLED;
+       }
 
-       BKE_get_tracking_mat(scene, NULL, mat);
+       BKE_get_tracking_mat(scene, camera, mat);
 
-       track= clip->tracking.tracks.first;
+       track= tracksbase->first;
        while(track) {
                if(TRACK_VIEW_SELECTED(sc, track)) {
                        mul_v3_m4v3(vec[tot], mat, track->bundle_pos);
@@ -2213,11 +2465,29 @@ static int set_scale_exec(bContext *C, wmOperator *op)
        if(len_v3(vec[0])>1e-5f) {
                scale= dist / len_v3(vec[0]);
 
-               mul_v3_fl(parent->size, scale);
-               mul_v3_fl(parent->loc, scale);
+               if(tracking_object->flag&TRACKING_OBJECT_CAMERA) {
+                       mul_v3_fl(object->size, scale);
+                       mul_v3_fl(object->loc, scale);
+               } else
+               if(!scale_solution){
+                       Object *camera= object_solver_camera(scene, object);
+
+                       object->size[0]= object->size[1]= object->size[2]= 1.0f/scale;
+
+                       if(camera) {
+                               object->size[0]/= camera->size[0];
+                               object->size[1]/= camera->size[1];
+                               object->size[2]/= camera->size[2];
+                       }
+               }
+               else {
+                       tracking_object->scale= scale;
+               }
 
                DAG_id_tag_update(&clip->id, 0);
-               DAG_id_tag_update(&parent->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);
@@ -2226,6 +2496,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);
@@ -2248,7 +2523,60 @@ void CLIP_OT_set_scale(wmOperatorType *ot)
        /* api callbacks */
        ot->exec= set_scale_exec;
        ot->invoke= set_scale_invoke;
-       ot->poll= space_clip_frame_camera_poll;
+       ot->poll= set_orientation_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 solution scale operator *********************/
+
+static int set_solution_scale_poll(bContext *C)
+{
+       if(space_clip_frame_poll(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;
@@ -2301,11 +2629,14 @@ static int hide_tracks_exec(bContext *C, wmOperator *op)
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
        MovieTrackingTrack *track;
+       MovieTracking *tracking= &clip->tracking;
+       ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
+       MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking);
        int unselected;
 
        unselected= RNA_boolean_get(op->ptr, "unselected");
 
-       track= clip->tracking.tracks.first;
+       track= tracksbase->first;
        while(track) {
                if(unselected==0 && TRACK_VIEW_SELECTED(sc, track)) {
                        track->flag|= TRACK_HIDDEN;
@@ -2316,7 +2647,7 @@ static int hide_tracks_exec(bContext *C, wmOperator *op)
                track= track->next;
        }
 
-       if(clip->tracking.act_track && clip->tracking.act_track->flag&TRACK_HIDDEN)
+       if(act_track && act_track->flag&TRACK_HIDDEN)
                clip->tracking.act_track= NULL;
 
        if(unselected==0) {
@@ -2353,9 +2684,10 @@ static int hide_tracks_clear_exec(bContext *C, wmOperator *UNUSED(op))
 {
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
+       ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
        MovieTrackingTrack *track;
 
-       track= clip->tracking.tracks.first;
+       track= tracksbase->first;
        while(track) {
                track->flag&= ~TRACK_HIDDEN;
 
@@ -2408,7 +2740,9 @@ static int detect_features_exec(bContext *C, wmOperator *op)
        MovieClip *clip= ED_space_clip(sc);
        int clip_flag= clip->flag&MCLIP_TIMECODE_FLAGS;
        ImBuf *ibuf= BKE_movieclip_get_ibuf_flag(clip, &sc->user, clip_flag);
-       MovieTrackingTrack *track= clip->tracking.tracks.first;
+       MovieTracking *tracking= &clip->tracking;
+       ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
+       MovieTrackingTrack *track= tracksbase->first;
        int placement= RNA_enum_get(op->ptr, "placement");
        int margin= RNA_int_get(op->ptr, "margin");
        int min_trackability= RNA_int_get(op->ptr, "min_trackability");
@@ -2430,7 +2764,8 @@ static int detect_features_exec(bContext *C, wmOperator *op)
                track= track->next;
        }
 
-       BKE_tracking_detect_fast(&clip->tracking, ibuf, sc->user.framenr, margin, min_trackability, min_distance, layer, place_outside_layer);
+       BKE_tracking_detect_fast(tracking, tracksbase, ibuf, sc->user.framenr, margin,
+                               min_trackability, min_distance, layer, place_outside_layer);
 
        IMB_freeImBuf(ibuf);
 
@@ -2479,7 +2814,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op)
        int delta;
 
        if(pos<=1) {    /* jump to path */
-               track= clip->tracking.act_track;
+               track= BKE_tracking_active_track(&clip->tracking);
 
                if(!track)
                        return OPERATOR_CANCELLED;
@@ -2499,13 +2834,16 @@ static int frame_jump_exec(bContext *C, wmOperator *op)
                if(clip->tracking.reconstruction.flag&TRACKING_RECONSTRUCTED) {
                        int a= sc->user.framenr;
                        MovieTracking *tracking= &clip->tracking;
+                       MovieTrackingObject *object= BKE_tracking_active_object(tracking);
 
                        delta= pos == 3 ? 1 : -1;
 
                        a+= delta;
 
                        while(a+delta >= SFRA && a+delta <= EFRA) {
-                               MovieReconstructedCamera *cam= BKE_tracking_get_reconstructed_camera(tracking, a);
+                               MovieReconstructedCamera *cam;
+
+                               cam= BKE_tracking_get_reconstructed_camera(tracking, object, a);
 
                                if(!cam) {
                                        sc->user.framenr= a;
@@ -2562,16 +2900,18 @@ static int join_tracks_exec(bContext *C, wmOperator *op)
 {
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
+       MovieTracking *tracking= &clip->tracking;
+       ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
        MovieTrackingTrack *act_track, *track, *next;
 
-       act_track= clip->tracking.act_track;
+       act_track= BKE_tracking_active_track(tracking);
 
        if(!act_track) {
                BKE_report(op->reports, RPT_ERROR, "No active track to join to");
                return OPERATOR_CANCELLED;
        }
 
-       track= clip->tracking.tracks.first;
+       track= tracksbase->first;
        while(track) {
                if(TRACK_VIEW_SELECTED(sc, track) && track!=act_track) {
                        if(!BKE_tracking_test_join_tracks(act_track, track)) {
@@ -2583,7 +2923,7 @@ static int join_tracks_exec(bContext *C, wmOperator *op)
                track= track->next;
        }
 
-       track= clip->tracking.tracks.first;
+       track= tracksbase->first;
        while(track) {
                next= track->next;
 
@@ -2591,7 +2931,7 @@ static int join_tracks_exec(bContext *C, wmOperator *op)
                        BKE_tracking_join_tracks(act_track, track);
 
                        BKE_tracking_free_track(track);
-                       BLI_freelinkN(&clip->tracking.tracks, track);
+                       BLI_freelinkN(tracksbase, track);
                }
 
                track= next;
@@ -2624,7 +2964,8 @@ static int lock_tracks_exec(bContext *C, wmOperator *op)
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
        MovieTracking *tracking= &clip->tracking;
-       MovieTrackingTrack *track= tracking->tracks.first;
+       ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
+       MovieTrackingTrack *track= tracksbase->first;
        int action= RNA_enum_get(op->ptr, "action");
 
        while(track) {
@@ -2673,12 +3014,14 @@ static int track_copy_color_exec(bContext *C, wmOperator *UNUSED(op))
 {
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
-       MovieTrackingTrack *track, *act_track= clip->tracking.act_track;
+       MovieTracking *tracking= &clip->tracking;
+       ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
+       MovieTrackingTrack *track, *act_track= BKE_tracking_active_track(tracking);
 
        if(!act_track)
                return OPERATOR_CANCELLED;
 
-       track= clip->tracking.tracks.first;
+       track= tracksbase->first;
        while(track) {
                if(TRACK_VIEW_SELECTED(sc, track) && track!=act_track) {
                        track->flag&= ~TRACK_CUSTOMCOLOR;
@@ -2719,11 +3062,12 @@ static int stabilize_2d_add_exec(bContext *C, wmOperator *UNUSED(op))
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
        MovieTracking *tracking= &clip->tracking;
+       ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
        MovieTrackingTrack *track;
        MovieTrackingStabilization *stab= &tracking->stabilization;
        int update= 0;
 
-       track= tracking->tracks.first;
+       track= tracksbase->first;
        while(track) {
                if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_USE_2D_STAB)==0) {
                        track->flag|= TRACK_USE_2D_STAB;
@@ -2768,10 +3112,11 @@ static int stabilize_2d_remove_exec(bContext *C, wmOperator *UNUSED(op))
        MovieClip *clip= ED_space_clip(sc);
        MovieTracking *tracking= &clip->tracking;
        MovieTrackingStabilization *stab= &tracking->stabilization;
+       ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
        MovieTrackingTrack *track;
        int a= 0, update= 0;
 
-       track= tracking->tracks.first;
+       track= tracksbase->first;
        while(track) {
                if(track->flag&TRACK_USE_2D_STAB) {
                        if(a==stab->act_track) {
@@ -2826,10 +3171,11 @@ static int stabilize_2d_select_exec(bContext *C, wmOperator *UNUSED(op))
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
        MovieTracking *tracking= &clip->tracking;
+       ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
        MovieTrackingTrack *track;
        int update= 0;
 
-       track= tracking->tracks.first;
+       track= tracksbase->first;
        while(track) {
                if(track->flag&TRACK_USE_2D_STAB) {
                        BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, 0);
@@ -2868,11 +3214,12 @@ static int stabilize_2d_set_rotation_exec(bContext *C, wmOperator *UNUSED(op))
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
        MovieTracking *tracking= &clip->tracking;
+       MovieTrackingTrack *act_track= BKE_tracking_active_track(tracking);
 
-       if(tracking->act_track) {
+       if(act_track) {
                MovieTrackingStabilization *stab= &tracking->stabilization;
 
-               stab->rot_track= tracking->act_track;
+               stab->rot_track= act_track;
                stab->ok= 0;
 
                DAG_id_tag_update(&clip->id, 0);
@@ -2997,7 +3344,8 @@ static int clean_tracks_exec(bContext *C, wmOperator *op)
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
        MovieTracking *tracking= &clip->tracking;
-       MovieTrackingTrack *track, *next, *act_track= clip->tracking.act_track;
+       ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
+       MovieTrackingTrack *track, *next, *act_track= BKE_tracking_active_track(tracking);
        int frames= RNA_int_get(op->ptr, "frames");
        int action= RNA_enum_get(op->ptr, "action");
        float error= RNA_float_get(op->ptr, "error");
@@ -3005,7 +3353,7 @@ static int clean_tracks_exec(bContext *C, wmOperator *op)
        if(error && action==TRACKING_CLEAN_DELETE_SEGMENT)
                action= TRACKING_CLEAN_DELETE_TRACK;
 
-       track= tracking->tracks.first;
+       track= tracksbase->first;
        while(track) {
                next= track->next;
 
@@ -3024,7 +3372,7 @@ static int clean_tracks_exec(bContext *C, wmOperator *op)
                                                clip->tracking.act_track= NULL;
 
                                        BKE_tracking_free_track(track);
-                                       BLI_freelinkN(&clip->tracking.tracks, track);
+                                       BLI_freelinkN(tracksbase, track);
                                        track= NULL;
                                }
 
@@ -3034,7 +3382,7 @@ static int clean_tracks_exec(bContext *C, wmOperator *op)
                                                clip->tracking.act_track= NULL;
 
                                        BKE_tracking_free_track(track);
-                                       BLI_freelinkN(&clip->tracking.tracks, track);
+                                       BLI_freelinkN(tracksbase, track);
                                }
                        }
                }
@@ -3091,3 +3439,71 @@ void CLIP_OT_clean_tracks(wmOperatorType *ot)
        RNA_def_float(ot->srna, "error", 0.0f, 0.0f, FLT_MAX, "Reprojection Error", "Effect on tracks with have got larger reprojection error", 0.0f, 100.0f);
        RNA_def_enum(ot->srna, "action", actions_items, 0, "Action", "Cleanup action to execute");
 }
+
+/********************** add tracking object *********************/
+
+static int tracking_object_new_exec(bContext *C, wmOperator *UNUSED(op))
+{
+       SpaceClip *sc= CTX_wm_space_clip(C);
+       MovieClip *clip= ED_space_clip(sc);
+       MovieTracking *tracking= &clip->tracking;
+
+       BKE_tracking_new_object(tracking, "Object");
+
+       WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip);
+
+       return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_tracking_object_new(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Add Tracking Object";
+       ot->description= "Add new object for tracking";
+       ot->idname= "CLIP_OT_tracking_object_new";
+
+       /* api callbacks */
+       ot->exec= tracking_object_new_exec;
+       ot->poll= ED_space_clip_poll;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** remove tracking object *********************/
+
+static int tracking_object_remove_exec(bContext *C, wmOperator *op)
+{
+       SpaceClip *sc= CTX_wm_space_clip(C);
+       MovieClip *clip= ED_space_clip(sc);
+       MovieTracking *tracking= &clip->tracking;
+       MovieTrackingObject *object;
+
+       object= BKE_tracking_active_object(tracking);
+
+       if(object->flag&TRACKING_OBJECT_CAMERA) {
+               BKE_report(op->reports, RPT_WARNING, "Object used for camera tracking can't be deleted");
+               return OPERATOR_CANCELLED;
+       }
+
+       BKE_tracking_remove_object(tracking, object);
+
+       WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip);
+
+       return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_tracking_object_remove(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Movie Tracking Object";
+       ot->description= "Remove object for tracking";
+       ot->idname= "CLIP_OT_tracking_object_remove";
+
+       /* api callbacks */
+       ot->exec= tracking_object_remove_exec;
+       ot->poll= ED_space_clip_poll;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
index c647ff3df53ea60b775ceafdf57e45b4ba39bafd..8d8c79386c543cdd939e3f7872f2084260251162 100644 (file)
@@ -750,7 +750,9 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
                                        uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "use_fields"));
                                        uiItemR(row, &imaptr, "field_order", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
                                        
-                                       uiItemR(split, &imaptr, "use_premultiply", 0, NULL, ICON_NONE);
+                                       row= uiLayoutRow(layout, 0);
+                                       uiItemR(row, &imaptr, "use_premultiply", 0, NULL, ICON_NONE);
+                                       uiItemR(row, &imaptr, "use_color_unpremultiply", 0, NULL, ICON_NONE);
                                }
                        }
 
index 1a808e8ee5f2aed734a06f1ee6d0a7f9650ffc0f..9d4c5705bd17821b2b60f39edbcd45578b010b82 100644 (file)
@@ -248,12 +248,10 @@ static void node_area_listener(ScrArea *sa, wmNotifier *wmn)
                case NC_IMAGE:
                        if (wmn->action == NA_EDITED) {
                                if(type==NTREE_COMPOSIT) {
-                                       Scene *scene= wmn->window->screen->scene;
-                                       
                                        /* note that nodeUpdateID is already called by BKE_image_signal() on all
                                         * scenes so really this is just to know if the images is used in the compo else
                                         * painting on images could become very slow when the compositor is open. */
-                                       if(nodeUpdateID(scene->nodetree, wmn->reference))
+                                       if(nodeUpdateID(snode->nodetree, wmn->reference))
                                                ED_area_tag_refresh(sa);
                                }
                        }
index 3a45f3eb5bbb26346195a4b3a411db5ca8c8dbe2..5c33a138ad9917eb4a183d8dee98b44688795653 100644 (file)
@@ -1511,48 +1511,49 @@ static void draw_bundle_sphere(void)
        glCallList(displist);
 }
 
-static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, MovieClip *clip, int flag)
+static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D *v3d,
+                       MovieClip *clip, MovieTrackingObject *tracking_object, int flag, int *global_track_index)
 {
        MovieTracking *tracking= &clip->tracking;
        MovieTrackingTrack *track;
-       float mat[4][4], imat[4][4], curcol[4];
+       float mat[4][4], imat[4][4];
        unsigned char col[4], scol[4];
-       int bundlenr= 1;
-
-       if((v3d->flag2&V3D_SHOW_RECONSTRUCTION)==0)
-               return;
-
-       if(v3d->flag2&V3D_RENDER_OVERRIDE)
-               return;
-
-       glGetFloatv(GL_CURRENT_COLOR, curcol);
+       int tracknr= *global_track_index;
+       ListBase *tracksbase= BKE_tracking_object_tracks(tracking, tracking_object);
 
        UI_GetThemeColor4ubv(TH_TEXT, col);
        UI_GetThemeColor4ubv(TH_SELECT, scol);
 
        BKE_get_tracking_mat(scene, base->object, mat);
 
-       glEnable(GL_LIGHTING);
-       glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
-       glEnable(GL_COLOR_MATERIAL);
-       glShadeModel(GL_SMOOTH);
+       glPushMatrix();
 
-       /* current ogl matrix is translated in camera space, bundles should
-          be rendered in world space, so camera matrix should be "removed"
-          from current ogl matrix */
-       invert_m4_m4(imat, base->object->obmat);
+       if(tracking_object->flag & TRACKING_OBJECT_CAMERA) {
+               /* current ogl matrix is translated in camera space, bundles should
+                  be rendered in world space, so camera matrix should be "removed"
+                  from current ogl matrix */
+               invert_m4_m4(imat, base->object->obmat);
 
-       glPushMatrix();
-       glMultMatrixf(imat);
-       glMultMatrixf(mat);
+               glMultMatrixf(imat);
+               glMultMatrixf(mat);
+       }
+       else {
+               float obmat[4][4];
+
+               BKE_tracking_get_interpolated_camera(tracking, tracking_object, scene->r.cfra, obmat);
+
+               invert_m4_m4(imat, obmat);
+               glMultMatrixf(imat);
+       }
+
+       for (track= tracksbase->first; track; track= track->next) {
+               int selected= TRACK_SELECTED(track);
 
-       for ( track= tracking->tracks.first; track; track= track->next) {
-               int selected= track->flag&SELECT || track->pat_flag&SELECT || track->search_flag&SELECT;
                if((track->flag&TRACK_HAS_BUNDLE)==0)
                        continue;
 
                if(flag&DRAW_PICKING)
-                       glLoadName(base->selcol + (bundlenr<<16));
+                       glLoadName(base->selcol + (tracknr<<16));
 
                glPushMatrix();
                        glTranslatef(track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
@@ -1560,7 +1561,6 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d,
 
                        if(v3d->drawtype==OB_WIRE) {
                                glDisable(GL_LIGHTING);
-                               glDepthMask(0);
 
                                if(selected) {
                                        if(base==BASACT) UI_ThemeColor(TH_ACTIVE);
@@ -1572,7 +1572,6 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d,
 
                                drawaxes(0.05f, v3d->bundle_drawtype);
 
-                               glDepthMask(1);
                                glEnable(GL_LIGHTING);
                        } else if(v3d->drawtype>OB_WIRE) {
                                if(v3d->bundle_drawtype==OB_EMPTY_SPHERE) {
@@ -1581,7 +1580,6 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d,
                                                if(base==BASACT) UI_ThemeColor(TH_ACTIVE);
                                                else UI_ThemeColor(TH_SELECT);
 
-                                               glDepthMask(0);
                                                glLineWidth(2.f);
                                                glDisable(GL_LIGHTING);
                                                glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@@ -1591,7 +1589,6 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d,
                                                glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
                                                glEnable(GL_LIGHTING);
                                                glLineWidth(1.f);
-                                               glDepthMask(1);
                                        }
 
                                        if(track->flag&TRACK_CUSTOMCOLOR) glColor3fv(track->color);
@@ -1600,7 +1597,6 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d,
                                        draw_bundle_sphere();
                                } else {
                                        glDisable(GL_LIGHTING);
-                                       glDepthMask(0);
 
                                        if(selected) {
                                                if(base==BASACT) UI_ThemeColor(TH_ACTIVE);
@@ -1612,7 +1608,6 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d,
 
                                        drawaxes(0.05f, v3d->bundle_drawtype);
 
-                                       glDepthMask(1);
                                        glEnable(GL_LIGHTING);
                                }
                        }
@@ -1630,32 +1625,67 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d,
                        view3d_cached_text_draw_add(pos, track->name, 10, V3D_CACHE_TEXT_GLOBALSPACE, tcol);
                }
 
-               bundlenr++;
+               tracknr++;
        }
 
        if((flag & DRAW_PICKING)==0) {
-               if(v3d->flag2&V3D_SHOW_CAMERAPATH && clip->tracking.reconstruction.camnr) {
-                       int a= 0;
-                       MovieTrackingReconstruction *reconstruction= &tracking->reconstruction;
-                       MovieReconstructedCamera *camera= tracking->reconstruction.cameras;
+               if((v3d->flag2&V3D_SHOW_CAMERAPATH) && (tracking_object->flag&TRACKING_OBJECT_CAMERA)) {
+                       MovieTrackingReconstruction *reconstruction;
+                       reconstruction= BKE_tracking_object_reconstruction(tracking, tracking_object);
 
-                       glDisable(GL_LIGHTING);
-                       UI_ThemeColor(TH_CAMERA_PATH);
-                       glLineWidth(2.0f);
+                       if(reconstruction->camnr) {
+                               MovieReconstructedCamera *camera= reconstruction->cameras;
+                               int a= 0;
 
-                       glBegin(GL_LINE_STRIP);
-                               for(a= 0; a<reconstruction->camnr; a++, camera++) {
-                                       glVertex3fv(camera->mat[3]);
-                               }
-                       glEnd();
+                               glDisable(GL_LIGHTING);
+                               UI_ThemeColor(TH_CAMERA_PATH);
+                               glLineWidth(2.0f);
 
-                       glLineWidth(1.0f);
-                       glEnable(GL_LIGHTING);
+                               glBegin(GL_LINE_STRIP);
+                                       for(a= 0; a<reconstruction->camnr; a++, camera++) {
+                                               glVertex3fv(camera->mat[3]);
+                                       }
+                                       glEnd();
+
+                                       glLineWidth(1.0f);
+                                       glEnable(GL_LIGHTING);
+                       }
                }
        }
 
        glPopMatrix();
 
+       *global_track_index= tracknr;
+}
+
+static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, MovieClip *clip, int flag)
+{
+       MovieTracking *tracking= &clip->tracking;
+       MovieTrackingObject *tracking_object;
+       float curcol[4];
+       int global_track_index= 1;
+
+       if((v3d->flag2&V3D_SHOW_RECONSTRUCTION)==0)
+               return;
+
+       if(v3d->flag2&V3D_RENDER_OVERRIDE)
+               return;
+
+       glGetFloatv(GL_CURRENT_COLOR, curcol);
+
+       glEnable(GL_LIGHTING);
+       glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+       glEnable(GL_COLOR_MATERIAL);
+       glShadeModel(GL_SMOOTH);
+
+       tracking_object= tracking->objects.first;
+       while(tracking_object) {
+               draw_viewport_object_reconstruction(scene, base, v3d, clip, tracking_object,
+                                       flag, &global_track_index);
+
+               tracking_object= tracking_object->next;
+       }
+
        /* restore */
        glShadeModel(GL_FLAT);
        glDisable(GL_COLOR_MATERIAL);
@@ -6922,7 +6952,34 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                                ListBase targets = {NULL, NULL};
                                bConstraintTarget *ct;
                                
-                               if ((curcon->flag & CONSTRAINT_EXPAND) && (cti) && (cti->get_constraint_targets)) {
+                               if(ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_OBJECTSOLVER)) {
+                                       /* special case for object solver and follow track constraints because they don't fill
+                                          constraint targets properly (design limitation -- scene is needed for their target
+                                          but it can't be accessed from get_targets callvack) */
+
+                                       Object *camob= NULL;
+
+                                       if(cti->type==CONSTRAINT_TYPE_FOLLOWTRACK) {
+                                               bFollowTrackConstraint *data= (bFollowTrackConstraint *)curcon->data;
+
+                                               camob= data->camera ? data->camera : scene->camera;
+                                       }
+                                       else if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER) {
+                                               bObjectSolverConstraint *data= (bObjectSolverConstraint *)curcon->data;
+
+                                               camob= data->camera ? data->camera : scene->camera;
+                                       }
+
+                                       if(camob) {
+                                               setlinestyle(3);
+                                               glBegin(GL_LINES);
+                                               glVertex3fv(camob->obmat[3]);
+                                               glVertex3fv(ob->obmat[3]);
+                                               glEnd();
+                                               setlinestyle(0);
+                                       }
+                               }
+                               else if ((curcon->flag & CONSTRAINT_EXPAND) && (cti) && (cti->get_constraint_targets)) {
                                        cti->get_constraint_targets(curcon, &targets);
                                        
                                        for (ct= targets.first; ct; ct= ct->next) {
index 44264bd035511a4b7558fc108031e2eb2aeabece..0048d67b4fddec7116aa339dffef58c4497254f8 100644 (file)
@@ -1328,6 +1328,25 @@ Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2])
        return basact;
 }
 
+static void deselect_all_tracks(MovieTracking *tracking)
+{
+       MovieTrackingObject *object;
+
+       object= tracking->objects.first;
+       while(object) {
+               ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object);
+               MovieTrackingTrack *track= tracksbase->first;
+
+               while(track) {
+                       BKE_tracking_deselect_track(track, TRACK_AREA_ALL);
+
+                       track= track->next;
+               }
+
+               object= object->next;
+       }
+}
+
 /* mval is region coords */
 static int mouse_select(bContext *C, const int mval[2], short extend, short obcenter, short enumerate)
 {
@@ -1399,27 +1418,41 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short obce
                                if(basact->object->type==OB_CAMERA) {
                                        if(BASACT==basact) {
                                                int i, hitresult;
-                                               MovieTrackingTrack *track;
+                                               int changed= 0;
 
                                                for (i=0; i< hits; i++) {
                                                        hitresult= buffer[3+(i*4)];
 
                                                        /* if there's bundles in buffer select bundles first,
                                                           so non-camera elements should be ignored in buffer */
-                                                       if(basact->selcol != (hitresult & 0xFFFF))
+                                                       if(basact->selcol != (hitresult & 0xFFFF)) {
                                                                continue;
+                                                       }
 
                                                        /* index of bundle is 1<<16-based. if there's no "bone" index
                                                           in hight word, this buffer value belongs to camera,. not to bundle */
                                                        if(buffer[4*i+3] & 0xFFFF0000) {
                                                                MovieClip *clip= object_get_movieclip(scene, basact->object, 0);
-                                                               int selected;
-                                                               track= BKE_tracking_indexed_track(&clip->tracking, hitresult >> 16);
+                                                               MovieTracking *tracking= &clip->tracking;
+                                                               ListBase *tracksbase;
+                                                               MovieTrackingTrack *track;
+
+                                                               track= BKE_tracking_indexed_track(&clip->tracking, hitresult >> 16, &tracksbase);
+
+                                                               if(TRACK_SELECTED(track) && extend) {
+                                                                       changed= 0;
+                                                                       BKE_tracking_deselect_track(track, TRACK_AREA_ALL);
+                                                               }
+                                                               else {
+                                                                       int oldsel= TRACK_SELECTED(track) ? 1 : 0;
+                                                                       if(!extend)
+                                                                               deselect_all_tracks(tracking);
 
-                                                               selected= (track->flag&SELECT) || (track->pat_flag&SELECT) || (track->search_flag&SELECT);
+                                                                       BKE_tracking_select_track(tracksbase, track, TRACK_AREA_ALL, extend);
 
-                                                               if(selected && extend)  BKE_tracking_deselect_track(track, TRACK_AREA_ALL);
-                                                               else BKE_tracking_select_track(&clip->tracking, track, TRACK_AREA_ALL, extend);
+                                                                       if(oldsel!=(TRACK_SELECTED(track) ? 1 : 0))
+                                                                               changed= 1;
+                                                               }
 
                                                                basact->flag|= SELECT;
                                                                basact->object->flag= basact->flag;
@@ -1432,6 +1465,12 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short obce
                                                                break;
                                                        }
                                                }
+
+                                               if(!changed) {
+                                                       /* fallback to regular object selection if no new bundles were selected,
+                                                          allows to select object parented to reconstruction object */
+                                                       basact= mouse_select_eval_buffer(&vc, buffer, hits, mval, startbase, 0);
+                                               }
                                        }
                                }
                                else if(ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend) ) {        /* then bone is found */
index cf61fe9281428cc9e019023cb70fbb21e919ed1a..1f1a17ce5cd74e33969e638d5561c3828bc95b4e 100644 (file)
@@ -57,6 +57,7 @@
 #include "BKE_object.h"
 #include "BKE_tessmesh.h"
 #include "BKE_DerivedMesh.h"
+#include "BKE_scene.h"
 #include "BKE_tracking.h"
 
 #include "WM_api.h"
@@ -815,28 +816,55 @@ void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot)
 
 static void bundle_midpoint(Scene *scene, Object *ob, float vec[3])
 {
-       MovieTrackingTrack *track;
        MovieClip *clip= object_get_movieclip(scene, ob, 0);
+       MovieTracking *tracking= &clip->tracking;
+       MovieTrackingObject *object= tracking->objects.first;
        int ok= 0;
-       float min[3], max[3], mat[4][4], pos[3];
+       float min[3], max[3], mat[4][4], pos[3], cammat[4][4];
 
        if(!clip)
                return;
 
+       unit_m4(cammat);
+
+       if(!scene->camera)
+               scene->camera= scene_find_camera(scene);
+
+       if(scene->camera)
+               copy_m4_m4(cammat, scene->camera->obmat);
+
        BKE_get_tracking_mat(scene, ob, mat);
 
        INIT_MINMAX(min, max);
 
-       track= clip->tracking.tracks.first;
-       while(track) {
-               int selected= (track->flag&SELECT) || (track->pat_flag&SELECT) || (track->search_flag&SELECT);
-               if((track->flag&TRACK_HAS_BUNDLE) && selected) {
-                       ok= 1;
-                       mul_v3_m4v3(pos, mat, track->bundle_pos);
-                       DO_MINMAX(pos, min, max);
+       while(object) {
+               ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object);
+               MovieTrackingTrack *track= tracksbase->first;
+               float obmat[4][4];
+
+               if(object->flag & TRACKING_OBJECT_CAMERA) {
+                       copy_m4_m4(obmat, mat);
+               }
+               else {
+                       float imat[4][4];
+
+                       BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, imat);
+                       invert_m4(imat);
+
+                       mult_m4_m4m4(obmat, cammat, imat);
+               }
+
+               while(track) {
+                       if((track->flag&TRACK_HAS_BUNDLE) && TRACK_SELECTED(track)) {
+                               ok= 1;
+                               mul_v3_m4v3(pos, obmat, track->bundle_pos);
+                               DO_MINMAX(pos, min, max);
+                       }
+
+                       track= track->next;
                }
 
-               track= track->next;
+               object= object->next;
        }
 
        if(ok) {
index e916ae3486d5cc7083a16cdcd23f2bc6b42a8d5f..595303c0da45d3aac8b88bedad142105b81e467a 100644 (file)
@@ -4264,6 +4264,7 @@ static short constraints_list_needinv(TransInfo *t, ListBase *list)
                                if (con->type == CONSTRAINT_TYPE_CHILDOF) return 1;
                                if (con->type == CONSTRAINT_TYPE_FOLLOWPATH) return 1;
                                if (con->type == CONSTRAINT_TYPE_CLAMPTO) return 1;
+                               if (con->type == CONSTRAINT_TYPE_OBJECTSOLVER) return 1;
                                
                                        /* constraints that require this only under special conditions */
                                if (con->type == CONSTRAINT_TYPE_ROTLIKE) {
@@ -5441,6 +5442,7 @@ static void createTransTrackingData(bContext *C, TransInfo *t)
        TransData2D *td2d;
        SpaceClip *sc = CTX_wm_space_clip(C);
        MovieClip *clip = ED_space_clip(sc);
+       ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
        MovieTrackingTrack *track;
        MovieTrackingMarker *marker;
        TransDataTracking *tdt;
@@ -5454,7 +5456,7 @@ static void createTransTrackingData(bContext *C, TransInfo *t)
        /* count */
        t->total = 0;
 
-       track = clip->tracking.tracks.first;
+       track = tracksbase->first;
        while(track) {
                if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_LOCKED)==0) {
                        marker= BKE_tracking_get_marker(track, framenr);
@@ -5481,7 +5483,7 @@ static void createTransTrackingData(bContext *C, TransInfo *t)
        t->customFree= transDataTrackingFree;
 
        /* create actual data */
-       track = clip->tracking.tracks.first;
+       track = tracksbase->first;
        while(track) {
                if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_LOCKED)==0) {
                        marker= BKE_tracking_get_marker(track, framenr);
index dee7f958f2ebf79993d7bb8f75e0a56752941f9b..b6f75fe1b48c49d76b18c5b13f3621968b619d09 100644 (file)
@@ -641,10 +641,11 @@ static void recalcData_clip(TransInfo *t)
 {
        SpaceClip *sc= t->sa->spacedata.first;
        MovieClip *clip= ED_space_clip(sc);
+       ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
        MovieTrackingTrack *track;
        
        if(t->state == TRANS_CANCEL) {
-               track= clip->tracking.tracks.first;
+               track= tracksbase->first;
                while(track) {
                        if(TRACK_VIEW_SELECTED(sc, track)) {
                                MovieTrackingMarker *marker= BKE_tracking_ensure_marker(track, sc->user.framenr);
@@ -658,7 +659,7 @@ static void recalcData_clip(TransInfo *t)
        
        flushTransTracking(t);
        
-       track= clip->tracking.tracks.first;
+       track= tracksbase->first;
        while(track) {
                if(TRACK_VIEW_SELECTED(sc, track)) {
                        if (t->mode == TFM_TRANSLATION) {
index 5ce3d63fe86079d32087da9106ef42eee4c470e8..adf6f4a143bbae5c445d12e387b14f1fb7a5d743 100644 (file)
@@ -158,6 +158,7 @@ typedef struct ImBuf {
 #define IB_tiles                       (1 << 10)
 #define IB_tilecache           (1 << 11)
 #define IB_premul                      (1 << 12)
+#define IB_cm_predivide                (1 << 13)
 
 /*
  * The bit flag is stored in the ImBuf.ftype variable.
index 8a3f6358c5b3f68f6b1158b9131d3d7ca8602219..0dfc1852e290ce7bf997ce112cf0d0dfc5fc3a16 100644 (file)
@@ -453,7 +453,8 @@ void IMB_buffer_byte_from_byte(uchar *rect_to, const uchar *rect_from,
 
 void IMB_rect_from_float(struct ImBuf *ibuf)
 {
-       int predivide= 0, profile_from;
+       int predivide= (ibuf->flags & IB_cm_predivide);
+       int profile_from;
 
        /* verify we have a float buffer */
        if(ibuf->rect_float==NULL)
@@ -485,7 +486,8 @@ void IMB_partial_rect_from_float(struct ImBuf *ibuf, float *buffer, int x, int y
 {
        float *rect_float;
        uchar *rect_byte;
-       int predivide= 0, profile_from;
+       int predivide= (ibuf->flags & IB_cm_predivide);
+       int profile_from;
 
        /* verify we have a float buffer */
        if(ibuf->rect_float==NULL || buffer==NULL)
@@ -521,7 +523,8 @@ void IMB_partial_rect_from_float(struct ImBuf *ibuf, float *buffer, int x, int y
 
 void IMB_float_from_rect(struct ImBuf *ibuf)
 {
-       int predivide= 0, profile_from;
+       int predivide= (ibuf->flags & IB_cm_predivide);
+       int profile_from;
 
        /* verify if we byte and float buffers */
        if(ibuf->rect==NULL)
@@ -546,7 +549,7 @@ void IMB_float_from_rect(struct ImBuf *ibuf)
 /* no profile conversion */
 void IMB_float_from_rect_simple(struct ImBuf *ibuf)
 {
-       int predivide= 0;
+       int predivide= (ibuf->flags & IB_cm_predivide);
 
        if(ibuf->rect_float==NULL)
                imb_addrectfloatImBuf(ibuf);
@@ -558,7 +561,8 @@ void IMB_float_from_rect_simple(struct ImBuf *ibuf)
 
 void IMB_convert_profile(struct ImBuf *ibuf, int profile)
 {
-       int predivide= 0, profile_from, profile_to;
+       int predivide= (ibuf->flags & IB_cm_predivide);
+       int profile_from, profile_to;
 
        if(ibuf->profile == profile)
                return;
@@ -599,7 +603,8 @@ void IMB_convert_profile(struct ImBuf *ibuf, int profile)
  * if the return  */
 float *IMB_float_profile_ensure(struct ImBuf *ibuf, int profile, int *alloc)
 {
-       int predivide= 0, profile_from, profile_to;
+       int predivide= (ibuf->flags & IB_cm_predivide);
+       int profile_from, profile_to;
 
        /* determine profiles */
        if(ibuf->profile == IB_PROFILE_NONE)
index dd18ba903f6a5fb5c2db48b9e64844f2a3a18ef8..8fdbde60bab1047dafa708e3ef0d164440edb38b 100644 (file)
@@ -415,6 +415,8 @@ typedef struct bFollowTrackConstraint {
        struct MovieClip        *clip;
        char    track[24];
        int             flag, pad;
+       char            object[24];
+       struct Object *camera;
 } bFollowTrackConstraint;
 
 /* Camera Solver constraints */
@@ -423,6 +425,15 @@ typedef struct bCameraSolverConstraint {
        int             flag, pad;
 } bCameraSolverConstraint;
 
+/* Camera Solver constraints */
+typedef struct bObjectSolverConstraint {
+       struct MovieClip        *clip;
+       int             flag, pad;
+       char            object[24];
+       float           invmat[4][4];   /* parent-inverse matrix to use */
+       struct Object *camera;
+} bObjectSolverConstraint;
+
 /* ------------------------------------------ */
 
 /* bConstraint->type 
@@ -458,6 +469,7 @@ typedef enum eBConstraint_Types {
        CONSTRAINT_TYPE_PIVOT,                          /* Pivot Constraint */
        CONSTRAINT_TYPE_FOLLOWTRACK,            /* Follow Track Constraint */
        CONSTRAINT_TYPE_CAMERASOLVER,           /* Camera Solver Constraint */
+       CONSTRAINT_TYPE_OBJECTSOLVER,           /* Object Solver Constraint */
        
        /* NOTE: no constraints are allowed to be added after this */
        NUM_CONSTRAINT_TYPES
@@ -765,6 +777,11 @@ typedef enum eCameraSolver_Flags {
        CAMERASOLVER_ACTIVECLIP = (1<<0)
 } eCameraSolver_Flags;
 
+/* ObjectSolver Constraint -> flag */
+typedef enum eObjectSolver_Flags {
+       OBJECTSOLVER_ACTIVECLIP = (1<<0)
+} eObjectSolver_Flags;
+
 /* Rigid-Body Constraint */
 #define CONSTRAINT_DRAW_PIVOT 0x40
 #define        CONSTRAINT_DISABLE_LINKED_COLLISION 0x80
index fc8807d0f7cfc831e129401acbb5132be0280368..a1b0ab06ecd7b7dca42dc52d5cc8ca5b90251d4e 100644 (file)
@@ -112,14 +112,14 @@ typedef struct Image {
 /* **************** IMAGE ********************* */
 
 /* Image.flag */
-#define IMA_FIELDS             1
-#define IMA_STD_FIELD  2
-#define IMA_DO_PREMUL  4
-
-#define        IMA_REFLECT             16
-#define IMA_NOCOLLECT   32
-#define IMA_DEPRECATED 64
-#define IMA_OLD_PREMUL 128
+#define IMA_FIELDS                     1
+#define IMA_STD_FIELD          2
+#define IMA_DO_PREMUL          4
+#define IMA_REFLECT                    16
+#define IMA_NOCOLLECT          32
+#define IMA_DEPRECATED         64
+#define IMA_OLD_PREMUL         128
+#define IMA_CM_PREDIVIDE       256
 
 /* Image.tpageflag */
 #define IMA_TILES                      1
index d1ab12433fb6b7371ecc2f3f2d2fe263d37dd981..9b49bc53ef3684eed33676eac138eb9819423390 100644 (file)
@@ -1100,7 +1100,8 @@ typedef struct Scene {
 #define R_ALPHAKEY             2
 
 /* color_mgt_flag */
-#define R_COLOR_MANAGEMENT     1
+#define R_COLOR_MANAGEMENT              (1 << 0)
+#define R_COLOR_MANAGEMENT_PREDIVIDE    (1 << 1)
 
 /* subimtype, flag options for imtype */
 #define R_OPENEXR_HALF    1                                      /*deprecated*/
index a93ce75ebc9d9a702793fd5b7bb35a4ae3dfd260..131c540ac4708553c101222e9c6227d39a5811b4 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 {
@@ -172,6 +175,17 @@ typedef struct MovieTrackingReconstruction {
        struct MovieReconstructedCamera *cameras;       /* reconstructed cameras */
 } MovieTrackingReconstruction;
 
+typedef struct MovieTrackingObject {
+       struct MovieTrackingObject *next, *prev;
+
+       char name[24];                  /* Name of tracking object */
+       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;
+
 typedef struct MovieTrackingStats {
        char message[256];
 } MovieTrackingStats;
@@ -179,11 +193,14 @@ typedef struct MovieTrackingStats {
 typedef struct MovieTracking {
        MovieTrackingSettings settings; /* different tracking-related settings */
        MovieTrackingCamera camera;             /* camera intrinsics */
-       ListBase tracks;                                /* all tracks */
-       MovieTrackingReconstruction reconstruction;     /* reconstruction data */
+       ListBase tracks;                                /* list of tracks used for camera object */
+       MovieTrackingReconstruction reconstruction;     /* reconstruction data for camera object */
        MovieTrackingStabilization stabilization;       /* stabilization data */
        MovieTrackingTrack *act_track;          /* active track */
 
+       ListBase objects;
+       int objectnr, tot_object;               /* index of active object and total number of objects */
+
        MovieTrackingStats *stats;              /* statistics displaying in clip editor */
 } MovieTracking;
 
@@ -207,6 +224,7 @@ enum {
 #define TRACK_LOCKED           (1<<6)
 #define TRACK_CUSTOMCOLOR      (1<<7)
 #define TRACK_USE_2D_STAB      (1<<8)
+#define TRACK_PREVIEW_GRAYSCALE        (1<<9)
 
 /* MovieTrackingTrack->tracker */
 #define TRACKER_KLT            0
@@ -241,6 +259,9 @@ enum {
 /* MovieTrackingReconstruction->flag */
 #define TRACKING_RECONSTRUCTED (1<<0)
 
+/* MovieTrackingObject->flag */
+#define TRACKING_OBJECT_CAMERA         (1<<0)
+
 #define TRACKING_CLEAN_SELECT                  0
 #define TRACKING_CLEAN_DELETE_TRACK            1
 #define TRACKING_CLEAN_DELETE_SEGMENT  2
index fb0fcfc558a663c6f7f0ea327579eab11752125d..d95b7685d078aec566cdda633851e9cbfab2353b 100644 (file)
@@ -334,6 +334,7 @@ extern StructRNA RNA_MotionPath;
 extern StructRNA RNA_MotionPathVert;
 extern StructRNA RNA_MouseSensor;
 extern StructRNA RNA_MovieSequence;
+extern StructRNA RNA_MovieTrackingObject;
 extern StructRNA RNA_MulticamSequence;
 extern StructRNA RNA_MultiresModifier;
 extern StructRNA RNA_MusgraveTexture;
index 4ab14550fd1a5ff2aebe00727b03c308945ba9c9..6439d22e8085aeda1dfdf39f6f8ab572a555028f 100644 (file)
@@ -45,6 +45,7 @@
 EnumPropertyItem constraint_type_items[] ={
        {0, "", 0, "Motion Tracking", ""},
        {CONSTRAINT_TYPE_CAMERASOLVER, "CAMERA_SOLVER", ICON_CONSTRAINT_DATA, "Camera Solver", ""},
+       {CONSTRAINT_TYPE_OBJECTSOLVER, "OBJECT_SOLVER", ICON_CONSTRAINT_DATA, "Object Solver", ""},
        {CONSTRAINT_TYPE_FOLLOWTRACK, "FOLLOW_TRACK", ICON_CONSTRAINT_DATA, "Follow Track", ""},
        {0, "", 0, "Transform", ""},
        {CONSTRAINT_TYPE_LOCLIKE, "COPY_LOCATION", ICON_CONSTRAINT_DATA, "Copy Location", ""},
@@ -163,6 +164,8 @@ static StructRNA *rna_ConstraintType_refine(struct PointerRNA *ptr)
                        return &RNA_FollowTrackConstraint;
                case CONSTRAINT_TYPE_CAMERASOLVER:
                        return &RNA_CameraSolverConstraint;
+               case CONSTRAINT_TYPE_OBJECTSOLVER:
+                       return &RNA_ObjectSolverConstraint;
                default:
                        return &RNA_UnknownType;
        }
@@ -327,6 +330,49 @@ static void rna_SplineIKConstraint_joint_bindings_set(PointerRNA *ptr, const flo
        memcpy(ikData->points, values, ikData->numpoints * sizeof(float));
 }
 
+static int rna_Constraint_cameraObject_poll(PointerRNA *ptr, PointerRNA value)
+{
+       Object *ob= (Object*)value.data;
+
+       if (ob) {
+               if (ob->type == OB_CAMERA && ob != (Object*)ptr->id.data) {
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+static void rna_Constraint_followTrack_camera_set(PointerRNA *ptr, PointerRNA value)
+{
+       bConstraint *con= (bConstraint*)ptr->data;
+       bFollowTrackConstraint *data= (bFollowTrackConstraint*)con->data;
+       Object *ob= (Object*)value.data;
+
+       if (ob) {
+               if (ob->type == OB_CAMERA && ob != (Object*)ptr->id.data) {
+                       data->camera= ob;
+               }
+       } else {
+               data->camera= NULL;
+       }
+}
+
+static void rna_Constraint_objectSolver_camera_set(PointerRNA *ptr, PointerRNA value)
+{
+       bConstraint *con= (bConstraint*)ptr->data;
+       bObjectSolverConstraint *data= (bObjectSolverConstraint*)con->data;
+       Object *ob= (Object*)value.data;
+
+       if (ob) {
+               if (ob->type == OB_CAMERA && ob != (Object*)ptr->id.data) {
+                       data->camera= ob;
+               }
+       } else {
+               data->camera= NULL;
+       }
+}
+
 #else
 
 EnumPropertyItem constraint_distance_items[] = {
@@ -2066,6 +2112,20 @@ static void rna_def_constraint_follow_track(BlenderRNA *brna)
        RNA_def_property_boolean_sdna(prop, NULL, "flag", FOLLOWTRACK_USE_3D_POSITION);
        RNA_def_property_ui_text(prop, "3D Position", "Use 3D position of track to parent to");
        RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+
+       /* object */
+       prop= RNA_def_property(srna, "object", PROP_STRING, PROP_NONE);
+       RNA_def_property_string_sdna(prop, NULL, "object");
+       RNA_def_property_ui_text(prop, "Object", "Movie tracking object to follow (if empty, camera object is used)");
+       RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
+
+       /* camera */
+       prop= RNA_def_property(srna, "camera", PROP_POINTER, PROP_NONE);
+       RNA_def_property_pointer_sdna(prop, NULL, "camera");
+       RNA_def_property_ui_text(prop, "Camera", "Camera to which motion is parented (if empty active scene camera is used)");
+       RNA_def_property_flag(prop, PROP_EDITABLE);
+       RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
+       RNA_def_property_pointer_funcs(prop, NULL, "rna_Constraint_followTrack_camera_set", NULL, "rna_Constraint_cameraObject_poll");
 }
 
 static void rna_def_constraint_camera_solver(BlenderRNA *brna)
@@ -2074,7 +2134,7 @@ static void rna_def_constraint_camera_solver(BlenderRNA *brna)
        PropertyRNA *prop;
 
        srna= RNA_def_struct(brna, "CameraSolverConstraint", "Constraint");
-       RNA_def_struct_ui_text(srna, "Follow Track Constraint", "Lock motion to the reconstructed camera movement");
+       RNA_def_struct_ui_text(srna, "Camera Solver Constraint", "Lock motion to the reconstructed camera movement");
        RNA_def_struct_sdna_from(srna, "bCameraSolverConstraint", "data");
 
        /* movie clip */
@@ -2091,6 +2151,43 @@ static void rna_def_constraint_camera_solver(BlenderRNA *brna)
        RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
 }
 
+static void rna_def_constraint_object_solver(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+
+       srna= RNA_def_struct(brna, "ObjectSolverConstraint", "Constraint");
+       RNA_def_struct_ui_text(srna, "Object Solver Constraint", "Lock motion to the reconstructed object movement");
+       RNA_def_struct_sdna_from(srna, "bObjectSolverConstraint", "data");
+
+       /* movie clip */
+       prop= RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE);
+       RNA_def_property_pointer_sdna(prop, NULL, "clip");
+       RNA_def_property_ui_text(prop, "Movie Clip", "Movie Clip to get tracking data from");
+       RNA_def_property_flag(prop, PROP_EDITABLE);
+       RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
+
+       /* use default clip */
+       prop= RNA_def_property(srna, "use_active_clip", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", CAMERASOLVER_ACTIVECLIP);
+       RNA_def_property_ui_text(prop, "Active Clip", "Use active clip defined in scene");
+       RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+
+       /* object */
+       prop= RNA_def_property(srna, "object", PROP_STRING, PROP_NONE);
+       RNA_def_property_string_sdna(prop, NULL, "object");
+       RNA_def_property_ui_text(prop, "Object", "Movie tracking object to follow");
+       RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
+
+       /* camera */
+       prop= RNA_def_property(srna, "camera", PROP_POINTER, PROP_NONE);
+       RNA_def_property_pointer_sdna(prop, NULL, "camera");
+       RNA_def_property_ui_text(prop, "Camera", "Camera to which motion is parented (if empty active scene camera is used)");
+       RNA_def_property_flag(prop, PROP_EDITABLE);
+       RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
+       RNA_def_property_pointer_funcs(prop, NULL, "rna_Constraint_objectSolver_camera_set", NULL, "rna_Constraint_cameraObject_poll");
+}
+
 /* base struct for constraints */
 void RNA_def_constraint(BlenderRNA *brna)
 {
@@ -2203,6 +2300,7 @@ void RNA_def_constraint(BlenderRNA *brna)
        rna_def_constraint_pivot(brna);
        rna_def_constraint_follow_track(brna);
        rna_def_constraint_camera_solver(brna);
+       rna_def_constraint_object_solver(brna);
 }
 
 #endif
index 6f6a27abe7c911b2ad0a78cc8eb91d08d5c57ed1..9e7f4a349e7c534ef4fcf3464aae2ba94a2c073b 100644 (file)
@@ -40,6 +40,7 @@
 #include "BKE_image.h"
 
 #include "WM_types.h"
+#include "WM_api.h"
 
 static EnumPropertyItem image_source_items[]= {
        {IMA_SRC_FILE, "FILE", 0, "Single Image", "Single image file"},
@@ -110,6 +111,7 @@ static void rna_Image_reload_update(Main *UNUSED(bmain), Scene *UNUSED(scene), P
 {
        Image *ima= ptr->id.data;
        BKE_image_signal(ima, NULL, IMA_SIGNAL_RELOAD);
+       WM_main_add_notifier(NC_IMAGE|NA_EDITED, &ima->id);
        DAG_id_tag_update(&ima->id, 0);
 }
 
@@ -475,6 +477,11 @@ static void rna_def_image(BlenderRNA *brna)
        RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_DO_PREMUL);
        RNA_def_property_ui_text(prop, "Premultiply", "Convert RGB from key alpha to premultiplied alpha");
        RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_reload_update");
+       
+       prop= RNA_def_property(srna, "use_color_unpremultiply", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_CM_PREDIVIDE);
+       RNA_def_property_ui_text(prop, "Color Unpremultiply", "For premultiplied alpha images, do color space conversion on colors without alpha, to avoid fringing for images with light backgrounds");
+       RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, "rna_Image_reload_update");
 
        prop= RNA_def_property(srna, "is_dirty", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_funcs(prop, "rna_Image_dirty_get", NULL);
index c618912f4b53cc08938d12b3d6d01080922733cd..529bea38632ce0f25f06dcb779144ea77449c8c8 100644 (file)
@@ -3230,7 +3230,11 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
        RNA_def_property_boolean_sdna(prop, NULL, "color_mgt_flag", R_COLOR_MANAGEMENT);
        RNA_def_property_ui_text(prop, "Color Management", "Use linear workflow - gamma corrected imaging pipeline");
        RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_RenderSettings_color_management_update");
-
+       
+       prop= RNA_def_property(srna, "use_color_unpremultiply", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "color_mgt_flag", R_COLOR_MANAGEMENT_PREDIVIDE);
+       RNA_def_property_ui_text(prop, "Color Unpremultipy", "For premultiplied alpha render output, do color space conversion on colors without alpha, to avoid fringing on light backgrounds");
+       RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
        
        prop= RNA_def_property(srna, "use_file_extension", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_EXTENSION);
index 2fdf733752b27384cd5a49ea8820a810eb6dae9b..bbec6484c5f144c03ce8c421ee755dd42c7a6401 100644 (file)
@@ -90,43 +90,87 @@ static void rna_tracking_defaultSettings_searchUpdate(Main *UNUSED(bmain), Scene
 static void rna_tracking_tracks_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
        MovieClip *clip= (MovieClip*)ptr->id.data;
+
        rna_iterator_listbase_begin(iter, &clip->tracking.tracks, NULL);
 }
 
-static void rna_tracking_tracks_add(MovieTracking *tracking, int frame, int number)
+static void rna_tracking_objects_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
-       int a;
+       MovieClip *clip= (MovieClip*)ptr->id.data;
 
-       for(a= 0; a<number; a++)
-               BKE_tracking_add_track(tracking, 0, 0, frame, 1, 1);
+       rna_iterator_listbase_begin(iter, &clip->tracking.objects, NULL);
+}
 
-       WM_main_add_notifier(NC_MOVIECLIP|NA_EDITED, NULL);
+static int rna_tracking_active_object_index_get(PointerRNA *ptr)
+{
+       MovieClip *clip= (MovieClip*)ptr->id.data;
+
+       return clip->tracking.objectnr;
+}
+
+static void rna_tracking_active_object_index_set(PointerRNA *ptr, int value)
+{
+       MovieClip *clip= (MovieClip*)ptr->id.data;
+
+       clip->tracking.objectnr= value;
+}
+
+static void rna_tracking_active_object_index_range(PointerRNA *ptr, int *min, int *max)
+{
+       MovieClip *clip= (MovieClip*)ptr->id.data;
+
+       *min= 0;
+       *max= clip->tracking.tot_object-1;
+       *max= MAX2(0, *max);
 }
 
 static PointerRNA rna_tracking_active_track_get(PointerRNA *ptr)
 {
        MovieClip *clip= (MovieClip*)ptr->id.data;
+       MovieTrackingTrack *act_track= BKE_tracking_active_track(&clip->tracking);
 
-       return rna_pointer_inherit_refine(ptr, &RNA_MovieTrackingTrack, clip->tracking.act_track);
+       return rna_pointer_inherit_refine(ptr, &RNA_MovieTrackingTrack, act_track);
 }
 
 static void rna_tracking_active_track_set(PointerRNA *ptr, PointerRNA value)
 {
        MovieClip *clip= (MovieClip*)ptr->id.data;
        MovieTrackingTrack *track= (MovieTrackingTrack *)value.data;
-       int index= BLI_findindex(&clip->tracking.tracks, track);
+       ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
+       int index= BLI_findindex(tracksbase, track);
 
-       if(index>=0) clip->tracking.act_track= track;
-       else clip->tracking.act_track= NULL;
+       if(index>=0)
+               clip->tracking.act_track= track;
+       else
+               clip->tracking.act_track= NULL;
 }
 
 void rna_trackingTrack_name_set(PointerRNA *ptr, const char *value)
 {
        MovieClip *clip= (MovieClip *)ptr->id.data;
+       MovieTracking *tracking= &clip->tracking;
        MovieTrackingTrack *track= (MovieTrackingTrack *)ptr->data;
+       ListBase *tracksbase= &tracking->tracks;
+
        BLI_strncpy(track->name, value, sizeof(track->name));
 
-       BKE_track_unique_name(&clip->tracking, track);
+       /* TODO: it's a bit difficult to find list track came from knowing just
+                movie clip ID and MovieTracking structure, so keep this naive
+                        search for a while */
+       if(BLI_findindex(tracksbase, track) < 0) {
+               MovieTrackingObject *object= tracking->objects.first;
+
+               while(object) {
+                       if(BLI_findindex(&object->tracks, track)) {
+                               tracksbase= &object->tracks;
+                               break;
+                       }
+
+                       object= object->next;
+               }
+       }
+
+       BKE_track_unique_name(tracksbase, track);
 }
 
 static int rna_trackingTrack_select_get(PointerRNA *ptr)
@@ -257,8 +301,102 @@ static void rna_tracking_flushUpdate(Main *UNUSED(bmain), Scene *scene, PointerR
        DAG_id_tag_update(&clip->id, 0);
 }
 
+static void rna_trackingObject_tracks_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+       MovieTrackingObject *object= (MovieTrackingObject* )ptr->data;
+
+       rna_iterator_listbase_begin(iter, &object->tracks, NULL);
+}
+
+static PointerRNA rna_tracking_active_object_get(PointerRNA *ptr)
+{
+       MovieClip *clip= (MovieClip*)ptr->id.data;
+       MovieTrackingObject *object= BLI_findlink(&clip->tracking.objects, clip->tracking.objectnr);
+
+       return rna_pointer_inherit_refine(ptr, &RNA_MovieTrackingObject, object);
+}
+
+static void rna_tracking_active_object_set(PointerRNA *ptr, PointerRNA value)
+{
+       MovieClip *clip= (MovieClip*)ptr->id.data;
+       MovieTrackingObject *object= (MovieTrackingObject *)value.data;
+       int index= BLI_findindex(&clip->tracking.objects, object);
+
+       if(index>=0) clip->tracking.objectnr= index;
+       else clip->tracking.objectnr= 0;
+}
+
+void rna_trackingObject_name_set(PointerRNA *ptr, const char *value)
+{
+       MovieClip *clip= (MovieClip *)ptr->id.data;
+       MovieTrackingObject *object= (MovieTrackingObject *)ptr->data;
+
+       BLI_strncpy(object->name, value, sizeof(object->name));
+
+       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)
+{
+       int a, width, height;
+       MovieClipUser user= {0};
+
+       user.framenr= 1;
+
+       BKE_movieclip_get_size(clip, &user, &width, &height);
+
+       for(a= 0; a<number; a++)
+               BKE_tracking_add_track(tracking, tracksbase, 0, 0, frame, width, height);
+}
+
+static void rna_tracking_tracks_add(ID *id, MovieTracking *tracking, int frame, int number)
+{
+       MovieClip *clip= (MovieClip *) id;
+
+       add_tracks_to_base(clip, tracking, &tracking->tracks, frame, number);
+
+       WM_main_add_notifier(NC_MOVIECLIP|NA_EDITED, NULL);
+}
+
+static void rna_trackingObject_tracks_add(ID *id, MovieTrackingObject *object, int frame, int number)
+{
+       MovieClip *clip= (MovieClip *) id;
+       ListBase *tracksbase= &object->tracks;
+
+       if(object->flag&TRACKING_OBJECT_CAMERA)
+               tracksbase= &clip->tracking.tracks;
+
+       add_tracks_to_base(clip, &clip->tracking, tracksbase, frame, number);
+
+       WM_main_add_notifier(NC_MOVIECLIP|NA_EDITED, NULL);
+}
+
+static MovieTrackingObject *rna_tracking_object_new(MovieTracking *tracking, const char *name)
+{
+       MovieTrackingObject *object= BKE_tracking_new_object(tracking, name);
+
+       WM_main_add_notifier(NC_MOVIECLIP|NA_EDITED, NULL);
+
+       return object;
+}
+
+void rna_tracking_object_remove(MovieTracking *tracking, MovieTrackingObject *object)
+{
+       BKE_tracking_remove_object(tracking, object);
+
+       WM_main_add_notifier(NC_MOVIECLIP|NA_EDITED, NULL);
+}
+
 static MovieTrackingMarker *rna_trackingTrack_marker_find_frame(MovieTrackingTrack *track, int framenr)
 {
        return BKE_tracking_get_marker(track, framenr);
@@ -442,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)
@@ -673,6 +819,12 @@ static void rna_def_trackingTrack(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Use Blue Channel", "Use blue channel from footage for tracking");
        RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL);
 
+       /* preview_grayscale */
+       prop= RNA_def_property(srna, "use_grayscale_preview", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_PREVIEW_GRAYSCALE);
+       RNA_def_property_ui_text(prop, "Grayscale", "Display what the tracking algorithm sees in the preview");
+       RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL);
+
        /* has bundle */
        prop= RNA_def_property(srna, "has_bundle", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_HAS_BUNDLE);
@@ -883,18 +1035,42 @@ static void rna_def_trackingReconstruction(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Cameras", "Collection of solved cameras");
 }
 
-static void rna_def_trackingTracks(BlenderRNA *brna, PropertyRNA *cprop)
+static void rna_def_trackingTracks(BlenderRNA *brna)
 {
        StructRNA *srna;
        FunctionRNA *func;
        PropertyRNA *prop;
 
-       RNA_def_property_srna(cprop, "MovieTrackingTracks");
        srna= RNA_def_struct(brna, "MovieTrackingTracks", NULL);
        RNA_def_struct_sdna(srna, "MovieTracking");
        RNA_def_struct_ui_text(srna, "Movie Tracks", "Collection of movie tracking tracks");
 
        func= RNA_def_function(srna, "add", "rna_tracking_tracks_add");
+       RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+       RNA_def_function_ui_description(func, "Add a number of tracks to this movie clip");
+       RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to add tracks on", MINFRAME, MAXFRAME);
+       RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of tracks to add to the movie clip", 0, INT_MAX);
+
+       /* active track */
+       prop= RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
+       RNA_def_property_struct_type(prop, "MovieTrackingTrack");
+       RNA_def_property_pointer_funcs(prop, "rna_tracking_active_track_get", "rna_tracking_active_track_set", NULL, NULL);
+       RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK);
+       RNA_def_property_ui_text(prop, "Active Track", "Active track in this tracking data object");
+}
+
+static void rna_def_trackingObjectTracks(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       FunctionRNA *func;
+       PropertyRNA *prop;
+
+       srna= RNA_def_struct(brna, "MovieTrackingObjectTracks", NULL);
+       RNA_def_struct_sdna(srna, "MovieTrackingObject");
+       RNA_def_struct_ui_text(srna, "Movie Tracks", "Collection of movie tracking tracks");
+
+       func= RNA_def_function(srna, "add", "rna_trackingObject_tracks_add");
+       RNA_def_function_flag(func, FUNC_USE_SELF_ID);
        RNA_def_function_ui_description(func, "Add a number of tracks to this movie clip");
        RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to add tracks on", MINFRAME, MAXFRAME);
        RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of tracks to add to the movie clip", 0, INT_MAX);
@@ -907,6 +1083,81 @@ static void rna_def_trackingTracks(BlenderRNA *brna, PropertyRNA *cprop)
        RNA_def_property_ui_text(prop, "Active Track", "Active track in this tracking data object");
 }
 
+static void rna_def_trackingObject(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+
+       srna= RNA_def_struct(brna, "MovieTrackingObject", NULL);
+       RNA_def_struct_ui_text(srna, "Movie tracking object data", "Match-moving object tracking and reconstruction data");
+
+       /* name */
+       prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+       RNA_def_property_ui_text(prop, "Name", "Unique name of object");
+       RNA_def_property_string_funcs(prop, NULL, NULL, "rna_trackingObject_name_set");
+       RNA_def_property_string_maxlength(prop, MAX_ID_NAME);
+       RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
+       RNA_def_struct_name_property(srna, prop);
+
+       /* is_camera */
+       prop= RNA_def_property(srna, "is_camera", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_OBJECT_CAMERA);
+       RNA_def_property_ui_text(prop, "Camera", "Object is used for camera tracking");
+       RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL);
+
+       /* tracks */
+       prop= RNA_def_property(srna, "tracks", PROP_COLLECTION, PROP_NONE);
+       RNA_def_property_collection_funcs(prop, "rna_trackingObject_tracks_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0);
+       RNA_def_property_struct_type(prop, "MovieTrackingTrack");
+       RNA_def_property_ui_text(prop, "Tracks", "Collection of tracks in this tracking data object");
+       RNA_def_property_srna(prop, "MovieTrackingObjectTracks");
+
+       /* 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)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+
+       FunctionRNA *func;
+       PropertyRNA *parm;
+
+       RNA_def_property_srna(cprop, "MovieTrackingObjects");
+       srna= RNA_def_struct(brna, "MovieTrackingObjects", NULL);
+       RNA_def_struct_sdna(srna, "MovieTracking");
+       RNA_def_struct_ui_text(srna, "Movie Objects", "Collection of movie trackingobjects");
+
+       func= RNA_def_function(srna, "new", "rna_tracking_object_new");
+       RNA_def_function_ui_description(func, "Add tracking object to this movie clip");
+       RNA_def_string(func, "name", "", 0, "", "Name of new object");
+       parm= RNA_def_pointer(func, "object", "MovieTrackingObject", "", "New motion tracking object");
+       RNA_def_function_return(func, parm);
+
+       func= RNA_def_function(srna, "remove", "rna_tracking_object_remove");
+       RNA_def_function_ui_description(func, "Remove tracking object from this movie clip");
+       parm= RNA_def_pointer(func, "object", "MovieTrackingObject", "", "Motion tracking object to be removed");
+
+       /* active object */
+       prop= RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
+       RNA_def_property_struct_type(prop, "MovieTrackingObject");
+       RNA_def_property_pointer_funcs(prop, "rna_tracking_active_object_get", "rna_tracking_active_object_set", NULL, NULL);
+       RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK);
+       RNA_def_property_ui_text(prop, "Active Object", "Active object in this tracking data object");
+}
+
 static void rna_def_tracking(BlenderRNA *brna)
 {
        StructRNA *srna;
@@ -915,8 +1166,11 @@ static void rna_def_tracking(BlenderRNA *brna)
        rna_def_trackingSettings(brna);
        rna_def_trackingCamera(brna);
        rna_def_trackingTrack(brna);
+       rna_def_trackingTracks(brna);
+       rna_def_trackingObjectTracks(brna);
        rna_def_trackingStabilization(brna);
        rna_def_trackingReconstruction(brna);
+       rna_def_trackingObject(brna);
 
        srna= RNA_def_struct(brna, "MovieTracking", NULL);
        RNA_def_struct_ui_text(srna, "Movie tracking data", "Match-moving data for tracking");
@@ -934,7 +1188,7 @@ static void rna_def_tracking(BlenderRNA *brna)
        RNA_def_property_collection_funcs(prop, "rna_tracking_tracks_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0);
        RNA_def_property_struct_type(prop, "MovieTrackingTrack");
        RNA_def_property_ui_text(prop, "Tracks", "Collection of tracks in this tracking data object");
-       rna_def_trackingTracks(brna, prop);
+       RNA_def_property_srna(prop, "MovieTrackingTracks");
 
        /* stabilization */
        prop= RNA_def_property(srna, "stabilization", PROP_POINTER, PROP_NONE);
@@ -943,6 +1197,20 @@ static void rna_def_tracking(BlenderRNA *brna)
        /* reconstruction */
        prop= RNA_def_property(srna, "reconstruction", PROP_POINTER, PROP_NONE);
        RNA_def_property_struct_type(prop, "MovieTrackingReconstruction");
+
+       /* objects */
+       prop= RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE);
+       RNA_def_property_collection_funcs(prop, "rna_tracking_objects_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0);
+       RNA_def_property_struct_type(prop, "MovieTrackingObject");
+       RNA_def_property_ui_text(prop, "Objects", "Collection of objects in this tracking data object");
+       rna_def_trackingObjects(brna, prop);
+
+       /* active object index */
+       prop= RNA_def_property(srna, "active_object_index", PROP_INT, PROP_NONE);
+       RNA_def_property_int_sdna(prop, NULL, "objectnr");
+       RNA_def_property_int_funcs(prop, "rna_tracking_active_object_index_get", "rna_tracking_active_object_index_set", "rna_tracking_active_object_index_range");
+       RNA_def_property_ui_text(prop, "Active Object Index", "Index of active object");
+       RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL);
 }
 
 void RNA_def_tracking(BlenderRNA *brna)
index 8aaf1771b68eaa1da3dfbb3e895d55ca265606cf..72037f232add2e6d3ff836afe52fe91217dd1743 100644 (file)
@@ -607,7 +607,7 @@ void generate_preview(void *data, bNode *node, CompBuf *stackbuf)
        bNodePreview *preview= node->preview;
        int xsize, ysize;
        int profile_from= (rd->color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
-       int predivide= 0;
+       int predivide= (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
        int dither= 0;
        unsigned char *rect;
        
index fd7c87adea20bbf3d129436961dbd2a6fda4d1b5..57b5cec4256d1b76f645ccbc9285f04518a670be 100644 (file)
@@ -62,7 +62,7 @@ static bNodeSocketTemplate cmp_node_rlayers_out[]= {
 float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc)
 {
        float *rect;
-       int predivide= 0;
+       int predivide= (ibuf->flags & IB_cm_predivide);
 
        *alloc= FALSE;
 
index 7713dcffc5c8674c27809085d4020468cc95569c..555d5c12a8649ed46b74d6841bef8c518903d072 100644 (file)
@@ -1154,7 +1154,7 @@ void RE_ResultGet32(Render *re, unsigned int *rect)
        }
        else if(rres.rectf) {
                int profile_from= (re->r.color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
-               int predivide= 0;
+               int predivide= (re->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
                int dither= 0;
 
                IMB_buffer_byte_from_float((unsigned char*)rect, rres.rectf,
@@ -2556,7 +2556,7 @@ static void do_render_seq(Render * re)
                         * render engine delivers */
                        int profile_to= (re->r.color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
                        int profile_from= (ibuf->profile == IB_PROFILE_LINEAR_RGB)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
-                       int predivide= 0;
+                       int predivide= (re->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
 
                        if (!rr->rectf)
                                rr->rectf= MEM_mallocN(4*sizeof(float)*rr->rectx*rr->recty, "render_seq rectf");
@@ -2995,7 +2995,8 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie
                        }
                }
                else {
-                       ImBuf *ibuf= IMB_allocImBuf(rres.rectx, rres.recty, scene->r.im_format.planes, 0);
+                       int flags = (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE)? IB_cm_predivide: 0;
+                       ImBuf *ibuf= IMB_allocImBuf(rres.rectx, rres.recty, scene->r.im_format.planes, flags);
                        
                        /* if not exists, BKE_write_ibuf makes one */
                        ibuf->rect= (unsigned int *)rres.rect32;    
index e5a892ff82d9b19fa7392d639f463a0b7635d97a..931858b7eed4d6f90515089d8c1a40e9a222c507 100644 (file)
@@ -43,7 +43,7 @@ public:
        virtual CValue*         GetReplica();
 #ifdef WITH_PYTHON
        virtual PyObject*       ConvertValueToPython() {
-               return PyUnicode_FromString(m_strString.Ptr());
+               return PyUnicode_From_STR_String(m_strString);
        }
 #endif // WITH_PYTHON
 
index f9697a55d3f8fb4ae002d2fddc6d49e82cbee379..10d8a8abd8fee4a0afbe15c0ef763e0588dbdd8d 100644 (file)
@@ -221,7 +221,7 @@ public:
        //static PyObject*      PyMake(PyObject*,PyObject*);
        virtual PyObject *py_repr(void)
        {
-               return PyUnicode_FromString((const char*)GetText());
+               return PyUnicode_From_STR_String(GetText());
        }
 
        virtual PyObject*       ConvertValueToPython() {
index fd0756d067d2d3fef3078dce7c171c82e751bdbb..092f9273a6b16235c800882cfbc70243dafdb4c8 100644 (file)
@@ -98,21 +98,24 @@ void BL_Material::Initialize()
        }
 }
 
-void BL_Material::SetConversionRGB(unsigned int *nrgb) {
+void BL_Material::SetConversionRGB(unsigned int *nrgb)
+{
        rgb[0]=*nrgb++;
        rgb[1]=*nrgb++;
        rgb[2]=*nrgb++;
        rgb[3]=*nrgb;
 }
 
-void BL_Material::GetConversionRGB(unsigned int *nrgb) {
+void BL_Material::GetConversionRGB(unsigned int *nrgb)
+{
        *nrgb++ = rgb[0];
        *nrgb++ = rgb[1];
        *nrgb++ = rgb[2];
        *nrgb   = rgb[3];
 }
 
-void BL_Material::SetConversionUV(const STR_String& name, MT_Point2 *nuv) {
+void BL_Material::SetConversionUV(const STR_String& name, MT_Point2 *nuv)
+{
        uvName = name;
        uv[0] = *nuv++;
        uv[1] = *nuv++;
@@ -120,13 +123,15 @@ void BL_Material::SetConversionUV(const STR_String& name, MT_Point2 *nuv) {
        uv[3] = *nuv;
 }
 
-void BL_Material::GetConversionUV(MT_Point2 *nuv){
+void BL_Material::GetConversionUV(MT_Point2 *nuv)
+{
        *nuv++ = uv[0];
        *nuv++ = uv[1];
        *nuv++ = uv[2];
        *nuv   = uv[3];
 }
-void BL_Material::SetConversionUV2(const STR_String& name, MT_Point2 *nuv) {
+void BL_Material::SetConversionUV2(const STR_String& name, MT_Point2 *nuv)
+{
        uv2Name = name;
        uv2[0] = *nuv++;
        uv2[1] = *nuv++;
@@ -134,7 +139,8 @@ void BL_Material::SetConversionUV2(const STR_String& name, MT_Point2 *nuv) {
        uv2[3] = *nuv;
 }
 
-void BL_Material::GetConversionUV2(MT_Point2 *nuv){
+void BL_Material::GetConversionUV2(MT_Point2 *nuv)
+{
        *nuv++ = uv2[0];
        *nuv++ = uv2[1];
        *nuv++ = uv2[2];
index 6c57776cb60f7089226059482256e34e152009dd..2c57004e6c4204796f3eaf23a277d043ce90958b 100644 (file)
@@ -38,10 +38,12 @@ extern "C" {
 }
 
 // (n&(n-1)) zeros the least significant bit of n 
-static int is_power_of_2_i(int num) {
+static int is_power_of_2_i(int num)
+{
        return ((num)&(num-1))==0;
 }
-static int power_of_2_min_i(int num) {
+static int power_of_2_min_i(int num)
+{
        while (!is_power_of_2_i(num))
                num= num&(num-1);
        return num;     
index 2736516bf33573c58b7f7db42c600209aa22f063..18f9875a804afbd1523074f98060df4603bc283a 100644 (file)
@@ -106,7 +106,7 @@ public:
 
 #ifdef WITH_PYTHON
        // --------------------------------
-       virtual PyObject* py_repr(void) { return PyUnicode_FromString(mMaterial->matname.ReadPtr()); }
+       virtual PyObject* py_repr(void) { return PyUnicode_From_STR_String(mMaterial->matname); }
 
        static PyObject* pyattr_get_shader(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
        static PyObject* pyattr_get_materialIndex(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
index 828c327a22870c30bdb51439695b748ab01a5caf..4f959d9d2f95ad7ae7c99944f8ad52f84a145999 100644 (file)
@@ -255,7 +255,8 @@ void KX_Dome::CalculateImageSize(void)
        }
 }
 
-bool KX_Dome::CreateDL(){
+bool KX_Dome::CreateDL()
+{
        dlistId = glGenLists((GLsizei) m_numimages);
        if (dlistId != 0) {
                if(m_mode == DOME_FISHEYE || m_mode == DOME_TRUNCATED_FRONT || m_mode == DOME_TRUNCATED_REAR){
index 7e40af2f3c44902c7a92a0ee235cb8949e37b141..eca9a14ce7cf0058534fbd4d9bbfe21e59a261d8 100644 (file)
@@ -41,6 +41,26 @@ extern "C" {
 
 #define BGE_FONT_RES 100
 
+std::vector<STR_String> split_string(STR_String str)
+{
+       std::vector<STR_String> text = std::vector<STR_String>();
+
+       /* Split the string upon new lines */
+       int begin=0, end=0;
+       while (end < str.Length())
+       {
+               if(str.GetAt(end) == '\n')
+               {
+                       text.push_back(str.Mid(begin, end-begin));
+                       begin = end+1;
+               }
+               end++;
+       }
+       //Now grab the last line
+       text.push_back(str.Mid(begin, end-begin));
+
+       return text;
+}
 KX_FontObject::KX_FontObject(  void* sgReplicationInfo,
                                                                SG_Callbacks callbacks,
                                                                RAS_IRenderTools* rendertools,
@@ -52,8 +72,10 @@ KX_FontObject::KX_FontObject(        void* sgReplicationInfo,
        m_rendertools(rendertools)
 {
        Curve *text = static_cast<Curve *> (ob->data);
-       m_text = text->str;
+       m_text = split_string(text->str);
        m_fsize = text->fsize;
+       m_line_spacing = text->linedist;
+       m_offset = MT_Vector3(text->xof, text->yof, 0);
 
        /* FO_BUILTIN_NAME != "default" */
        /* I hope at some point Blender (2.5x) can have a single font   */
@@ -95,20 +117,45 @@ void KX_FontObject::ProcessReplica()
 
 void KX_FontObject::DrawText()
 {
+       /* Allow for some logic brick control */
+       if(this->GetProperty("text"))
+               m_text = split_string(this->GetProperty("text")->GetText());
+
        /* only draws the text if visible */
        if(this->GetVisible() == 0) return;
 
        /* update the animated color */
        this->GetObjectColor().getValue(m_color);
 
-       /* XXX 2DO - handle multiple lines */
        /* HARDCODED MULTIPLICATION FACTOR - this will affect the render resolution directly */
        float RES = BGE_FONT_RES * m_resolution;
 
        float size = m_fsize * m_object->size[0] * RES;
        float aspect = 1.f / (m_object->size[0] * RES);
 
-       m_rendertools->RenderText3D(m_fontid, m_text, int(size), m_dpi, m_color, this->GetOpenGLMatrix(), aspect);
+       /* Get a working copy of the OpenGLMatrix to use */
+       double mat[16];
+       memcpy(mat, this->GetOpenGLMatrix(), sizeof(double)*16);
+
+       /* Account for offset */
+       MT_Vector3 offset = this->NodeGetWorldOrientation() * m_offset * this->NodeGetWorldScaling();
+       mat[12] += offset[0]; mat[13] += offset[1]; mat[14] += offset[2];
+
+       /* Orient the spacing vector */
+       MT_Vector3 spacing = MT_Vector3(0, m_fsize*m_line_spacing, 0);
+       spacing = this->NodeGetWorldOrientation() * spacing * this->NodeGetWorldScaling()[1];
+
+       /* Draw each line, taking spacing into consideration */
+       for(int i=0; i<m_text.size(); ++i)
+       {
+               if (i!=0)
+               {
+                       mat[12] -= spacing[0];
+                       mat[13] -= spacing[1];
+                       mat[14] -= spacing[2];
+               }
+               m_rendertools->RenderText3D(m_fontid, m_text[i], int(size), m_dpi, m_color, mat, aspect);
+       }
 }
 
 #ifdef WITH_PYTHON
@@ -150,11 +197,35 @@ PyMethodDef KX_FontObject::Methods[] = {
 };
 
 PyAttributeDef KX_FontObject::Attributes[] = {
-       KX_PYATTRIBUTE_STRING_RW("text", 0, 280, false, KX_FontObject, m_text), //arbitrary limit. 280 = 140 unicode chars in unicode
+       //KX_PYATTRIBUTE_STRING_RW("text", 0, 280, false, KX_FontObject, m_text[0]), //arbitrary limit. 280 = 140 unicode chars in unicode
+       KX_PYATTRIBUTE_RW_FUNCTION("text", KX_FontObject, pyattr_get_text, pyattr_set_text),
        KX_PYATTRIBUTE_FLOAT_RW("size", 0.0001f, 10000.0f, KX_FontObject, m_fsize),
        KX_PYATTRIBUTE_FLOAT_RW("resolution", 0.0001f, 10000.0f, KX_FontObject, m_resolution),
        /* KX_PYATTRIBUTE_INT_RW("dpi", 0, 10000, false, KX_FontObject, m_dpi), */// no real need for expose this I think
        { NULL }        //Sentinel
 };
 
+PyObject* KX_FontObject::pyattr_get_text(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+       KX_FontObject* self= static_cast<KX_FontObject*>(self_v);
+       STR_String str = STR_String();
+       for(int i=0; i<self->m_text.size(); ++i)
+       {
+               if(i!=0)
+                       str += '\n';
+               str += self->m_text[i];
+       }
+       return PyUnicode_From_STR_String(str);
+}
+
+int KX_FontObject::pyattr_set_text(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+       KX_FontObject* self= static_cast<KX_FontObject*>(self_v);
+       if(!PyUnicode_Check(value))
+               return PY_SET_ATTR_FAIL;
+       char* chars = _PyUnicode_AsString(value);
+       self->m_text = split_string(STR_String(chars));
+       return PY_SET_ATTR_SUCCESS;
+}
+
 #endif // WITH_PYTHON
index 8fc7a9e9f285e1627ba2fed0762765f93a3bbc63..958a6cd3360629df642329d2d54da5ed4c1f0e78 100644 (file)
@@ -57,13 +57,15 @@ public:
        virtual void ProcessReplica();
 
 protected:
-       STR_String              m_text;
+       std::vector<STR_String>         m_text;
        Object*                 m_object;
        int                     m_fontid;
        int                     m_dpi;
        float                   m_fsize;
        float                   m_resolution;
        float                   m_color[4];
+       float                   m_line_spacing;
+       MT_Vector3              m_offset;
 
        class RAS_IRenderTools* m_rendertools;  //needed for drawing routine
 
@@ -76,6 +78,8 @@ public:
 */
 
 #ifdef WITH_PYTHON
+       static PyObject*        pyattr_get_text(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+       static int                      pyattr_set_text(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
 #endif
 
 };
index 245a92a96de7d051df216b7d8899ee562e7d2492..cc078e96e643bd6b02f09c9f59d91e4ca3bf80f1 100644 (file)
@@ -888,7 +888,7 @@ public:
         */
        virtual PyObject* py_repr(void)
        {
-               return PyUnicode_FromString(GetName().ReadPtr());
+               return PyUnicode_From_STR_String(GetName());
        }
 
        KX_PYMETHOD_O(KX_GameObject,SetWorldPosition);
index fec1d9d296ca1d84b47d2d882ce06926e422ca4c..fa1366874a3c24f76b700583f17aaae23ddbadfc 100644 (file)
@@ -247,12 +247,14 @@ PyObject* KX_MeshProxy::pyattr_get_materials(void *self_v, const KX_PYATTRIBUTE_
        return materials;
 }
 
-PyObject * KX_MeshProxy::pyattr_get_numMaterials(void * selfv, const KX_PYATTRIBUTE_DEF * attrdef) {
+PyObject * KX_MeshProxy::pyattr_get_numMaterials(void * selfv, const KX_PYATTRIBUTE_DEF * attrdef)
+{
        KX_MeshProxy * self = static_cast<KX_MeshProxy *> (selfv);
        return PyLong_FromSsize_t(self->m_meshobj->NumMaterials());
 }
 
-PyObject * KX_MeshProxy::pyattr_get_numPolygons(void * selfv, const KX_PYATTRIBUTE_DEF * attrdef) {
+PyObject * KX_MeshProxy::pyattr_get_numPolygons(void * selfv, const KX_PYATTRIBUTE_DEF * attrdef)
+{
        KX_MeshProxy * self = static_cast<KX_MeshProxy *> (selfv);
        return PyLong_FromSsize_t(self->m_meshobj->NumPolygons());
 }
index c8070736b7f930b6be413aabdb6a83a0e36d5d8f..c3e6fa376dd20621baa6878c00fcc2630d86af88 100644 (file)
@@ -617,7 +617,7 @@ public:
        static PyObject*        pyattr_get_drawing_callback_post(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
        static int                      pyattr_set_drawing_callback_post(void *selv_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
 
-       virtual PyObject* py_repr(void) { return PyUnicode_FromString(GetName().ReadPtr()); }
+       virtual PyObject* py_repr(void) { return PyUnicode_From_STR_String(GetName()); }
        
        /* getitem/setitem */
        static PyMappingMethods Mapping;