示例#1
0
/**
 * \note use #ED_view3d_ob_project_mat_get to get the projection matrix
 */
void ED_view3d_project_float_v2_m4(const ARegion *ar, const float co[3], float r_co[2], float mat[4][4])
{
	float vec4[4];
	
	copy_v3_v3(vec4, co);
	vec4[3] = 1.0;
	/* r_co[0] = IS_CLIPPED; */ /* always overwritten */
	
	mul_m4_v4(mat, vec4);
	
	if (vec4[3] > FLT_EPSILON) {
		r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3];
		r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3];
	}
	else {
		zero_v2(r_co);
	}
}
示例#2
0
文件: scanfill.c 项目: sftd/blender
ScanFillVert *BLI_scanfill_vert_add(ScanFillContext *sf_ctx, const float vec[3])
{
	ScanFillVert *sf_v;
	
	sf_v = BLI_memarena_alloc(sf_ctx->arena, sizeof(ScanFillVert));

	BLI_addtail(&sf_ctx->fillvertbase, sf_v);

	sf_v->tmp.p = NULL;
	copy_v3_v3(sf_v->co, vec);

	/* just zero out the rest */
	zero_v2(sf_v->xy);
	sf_v->keyindex = 0;
	sf_v->poly_nr = sf_ctx->poly_nr;
	sf_v->edge_tot = 0;
	sf_v->f = SF_VERT_NEW;
	sf_v->user_flag = 0;

	return sf_v;
}
static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op))
{
	Mask *mask = CTX_data_edit_mask(C);
	MaskLayer *masklay;

	/* parent info */
	SpaceClip *sc = CTX_wm_space_clip(C);
	MovieClip *clip = ED_space_clip_get_clip(sc);
	MovieTracking *tracking;
	MovieTrackingTrack *track;
	MovieTrackingPlaneTrack *plane_track;
	MovieTrackingObject *tracking_object;
	/* done */

	int framenr, parent_type;
	float parmask_pos[2], orig_corners[4][2];
	char *sub_parent_name;

	if (ELEM(NULL, sc, clip)) {
		return OPERATOR_CANCELLED;
	}

	framenr = ED_space_clip_get_clip_frame_number(sc);

	tracking = &clip->tracking;
	tracking_object = BKE_tracking_object_get_active(&clip->tracking);

	if (tracking_object == NULL) {
		return OPERATOR_CANCELLED;
	}

	if ((track = BKE_tracking_track_get_active(tracking)) != NULL) {
		MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
		float marker_pos_ofs[2];

		add_v2_v2v2(marker_pos_ofs, marker->pos, track->offset);

		BKE_mask_coord_from_movieclip(clip, &sc->user, parmask_pos, marker_pos_ofs);

		sub_parent_name = track->name;
		parent_type = MASK_PARENT_POINT_TRACK;
		memset(orig_corners, 0, sizeof(orig_corners));
	}
	else if ((plane_track = BKE_tracking_plane_track_get_active(tracking)) != NULL) {
		MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);

		zero_v2(parmask_pos);
		sub_parent_name = plane_track->name;
		parent_type = MASK_PARENT_PLANE_TRACK;
		memcpy(orig_corners, plane_marker->corners, sizeof(orig_corners));
	}
	else {
		return OPERATOR_CANCELLED;
	}

	for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
		MaskSpline *spline;
		int i;

		if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
			continue;
		}

		for (spline = masklay->splines.first; spline; spline = spline->next) {
			for (i = 0; i < spline->tot_point; i++) {
				MaskSplinePoint *point = &spline->points[i];

				if (MASKPOINT_ISSEL_ANY(point)) {
					point->parent.id_type = ID_MC;
					point->parent.id = &clip->id;
					point->parent.type = parent_type;
					BLI_strncpy(point->parent.parent, tracking_object->name, sizeof(point->parent.parent));
					BLI_strncpy(point->parent.sub_parent, sub_parent_name, sizeof(point->parent.sub_parent));

					copy_v2_v2(point->parent.parent_orig, parmask_pos);
					memcpy(point->parent.parent_corners_orig, orig_corners, sizeof(point->parent.parent_corners_orig));
				}
			}
		}
	}

	WM_event_add_notifier(C, NC_MASK | ND_DATA, mask);
	DAG_id_tag_update(&mask->id, 0);

	return OPERATOR_FINISHED;
}
示例#4
0
void clip_draw_main(const bContext *C, SpaceClip *sc, ARegion *ar)
{
	MovieClip *clip = ED_space_clip_get_clip(sc);
	Scene *scene = CTX_data_scene(C);
	ImBuf *ibuf = NULL;
	int width, height;
	float zoomx, zoomy;

	ED_space_clip_get_size(sc, &width, &height);
	ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy);

	/* if no clip, nothing to do */
	if (!clip) {
		ED_region_grid_draw(ar, zoomx, zoomy);
		return;
	}

	if (sc->flag & SC_SHOW_STABLE) {
		float smat[4][4], ismat[4][4];

		ibuf = ED_space_clip_get_stable_buffer(sc, sc->loc, &sc->scale, &sc->angle);

		if (ibuf) {
			float translation[2];
			float aspect = clip->tracking.camera.pixel_aspect;

			if (width != ibuf->x)
				mul_v2_v2fl(translation, sc->loc, (float)width / ibuf->x);
			else
				copy_v2_v2(translation, sc->loc);

			BKE_tracking_stabilization_data_to_mat4(width, height, aspect,
			                                        translation, sc->scale, sc->angle, sc->stabmat);

			unit_m4(smat);
			smat[0][0] = 1.0f / width;
			smat[1][1] = 1.0f / height;
			invert_m4_m4(ismat, smat);

			mul_serie_m4(sc->unistabmat, smat, sc->stabmat, ismat, NULL, NULL, NULL, NULL, NULL);
		}
	}
	else if ((sc->flag & SC_MUTE_FOOTAGE) == 0) {
		ibuf = ED_space_clip_get_buffer(sc);

		zero_v2(sc->loc);
		sc->scale = 1.0f;
		unit_m4(sc->stabmat);
		unit_m4(sc->unistabmat);
	}

	if (ibuf) {
		draw_movieclip_buffer(C, sc, ar, ibuf, width, height, zoomx, zoomy);
		IMB_freeImBuf(ibuf);
	}
	else if (sc->flag & SC_MUTE_FOOTAGE) {
		draw_movieclip_muted(ar, width, height, zoomx, zoomy);
	}
	else {
		ED_region_grid_draw(ar, zoomx, zoomy);
	}

	if (width && height) {
		draw_stabilization_border(sc, ar, width, height, zoomx, zoomy);
		draw_tracking_tracks(sc, scene, ar, clip, width, height, zoomx, zoomy);
		draw_distortion(sc, ar, clip, width, height, zoomx, zoomy);
	}
}
示例#5
0
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();
}
示例#6
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);
	}
}
/* Stabilize given image buffer using stabilization data for
 * a specified frame number.
 *
 * NOTE: frame number should be in clip space, not scene space
 */
ImBuf *BKE_tracking_stabilize_frame(MovieTracking *tracking, int framenr, ImBuf *ibuf,
                                    float translation[2], float *scale, float *angle)
{
	float tloc[2], tscale, tangle;
	MovieTrackingStabilization *stab = &tracking->stabilization;
	ImBuf *tmpibuf;
	int width = ibuf->x, height = ibuf->y;
	float aspect = tracking->camera.pixel_aspect;
	float mat[4][4];
	int j, filter = tracking->stabilization.filter;
	void (*interpolation)(struct ImBuf *, struct ImBuf *, float, float, int, int) = NULL;
	int ibuf_flags;

	if (translation)
		copy_v2_v2(tloc, translation);

	if (scale)
		tscale = *scale;

	/* Perform early output if no stabilization is used. */
	if ((stab->flag & TRACKING_2D_STABILIZATION) == 0) {
		if (translation)
			zero_v2(translation);

		if (scale)
			*scale = 1.0f;

		if (angle)
			*angle = 0.0f;

		return ibuf;
	}

	/* Allocate frame for stabilization result. */
	ibuf_flags = 0;
	if (ibuf->rect)
		ibuf_flags |= IB_rect;
	if (ibuf->rect_float)
		ibuf_flags |= IB_rectfloat;

	tmpibuf = IMB_allocImBuf(ibuf->x, ibuf->y, ibuf->planes, ibuf_flags);

	/* Calculate stabilization matrix. */
	BKE_tracking_stabilization_data_get(tracking, framenr, width, height, tloc, &tscale, &tangle);
	BKE_tracking_stabilization_data_to_mat4(ibuf->x, ibuf->y, aspect, tloc, tscale, tangle, mat);
	invert_m4(mat);

	if (filter == TRACKING_FILTER_NEAREST)
		interpolation = nearest_interpolation;
	else if (filter == TRACKING_FILTER_BILINEAR)
		interpolation = bilinear_interpolation;
	else if (filter == TRACKING_FILTER_BICUBIC)
		interpolation = bicubic_interpolation;
	else
		/* fallback to default interpolation method */
		interpolation = nearest_interpolation;

	/* This function is only used for display in clip editor and
	 * sequencer only, which would only benefit of using threads
	 * here.
	 *
	 * But need to keep an eye on this if the function will be
	 * used in other cases.
	 */
#pragma omp parallel for if (tmpibuf->y > 128)
	for (j = 0; j < tmpibuf->y; j++) {
		int i;
		for (i = 0; i < tmpibuf->x; i++) {
			float vec[3] = {i, j, 0.0f};

			mul_v3_m4v3(vec, mat, vec);

			interpolation(ibuf, tmpibuf, vec[0], vec[1], i, j);
		}
	}

	if (tmpibuf->rect_float)
		tmpibuf->userflags |= IB_RECT_INVALID;

	if (translation)
		copy_v2_v2(translation, tloc);

	if (scale)
		*scale = tscale;

	if (angle)
		*angle = tangle;

	return tmpibuf;
}