Example #1
0
/**
 * Calculate a depth value from \a co, use with #ED_view3d_win_to_delta
 */
float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3], bool *r_flip)
{
	float zfac = mul_project_m4_v3_zfac((float (*)[4])rv3d->persmat, co);

	if (r_flip) {
		*r_flip = (zfac < 0.0f);
	}

	/* if x,y,z is exactly the viewport offset, zfac is 0 and we don't want that
	 * (accounting for near zero values) */
	if (zfac < 1.e-6f && zfac > -1.e-6f) {
		zfac = 1.0f;
	}

	/* Negative zfac means x, y, z was behind the camera (in perspective).
	 * This gives flipped directions, so revert back to ok default case. */
	if (zfac < 0.0f) {
		zfac = -zfac;
	}

	return zfac;
}
static void setNearestAxis3d(TransInfo *t)
{
	float zfac;
	float mvec[3], proj[3];
	float len[3];
	int i;

	/* calculate mouse movement */
	mvec[0] = (float)(t->mval[0] - t->con.imval[0]);
	mvec[1] = (float)(t->mval[1] - t->con.imval[1]);
	mvec[2] = 0.0f;

	/* we need to correct axis length for the current zoomlevel of view,
	 * this to prevent projected values to be clipped behind the camera
	 * and to overflow the short integers.
	 * The formula used is a bit stupid, just a simplification of the subtraction
	 * of two 2D points 30 pixels apart (that's the last factor in the formula) after
	 * projecting them with ED_view3d_win_to_delta and then get the length of that vector.
	 */
	zfac = mul_project_m4_v3_zfac(t->persmat, t->center);
	zfac = len_v3(t->persinv[0]) * 2.0f / t->ar->winx * zfac * 30.0f;

	for (i = 0; i < 3; i++) {
		float axis[3], axis_2d[2];

		copy_v3_v3(axis, t->con.mtx[i]);

		mul_v3_fl(axis, zfac);
		/* now we can project to get window coordinate */
		add_v3_v3(axis, t->center_global);
		projectFloatView(t, axis, axis_2d);

		sub_v2_v2v2(axis, axis_2d, t->center2d);
		axis[2] = 0.0f;

		if (normalize_v3(axis) > 1e-3f) {
			project_v3_v3v3(proj, mvec, axis);
			sub_v3_v3v3(axis, mvec, proj);
			len[i] = normalize_v3(axis);
		}
		else {
			len[i] = 1e10f;
		}
	}

	if (len[0] <= len[1] && len[0] <= len[2]) {
		if (t->modifiers & MOD_CONSTRAINT_PLANE) {
			t->con.mode |= (CON_AXIS1 | CON_AXIS2);
			BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" locking %s X axis"), t->spacename);
		}
		else {
			t->con.mode |= CON_AXIS0;
			BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" along %s X axis"), t->spacename);
		}
	}
	else if (len[1] <= len[0] && len[1] <= len[2]) {
		if (t->modifiers & MOD_CONSTRAINT_PLANE) {
			t->con.mode |= (CON_AXIS0 | CON_AXIS2);
			BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" locking %s Y axis"), t->spacename);
		}
		else {
			t->con.mode |= CON_AXIS1;
			BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" along %s Y axis"), t->spacename);
		}
	}
	else if (len[2] <= len[1] && len[2] <= len[0]) {
		if (t->modifiers & MOD_CONSTRAINT_PLANE) {
			t->con.mode |= (CON_AXIS0 | CON_AXIS1);
			BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" locking %s Z axis"), t->spacename);
		}
		else {
			t->con.mode |= CON_AXIS2;
			BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" along %s Z axis"), t->spacename);
		}
	}
}
Example #3
0
float ED_view3d_pixel_size(RegionView3D *rv3d, const float co[3])
{
	return mul_project_m4_v3_zfac(rv3d->persmat, co) * rv3d->pixsize * U.pixelsize;
}