예제 #1
0
static void calc_ray_shift(rcti *rect, float x, float y, const float source[2], float ray_length)
{
	float co[2] = {(float)x, (float)y};
	float dir[2], dist;

	/* move (x,y) vector toward the source by ray_length distance */
	sub_v2_v2v2(dir, co, source);
	dist = normalize_v2(dir);
	mul_v2_fl(dir, min_ff(dist, ray_length));
	sub_v2_v2(co, dir);

	int ico[2] = {(int)co[0], (int)co[1]};
	BLI_rcti_do_minmax_v(rect, ico);
}
예제 #2
0
/* 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);
}
예제 #3
0
static void marker_block_handler(bContext *C, void *arg_cb, int event)
{
	MarkerUpdateCb *cb = (MarkerUpdateCb *) arg_cb;
	MovieTrackingMarker *marker;
	int width, height, ok = FALSE;

	BKE_movieclip_get_size(cb->clip, cb->user, &width, &height);

	marker = BKE_tracking_marker_ensure(cb->track, cb->framenr);

	if (event == B_MARKER_POS) {
		marker->pos[0] = cb->marker_pos[0] / width;
		marker->pos[1] = cb->marker_pos[1] / height;

		/* to update position of "parented" objects */
		DAG_id_tag_update(&cb->clip->id, 0);
		WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);

		ok = TRUE;
	}
	else if (event == B_MARKER_PAT_DIM) {
		float dim[2], pat_dim[2], pat_min[2], pat_max[2];
		float scale_x, scale_y;
		int a;

		BKE_tracking_marker_pattern_minmax(cb->marker, pat_min, pat_max);

		sub_v2_v2v2(pat_dim, pat_max, pat_min);

		dim[0] = cb->marker_pat[0] / width;
		dim[1] = cb->marker_pat[1] / height;

		scale_x = dim[0] / pat_dim[0];
		scale_y = dim[1] / pat_dim[1];

		for (a = 0; a < 4; a++) {
			cb->marker->pattern_corners[a][0] *= scale_x;
			cb->marker->pattern_corners[a][1] *= scale_y;
		}

		BKE_tracking_marker_clamp(cb->marker, CLAMP_PAT_DIM);

		ok = TRUE;
	}
	else if (event == B_MARKER_SEARCH_POS) {
		float delta[2], side[2];

		sub_v2_v2v2(side, cb->marker->search_max, cb->marker->search_min);
		mul_v2_fl(side, 0.5f);

		delta[0] = cb->marker_search_pos[0] / width;
		delta[1] = cb->marker_search_pos[1] / height;

		sub_v2_v2v2(cb->marker->search_min, delta, side);
		add_v2_v2v2(cb->marker->search_max, delta, side);

		BKE_tracking_marker_clamp(cb->marker, CLAMP_SEARCH_POS);

		ok = TRUE;
	}
	else if (event == B_MARKER_SEARCH_DIM) {
		float dim[2], search_dim[2];

		sub_v2_v2v2(search_dim, cb->marker->search_max, cb->marker->search_min);

		dim[0] = cb->marker_search[0] / width;
		dim[1] = cb->marker_search[1] / height;

		sub_v2_v2(dim, search_dim);
		mul_v2_fl(dim, 0.5f);

		cb->marker->search_min[0] -= dim[0];
		cb->marker->search_min[1] -= dim[1];

		cb->marker->search_max[0] += dim[0];
		cb->marker->search_max[1] += dim[1];

		BKE_tracking_marker_clamp(cb->marker, CLAMP_SEARCH_DIM);

		ok = TRUE;
	}
	else if (event == B_MARKER_FLAG) {
		marker->flag = cb->marker_flag;

		ok = TRUE;
	}
	else if (event == B_MARKER_OFFSET) {
		float offset[2], delta[2];
		int i;

		offset[0] = cb->track_offset[0] / width;
		offset[1] = cb->track_offset[1] / height;

		sub_v2_v2v2(delta, offset, cb->track->offset);
		copy_v2_v2(cb->track->offset, offset);

		for (i = 0; i < cb->track->markersnr; i++)
			sub_v2_v2(cb->track->markers[i].pos, delta);

		/* to update position of "parented" objects */
		DAG_id_tag_update(&cb->clip->id, 0);
		WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);

		ok = TRUE;
	}

	if (ok)
		WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, cb->clip);
}
예제 #4
0
static void object_warp_transverts(TransVertStore *tvs,
                                   float mat_view[4][4], const float center_view[3],
                                   const float angle_, const float min, const float max)
{
	TransVert *tv;
	int i;
	const float angle = -angle_;
	/* cache vars for tiny speedup */
#if 1
	const float range = max - min;
	const float range_inv = 1.0f / range;
	const float min_ofs = min + (0.5f * range);
#endif

	float dir_min[2], dir_max[2];
	float imat_view[4][4];


	invert_m4_m4(imat_view, mat_view);

	/* calculate the direction vectors outside min/max range */
	{
		const float phi = angle * 0.5f;

		dir_max[0] = cosf(phi);
		dir_max[1] = sinf(phi);

		dir_min[0] = -dir_max[0];
		dir_min[1] =  dir_max[1];
	}


	tv = tvs->transverts;
	for (i = 0; i < tvs->transverts_tot; i++, tv++) {
		float co[3], co_add[2];
		float val, phi;

		/* convert objectspace->viewspace */
		mul_v3_m4v3(co, mat_view, tv->loc);
		sub_v2_v2(co, center_view);

		val = co[0];
		/* is overwritten later anyway */
		// co[0] = 0.0f;

		if (val < min) {
			mul_v2_v2fl(co_add, dir_min, min - val);
			val = min;
		}
		else if (val > max) {
			mul_v2_v2fl(co_add, dir_max, val - max);
			val = max;
		}
		else {
			zero_v2(co_add);
		}

		/* map from x axis to (-0.5 - 0.5) */
#if 0
		val = ((val - min) / (max - min)) - 0.5f;
#else
		val = (val - min_ofs) * range_inv;
#endif

		/* convert the x axis into a rotation */
		phi = val * angle;

		co[0] = -sinf(phi) * co[1];
		co[1] =  cosf(phi) * co[1];

		add_v2_v2(co, co_add);

		/* convert viewspace->objectspace */
		add_v2_v2(co, center_view);
		mul_v3_m4v3(tv->loc, imat_view, co);
	}
}
예제 #5
0
static void setup_vertex_point(Mask *mask, MaskSpline *spline, MaskSplinePoint *new_point,
                               const float point_co[2], const float tangent[2], const float u,
                               MaskSplinePoint *reference_point, const short reference_adjacent,
                               const float view_zoom)
{
	MaskSplinePoint *prev_point = NULL;
	MaskSplinePoint *next_point = NULL;
	BezTriple *bezt;
	float co[3];
	const float len = 10.0; /* default length of handle in pixel space */

	copy_v2_v2(co, point_co);
	co[2] = 0.0f;

	/* point coordinate */
	bezt = &new_point->bezt;

	bezt->h1 = bezt->h2 = HD_ALIGN;

	if (reference_point) {
		bezt->h1 = bezt->h2 = MAX2(reference_point->bezt.h2, reference_point->bezt.h1);
	}
	else if (reference_adjacent) {
		if (spline->tot_point != 1) {
			int index = (int)(new_point - spline->points);
			prev_point = &spline->points[(index - 1) % spline->tot_point];
			next_point = &spline->points[(index + 1) % spline->tot_point];

			bezt->h1 = bezt->h2 = MAX2(prev_point->bezt.h2, next_point->bezt.h1);

			/* note, we may want to copy other attributes later, radius? pressure? color? */
		}
	}

	copy_v3_v3(bezt->vec[0], co);
	copy_v3_v3(bezt->vec[1], co);
	copy_v3_v3(bezt->vec[2], co);

	/* initial offset for handles */
	if (spline->tot_point == 1) {
		/* first point of splien is aligned horizontally */
		bezt->vec[0][0] -= len * view_zoom;
		bezt->vec[2][0] += len * view_zoom;
	}
	else if (tangent) {
		float vec[2];

		copy_v2_v2(vec, tangent);

		mul_v2_fl(vec, len);

		sub_v2_v2(bezt->vec[0], vec);
		add_v2_v2(bezt->vec[2], vec);

		if (reference_adjacent) {
			BKE_mask_calc_handle_adjacent_interp(spline, new_point, u);
		}
	}
	else {

		/* calculating auto handles works much nicer */
#if 0
		/* next points are aligning in the direction of previous/next point */
		MaskSplinePoint *point;
		float v1[2], v2[2], vec[2];
		float dir = 1.0f;

		if (new_point == spline->points) {
			point = new_point + 1;
			dir = -1.0f;
		}
		else
			point = new_point - 1;

		if (spline->tot_point < 3) {
			v1[0] = point->bezt.vec[1][0] * width;
			v1[1] = point->bezt.vec[1][1] * height;

			v2[0] = new_point->bezt.vec[1][0] * width;
			v2[1] = new_point->bezt.vec[1][1] * height;
		}
		else {
			if (new_point == spline->points) {
				v1[0] = spline->points[1].bezt.vec[1][0] * width;
				v1[1] = spline->points[1].bezt.vec[1][1] * height;

				v2[0] = spline->points[spline->tot_point - 1].bezt.vec[1][0] * width;
				v2[1] = spline->points[spline->tot_point - 1].bezt.vec[1][1] * height;
			}
			else {
				v1[0] = spline->points[0].bezt.vec[1][0] * width;
				v1[1] = spline->points[0].bezt.vec[1][1] * height;

				v2[0] = spline->points[spline->tot_point - 2].bezt.vec[1][0] * width;
				v2[1] = spline->points[spline->tot_point - 2].bezt.vec[1][1] * height;
			}
		}

		sub_v2_v2v2(vec, v1, v2);
		mul_v2_fl(vec, len * dir / len_v2(vec));

		vec[0] /= width;
		vec[1] /= height;

		add_v2_v2(bezt->vec[0], vec);
		sub_v2_v2(bezt->vec[2], vec);
#else
		BKE_mask_calc_handle_point_auto(spline, new_point, TRUE);
		BKE_mask_calc_handle_adjacent_interp(spline, new_point, u);

#endif
	}

	BKE_mask_parent_init(&new_point->parent);

	/* select new point */
	MASKPOINT_SEL_ALL(new_point);
	ED_mask_select_flush_all(mask);
}