From 5c82926f94f333c326ff1f835b18f6d92cc6afd8 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 4 Dec 2011 16:07:50 +0000 Subject: [PATCH 01/18] Use own bilinear interpolation function for preview widget sampling Solves issue with image clamping, but issue with dark edge is still present --- .../editors/interface/interface_draw.c | 101 +++++++----------- 1 file changed, 36 insertions(+), 65 deletions(-) diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index ad8885e3394..b9c4dbcf5f7 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -1471,12 +1471,27 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *rect fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax); } +static ImBuf *scale_trackpreview_ibuf(ImBuf *ibuf, float zoomx, float zoomy) +{ + ImBuf *scaleibuf; + int x, y, w= ibuf->x*zoomx, h= ibuf->y*zoomy; + + scaleibuf= IMB_allocImBuf(w, h, 32, IB_rect); + + for(y= 0; yy; y++) { + for (x= 0; xx; x++) { + bilinear_interpolation(ibuf, scaleibuf, ((float)x)/zoomx, ((float)y)/zoomy, x, y); + } + } + + return scaleibuf; +} + void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti) { rctf rect; int ok= 0; GLint scissor[4]; - int preview_width, preview_height; MovieClipScopes *scopes = (MovieClipScopes *)but->poin; rect.xmin = (float)recti->xmin+1; @@ -1484,20 +1499,12 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc rect.ymin = (float)recti->ymin+SCOPE_RESIZE_PAD+2; rect.ymax = (float)recti->ymax-1; - preview_width = rect.xmax - rect.xmin; - preview_height = rect.ymax - rect.ymin; - - glPushAttrib(GL_ALL_ATTRIB_BITS); - glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); /* need scissor test, preview image can draw outside of boundary */ glGetIntegerv(GL_VIEWPORT, scissor); - glScissor(ar->winrct.xmin + (rect.xmin-1), - ar->winrct.ymin+(rect.ymin-1), - (rect.xmax+1)-(rect.xmin-1), - (rect.ymax+1)-(rect.ymin-1)); + glScissor(ar->winrct.xmin + (rect.xmin-1), ar->winrct.ymin+(rect.ymin-1), (rect.xmax+1)-(rect.xmin-1), (rect.ymax+1)-(rect.ymin-1)); if(scopes->track_disabled) { glColor4f(0.7f, 0.3f, 0.3f, 0.3f); @@ -1507,66 +1514,30 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc ok= 1; } else if(scopes->track_preview) { - int a; + int a, off_x, off_y; + float zoomx, zoomy; ImBuf *drawibuf; - GLuint preview_texture; - float pattern_width, pattern_height; - - pattern_width = scopes->track_preview->x; - pattern_height = scopes->track_preview->y; glPushMatrix(); /* draw content of pattern area */ - glScissor(ar->winrct.xmin + rect.xmin, - ar->winrct.ymin + rect.ymin, - scissor[2], - scissor[3]); + glScissor(ar->winrct.xmin+rect.xmin, ar->winrct.ymin+rect.ymin, scissor[2], scissor[3]); - /* make a texture from the pattern */ - /* TODO(keir): add a switch for bilinear filtering or not. */ - glGenTextures(1, &preview_texture); - glBindTexture(GL_TEXTURE_2D, preview_texture); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, - scopes->track_preview->x, - scopes->track_preview->y, - 0, GL_RGBA, GL_UNSIGNED_BYTE, - scopes->track_preview->rect); - glEnable(GL_TEXTURE_2D); + zoomx= (rect.xmax-rect.xmin) / (scopes->track_preview->x-2.0f); + zoomy= (rect.ymax-rect.ymin) / (scopes->track_preview->y-2.0f); - /* reposition so the preview area goes from -0.5 to 0.5 on x and y. */ - glTranslatef((rect.xmin + rect.xmax) / 2.0f, - (rect.ymin + rect.ymax) / 2.0f, 0.0f); - glScalef(preview_width, preview_height, 1.0f); + off_x= ((int)scopes->track_pos[0]-scopes->track_pos[0]-0.5f)*zoomx; + off_y= ((int)scopes->track_pos[1]-scopes->track_pos[1]-0.5f)*zoomy; - /* this matrix is reused below to draw the crosshair */ - glPushMatrix(); + drawibuf= scale_trackpreview_ibuf(scopes->track_preview, zoomx, zoomy); + glaDrawPixelsSafe(off_x+rect.xmin, off_y+rect.ymin, rect.xmax-rect.xmin+1.f-off_x, rect.ymax-rect.ymin+1.f-off_y, drawibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, drawibuf->rect); - /* make scale match the pattern and apply the subpixel marker translation. */ - glScalef(1.0f / pattern_width, - 1.0f / pattern_width, 1.0f); - glTranslatef(-scopes->track_pos[0], - -scopes->track_pos[1], 0.f); - glScalef(pattern_width, pattern_height, 1.0f); + IMB_freeImBuf(drawibuf); - /* draw the pattern over the preview area. */ - glBegin(GL_QUADS); - glTexCoord2f(0.0f,0.0f); glVertex2f(0.0f, 0.0f); - glTexCoord2f(1.0f,0.0f); glVertex2f(1.0f, 0.0f); - glTexCoord2f(1.0f,1.0f); glVertex2f(1.0f, 1.0f); - glTexCoord2f(0.0f,1.0f); glVertex2f(0.0f, 1.0f); - glEnd(); + /* draw cross for pizel position */ + glTranslatef(off_x+rect.xmin+scopes->track_pos[0]*zoomx, off_y+rect.ymin+scopes->track_pos[1]*zoomy, 0.f); + glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin+rect.ymin, rect.xmax-rect.xmin, rect.ymax-rect.ymin); - glDeleteTextures(1, &preview_texture); - glPopMatrix(); - - /* draw the crosshair */ for(a= 0; a< 2; a++) { if(a==1) { glLineStipple(3, 0xaaaa); @@ -1578,14 +1549,14 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc } glBegin(GL_LINES); - glVertex2f(-0.10f, 0.0f); - glVertex2f( 0.10f, 0.0f); - glVertex2f( 0.0f, -0.10f); - glVertex2f( 0.0f, 0.10f); + glVertex2f(-10.0f, 0.0f); + glVertex2f(10.0f, 0.0f); + glVertex2f(0.0f, -10.0f); + glVertex2f(0.0f, 10.0f); glEnd(); } - glDisable(GL_LINE_STIPPLE); + glDisable(GL_LINE_STIPPLE); glPopMatrix(); ok= 1; @@ -1600,7 +1571,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc /* outline, scale gripper */ draw_scope_end(&rect, scissor); - glPopAttrib(); + glDisable(GL_BLEND); } /* ****************************************************** */ From 17493c77f4f876910436648f18c0125d20f24809 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 4 Dec 2011 17:12:10 +0000 Subject: [PATCH 02/18] Fixed dark edges on preview widget sides: it was interpolating beyond the image bounds --- source/blender/editors/interface/interface_draw.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index b9c4dbcf5f7..12187283470 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -1480,7 +1480,13 @@ static ImBuf *scale_trackpreview_ibuf(ImBuf *ibuf, float zoomx, float zoomy) for(y= 0; yy; y++) { for (x= 0; xx; x++) { - bilinear_interpolation(ibuf, scaleibuf, ((float)x)/zoomx, ((float)y)/zoomy, x, y); + float src_x= ((float)x)/zoomx; + float src_y= ((float)y)/zoomy; + + CLAMP(src_x, 0, ibuf->x-1.0f); + CLAMP(src_y, 0, ibuf->y-1.0f); + + bilinear_interpolation(ibuf, scaleibuf, src_x, src_y, x, y); } } From 9e51f4b94368a612c5561f20f4b44f858ab5318e Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 4 Dec 2011 18:39:47 +0000 Subject: [PATCH 03/18] Optimization of preview widget scaling. Thanks to Campbell for pointing into issues. --- source/blender/editors/interface/interface_draw.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 12187283470..767c6b0353c 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -1475,16 +1475,20 @@ 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; scaleibuf= IMB_allocImBuf(w, h, 32, IB_rect); for(y= 0; yy; y++) { for (x= 0; xx; x++) { - float src_x= ((float)x)/zoomx; - float src_y= ((float)y)/zoomy; + float src_x= scalex*x; + float src_y= scaley*y; - CLAMP(src_x, 0, ibuf->x-1.0f); - CLAMP(src_y, 0, ibuf->y-1.0f); + CLAMP(src_x, 0, max_x); + CLAMP(src_y, 0, max_y); bilinear_interpolation(ibuf, scaleibuf, src_x, src_y, x, y); } From 9355cc5c399a9d7cd49815c68eeeac788022ba1a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 5 Dec 2011 18:57:17 +0000 Subject: [PATCH 04/18] Object tracking; initial commit This commit implements basis stuff needed for object tracking, use case isn't perfect now, interface also should be cleaned a bit. - Added list of objects to be tracked. Default there's only one object called "Camera" which is used for solving camera motion. Other objects can be added and each of them will have it;s own list of tracks. Only one object can be used for camera solving at this moment. - Added new constraint called "Object Tracking" which makes oriented object be moving in the save way as solved object motion. - Scene orientation tools can be used for orienting object to bundles. - All tools which works with list of tracks or reconstruction data now gets that lists from active editing object. - All objects and their tracking data are available via python api. --- .../bl_ui/properties_object_constraint.py | 11 + release/scripts/startup/bl_ui/space_clip.py | 39 +- source/blender/blenkernel/BKE_tracking.h | 44 +- source/blender/blenkernel/intern/constraint.c | 180 ++++++-- source/blender/blenkernel/intern/depsgraph.c | 21 +- source/blender/blenkernel/intern/movieclip.c | 9 +- source/blender/blenkernel/intern/tracking.c | 363 ++++++++++++--- source/blender/blenloader/intern/readfile.c | 52 ++- source/blender/blenloader/intern/writefile.c | 39 +- .../editors/interface/interface_templates.c | 11 + .../editors/object/object_constraint.c | 15 +- source/blender/editors/space_clip/clip_draw.c | 27 +- .../blender/editors/space_clip/clip_editor.c | 3 +- .../editors/space_clip/clip_graph_draw.c | 5 +- .../editors/space_clip/clip_graph_ops.c | 29 +- .../blender/editors/space_clip/clip_intern.h | 9 +- .../blender/editors/space_clip/clip_utils.c | 17 +- .../blender/editors/space_clip/space_clip.c | 4 + .../blender/editors/space_clip/tracking_ops.c | 423 +++++++++++++----- .../blender/editors/space_view3d/drawobject.c | 108 +++-- .../editors/space_view3d/view3d_select.c | 8 +- .../editors/transform/transform_conversions.c | 5 +- .../editors/transform/transform_generics.c | 5 +- .../blender/makesdna/DNA_constraint_types.h | 14 + source/blender/makesdna/DNA_tracking_types.h | 19 +- source/blender/makesrna/RNA_access.h | 1 + .../blender/makesrna/intern/rna_constraint.c | 41 +- source/blender/makesrna/intern/rna_tracking.c | 263 ++++++++++- 28 files changed, 1424 insertions(+), 341 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_object_constraint.py b/release/scripts/startup/bl_ui/properties_object_constraint.py index 038d7a38fd6..f88f501ab1f 100644 --- a/release/scripts/startup/bl_ui/properties_object_constraint.py +++ b/release/scripts/startup/bl_ui/properties_object_constraint.py @@ -763,6 +763,7 @@ class ConstraintButtonsPanel(): if not con.use_active_clip: layout.prop(con, "clip") + layout.prop(con, "object") layout.prop(con, "track") layout.operator("clip.constraint_to_fcurve") @@ -775,6 +776,16 @@ class ConstraintButtonsPanel(): layout.operator("clip.constraint_to_fcurve") + def OBJECT_SOLVER(self, context, layout, con): + layout.prop(con, "use_active_clip") + + if not con.use_active_clip: + layout.prop(con, "clip") + + layout.prop(con, "object") + + layout.operator("clip.constraint_to_fcurve") + def SCRIPT(self, context, layout, con): layout.label("Blender 2.5 has no py-constraints") diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index c7511174e98..771231c6bde 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -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" % @@ -316,6 +322,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' diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index e55d40ebfe5..6c43493d1d4 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -34,11 +34,13 @@ 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,16 +74,27 @@ 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_named_track(struct MovieTracking *tracking, struct MovieTrackingObject *object, const char *name); struct MovieTrackingTrack *BKE_tracking_indexed_track(struct MovieTracking *tracking, int tracknr); 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, @@ -92,20 +105,23 @@ void BKE_tracking_sync_user(struct MovieClipUser *user, struct MovieTrackingCont 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)) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 6f29594f811..9d8aae3bb52 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -3953,67 +3953,95 @@ 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; + if (data->flag & FOLLOWTRACK_ACTIVECLIP) clip= scene->clip; - + if (!clip || !data->track[0]) 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]; - - copy_m4_m4(obmat, cob->matrix); - - BKE_get_tracking_mat(cob->scene, NULL, mat); + MovieTracking *tracking= &clip->tracking; + float pos[3], mat[4][4]; + + if((tracking_object->flag&TRACKING_OBJECT_CAMERA)==0) { + Object *camob= scene->camera; + float obmat[4][4], imat[4][4]; + + if(!camob) + return; + + copy_m4_m4(mat, camob->obmat); + + BKE_tracking_get_interpolated_camera(tracking, tracking_object, scene->r.cfra, obmat); + + invert_m4_m4(imat, obmat); + mul_m4_m4m4(mat, imat, mat); + } + else { + 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]; + + cob->matrix[3][0] = pos[0]; + cob->matrix[3][1] = pos[1]; + cob->matrix[3][2] = pos[2]; } } else { - Object *camob= cob->scene->camera; - + Object *camob= 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(¶ms); camera_params_from_object(¶ms, camob); @@ -4021,35 +4049,35 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase 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]); mul_m4_m4m4(cob->matrix, rmat, cob->matrix); - + 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]); mul_m4_m4m4(cob->matrix, rmat, cob->matrix); - + copy_v3_v3(cob->matrix[3], disp); } } @@ -4095,16 +4123,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); + mul_m4_m4m4(cob->matrix, mat, obmat); } } @@ -4125,6 +4156,76 @@ 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; +} + +static void objectsolver_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata) +{ + bObjectSolverConstraint *data= con->data; + + func(con, (ID**)&data->clip, userdata); +} + +static void objectsolver_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets)) +{ + Scene *scene= cob->scene; + bObjectSolverConstraint *data= con->data; + MovieClip *clip= data->clip; + + if (data->flag & OBJECTSOLVER_ACTIVECLIP) + clip= scene->clip; + + if(!scene->camera) + 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]; + + where_is_object_mat(scene, scene->camera, cammat); + + BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, mat); + + invert_m4_m4(camimat, cammat); + + copy_m4_m4(cammat, scene->camera->obmat); + copy_m4_m4(obmat, cob->matrix); + + invert_m4_m4(imat, mat); + + mul_serie_m4(cob->matrix, cammat, imat, camimat, obmat, NULL, 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. @@ -4165,6 +4266,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 diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 4eaf49dc679..b0776a0b51b 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -647,16 +647,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"); @@ -2160,7 +2165,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) { diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 75d8ec584e8..04686e6a897 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -813,7 +813,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); @@ -824,8 +825,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) { diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 0786abba67d..5d20445b53f 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -54,6 +54,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" @@ -89,6 +90,8 @@ void BKE_tracking_init_settings(MovieTracking *tracking) 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) @@ -207,7 +210,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; @@ -250,8 +253,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; } @@ -523,18 +526,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); +} - if(tracking->reconstruction.cameras) - MEM_freeN(tracking->reconstruction.cameras); +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); + + 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); @@ -546,6 +575,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; @@ -557,10 +589,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; @@ -606,10 +641,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) */ @@ -633,7 +682,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; @@ -684,7 +733,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)) @@ -744,7 +793,9 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u 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; @@ -754,7 +805,7 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u context->first_time= 1; /* 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); @@ -769,12 +820,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); @@ -1370,6 +1422,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 +1445,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 +1495,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 +1582,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,8 +1598,6 @@ 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); @@ -1560,13 +1624,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 +1643,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,17 +1663,22 @@ 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; MovieTrackingMarker *first_marker= &track->markers[0]; @@ -1640,7 +1711,7 @@ 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); @@ -1740,8 +1811,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 +1836,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 +1856,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 +1909,31 @@ static int reconstruction_camera_index(MovieTracking *tracking, int framenr, int return -1; } -MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(MovieTracking *tracking, int framenr) +MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(MovieTracking *tracking, + MovieTrackingObject *object, int framenr) { - int a= reconstruction_camera_index(tracking, framenr, 0); + 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); @@ -1890,7 +1985,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 +2019,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 +2029,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 +2186,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 +2208,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 +2217,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 +2225,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 @@ -2077,7 +2248,8 @@ void BKE_tracking_detect_fast(MovieTracking *tracking, ImBuf *ibuf, MovieTrackingTrack *BKE_tracking_indexed_track(MovieTracking *tracking, int tracknr) { - MovieTrackingTrack *track= tracking->tracks.first; + ListBase *tracksbase= &tracking->tracks; /* XXX: need proper tracks base */ + MovieTrackingTrack *track= tracksbase->first; int cur= 1; while(track) { @@ -2102,6 +2274,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 +2713,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 +2738,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; +} diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 13e2ed49e6a..6479c3ee04d 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5934,10 +5934,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; @@ -5945,16 +5964,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); @@ -5965,6 +5976,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) @@ -12657,7 +12678,14 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* put compatibility code here until next subversion bump */ { - /* nothing! */ + MovieClip *clip; + + for (clip= main->movieclip.first; clip; clip= clip->id.next) { + MovieTracking *tracking= &clip->tracking; + + if(tracking->objects.first == NULL) + BKE_tracking_new_object(tracking, "Camera"); + } } /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 00710e67cf2..4828e9703fb 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2522,6 +2522,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; @@ -2530,20 +2551,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; } } diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 7f01d4f031d..ea45337ddb3 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2198,6 +2198,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, diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 2a45a7df735..7b9e809fffc 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -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; } diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 3f9ec3f3c82..8f2398b156b 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -96,6 +96,7 @@ 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); glEnable(GL_BLEND); @@ -119,8 +120,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; @@ -835,8 +836,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 +860,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 +882,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 +904,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 +914,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 +938,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 +976,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 +1030,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) { diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index c5036145792..d75df0ab51e 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -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); diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c index 7b14783d4ca..d1e7c86d473 100644 --- a/source/blender/editors/space_clip/clip_graph_draw.c +++ b/source/blender/editors/space_clip/clip_graph_draw.c @@ -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 */ diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c index 56ca1632bae..08d6bcf47bc 100644 --- a/source/blender/editors/space_clip/clip_graph_ops.c +++ b/source/blender/editors/space_clip/clip_graph_ops.c @@ -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(amarkersnr) { - MovieTrackingMarker *marker= &track->markers[a]; + while(amarkersnr) { + 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++; } diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h index da0b589652e..38da4dd86ff 100644 --- a/source/blender/editors/space_clip/clip_intern.h +++ b/source/blender/editors/space_clip/clip_intern.h @@ -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); @@ -139,6 +139,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 */ diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c index 649b278ab3d..3ca8fc35c7f 100644 --- a/source/blender/editors/space_clip/clip_utils.c +++ b/source/blender/editors/space_clip/clip_utils.c @@ -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); diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index c8577f7760e..01779a806b9 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -372,6 +372,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) diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 3d004ab73da..65505fea89e 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -117,14 +117,16 @@ static int space_clip_camera_poll(bContext *C) 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 +193,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 +233,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 +247,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 +433,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 +442,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 +726,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 +769,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 +790,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 +873,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 +891,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 +959,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 +980,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 +1034,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 +1052,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 +1117,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 +1143,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 +1221,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 +1242,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 +1250,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); @@ -1448,6 +1463,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 +1566,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 +1580,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 +1691,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 +1713,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 +1773,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 +1783,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 +1821,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 +1869,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) { @@ -1892,10 +1923,11 @@ 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++; @@ -1910,20 +1942,33 @@ 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; + Object *object; + ListBase *tracksbase; float mat[4][4], vec[3]; 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); - track= clip->tracking.tracks.first; + if(tracking_object->flag&TRACKING_OBJECT_CAMERA) + object= scene->camera; + else + object= OBACT; + + if(object->parent) + object= object->parent; + + tracksbase= BKE_tracking_object_tracks(tracking, tracking_object); + + track= tracksbase->first; while(track) { if(TRACK_VIEW_SELECTED(sc, track)) break; @@ -1932,12 +1977,16 @@ static int set_origin_exec(bContext *C, wmOperator *op) } BKE_get_tracking_mat(scene, NULL, mat); + mul_v3_m4v3(vec, mat, track->bundle_pos); - sub_v3_v3(parent->loc, vec); + if(tracking_object->flag&TRACKING_OBJECT_CAMERA) + sub_v3_v3(object->loc, vec); + else + 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); @@ -1962,12 +2011,27 @@ void CLIP_OT_set_origin(wmOperatorType *ot) /********************** set floor operator *********************/ -static void set_axis(Scene *scene, Object *ob, MovieTrackingTrack *track, char axis) +static void set_axis(Scene *scene, Object *ob, MovieTrackingObject *tracking_object, + MovieTrackingTrack *track, char axis) { - float mat[4][4], vec[3], obmat[4][4]; + 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); mul_v3_m4v3(vec, mat, track->bundle_pos); + copy_v3_v3(dvec, vec); + + if(!is_camera) { + float imat[4][4]; + + 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 +2039,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 +2088,25 @@ 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); + + mul_m4_m4m4(mat, obmat, mat); + } + else { + if(!flip) { + float rmat[3][3], tmat[4][4]; + + object_rot_to_mat3(ob, rmat); + copy_m4_m3(tmat, rmat); + invert_m4(tmat); + + mul_m4_m4m4(mat, mat, tmat); + } + + mul_m4_m4m4(mat, mat, obmat); + } - object_to_mat4(ob, obmat); - mul_m4_m4m4(mat, obmat, mat); object_apply_mat4(ob, mat, 0, 0); } @@ -2014,9 +2115,11 @@ 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; 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 +2129,31 @@ 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); + + if(tracking_object->flag&TRACKING_OBJECT_CAMERA) + object= scene->camera; + else + object= OBACT; + + if(object->parent) + object= object->parent; BKE_get_tracking_mat(scene, NULL, 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 +2183,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); - mul_m4_m4m4(mat, obmat, mat); - mul_m4_m4m4(newmat, mat, rot); - 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); + mul_m4_m4m4(mat, obmat, mat); mul_m4_m4m4(newmat, mat, rot); - 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); + mul_m4_m4m4(newmat, mat, rot); + 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, 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); @@ -2117,9 +2235,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 +2249,17 @@ static int set_axis_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - if(scene->camera->parent) - parent= scene->camera->parent; + if(tracking_object->flag & TRACKING_OBJECT_CAMERA) + object= scene->camera; + else + object= OBACT; - track= clip->tracking.tracks.first; + if(object->parent) + object= object->parent; + + tracksbase= BKE_tracking_object_tracks(tracking, tracking_object); + + track=tracksbase->first; while(track) { if(TRACK_VIEW_SELECTED(sc, track)) break; @@ -2139,10 +2267,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, 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); @@ -2183,6 +2311,7 @@ static int set_scale_exec(bContext *C, wmOperator *op) MovieTrackingTrack *track; Scene *scene= CTX_data_scene(C); Object *parent= scene->camera; + ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking); int tot= 0; float vec[2][3], mat[4][4], scale; float dist= RNA_float_get(op->ptr, "distance"); @@ -2198,7 +2327,7 @@ static int set_scale_exec(bContext *C, wmOperator *op) BKE_get_tracking_mat(scene, NULL, 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); @@ -2301,11 +2430,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 +2448,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 +2485,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; @@ -2407,7 +2540,9 @@ static int detect_features_exec(bContext *C, wmOperator *op) SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); ImBuf *ibuf= BKE_movieclip_get_ibuf_flag(clip, &sc->user, 0); - 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"); @@ -2429,7 +2564,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); @@ -2478,7 +2614,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; @@ -2498,13 +2634,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; @@ -2561,16 +2700,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)) { @@ -2582,7 +2723,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; @@ -2590,7 +2731,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; @@ -2623,7 +2764,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) { @@ -2672,12 +2814,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; @@ -2718,11 +2862,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; @@ -2767,10 +2912,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) { @@ -2825,10 +2971,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); @@ -2867,11 +3014,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); @@ -2996,7 +3144,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"); @@ -3004,7 +3153,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; @@ -3023,7 +3172,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; } @@ -3033,7 +3182,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); } } } @@ -3090,3 +3239,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; +} diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 547d89cd1a2..a36f49a35d8 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -1458,43 +1458,44 @@ 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) { 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); + 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); - - /* 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); - for ( track= tracking->tracks.first; track; track= track->next) { - int selected= track->flag&SELECT || track->pat_flag&SELECT || track->search_flag&SELECT; + 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); + + 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); + if((track->flag&TRACK_HAS_BUNDLE)==0) continue; @@ -1581,27 +1582,58 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, } 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; acamnr; 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; acamnr; a++, camera++) { + glVertex3fv(camera->mat[3]); + } + glEnd(); + + glLineWidth(1.0f); + glEnable(GL_LIGHTING); + } } } glPopMatrix(); +} + +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]; + + 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); + + tracking_object= tracking_object->next; + } /* restore */ glShadeModel(GL_FLAT); diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 33f7acf2a37..d8ff01a880d 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -1405,13 +1405,17 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short obce 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); + MovieTracking *tracking= &clip->tracking; int selected; + track= BKE_tracking_indexed_track(&clip->tracking, hitresult >> 16); selected= (track->flag&SELECT) || (track->pat_flag&SELECT) || (track->search_flag&SELECT); - if(selected && extend) BKE_tracking_deselect_track(track, TRACK_AREA_ALL); - else BKE_tracking_select_track(&clip->tracking, track, TRACK_AREA_ALL, extend); + if(selected && extend) + BKE_tracking_deselect_track(track, TRACK_AREA_ALL); + else + BKE_tracking_select_track(&tracking->tracks, track, TRACK_AREA_ALL, extend); basact->flag|= SELECT; basact->object->flag= basact->flag; diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 5527ab0d331..96eb60272c1 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5391,6 +5391,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; @@ -5404,7 +5405,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); @@ -5431,7 +5432,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); diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index d0857958a4b..0b0a0eb2e2d 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -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) { diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 4aff540a948..10c4153702d 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -412,6 +412,7 @@ typedef struct bFollowTrackConstraint { struct MovieClip *clip; char track[24]; int flag, pad; + char object[24]; } bFollowTrackConstraint; /* Camera Solver constraints */ @@ -420,6 +421,13 @@ typedef struct bCameraSolverConstraint { int flag, pad; } bCameraSolverConstraint; +/* Camera Solver constraints */ +typedef struct bObjectSolverConstraint { + struct MovieClip *clip; + int flag, pad; + char object[24]; +} bObjectSolverConstraint; + /* ------------------------------------------ */ /* bConstraint->type @@ -455,6 +463,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 @@ -762,6 +771,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 diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index 9058e82b367..fd0e281b60f 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -172,6 +172,15 @@ 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, pad; + 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 +188,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; @@ -242,6 +254,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 diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 37a5b5643b8..215c7992ff3 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -329,6 +329,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; diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 4ab14550fd1..4d064c01fae 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -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; } @@ -2066,6 +2069,12 @@ 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"); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); } static void rna_def_constraint_camera_solver(BlenderRNA *brna) @@ -2074,7 +2083,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 +2100,35 @@ 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"); +} + /* base struct for constraints */ void RNA_def_constraint(BlenderRNA *brna) { @@ -2203,6 +2241,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 diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index f06c020400d..6332cd40bca 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -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; atracking.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,94 @@ 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); +} + /* 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; atracks, 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); @@ -889,18 +1019,18 @@ 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); @@ -913,6 +1043,96 @@ 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_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); + + /* 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_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"); +} + +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; @@ -921,8 +1141,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"); @@ -940,7 +1163,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); @@ -949,6 +1172,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) From cbe9713b5082011c3c366dcf9a03631b8b3ae7f1 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 5 Dec 2011 19:31:21 +0000 Subject: [PATCH 05/18] Object solver: minor tweaks - Rename solving button to Object Motion if active tracking object isn't a camera - Ignore refine flags when solving object --- release/scripts/startup/bl_ui/space_clip.py | 13 +++++++++++-- source/blender/blenkernel/intern/tracking.c | 7 +++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 771231c6bde..623ac8dc131 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -203,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) @@ -214,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="") diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 5d20445b53f..e7f99990dc5 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1604,11 +1604,14 @@ static int retrieve_libmv_reconstruct(MovieReconstructContext *context, MovieTra 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; @@ -1714,7 +1717,7 @@ MovieReconstructContext* BKE_tracking_reconstruction_context_new(MovieTracking * 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; From ec9ac9faba1b9f82fa16e710e881b38d1ff7ea76 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 5 Dec 2011 20:07:13 +0000 Subject: [PATCH 06/18] Object tracking: fix setting axis in cases when object is scaled --- source/blender/editors/space_clip/tracking_ops.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 65505fea89e..59631e3a181 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -2094,6 +2094,12 @@ static void set_axis(Scene *scene, Object *ob, MovieTrackingObject *tracking_ob mul_m4_m4m4(mat, obmat, mat); } else { + float lmat[4][4], ilmat[4][4], m[4][4]; + + unit_m4(lmat); + copy_v3_v3(lmat[3], obmat[3]); + invert_m4_m4(ilmat, lmat); + if(!flip) { float rmat[3][3], tmat[4][4]; @@ -2104,7 +2110,7 @@ static void set_axis(Scene *scene, Object *ob, MovieTrackingObject *tracking_ob mul_m4_m4m4(mat, mat, tmat); } - mul_m4_m4m4(mat, mat, obmat); + mul_serie_m4(mat, lmat, mat, ilmat, obmat, NULL, NULL, NULL, NULL); } object_apply_mat4(ob, mat, 0, 0); From 4fe2df3b8cebf45af4040d82dfa15404410c4851 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 6 Dec 2011 18:39:16 +0000 Subject: [PATCH 07/18] Make distortion panel be a bit more obvious label --- release/scripts/startup/bl_ui/space_clip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 139f674d6e8..5aec9a8e58c 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -474,7 +474,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") From a0723afe2016396473fe32801e7b7b9339c9f027 Mon Sep 17 00:00:00 2001 From: Keir Mierle Date: Wed, 7 Dec 2011 00:11:39 +0000 Subject: [PATCH 08/18] Use bicubic interpolation for the tracker preview. It looks fantastic, but is slower, so we may have to make this an option instead of the only choice. --- source/blender/editors/interface/interface_draw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 767c6b0353c..06b7822ad05 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -1490,7 +1490,7 @@ static ImBuf *scale_trackpreview_ibuf(ImBuf *ibuf, float zoomx, float zoomy) CLAMP(src_x, 0, max_x); CLAMP(src_y, 0, max_y); - bilinear_interpolation(ibuf, scaleibuf, src_x, src_y, x, y); + bicubic_interpolation(ibuf, scaleibuf, src_x, src_y, x, y); } } From dbc9227a3247e2138f964b1687e3467f3f4b9741 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 7 Dec 2011 11:02:34 +0000 Subject: [PATCH 09/18] Disable markers when doing frame-by-frame tracking and tracker library returns failure --- source/blender/blenkernel/BKE_tracking.h | 2 +- source/blender/blenkernel/intern/tracking.c | 7 +++---- source/blender/editors/space_clip/tracking_ops.c | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index 6c43493d1d4..d7bf7cb410f 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -98,7 +98,7 @@ struct MovieTrackingReconstruction *BKE_tracking_object_reconstruction(struct Mo /* 2D tracking */ struct MovieTrackingContext *BKE_tracking_context_new(struct MovieClip *clip, struct MovieClipUser *user, - short backwards, short disable_failed); + short backwards); 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); diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index d1929e25c40..164320562f4 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -784,11 +784,11 @@ typedef struct MovieTrackingContext { MovieTrackingSettings settings; TracksMap *tracks_map; - short backwards, disable_failed; + short backwards; int sync_frame; } MovieTrackingContext; -MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *user, short backwards, short disable_failed) +MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *user, short backwards) { MovieTrackingContext *context= MEM_callocN(sizeof(MovieTrackingContext), "trackingContext"); MovieTracking *tracking= &clip->tracking; @@ -800,7 +800,6 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u context->settings= *settings; context->backwards= backwards; - context->disable_failed= disable_failed; context->sync_frame= user->framenr; context->first_time= 1; @@ -1356,7 +1355,7 @@ int BKE_tracking_next(MovieTrackingContext *context) } coords_correct= !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 { diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 59631e3a181..49ea3247a55 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -1317,7 +1317,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); + tmj->context= BKE_tracking_context_new(clip, &sc->user, backwards); clip->tracking_context= tmj->context; @@ -1428,7 +1428,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); + context= BKE_tracking_context_new(clip, &sc->user, backwards); while(framenr != efra) { if(!BKE_tracking_next(context)) From ba16e7d631ad0fa5ae7add9bc5f0590c3d23e778 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 15 Dec 2011 16:09:57 +0000 Subject: [PATCH 10/18] Object tracking: object with object solver constraint is now parented to scene's camera Made Object Solver operator parent object to scene's camera. Behavior is pretty much familiar to Child Of constraint -- it stores inverted transformation matrix which gives constant offset in parent's space. Current files would open incorrect, to make object aligned well again, just press "Set Inverse" button in Object Solver constraint. Fixed orientation operators so now they should work in all cases. Also changed behavior of Set Origin operator which now sets origin to the median point of all selected tracks/ --- .../bl_ui/properties_object_constraint.py | 4 + source/blender/blenkernel/intern/constraint.c | 7 +- source/blender/blenlib/intern/math_matrix.c | 8 +- source/blender/blenloader/intern/readfile.c | 18 +++ .../editors/object/object_constraint.c | 128 +++++++++++++++--- source/blender/editors/object/object_intern.h | 2 + source/blender/editors/object/object_ops.c | 2 + .../blender/editors/space_clip/tracking_ops.c | 78 ++++++++--- .../blender/editors/space_view3d/drawobject.c | 15 +- .../editors/transform/transform_conversions.c | 1 + .../blender/makesdna/DNA_constraint_types.h | 1 + 11 files changed, 223 insertions(+), 41 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_object_constraint.py b/release/scripts/startup/bl_ui/properties_object_constraint.py index f88f501ab1f..02326fbceba 100644 --- a/release/scripts/startup/bl_ui/properties_object_constraint.py +++ b/release/scripts/startup/bl_ui/properties_object_constraint.py @@ -784,6 +784,10 @@ class ConstraintButtonsPanel(): layout.prop(con, "object") + 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): diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index ba1bfc8f303..1699cb05fde 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -825,7 +825,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]; @@ -4183,20 +4183,21 @@ static void objectsolver_evaluate (bConstraint *con, bConstraintOb *cob, ListBas 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]; + float mat[4][4], obmat[4][4], imat[4][4], cammat[4][4], camimat[4][4], parmat[4][4]; where_is_object_mat(scene, scene->camera, cammat); BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, mat); invert_m4_m4(camimat, cammat); + mul_m4_m4m4(parmat, data->invmat, cammat); copy_m4_m4(cammat, scene->camera->obmat); copy_m4_m4(obmat, cob->matrix); invert_m4_m4(imat, mat); - mul_serie_m4(cob->matrix, cammat, imat, camimat, obmat, NULL, NULL, NULL, NULL); + mul_serie_m4(cob->matrix, cammat, imat, camimat, parmat, obmat, NULL, NULL, NULL); } } } diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 37cb49fc17b..19aa86ee941 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -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]; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index c8130ba6f24..dbc8439e50d 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -12689,6 +12689,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* put compatibility code here until next subversion bump */ { MovieClip *clip; + Object *ob; for (clip= main->movieclip.first; clip; clip= clip->id.next) { MovieTracking *tracking= &clip->tracking; @@ -12696,6 +12697,23 @@ static void do_versions(FileData *fd, Library *lib, Main *main) if(tracking->objects.first == NULL) BKE_tracking_new_object(tracking, "Camera"); } + + 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); + } + } + } } /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 7b9e809fffc..a4a33b866ff 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -697,25 +697,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 : ""); - 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? @@ -761,7 +749,7 @@ static int childof_set_inverse_exec (bContext *C, wmOperator *op) */ invert_m4_m4(imat, pchan->pose_mat); mul_m4_m4m4(tmat, imat, pmat); - invert_m4_m4(data->invmat, tmat); + invert_m4_m4(invmat, tmat); /* 5. restore constraints */ pchan->constraints.last = lastcon; @@ -783,9 +771,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 : ""); + 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; @@ -859,6 +865,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 : ""); + 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) diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 185d8d43765..d4f68b8816e 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -185,6 +185,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); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 3b4a5ed976e..4f598ce4417 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -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); diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 59631e3a181..81741ffab31 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -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" @@ -1938,6 +1940,29 @@ static int count_selected_bundles(bContext *C) return tot; } +static void object_solver_inverted_matrix(Scene *scene, Object *ob, float invmat[4][4]) +{ + Object *cam= scene->camera; + bConstraint *con; + + where_is_object_mat(scene, cam, invmat); + + 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; + + mul_m4_m4m4(invmat, data->invmat, invmat); + } + } + + invert_m4(invmat); +} + static int set_origin_exec(bContext *C, wmOperator *op) { SpaceClip *sc= CTX_wm_space_clip(C); @@ -1948,10 +1973,11 @@ static int set_origin_exec(bContext *C, wmOperator *op) Scene *scene= CTX_data_scene(C); Object *object; ListBase *tracksbase; - float mat[4][4], vec[3]; + float mat[4][4], vec[3], median[3]; + int selected_count= count_selected_bundles(C); - if(count_selected_bundles(C)!=1) { - BKE_report(op->reports, RPT_ERROR, "Track with bundle should be selected to define origin position"); + 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; } @@ -1969,21 +1995,28 @@ static int set_origin_exec(bContext *C, wmOperator *op) tracksbase= BKE_tracking_object_tracks(tracking, tracking_object); 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); + mul_v3_m4v3(vec, mat, median); - if(tracking_object->flag&TRACKING_OBJECT_CAMERA) + if(tracking_object->flag&TRACKING_OBJECT_CAMERA) { sub_v3_v3(object->loc, vec); - else + } + 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(&object->id, OB_RECALC_OB); @@ -2007,6 +2040,9 @@ void CLIP_OT_set_origin(wmOperatorType *ot) /* 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 *********************/ @@ -2027,6 +2063,9 @@ static void set_axis(Scene *scene, Object *ob, MovieTrackingObject *tracking_ob 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); @@ -2094,23 +2133,22 @@ static void set_axis(Scene *scene, Object *ob, MovieTrackingObject *tracking_ob mul_m4_m4m4(mat, obmat, mat); } else { - float lmat[4][4], ilmat[4][4], m[4][4]; - - unit_m4(lmat); - copy_v3_v3(lmat[3], obmat[3]); - invert_m4_m4(ilmat, lmat); - if(!flip) { - float rmat[3][3], tmat[4][4]; + float lmat[4][4], ilmat[4][4], rmat[3][3]; object_rot_to_mat3(ob, rmat); - copy_m4_m3(tmat, rmat); - invert_m4(tmat); + invert_m3(rmat); + mul_m4_m4m3(mat, mat, rmat); - mul_m4_m4m4(mat, mat, tmat); + 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 { + mul_m4_m4m4(mat, mat, obmat); } - - mul_serie_m4(mat, lmat, mat, ilmat, obmat, NULL, NULL, NULL, NULL); } object_apply_mat4(ob, mat, 0, 0); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index cf210e67bdf..c6c42c64ca6 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -6820,7 +6820,20 @@ 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(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER) { + /* special case for object solver constraint because it doesn't fill + constraint targets properly (design limitation -- scene is needed for + it's target but it can't be accessed from get_targets callvack) */ + if(scene->camera) { + setlinestyle(3); + glBegin(GL_LINES); + glVertex3fv(scene->camera->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) { diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 264ca803135..98ad5363c39 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -4196,6 +4196,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) { diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 10c4153702d..5403bf26da0 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -426,6 +426,7 @@ typedef struct bObjectSolverConstraint { struct MovieClip *clip; int flag, pad; char object[24]; + float invmat[4][4]; /* parent-inverse matrix to use */ } bObjectSolverConstraint; /* ------------------------------------------ */ From 53f37cd1edb6e4aa5ea1c8a0da2c466e0cad497c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 15 Dec 2011 16:10:13 +0000 Subject: [PATCH 11/18] Object tracking fixes: - Do not draw bundles for object for opengl selection - Display reconstruction info for active object in cache line and graph editor --- source/blender/editors/space_clip/clip_draw.c | 7 ++++--- source/blender/editors/space_clip/clip_graph_draw.c | 2 +- source/blender/editors/space_view3d/drawobject.c | 4 ++++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 8f2398b156b..ca2646e9967 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -97,6 +97,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc 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); @@ -153,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); diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c index 93aba356c9a..9aba6db0c80 100644 --- a/source/blender/editors/space_clip/clip_graph_draw.c +++ b/source/blender/editors/space_clip/clip_graph_draw.c @@ -207,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); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index c6c42c64ca6..27bc13a8921 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -1487,6 +1487,10 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D else { float obmat[4][4]; + if(flag & DRAW_PICKING) { + return; + } + BKE_tracking_get_interpolated_camera(tracking, tracking_object, scene->r.cfra, obmat); invert_m4_m4(imat, obmat); From e534af906a938b6e3cf0727d577c89a51052f6ff Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 15 Dec 2011 16:10:49 +0000 Subject: [PATCH 12/18] Object tracking: various fixes and improvements - Bundles selection is now available for object's bundles - If bundles selection wasn't changed in 3D viewport, fallback to regular object selection, so objects behind bundles can be selected - Snap cursor to selection now respects object's bundle selection - Object and rack name now can be selected from list in constraint settings - Added preset for tracks used for object tracking --- .../presets/tracking_track_color/object.py | 5 ++ .../bl_ui/properties_object_constraint.py | 20 +++++-- source/blender/blenkernel/BKE_tracking.h | 2 +- source/blender/blenkernel/intern/tracking.c | 29 ++++++---- .../editors/object/object_constraint.c | 6 +++ .../blender/editors/space_view3d/drawobject.c | 24 ++++----- .../editors/space_view3d/view3d_select.c | 53 +++++++++++++++---- .../editors/space_view3d/view3d_snap.c | 48 +++++++++++++---- 8 files changed, 140 insertions(+), 47 deletions(-) create mode 100644 release/scripts/presets/tracking_track_color/object.py diff --git a/release/scripts/presets/tracking_track_color/object.py b/release/scripts/presets/tracking_track_color/object.py new file mode 100644 index 00000000000..5cb663d3f97 --- /dev/null +++ b/release/scripts/presets/tracking_track_color/object.py @@ -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 diff --git a/release/scripts/startup/bl_ui/properties_object_constraint.py b/release/scripts/startup/bl_ui/properties_object_constraint.py index 02326fbceba..6bec2fea74f 100644 --- a/release/scripts/startup/bl_ui/properties_object_constraint.py +++ b/release/scripts/startup/bl_ui/properties_object_constraint.py @@ -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,8 +772,9 @@ class ConstraintButtonsPanel(): if not con.use_active_clip: layout.prop(con, "clip") - layout.prop(con, "object") - 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.operator("clip.constraint_to_fcurve") @@ -777,12 +787,16 @@ 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") - layout.prop(con, "object") + if clip: + layout.prop_search(con, "object", clip.tracking, "objects", icon='OBJECT_DATA') row = layout.row() row.operator("constraint.objectsolver_set_inverse") diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index 772306967fc..7b3cb3f69bb 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -77,7 +77,7 @@ struct ImBuf *BKE_tracking_get_search_imbuf(struct ImBuf *ibuf, struct MovieTrac void BKE_track_unique_name(struct ListBase *tracksbase, struct MovieTrackingTrack *track); 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 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); diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 931f3f5fc72..262c0576186 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -2257,23 +2257,34 @@ void BKE_tracking_detect_fast(MovieTracking *tracking, ListBase *tracksbase, ImB #endif } -MovieTrackingTrack *BKE_tracking_indexed_track(MovieTracking *tracking, int tracknr) +MovieTrackingTrack *BKE_tracking_indexed_track(MovieTracking *tracking, int tracknr, ListBase **tracksbase_r) { - ListBase *tracksbase= &tracking->tracks; /* XXX: need proper tracks base */ - MovieTrackingTrack *track= tracksbase->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; - cur++; + while(track) { + if(track->flag&TRACK_HAS_BUNDLE) { + if(cur==tracknr) { + *tracksbase_r= tracksbase; + return track; + } + + cur++; + } + + track= track->next; } - track= track->next; + object= object->next; } + *tracksbase_r= NULL; + return NULL; } diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index a4a33b866ff..fa4f50e240f 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -433,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) { diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 27bc13a8921..82ee494630d 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -1459,13 +1459,13 @@ static void draw_bundle_sphere(void) } static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D *v3d, - MovieClip *clip, MovieTrackingObject *tracking_object, int flag) + MovieClip *clip, MovieTrackingObject *tracking_object, int flag, int *global_track_index) { MovieTracking *tracking= &clip->tracking; MovieTrackingTrack *track; float mat[4][4], imat[4][4]; unsigned char col[4], scol[4]; - int bundlenr= 1; + int tracknr= *global_track_index; ListBase *tracksbase= BKE_tracking_object_tracks(tracking, tracking_object); UI_GetThemeColor4ubv(TH_TEXT, col); @@ -1487,10 +1487,6 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D else { float obmat[4][4]; - if(flag & DRAW_PICKING) { - return; - } - BKE_tracking_get_interpolated_camera(tracking, tracking_object, scene->r.cfra, obmat); invert_m4_m4(imat, obmat); @@ -1504,7 +1500,7 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D 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]); @@ -1512,7 +1508,6 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D if(v3d->drawtype==OB_WIRE) { glDisable(GL_LIGHTING); - glDepthMask(0); if(selected) { if(base==BASACT) UI_ThemeColor(TH_ACTIVE); @@ -1524,7 +1519,6 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D drawaxes(0.05f, v3d->bundle_drawtype); - glDepthMask(1); glEnable(GL_LIGHTING); } else if(v3d->drawtype>OB_WIRE) { if(v3d->bundle_drawtype==OB_EMPTY_SPHERE) { @@ -1533,7 +1527,6 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D 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); @@ -1543,7 +1536,6 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glEnable(GL_LIGHTING); glLineWidth(1.f); - glDepthMask(1); } if(track->flag&TRACK_CUSTOMCOLOR) glColor3fv(track->color); @@ -1552,7 +1544,6 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D draw_bundle_sphere(); } else { glDisable(GL_LIGHTING); - glDepthMask(0); if(selected) { if(base==BASACT) UI_ThemeColor(TH_ACTIVE); @@ -1564,7 +1555,6 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D drawaxes(0.05f, v3d->bundle_drawtype); - glDepthMask(1); glEnable(GL_LIGHTING); } } @@ -1582,7 +1572,7 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D view3d_cached_text_draw_add(pos, track->name, 10, V3D_CACHE_TEXT_GLOBALSPACE, tcol); } - bundlenr++; + tracknr++; } if((flag & DRAW_PICKING)==0) { @@ -1611,6 +1601,8 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D } glPopMatrix(); + + *global_track_index= tracknr; } static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, MovieClip *clip, int flag) @@ -1618,6 +1610,7 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, MovieTracking *tracking= &clip->tracking; MovieTrackingObject *tracking_object; float curcol[4]; + int global_track_index= 1; if((v3d->flag2&V3D_SHOW_RECONSTRUCTION)==0) return; @@ -1634,7 +1627,8 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, tracking_object= tracking->objects.first; while(tracking_object) { - draw_viewport_object_reconstruction(scene, base, v3d, clip, tracking_object, flag); + draw_viewport_object_reconstruction(scene, base, v3d, clip, tracking_object, + flag, &global_track_index); tracking_object= tracking_object->next; } diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index d8ff01a880d..7da07149490 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -1320,6 +1320,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) { @@ -1391,31 +1410,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); MovieTracking *tracking= &clip->tracking; - int selected; + ListBase *tracksbase; + MovieTrackingTrack *track; - track= BKE_tracking_indexed_track(&clip->tracking, hitresult >> 16); + track= BKE_tracking_indexed_track(&clip->tracking, hitresult >> 16, &tracksbase); - selected= (track->flag&SELECT) || (track->pat_flag&SELECT) || (track->search_flag&SELECT); - - if(selected && extend) + if(TRACK_SELECTED(track) && extend) { + changed= 0; BKE_tracking_deselect_track(track, TRACK_AREA_ALL); - else - BKE_tracking_select_track(&tracking->tracks, track, TRACK_AREA_ALL, extend); + } + else { + int oldsel= TRACK_SELECTED(track) ? 1 : 0; + if(!extend) + deselect_all_tracks(tracking); + + BKE_tracking_select_track(tracksbase, track, TRACK_AREA_ALL, extend); + + if(oldsel!=(TRACK_SELECTED(track) ? 1 : 0)) + changed= 1; + } basact->flag|= SELECT; basact->object->flag= basact->flag; @@ -1428,6 +1457,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 */ diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index ecb54c77e0c..db33426a804 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -55,6 +55,7 @@ #include "BKE_lattice.h" #include "BKE_main.h" #include "BKE_object.h" +#include "BKE_scene.h" #include "BKE_tracking.h" #include "WM_api.h" @@ -756,28 +757,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); + + mul_m4_m4m4(obmat, imat, cammat); } - track= track->next; + 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; + } + + object= object->next; } if(ok) { From 8a9d901c81b0357bca833f3ccb2d4f674873e58d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 15 Dec 2011 20:38:23 +0000 Subject: [PATCH 13/18] Camera tracking: add camera to follow track and object solver constraint Object used to be parented to active camera which isn't very convenient when working with witness cameras. Now parent camera can be specified in constraint (if it's not specified, active camera is used) --- .../bl_ui/properties_object_constraint.py | 4 + source/blender/blenkernel/intern/constraint.c | 118 +++++++++--------- .../blender/editors/space_view3d/drawobject.c | 26 +++- .../blender/makesdna/DNA_constraint_types.h | 2 + .../blender/makesrna/intern/rna_constraint.c | 61 ++++++++- 5 files changed, 143 insertions(+), 68 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_object_constraint.py b/release/scripts/startup/bl_ui/properties_object_constraint.py index 6bec2fea74f..32ed1c3f1b1 100644 --- a/release/scripts/startup/bl_ui/properties_object_constraint.py +++ b/release/scripts/startup/bl_ui/properties_object_constraint.py @@ -776,6 +776,8 @@ class ConstraintButtonsPanel(): 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") def CAMERA_SOLVER(self, context, layout, con): @@ -798,6 +800,8 @@ class ConstraintButtonsPanel(): 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") diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 1699cb05fde..2e9934806b8 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -3937,6 +3937,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)) @@ -3947,11 +3948,12 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase 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; tracking= &clip->tracking; @@ -3975,12 +3977,8 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase float pos[3], mat[4][4]; if((tracking_object->flag&TRACKING_OBJECT_CAMERA)==0) { - Object *camob= scene->camera; float obmat[4][4], imat[4][4]; - if(!camob) - return; - copy_m4_m4(mat, camob->obmat); BKE_tracking_get_interpolated_camera(tracking, tracking_object, scene->r.cfra, obmat); @@ -4000,77 +3998,73 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase } } else { - Object *camob= scene->camera; + 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 (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); - 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); - /* 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); - /* 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); - len= len_v3(disp); + if (len > FLT_EPSILON) { + CameraParams params; + float pos[2], rmat[4][4]; - 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); - user.framenr= scene->r.cfra; - marker= BKE_tracking_get_marker(track, user.framenr); + add_v2_v2v2(pos, marker->pos, track->offset); - add_v2_v2v2(pos, marker->pos, track->offset); + camera_params_init(¶ms); + camera_params_from_object(¶ms, camob); - camera_params_init(¶ms); - camera_params_from_object(¶ms, 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 (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; - if (aspect > 1.0f) vec[1] /= aspect; - else vec[0] *= aspect; + mul_v3_m4v3(disp, camob->obmat, vec); - mul_v3_m4v3(disp, camob->obmat, vec); + copy_m4_m4(rmat, camob->obmat); + zero_v3(rmat[3]); + mul_m4_m4m4(cob->matrix, rmat, cob->matrix); - copy_m4_m4(rmat, camob->obmat); - zero_v3(rmat[3]); - mul_m4_m4m4(cob->matrix, rmat, cob->matrix); + copy_v3_v3(cob->matrix[3], disp); + } + else { + d= (len*params.sensor_x) / (2.0f*params.lens); - 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; - 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; - if (aspect > 1.0f) vec[1] /= aspect; - else vec[0] *= aspect; + mul_v3_m4v3(disp, camob->obmat, vec); - 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]); + mul_m4_m4m4(cob->matrix, rmat, cob->matrix); - /* apply camera rotation so Z-axis would be co-linear */ - copy_m4_m4(rmat, camob->obmat); - zero_v3(rmat[3]); - mul_m4_m4m4(cob->matrix, rmat, cob->matrix); - - copy_v3_v3(cob->matrix[3], disp); - } + copy_v3_v3(cob->matrix[3], disp); } } } @@ -4162,6 +4156,7 @@ static void objectsolver_id_looper (bConstraint *con, ConstraintIDFunc func, voi 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)) @@ -4169,11 +4164,12 @@ static void objectsolver_evaluate (bConstraint *con, bConstraintOb *cob, ListBas 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(!scene->camera) + if(!camob || !clip) return; if (clip) { @@ -4185,14 +4181,14 @@ static void objectsolver_evaluate (bConstraint *con, bConstraintOb *cob, ListBas 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, scene->camera, cammat); + where_is_object_mat(scene, camob, cammat); BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, mat); invert_m4_m4(camimat, cammat); mul_m4_m4m4(parmat, data->invmat, cammat); - copy_m4_m4(cammat, scene->camera->obmat); + copy_m4_m4(cammat, camob->obmat); copy_m4_m4(obmat, cob->matrix); invert_m4_m4(imat, mat); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 82ee494630d..21ac4e1431f 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -6818,14 +6818,28 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) ListBase targets = {NULL, NULL}; bConstraintTarget *ct; - if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER) { - /* special case for object solver constraint because it doesn't fill - constraint targets properly (design limitation -- scene is needed for - it's target but it can't be accessed from get_targets callvack) */ - if(scene->camera) { + 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(scene->camera->obmat[3]); + glVertex3fv(camob->obmat[3]); glVertex3fv(ob->obmat[3]); glEnd(); setlinestyle(0); diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 5403bf26da0..50c1779960d 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -413,6 +413,7 @@ typedef struct bFollowTrackConstraint { char track[24]; int flag, pad; char object[24]; + struct Object *camera; } bFollowTrackConstraint; /* Camera Solver constraints */ @@ -427,6 +428,7 @@ typedef struct bObjectSolverConstraint { int flag, pad; char object[24]; float invmat[4][4]; /* parent-inverse matrix to use */ + struct Object *camera; } bObjectSolverConstraint; /* ------------------------------------------ */ diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 4d064c01fae..6439d22e808 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -330,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[] = { @@ -2073,8 +2116,16 @@ static void rna_def_constraint_follow_track(BlenderRNA *brna) /* 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_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) @@ -2127,6 +2178,14 @@ static void rna_def_constraint_object_solver(BlenderRNA *brna) 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 */ From b1111bafa14b0b7ca7f2e3ee839893f18db75c54 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 15 Dec 2011 20:38:45 +0000 Subject: [PATCH 14/18] Camera tracking: follow track + 3d position now respects camera orientation and object offset --- source/blender/blenkernel/intern/constraint.c | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 2e9934806b8..4f4485fadee 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -3974,27 +3974,27 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase if (data->flag & FOLLOWTRACK_USE_3D_POSITION) { if (track->flag & TRACK_HAS_BUNDLE) { MovieTracking *tracking= &clip->tracking; - float pos[3], mat[4][4]; + float obmat[4][4], mat[4][4]; + + copy_m4_m4(obmat, cob->matrix); if((tracking_object->flag&TRACKING_OBJECT_CAMERA)==0) { - float obmat[4][4], imat[4][4]; + float imat[4][4]; copy_m4_m4(mat, camob->obmat); - BKE_tracking_get_interpolated_camera(tracking, tracking_object, scene->r.cfra, obmat); + BKE_tracking_get_interpolated_camera(tracking, tracking_object, scene->r.cfra, imat); + invert_m4(imat); - invert_m4_m4(imat, obmat); - mul_m4_m4m4(mat, imat, mat); + 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, NULL, mat); + BKE_get_tracking_mat(cob->scene, camob, mat); + + mul_m4_m4m4(cob->matrix, mat, obmat); + translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]); } - - 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]; } } else { From 3708d66c8858ca19be433698794d8d640f3e67ab Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 18 Dec 2011 18:03:20 +0000 Subject: [PATCH 15/18] Object tracking: forgot to initialize inverted matrix for object solver constraint --- source/blender/blenkernel/intern/constraint.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 4f4485fadee..831d4d1bc07 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -4149,6 +4149,7 @@ static void objectsolver_new_data (void *cdata) data->clip = NULL; data->flag |= OBJECTSOLVER_ACTIVECLIP; + unit_m4(data->invmat); } static void objectsolver_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata) From 5d15d8d2eebc98d7122e811dae2979b9a6c38b9d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 18 Dec 2011 18:31:02 +0000 Subject: [PATCH 16/18] Object tracking: scale object itself when setting scale in object tracking mode Also fixed incorrect poll functions which didn't check active object when orienting object. --- .../blender/editors/space_clip/tracking_ops.c | 79 +++++++++++-------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 81741ffab31..ca854c7befe 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -92,28 +92,6 @@ 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) @@ -1921,6 +1899,24 @@ void CLIP_OT_disable_markers(wmOperatorType *ot) /********************** set origin operator *********************/ +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 scene->camera != NULL; + else + return OBACT != NULL; + } + + return 0; +} + static int count_selected_bundles(bContext *C) { SpaceClip *sc= CTX_wm_space_clip(C); @@ -2036,7 +2032,7 @@ 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; @@ -2267,7 +2263,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; @@ -2337,7 +2333,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; @@ -2352,10 +2348,12 @@ static int set_scale_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; - ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking); + Object *object; + 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"); @@ -2366,8 +2364,13 @@ static int set_scale_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - if(scene->camera->parent) - parent= scene->camera->parent; + if(tracking_object->flag&TRACKING_OBJECT_CAMERA) + object= scene->camera; + else + object= OBACT; + + if(object->parent) + object= object->parent; BKE_get_tracking_mat(scene, NULL, mat); @@ -2386,11 +2389,21 @@ 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 { + object->size[0]= object->size[1]= object->size[2]= 1.0f/scale; + + if(scene->camera) { + object->size[0]/= scene->camera->size[0]; + object->size[1]/= scene->camera->size[1]; + object->size[2]/= scene->camera->size[2]; + } + } 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); @@ -2421,7 +2434,7 @@ 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; From 1dc74acc123721d366e3628663ed029db5761e4d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 19 Dec 2011 15:12:33 +0000 Subject: [PATCH 17/18] Object tracking: configurable scale for object solution Added slider to define scale of object solution which is used to define "depth" of object relative to camera position. This slider effects on all "users" of object solution such as bundles display, constrained objects and so. Added new operator called "Set Solution Scale" to set real scale for object solution based on real distance between two bundles reconstructed for this object. New slider and operator can be found on "Object" panel in toolbox when in reconstruction mode and active tracking object isn't a camera. --- release/scripts/startup/bl_ui/space_clip.py | 33 ++++++++ source/blender/blenkernel/intern/tracking.c | 13 +++ source/blender/blenloader/intern/readfile.c | 11 +++ .../blender/editors/space_clip/clip_intern.h | 1 + .../blender/editors/space_clip/space_clip.c | 1 + .../blender/editors/space_clip/tracking_ops.c | 83 +++++++++++++++++-- source/blender/makesdna/DNA_tracking_types.h | 9 +- source/blender/makesrna/intern/rna_tracking.c | 25 ++++++ 8 files changed, 166 insertions(+), 10 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 5aec9a8e58c..5234ffbcc32 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -302,6 +302,39 @@ class CLIP_PT_tools_orientation(Panel): col.prop(settings, "distance") +class CLIP_PT_tools_object(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' + bl_label = "Object" + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + if clip and sc.mode == 'RECONSTRUCTION': + tracking_object = clip.tracking.objects.active + return not tracking_object.is_camera + + return False + + def draw(self, context): + sc = context.space_data + clip = sc.clip + layout = self.layout + tracking_object = clip.tracking.objects.active + settings = sc.clip.tracking.settings + + col = layout.column() + + col.prop(tracking_object, "scale") + + col.separator() + + col.operator("clip.set_solution_scale", text="Set Scale") + col.prop(settings, "object_distance") + + class CLIP_PT_tools_grease_pencil(Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'TOOLS' diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 06680dc9da4..0b58d1562fa 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -86,6 +86,7 @@ void BKE_tracking_init_settings(MovieTracking *tracking) tracking->settings.keyframe1= 1; tracking->settings.keyframe2= 30; tracking->settings.dist= 1; + tracking->settings.object_distance= 1; tracking->stabilization.scaleinf= 1.0f; tracking->stabilization.locinf= 1.0f; @@ -1920,6 +1921,16 @@ static int reconstruction_camera_index(MovieTrackingReconstruction *reconstructi return -1; } +static void scale_reconstructed_camera(MovieTrackingObject *object, float mat[4][4]) +{ + if((object->flag&TRACKING_OBJECT_CAMERA)==0) { + float smat[4][4]; + + scale_m4_fl(smat, 1.0f/object->scale); + mult_m4_m4m4(mat, mat, smat); + } +} + MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(MovieTracking *tracking, MovieTrackingObject *object, int framenr) { @@ -1958,6 +1969,8 @@ void BKE_tracking_get_interpolated_camera(MovieTracking *tracking, MovieTracking } else { copy_m4_m4(mat, cameras[a].mat); } + + scale_reconstructed_camera(object, mat); } void BKE_get_tracking_mat(Scene *scene, Object *ob, float mat[4][4]) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index dbc8439e50d..ab362fba143 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -12693,9 +12693,20 @@ static void do_versions(FileData *fd, Library *lib, Main *main) for (clip= main->movieclip.first; clip; clip= clip->id.next) { MovieTracking *tracking= &clip->tracking; + MovieTrackingObject *tracking_object= tracking->objects.first; + + if(!tracking->settings.object_distance) + tracking->settings.object_distance= 1.0f; if(tracking->objects.first == NULL) BKE_tracking_new_object(tracking, "Camera"); + + while(tracking_object) { + if(!tracking_object->scale) + tracking_object->scale= 1.0f; + + tracking_object= tracking_object->next; + } } for (ob= main->object.first; ob; ob= ob->id.next) { diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h index 38da4dd86ff..64881499a31 100644 --- a/source/blender/editors/space_clip/clip_intern.h +++ b/source/blender/editors/space_clip/clip_intern.h @@ -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); diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 01779a806b9..5291121571c 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -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); diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index c37113e924c..ff970a9db30 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -2344,7 +2344,7 @@ void CLIP_OT_set_axis(wmOperatorType *ot) /********************** set scale operator *********************/ -static int set_scale_exec(bContext *C, wmOperator *op) +static int do_set_scale(bContext *C, wmOperator *op, int scale_solution) { SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); @@ -2352,24 +2352,26 @@ static int set_scale_exec(bContext *C, wmOperator *op) MovieTrackingObject *tracking_object= BKE_tracking_active_object(tracking); MovieTrackingTrack *track; Scene *scene= CTX_data_scene(C); - Object *object; + Object *object= NULL; ListBase *tracksbase= BKE_tracking_get_tracks(tracking); int tot= 0; float vec[2][3], mat[4][4], scale; float dist= RNA_float_get(op->ptr, "distance"); if(count_selected_bundles(C)!=2) { - BKE_report(op->reports, RPT_ERROR, "Two tracks with bundles should be selected to scale scene"); + BKE_report(op->reports, RPT_ERROR, "Two tracks with bundles should be selected to set scale"); return OPERATOR_CANCELLED; } - if(tracking_object->flag&TRACKING_OBJECT_CAMERA) + if(tracking_object->flag&TRACKING_OBJECT_CAMERA) { object= scene->camera; - else + } + else if(!scale_solution) { object= OBACT; + } - if(object->parent) + if(object && object->parent) object= object->parent; BKE_get_tracking_mat(scene, NULL, mat); @@ -2392,7 +2394,8 @@ static int set_scale_exec(bContext *C, wmOperator *op) if(tracking_object->flag&TRACKING_OBJECT_CAMERA) { mul_v3_fl(object->size, scale); mul_v3_fl(object->loc, scale); - } else { + } else + if(!scale_solution){ object->size[0]= object->size[1]= object->size[2]= 1.0f/scale; if(scene->camera) { @@ -2401,9 +2404,14 @@ static int set_scale_exec(bContext *C, wmOperator *op) object->size[2]/= scene->camera->size[2]; } } + else { + tracking_object->scale= scale; + } DAG_id_tag_update(&clip->id, 0); - DAG_id_tag_update(&object->id, OB_RECALC_OB); + + if(object) + DAG_id_tag_update(&object->id, OB_RECALC_OB); WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip); WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); @@ -2412,6 +2420,11 @@ static int set_scale_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int set_scale_exec(bContext *C, wmOperator *op) +{ + return do_set_scale(C, op, 0); +} + static int set_scale_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { SpaceClip *sc= CTX_wm_space_clip(C); @@ -2444,6 +2457,60 @@ void CLIP_OT_set_scale(wmOperatorType *ot) "Distance", "Distance between selected tracks", -100.0f, 100.0f); } +/********************** set solution scale operator *********************/ + +static int set_solution_scale_poll(bContext *C) +{ + if(space_clip_frame_poll(C)) { + Scene *scene= CTX_data_scene(C); + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + MovieTrackingObject *tracking_object= BKE_tracking_active_object(tracking); + + return (tracking_object->flag&TRACKING_OBJECT_CAMERA) == 0; + } + + return 0; +} + +static int set_solution_scale_exec(bContext *C, wmOperator *op) +{ + return do_set_scale(C, op, 1); +} + +static int set_solution_scale_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + float dist= RNA_float_get(op->ptr, "distance"); + + if(dist==0.0f) + RNA_float_set(op->ptr, "distance", clip->tracking.settings.object_distance); + + return set_solution_scale_exec(C, op); +} + +void CLIP_OT_set_solution_scale(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Set Solution Scale"; + ot->description= "Set object solution scale using distance between two selected tracks"; + ot->idname= "CLIP_OT_set_solution_scale"; + + /* api callbacks */ + ot->exec= set_solution_scale_exec; + ot->invoke= set_solution_scale_invoke; + ot->poll= set_solution_scale_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_float(ot->srna, "distance", 0.0f, -FLT_MAX, FLT_MAX, + "Distance", "Distance between selected tracks", -100.0f, 100.0f); +} + /********************** set principal center operator *********************/ static int set_center_principal_exec(bContext *C, wmOperator *UNUSED(op)) diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index fd0e281b60f..25ae75dcb03 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -142,7 +142,10 @@ typedef struct MovieTrackingSettings { /* cleanup */ int clean_frames, clean_action; - float clean_error, pad; + float clean_error; + + /* set object scale */ + float object_distance; /* distance between two bundles used for object scaling */ } MovieTrackingSettings; typedef struct MovieTrackingStabilization { @@ -176,7 +179,9 @@ typedef struct MovieTrackingObject { struct MovieTrackingObject *next, *prev; char name[24]; /* Name of tracking object */ - int flag, pad; + int flag; + float scale; /* scale of object solution in amera space */ + ListBase tracks; /* list of tracks use to tracking this object */ MovieTrackingReconstruction reconstruction; /* reconstruction data for this object */ } MovieTrackingObject; diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index bf3806e5de4..bbec6484c5f 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -336,6 +336,14 @@ void rna_trackingObject_name_set(PointerRNA *ptr, const char *value) BKE_tracking_object_unique_name(&clip->tracking, object); } +static void rna_trackingObject_flushUpdate(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr) +{ + MovieClip *clip= (MovieClip*)ptr->id.data; + + WM_main_add_notifier(NC_OBJECT|ND_TRANSFORM, NULL); + DAG_id_tag_update(&clip->id, 0); +} + /* API */ static void add_tracks_to_base(MovieClip *clip, MovieTracking *tracking, ListBase *tracksbase, int frame, int number) @@ -572,6 +580,14 @@ static void rna_def_trackingSettings(BlenderRNA *brna) RNA_def_property_range(prop, 5, 1000); RNA_def_property_update(prop, 0, "rna_tracking_defaultSettings_searchUpdate"); RNA_def_property_ui_text(prop, "Search Size", "Size of search area for newly created tracks"); + + /* object distance */ + prop= RNA_def_property(srna, "object_distance", PROP_FLOAT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_float_sdna(prop, NULL, "object_distance"); + RNA_def_property_ui_text(prop, "Distance", "Distance between two bundles used for object scaling"); + RNA_def_property_range(prop, 0.001, 10000); + RNA_def_property_ui_range(prop, 0.001, 10000.0, 1, 3); } static void rna_def_trackingCamera(BlenderRNA *brna) @@ -1100,6 +1116,15 @@ static void rna_def_trackingObject(BlenderRNA *brna) /* reconstruction */ prop= RNA_def_property(srna, "reconstruction", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MovieTrackingReconstruction"); + + /* scale */ + prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_float_sdna(prop, NULL, "scale"); + RNA_def_property_range(prop, 0.0001f, 10000.0f); + RNA_def_property_ui_range(prop, 0.0001f, 10000.0, 1, 4); + RNA_def_property_ui_text(prop, "Scale", "Scale of object solution in camera space"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_trackingObject_flushUpdate"); } static void rna_def_trackingObjects(BlenderRNA *brna, PropertyRNA *cprop) From 0c8cde2bb6bf5f38b4f567342ca371ec164f211c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 21 Dec 2011 14:51:01 +0000 Subject: [PATCH 18/18] Object tracking: various fixes for scene orientation for witness cameras workflow --- .../blender/editors/space_clip/tracking_ops.c | 169 +++++++++++++----- 1 file changed, 122 insertions(+), 47 deletions(-) diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index ff970a9db30..dd5b78c5b8d 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -1899,6 +1899,51 @@ 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)) { @@ -1908,10 +1953,12 @@ static int set_orientation_poll(bContext *C) MovieTracking *tracking= &clip->tracking; MovieTrackingObject *tracking_object= BKE_tracking_active_object(tracking); - if(tracking_object->flag&TRACKING_OBJECT_CAMERA) - return scene->camera != NULL; - else + if(tracking_object->flag&TRACKING_OBJECT_CAMERA) { + return 1; + } + else { return OBACT != NULL; + } } return 0; @@ -1938,10 +1985,8 @@ static int count_selected_bundles(bContext *C) static void object_solver_inverted_matrix(Scene *scene, Object *ob, float invmat[4][4]) { - Object *cam= scene->camera; bConstraint *con; - - where_is_object_mat(scene, cam, invmat); + int found= 0; for (con= ob->constraints.first; con; con=con->next) { bConstraintTypeInfo *cti= constraint_get_typeinfo(con); @@ -1952,11 +1997,42 @@ static void object_solver_inverted_matrix(Scene *scene, Object *ob, float invmat 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; } } - invert_m4(invmat); + 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) @@ -1968,6 +2044,7 @@ static int set_origin_exec(bContext *C, wmOperator *op) MovieTrackingObject *tracking_object; Scene *scene= CTX_data_scene(C); 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); @@ -1978,16 +2055,15 @@ static int set_origin_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } + object= get_orientation_object(C); + if(!object) { + BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); + + return OPERATOR_CANCELLED; + } + tracking_object= BKE_tracking_active_object(tracking); - if(tracking_object->flag&TRACKING_OBJECT_CAMERA) - object= scene->camera; - else - object= OBACT; - - if(object->parent) - object= object->parent; - tracksbase= BKE_tracking_object_tracks(tracking, tracking_object); track= tracksbase->first; @@ -2001,7 +2077,7 @@ static int set_origin_exec(bContext *C, wmOperator *op) } mul_v3_fl(median, 1.0f/selected_count); - BKE_get_tracking_mat(scene, NULL, mat); + BKE_get_tracking_mat(scene, camera, mat); mul_v3_m4v3(vec, mat, median); @@ -2043,16 +2119,17 @@ void CLIP_OT_set_origin(wmOperatorType *ot) /********************** set floor operator *********************/ -static void set_axis(Scene *scene, Object *ob, MovieTrackingObject *tracking_object, +static void set_axis(Scene *scene, Object *ob, MovieClip *clip, MovieTrackingObject *tracking_object, MovieTrackingTrack *track, char axis) { + 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); @@ -2160,6 +2237,7 @@ static int set_floor_exec(bContext *C, wmOperator *op) 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}, @@ -2177,15 +2255,14 @@ static int set_floor_exec(bContext *C, wmOperator *op) tracksbase= BKE_tracking_object_tracks(tracking, tracking_object); act_track= BKE_tracking_active_track(tracking); - if(tracking_object->flag&TRACKING_OBJECT_CAMERA) - object= scene->camera; - else - object= OBACT; + object= get_orientation_object(C); + if(!object) { + BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); - if(object->parent) - object= object->parent; + 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= tracksbase->first; @@ -2243,7 +2320,7 @@ static int set_floor_exec(bContext *C, wmOperator *op) } where_is_object(scene, object); - set_axis(scene, object, tracking_object, axis_track, 'X'); + set_axis(scene, object, clip, tracking_object, axis_track, 'X'); DAG_id_tag_update(&clip->id, 0); DAG_id_tag_update(&object->id, OB_RECALC_OB); @@ -2289,13 +2366,12 @@ static int set_axis_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - if(tracking_object->flag & TRACKING_OBJECT_CAMERA) - object= scene->camera; - else - object= OBACT; + object= get_orientation_object(C); + if(!object) { + BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); - if(object->parent) - object= object->parent; + return OPERATOR_CANCELLED; + } tracksbase= BKE_tracking_object_tracks(tracking, tracking_object); @@ -2307,7 +2383,7 @@ static int set_axis_exec(bContext *C, wmOperator *op) track= track->next; } - set_axis(scene, object, tracking_object, 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(&object->id, OB_RECALC_OB); @@ -2353,6 +2429,7 @@ static int do_set_scale(bContext *C, wmOperator *op, int scale_solution) MovieTrackingTrack *track; Scene *scene= CTX_data_scene(C); 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; @@ -2364,17 +2441,14 @@ static int do_set_scale(bContext *C, wmOperator *op, int scale_solution) return OPERATOR_CANCELLED; } - if(tracking_object->flag&TRACKING_OBJECT_CAMERA) { - object= scene->camera; - } - else if(!scale_solution) { - object= OBACT; + object= get_orientation_object(C); + if(!object) { + BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); + + return OPERATOR_CANCELLED; } - if(object && object->parent) - object= object->parent; - - BKE_get_tracking_mat(scene, NULL, mat); + BKE_get_tracking_mat(scene, camera, mat); track= tracksbase->first; while(track) { @@ -2396,12 +2470,14 @@ static int do_set_scale(bContext *C, wmOperator *op, int scale_solution) 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(scene->camera) { - object->size[0]/= scene->camera->size[0]; - object->size[1]/= scene->camera->size[1]; - object->size[2]/= scene->camera->size[2]; + if(camera) { + object->size[0]/= camera->size[0]; + object->size[1]/= camera->size[1]; + object->size[2]/= camera->size[2]; } } else { @@ -2462,7 +2538,6 @@ void CLIP_OT_set_scale(wmOperatorType *ot) static int set_solution_scale_poll(bContext *C) { if(space_clip_frame_poll(C)) { - Scene *scene= CTX_data_scene(C); SpaceClip *sc= CTX_wm_space_clip(C); MovieClip *clip= ED_space_clip(sc); MovieTracking *tracking= &clip->tracking;