Example #1
0
void ED_view3d_win_to_segment(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3])
{
	RegionView3D *rv3d = ar->regiondata;

	if (rv3d->is_persp) {
		float vec[3];
		ED_view3d_win_to_vector(ar, mval, vec);

		copy_v3_v3(ray_start, rv3d->viewinv[3]);
		madd_v3_v3v3fl(ray_start, rv3d->viewinv[3], vec, v3d->near);
		madd_v3_v3v3fl(ray_end, rv3d->viewinv[3], vec, v3d->far);
	}
	else {
		float vec[4];
		vec[0] = 2.0f * mval[0] / ar->winx - 1;
		vec[1] = 2.0f * mval[1] / ar->winy - 1;
		vec[2] = 0.0f;
		vec[3] = 1.0f;

		mul_m4_v4(rv3d->persinv, vec);

		madd_v3_v3v3fl(ray_start, vec, rv3d->viewinv[2],  1000.0f);
		madd_v3_v3v3fl(ray_end, vec, rv3d->viewinv[2], -1000.0f);
	}
}
Example #2
0
/**
 * Calculate a 3d location from 2d window coordinates.
 * \param ar The region (used for the window width and height).
 * \param depth_pt The reference location used to calculate the Z depth.
 * \param mval The area relative location (such as event->mval converted to floats).
 * \param out The resulting world-space location.
 */
void ED_view3d_win_to_3d(ARegion *ar, const float depth_pt[3], const float mval[2], float out[3])
{
	RegionView3D *rv3d = ar->regiondata;
	
	float line_sta[3];
	float line_end[3];

	if (rv3d->is_persp) {
		float mousevec[3];
		copy_v3_v3(line_sta, rv3d->viewinv[3]);
		ED_view3d_win_to_vector(ar, mval, mousevec);
		add_v3_v3v3(line_end, line_sta, mousevec);

		if (isect_line_plane_v3(out, line_sta, line_end, depth_pt, rv3d->viewinv[2], TRUE) == 0) {
			/* highly unlikely to ever happen, mouse vec paralelle with view plane */
			zero_v3(out);
		}
	}
	else {
		const float dx = (2.0f * mval[0] / (float)ar->winx) - 1.0f;
		const float dy = (2.0f * mval[1] / (float)ar->winy) - 1.0f;
		line_sta[0] = (rv3d->persinv[0][0] * dx) + (rv3d->persinv[1][0] * dy) + rv3d->viewinv[3][0];
		line_sta[1] = (rv3d->persinv[0][1] * dx) + (rv3d->persinv[1][1] * dy) + rv3d->viewinv[3][1];
		line_sta[2] = (rv3d->persinv[0][2] * dx) + (rv3d->persinv[1][2] * dy) + rv3d->viewinv[3][2];

		add_v3_v3v3(line_end, line_sta, rv3d->viewinv[2]);
		closest_to_line_v3(out, depth_pt, line_sta, line_end);
	}
}
Example #3
0
/* create intersection coordinates in view Z direction at mouse coordinates */
void ED_view3d_win_to_segment_clip(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3])
{
	RegionView3D *rv3d= ar->regiondata;
	
	if(rv3d->is_persp) {
		float vec[3];
		ED_view3d_win_to_vector(ar, mval, vec);

		copy_v3_v3(ray_start, rv3d->viewinv[3]);
		madd_v3_v3v3fl(ray_start, rv3d->viewinv[3], vec, v3d->near);
		madd_v3_v3v3fl(ray_end, rv3d->viewinv[3], vec, v3d->far);
	}
	else {
		float vec[4];
		vec[0] = 2.0f * mval[0] / ar->winx - 1;
		vec[1] = 2.0f * mval[1] / ar->winy - 1;
		vec[2] = 0.0f;
		vec[3] = 1.0f;
		
		mul_m4_v4(rv3d->persinv, vec);
		
		madd_v3_v3v3fl(ray_start, vec, rv3d->viewinv[2],  1000.0f);
		madd_v3_v3v3fl(ray_end, vec, rv3d->viewinv[2], -1000.0f);
	}

	/* clipping */
	if(rv3d->rflag & RV3D_CLIPPING) {
		int a;
		for(a=0; a<4; a++) {
			clip_line_plane(ray_start, ray_end, rv3d->clip[a]);
		}
	}
}
static bool mesh_bisect_interactive_calc(
        bContext *C, wmOperator *op,
        BMEditMesh *em,
        float plane_co[3], float plane_no[3])
{
	wmGesture *gesture = op->customdata;
	BisectData *opdata;

	ARegion *ar = CTX_wm_region(C);
	RegionView3D *rv3d = ar->regiondata;

	int x_start = RNA_int_get(op->ptr, "xstart");
	int y_start = RNA_int_get(op->ptr, "ystart");
	int x_end = RNA_int_get(op->ptr, "xend");
	int y_end = RNA_int_get(op->ptr, "yend");

	/* reference location (some point in front of the view) for finding a point on a plane */
	const float *co_ref = rv3d->ofs;
	float co_a_ss[2] = {x_start, y_start}, co_b_ss[2] = {x_end, y_end}, co_delta_ss[2];
	float co_a[3], co_b[3];
	const float zfac = ED_view3d_calc_zfac(rv3d, co_ref, NULL);

	opdata = gesture->userdata;

	/* view vector */
	ED_view3d_win_to_vector(ar, co_a_ss, co_a);

	/* view delta */
	sub_v2_v2v2(co_delta_ss, co_a_ss, co_b_ss);
	ED_view3d_win_to_delta(ar, co_delta_ss, co_b, zfac);

	/* cross both to get a normal */
	cross_v3_v3v3(plane_no, co_a, co_b);
	normalize_v3(plane_no);  /* not needed but nicer for user */

	/* point on plane, can use either start or endpoint */
	ED_view3d_win_to_3d(ar, co_ref, co_a_ss, plane_co);

	if (opdata->is_first == false)
		EDBM_redo_state_restore(opdata->mesh_backup, em, false);

	opdata->is_first = false;

	return true;
}
Example #5
0
static void view3d_win_to_ray_segment(
        const ARegion *ar, const View3D *v3d, const float mval[2],
        float r_ray_co[3], float r_ray_dir[3], float r_ray_start[3], float r_ray_end[3])
{
	RegionView3D *rv3d = ar->regiondata;
	float _ray_co[3], _ray_dir[3], start_offset, end_offset;

	if (!r_ray_co) r_ray_co = _ray_co;
	if (!r_ray_dir) r_ray_dir = _ray_dir;

	ED_view3d_win_to_vector(ar, mval, r_ray_dir);

	if (rv3d->is_persp) {
		copy_v3_v3(r_ray_co, rv3d->viewinv[3]);
	}
	else {
		r_ray_co[0] = 2.0f * mval[0] / ar->winx - 1.0f;
		r_ray_co[1] = 2.0f * mval[1] / ar->winy - 1.0f;

		if (rv3d->persp == RV3D_CAMOB) {
			r_ray_co[2] = -1.0f;
		}
		else {
			r_ray_co[2] = 0.0f;
		}

		mul_project_m4_v3(rv3d->persinv, r_ray_co);
	}

	if ((rv3d->is_persp == false) && (rv3d->persp != RV3D_CAMOB)) {
		end_offset = v3d->far / 2.0f;
		start_offset = -end_offset;
	}
	else {
		ED_view3d_clip_range_get(v3d, rv3d, &start_offset, &end_offset, false);
	}

	if (r_ray_start) {
		madd_v3_v3v3fl(r_ray_start, r_ray_co, r_ray_dir, start_offset);
	}
	if (r_ray_end) {
		madd_v3_v3v3fl(r_ray_end, r_ray_co, r_ray_dir, end_offset);
	}
}
Example #6
0
/**
 * Calculate a 3d location from 2d window coordinates.
 * \param ar The region (used for the window width and height).
 * \param depth_pt The reference location used to calculate the Z depth.
 * \param mval The area relative location (such as event->mval converted to floats).
 * \param out The resulting world-space location.
 */
void ED_view3d_win_to_3d(const ARegion *ar, const float depth_pt[3], const float mval[2], float out[3])
{
	RegionView3D *rv3d = ar->regiondata;

	float ray_origin[3];
	float ray_direction[3];
	float lambda;

	if (rv3d->is_persp) {
		float plane[4];

		copy_v3_v3(ray_origin, rv3d->viewinv[3]);
		ED_view3d_win_to_vector(ar, mval, ray_direction);

		/* note, we could use isect_line_plane_v3() however we want the intersection to be infront of the
		 * view no matter what, so apply the unsigned factor instead */
		plane_from_point_normal_v3(plane, depth_pt, rv3d->viewinv[2]);

		isect_ray_plane_v3(ray_origin, ray_direction, plane, &lambda, false);
		lambda = fabsf(lambda);
	}
	else {
		float dx = (2.0f * mval[0] / (float)ar->winx) - 1.0f;
		float dy = (2.0f * mval[1] / (float)ar->winy) - 1.0f;
		if (rv3d->persp == RV3D_CAMOB) {
			/* ortho camera needs offset applied */
			const float zoomfac = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom) * 4.0f;
			dx += rv3d->camdx * zoomfac;
			dy += rv3d->camdy * zoomfac;
		}
		ray_origin[0] = (rv3d->persinv[0][0] * dx) + (rv3d->persinv[1][0] * dy) + rv3d->viewinv[3][0];
		ray_origin[1] = (rv3d->persinv[0][1] * dx) + (rv3d->persinv[1][1] * dy) + rv3d->viewinv[3][1];
		ray_origin[2] = (rv3d->persinv[0][2] * dx) + (rv3d->persinv[1][2] * dy) + rv3d->viewinv[3][2];

		copy_v3_v3(ray_direction, rv3d->viewinv[2]);
		lambda = ray_point_factor_v3(depth_pt, ray_origin, ray_direction);
	}

	madd_v3_v3v3fl(out, ray_origin, ray_direction, lambda);
}