/* convert the coordinates from the given stroke point into 3d-coordinates * - assumes that the active space is the 3D-View */ static void gp_strokepoint_convertcoords(bContext *C, bGPDstroke *gps, bGPDspoint *pt, float p3d[3], rctf *subrect) { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); ARegion *ar = CTX_wm_region(C); if (gps->flag & GP_STROKE_3DSPACE) { /* directly use 3d-coordinates */ copy_v3_v3(p3d, &pt->x); } else { const float *fp = ED_view3d_cursor3d_get(scene, v3d); float mvalf[2]; /* get screen coordinate */ if (gps->flag & GP_STROKE_2DSPACE) { View2D *v2d = &ar->v2d; UI_view2d_view_to_region_fl(v2d, pt->x, pt->y, &mvalf[0], &mvalf[1]); } else { if (subrect) { mvalf[0] = (((float)pt->x / 100.0f) * BLI_rctf_size_x(subrect)) + subrect->xmin; mvalf[1] = (((float)pt->y / 100.0f) * BLI_rctf_size_y(subrect)) + subrect->ymin; } else { mvalf[0] = (float)pt->x / 100.0f * ar->winx; mvalf[1] = (float)pt->y / 100.0f * ar->winy; } } ED_view3d_win_to_3d(ar, fp, mvalf, p3d); } }
static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, int width, int height, float zoomx, float zoomy) { float x, y; const int n = 10; int i, j, a; float pos[2], tpos[2], grid[11][11][2]; MovieTracking *tracking = &clip->tracking; bGPdata *gpd = NULL; float aspy = 1.0f / tracking->camera.pixel_aspect; float dx = (float)width / n, dy = (float)height / n * aspy; float offsx = 0.0f, offsy = 0.0f; if (!tracking->camera.focal) return; if ((sc->flag & SC_SHOW_GRID) == 0 && (sc->flag & SC_MANUAL_CALIBRATION) == 0) return; UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y); glPushMatrix(); glTranslatef(x, y, 0); glScalef(zoomx, zoomy, 0); glMultMatrixf(sc->stabmat); glScalef(width, height, 0); /* grid */ if (sc->flag & SC_SHOW_GRID) { float val[4][2], idx[4][2]; float min[2], max[2]; for (a = 0; a < 4; a++) { if (a < 2) val[a][a % 2] = FLT_MAX; else val[a][a % 2] = -FLT_MAX; } zero_v2(pos); for (i = 0; i <= n; i++) { for (j = 0; j <= n; j++) { if (i == 0 || j == 0 || i == n || j == n) { BKE_tracking_distort_v2(tracking, pos, tpos); for (a = 0; a < 4; a++) { int ok; if (a < 2) ok = tpos[a % 2] < val[a][a % 2]; else ok = tpos[a % 2] > val[a][a % 2]; if (ok) { copy_v2_v2(val[a], tpos); idx[a][0] = j; idx[a][1] = i; } } } pos[0] += dx; } pos[0] = 0.0f; pos[1] += dy; } INIT_MINMAX2(min, max); for (a = 0; a < 4; a++) { pos[0] = idx[a][0] * dx; pos[1] = idx[a][1] * dy; BKE_tracking_undistort_v2(tracking, pos, tpos); minmax_v2v2_v2(min, max, tpos); } copy_v2_v2(pos, min); dx = (max[0] - min[0]) / n; dy = (max[1] - min[1]) / n; for (i = 0; i <= n; i++) { for (j = 0; j <= n; j++) { BKE_tracking_distort_v2(tracking, pos, grid[i][j]); grid[i][j][0] /= width; grid[i][j][1] /= height * aspy; pos[0] += dx; } pos[0] = min[0]; pos[1] += dy; } glColor3f(1.0f, 0.0f, 0.0f); for (i = 0; i <= n; i++) { glBegin(GL_LINE_STRIP); for (j = 0; j <= n; j++) { glVertex2fv(grid[i][j]); } glEnd(); } for (j = 0; j <= n; j++) { glBegin(GL_LINE_STRIP); for (i = 0; i <= n; i++) { glVertex2fv(grid[i][j]); } glEnd(); } } if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { MovieTrackingTrack *track = BKE_tracking_track_get_active(&sc->clip->tracking); if (track) { int framenr = ED_space_clip_get_clip_frame_number(sc); MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); offsx = marker->pos[0]; offsy = marker->pos[1]; gpd = track->gpd; } } else { gpd = clip->gpd; } if (sc->flag & SC_MANUAL_CALIBRATION && gpd) { bGPDlayer *layer = gpd->layers.first; while (layer) { bGPDframe *frame = layer->frames.first; if (layer->flag & GP_LAYER_HIDE) { layer = layer->next; continue; } glColor4fv(layer->color); glLineWidth(layer->thickness); glPointSize((float)(layer->thickness + 2)); while (frame) { bGPDstroke *stroke = frame->strokes.first; while (stroke) { if (stroke->flag & GP_STROKE_2DSPACE) { if (stroke->totpoints > 1) { glBegin(GL_LINE_STRIP); for (i = 0; i < stroke->totpoints - 1; i++) { float npos[2], dpos[2], len; int steps; pos[0] = (stroke->points[i].x + offsx) * width; pos[1] = (stroke->points[i].y + offsy) * height * aspy; npos[0] = (stroke->points[i + 1].x + offsx) * width; npos[1] = (stroke->points[i + 1].y + offsy) * height * aspy; len = len_v2v2(pos, npos); steps = ceil(len / 5.0f); /* we want to distort only long straight lines */ if (stroke->totpoints == 2) { BKE_tracking_undistort_v2(tracking, pos, pos); BKE_tracking_undistort_v2(tracking, npos, npos); } sub_v2_v2v2(dpos, npos, pos); mul_v2_fl(dpos, 1.0f / steps); for (j = 0; j <= steps; j++) { BKE_tracking_distort_v2(tracking, pos, tpos); glVertex2f(tpos[0] / width, tpos[1] / (height * aspy)); add_v2_v2(pos, dpos); } } glEnd(); } else if (stroke->totpoints == 1) { glBegin(GL_POINTS); glVertex2f(stroke->points[0].x + offsx, stroke->points[0].y + offsy); glEnd(); } } stroke = stroke->next; } frame = frame->next; } layer = layer->next; } glLineWidth(1.0f); glPointSize(1.0f); } glPopMatrix(); }
/* Draw all kind of tracks. */ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, MovieClip *clip, int width, int height, float zoomx, float zoomy) { float x, y; MovieTracking *tracking = &clip->tracking; ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); MovieTrackingTrack *track, *act_track; MovieTrackingPlaneTrack *plane_track, *active_plane_track; MovieTrackingMarker *marker; int framenr = ED_space_clip_get_clip_frame_number(sc); int undistort = sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT; float *marker_pos = NULL, *fp, *active_pos = NULL, cur_pos[2]; /* ** find window pixel coordinates of origin ** */ /* UI_view2d_view_to_region_no_clip return integer values, this could * lead to 1px flickering when view is locked to selection during playbeck. * to avoid this flickering, calculate base point in the same way as it happens * in UI_view2d_view_to_region_no_clip, but do it in floats here */ UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y); glPushMatrix(); glTranslatef(x, y, 0); glPushMatrix(); glScalef(zoomx, zoomy, 0); glMultMatrixf(sc->stabmat); glScalef(width, height, 0); act_track = BKE_tracking_track_get_active(tracking); /* Draw plane tracks */ active_plane_track = BKE_tracking_plane_track_get_active(tracking); for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) { if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) { draw_plane_track(sc, scene, plane_track, framenr, plane_track == active_plane_track, width, height); } } if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) { int count = 0; /* count */ track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) count++; } track = track->next; } /* undistort */ if (count) { marker_pos = MEM_callocN(2 * sizeof(float) * count, "draw_tracking_tracks marker_pos"); track = tracksbase->first; fp = marker_pos; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { ED_clip_point_undistorted_pos(sc, marker->pos, fp); if (track == act_track) active_pos = fp; fp += 2; } } track = track->next; } } } if (sc->flag & SC_SHOW_TRACK_PATH) { track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) draw_track_path(sc, clip, track); track = track->next; } } /* markers outline and non-selected areas */ track = tracksbase->first; fp = marker_pos; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { copy_v2_v2(cur_pos, fp ? fp : marker->pos); draw_marker_outline(sc, track, marker, cur_pos, width, height); draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 0); draw_marker_slide_zones(sc, track, marker, cur_pos, 1, 0, 0, width, height); draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 0, 0, width, height); if (fp) fp += 2; } } track = track->next; } /* selected areas only, so selection wouldn't be overlapped by * non-selected areas */ track = tracksbase->first; fp = marker_pos; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { int act = track == act_track; marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { if (!act) { copy_v2_v2(cur_pos, fp ? fp : marker->pos); draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 1); draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 1, 0, width, height); } if (fp) fp += 2; } } track = track->next; } /* active marker would be displayed on top of everything else */ if (act_track) { if ((act_track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(act_track, framenr); if (MARKER_VISIBLE(sc, act_track, marker)) { copy_v2_v2(cur_pos, active_pos ? active_pos : marker->pos); draw_marker_areas(sc, act_track, marker, cur_pos, width, height, 1, 1); draw_marker_slide_zones(sc, act_track, marker, cur_pos, 0, 1, 1, width, height); } } } if (sc->flag & SC_SHOW_BUNDLES) { MovieTrackingObject *object = BKE_tracking_object_get_active(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_get_projection_matrix(tracking, object, framenr, width, height, mat); track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0 && track->flag & TRACK_HAS_BUNDLE) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { float npos[2]; copy_v3_v3(vec, track->bundle_pos); vec[3] = 1; mul_v4_m4v4(pos, mat, vec); pos[0] = (pos[0] / (pos[3] * 2.0f) + 0.5f) * width; pos[1] = (pos[1] / (pos[3] * 2.0f) + 0.5f) * height * aspy; BKE_tracking_distort_v2(tracking, pos, npos); if (npos[0] >= 0.0f && npos[1] >= 0.0f && npos[0] <= width && npos[1] <= height * aspy) { vec[0] = (marker->pos[0] + track->offset[0]) * width; vec[1] = (marker->pos[1] + track->offset[1]) * height * aspy; sub_v2_v2(vec, npos); if (len_squared_v2(vec) < (3.0f * 3.0f)) glColor3f(0.0f, 1.0f, 0.0f); else glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_POINTS); if (undistort) glVertex3f(pos[0] / width, pos[1] / (height * aspy), 0); else glVertex3f(npos[0] / width, npos[1] / (height * aspy), 0); glEnd(); } } } track = track->next; } glPointSize(1.0f); glDisable(GL_POINT_SMOOTH); } glPopMatrix(); if (sc->flag & SC_SHOW_NAMES) { /* scaling should be cleared before drawing texts, otherwise font would also be scaled */ track = tracksbase->first; fp = marker_pos; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { marker = BKE_tracking_marker_get(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { int act = track == act_track; copy_v2_v2(cur_pos, fp ? fp : marker->pos); draw_marker_texts(sc, track, marker, cur_pos, act, width, height, zoomx, zoomy); if (fp) fp += 2; } } track = track->next; } } glPopMatrix(); if (marker_pos) MEM_freeN(marker_pos); }