예제 #1
0
void BKE_camera_to_gpu_dof(struct Object *camera, struct GPUFXSettings *r_fx_settings)
{
	if (camera->type == OB_CAMERA) {
		Camera *cam = camera->data;
		r_fx_settings->dof = &cam->gpu_dof;
		r_fx_settings->dof->focal_length = cam->lens;
		r_fx_settings->dof->sensor = BKE_camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
		r_fx_settings->dof->focus_distance = BKE_camera_object_dof_distance(camera);
	}
}
예제 #2
0
void BKE_camera_to_gpu_dof(struct Object *camera, struct GPUFXSettings *r_fx_settings)
{
	if (camera->type == OB_CAMERA) {
		Camera *cam = camera->data;
		r_fx_settings->dof = &cam->gpu_dof;
		r_fx_settings->dof->focal_length = cam->lens;
		r_fx_settings->dof->sensor = BKE_camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
		if (cam->dof_ob) {
			r_fx_settings->dof->focus_distance = len_v3v3(cam->dof_ob->obmat[3], camera->obmat[3]);
		}
		else {
			r_fx_settings->dof->focus_distance = cam->YF_dofdist;
		}
	}
}
void ConvertDepthToRadiusOperation::initExecution()
{
	float cam_sensor = DEFAULT_SENSOR_WIDTH;
	Camera *camera = NULL;

	if (this->m_cameraObject && this->m_cameraObject->type == OB_CAMERA) {
		camera = (Camera *)this->m_cameraObject->data;
		cam_sensor = BKE_camera_sensor_size(camera->sensor_fit, camera->sensor_x, camera->sensor_y);
	}

	this->m_inputOperation = this->getInputSocketReader(0);
	float focalDistance = determineFocalDistance();
	if (focalDistance == 0.0f) focalDistance = 1e10f;  /* if the dof is 0.0 then set it to be far away */
	this->m_inverseFocalDistance = 1.0f / focalDistance;
	this->m_aspect = (this->getWidth() > this->getHeight()) ? (this->getHeight() / (float)this->getWidth()) : (this->getWidth() / (float)this->getHeight());
	this->m_aperture = 0.5f * (this->m_cam_lens / (this->m_aspect * cam_sensor)) / this->m_fStop;
	const float minsz = min(getWidth(), getHeight());
	this->m_dof_sp = minsz / ((cam_sensor / 2.0f) / this->m_cam_lens);    // <- == aspect * min(img->x, img->y) / tan(0.5f * fov);

	if (this->m_blurPostOperation) {
		m_blurPostOperation->setSigma(min(m_aperture * 128.0f, this->m_maxRadius));
	}
}
예제 #4
0
파일: camera.c 프로젝트: floored/blender
void BKE_camera_params_from_view3d(CameraParams *params, View3D *v3d, RegionView3D *rv3d)
{
	/* common */
	params->lens = v3d->lens;
	params->clipsta = v3d->near;
	params->clipend = v3d->far;

	if (rv3d->persp == RV3D_CAMOB) {
		/* camera view */
		BKE_camera_params_from_object(params, v3d->camera);

		params->zoom = BKE_screen_view3d_zoom_to_fac((float)rv3d->camzoom);

		params->offsetx = 2.0f * rv3d->camdx * params->zoom;
		params->offsety = 2.0f * rv3d->camdy * params->zoom;

		params->shiftx *= params->zoom;
		params->shifty *= params->zoom;

		params->zoom = 1.0f / params->zoom;
	}
	else if (rv3d->persp == RV3D_ORTHO) {
		/* orthographic view */
		int sensor_size = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y);
		params->clipend *= 0.5f;    // otherwise too extreme low zbuffer quality
		params->clipsta = -params->clipend;

		params->is_ortho = true;
		/* make sure any changes to this match ED_view3d_radius_to_ortho_dist() */
		params->ortho_scale = rv3d->dist * sensor_size / v3d->lens;
		params->zoom = 2.0f;
	}
	else {
		/* perspective view */
		params->zoom = 2.0f;
	}
}
예제 #5
0
static void rna_Camera_angle_set(PointerRNA *ptr, float value)
{
	Camera *cam = ptr->id.data;
	float sensor = BKE_camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
	cam->lens = fov_to_focallength(value, sensor);
}
예제 #6
0
static float rna_Camera_angle_get(PointerRNA *ptr)
{
	Camera *cam = ptr->id.data;
	float sensor = BKE_camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
	return focallength_to_fov(cam->lens, sensor);
}
예제 #7
0
파일: view3d_view.c 프로젝트: pawkoz/dyplom
/**
 * Return a new RegionView3D.dist value to fit the \a radius.
 *
 * \note Depth isn't taken into account, this will fit a flat plane exactly,
 * but points towards the view (with a perspective projection),
 * may be within the radius but outside the view. eg:
 *
 * <pre>
 *           +
 * pt --> + /^ radius
 *         / |
 *        /  |
 * view  +   +
 *        \  |
 *         \ |
 *          \|
 *           +
 * </pre>
 *
 * \param ar  Can be NULL if \a use_aspect is false.
 * \param persp  Allow the caller to tell what kind of perspective to use (ortho/view/camera)
 * \param use_aspect  Increase the distance to account for non 1:1 view aspect.
 * \param radius  The radius will be fitted exactly, typically pre-scaled by a margin (#VIEW3D_MARGIN).
 */
float ED_view3d_radius_to_dist(
        const View3D *v3d, const ARegion *ar,
        const char persp, const bool use_aspect,
        const float radius)
{
	float dist;

	BLI_assert(ELEM(persp, RV3D_ORTHO, RV3D_PERSP, RV3D_CAMOB));
	BLI_assert((persp != RV3D_CAMOB) || v3d->camera);

	if (persp == RV3D_ORTHO) {
		dist = ED_view3d_radius_to_dist_ortho(v3d->lens, radius);
	}
	else {
		float lens, sensor_size, zoom;
		float angle;

		if (persp == RV3D_CAMOB) {
			CameraParams params;
			BKE_camera_params_init(&params);
			params.clipsta = v3d->near;
			params.clipend = v3d->far;
			BKE_camera_params_from_object(&params, v3d->camera);

			lens = params.lens;
			sensor_size = BKE_camera_sensor_size(params.sensor_fit, params.sensor_x, params.sensor_y);

			/* ignore 'rv3d->camzoom' because we want to fit to the cameras frame */
			zoom = CAMERA_PARAM_ZOOM_INIT_CAMOB;
		}
		else {
			lens = v3d->lens;
			sensor_size = DEFAULT_SENSOR_WIDTH;
			zoom = CAMERA_PARAM_ZOOM_INIT_PERSP;
		}

		angle = focallength_to_fov(lens, sensor_size);

		/* zoom influences lens, correct this by scaling the angle as a distance (by the zoom-level) */
		angle = atanf(tanf(angle / 2.0f) * zoom) * 2.0f;

		dist = ED_view3d_radius_to_dist_persp(angle, radius);
	}

	if (use_aspect) {
		const RegionView3D *rv3d = ar->regiondata;

		float winx, winy;

		if (persp == RV3D_CAMOB) {
			/* camera frame x/y in pixels */
			winx = ar->winx / rv3d->viewcamtexcofac[0];
			winy = ar->winy / rv3d->viewcamtexcofac[1];
		}
		else {
			winx = ar->winx;
			winy = ar->winy;
		}

		if (winx && winy) {
			float aspect = winx / winy;
			if (aspect < 1.0f) {
				aspect = 1.0f / aspect;
			}
			dist *= aspect;
		}
	}

	return dist;
}
예제 #8
0
파일: camera.c 프로젝트: floored/blender
void BKE_camera_params_compute_viewplane(CameraParams *params, int winx, int winy, float xasp, float yasp)
{
	rctf viewplane;
	float pixsize, viewfac, sensor_size, dx, dy;
	int sensor_fit;

	/* fields rendering */
	params->ycor = yasp / xasp;
	if (params->use_fields)
		params->ycor *= 2.0f;

	if (params->is_ortho) {
		/* orthographic camera */
		/* scale == 1.0 means exact 1 to 1 mapping */
		pixsize = params->ortho_scale;
	}
	else {
		/* perspective camera */
		sensor_size = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y);
		pixsize = (sensor_size * params->clipsta) / params->lens;
	}

	/* determine sensor fit */
	sensor_fit = BKE_camera_sensor_fit(params->sensor_fit, xasp * winx, yasp * winy);

	if (sensor_fit == CAMERA_SENSOR_FIT_HOR)
		viewfac = winx;
	else
		viewfac = params->ycor * winy;

	pixsize /= viewfac;

	/* extra zoom factor */
	pixsize *= params->zoom;

	/* compute view plane:
	 * fully centered, zbuffer fills in jittered between -.5 and +.5 */
	viewplane.xmin = -0.5f * (float)winx;
	viewplane.ymin = -0.5f * params->ycor * (float)winy;
	viewplane.xmax =  0.5f * (float)winx;
	viewplane.ymax =  0.5f * params->ycor * (float)winy;

	/* lens shift and offset */
	dx = params->shiftx * viewfac + winx * params->offsetx;
	dy = params->shifty * viewfac + winy * params->offsety;

	viewplane.xmin += dx;
	viewplane.ymin += dy;
	viewplane.xmax += dx;
	viewplane.ymax += dy;

	/* fields offset */
	if (params->field_second) {
		if (params->field_odd) {
			viewplane.ymin -= 0.5f * params->ycor;
			viewplane.ymax -= 0.5f * params->ycor;
		}
		else {
			viewplane.ymin += 0.5f * params->ycor;
			viewplane.ymax += 0.5f * params->ycor;
		}
	}

	/* the window matrix is used for clipping, and not changed during OSA steps */
	/* using an offset of +0.5 here would give clip errors on edges */
	viewplane.xmin *= pixsize;
	viewplane.xmax *= pixsize;
	viewplane.ymin *= pixsize;
	viewplane.ymax *= pixsize;

	params->viewdx = pixsize;
	params->viewdy = params->ycor * pixsize;
	params->viewplane = viewplane;
}
예제 #9
0
static bool camera_frame_fit_calc_from_data(
        CameraParams *params, CameraViewFrameData *data, float r_co[3], float *r_scale)
{
	float plane_tx[CAMERA_VIEWFRAME_NUM_PLANES][3];
	unsigned int i;

	if (data->tot <= 1) {
		return false;
	}

	if (params->is_ortho) {
		const float *cam_axis_x = data->camera_rotmat[0];
		const float *cam_axis_y = data->camera_rotmat[1];
		const float *cam_axis_z = data->camera_rotmat[2];
		float dists[CAMERA_VIEWFRAME_NUM_PLANES];
		float scale_diff;

		/* apply the dist-from-plane's to the transformed plane points */
		for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) {
			dists[i] = sqrtf_signed(data->dist_vals_sq[i]);
		}

		if ((dists[0] + dists[2]) > (dists[1] + dists[3])) {
			scale_diff = (dists[1] + dists[3]) *
			             (BLI_rctf_size_x(&params->viewplane) / BLI_rctf_size_y(&params->viewplane));
		}
		else {
			scale_diff = (dists[0] + dists[2]) *
			             (BLI_rctf_size_y(&params->viewplane) / BLI_rctf_size_x(&params->viewplane));
		}
		*r_scale = params->ortho_scale - scale_diff;

		zero_v3(r_co);
		madd_v3_v3fl(r_co, cam_axis_x, (dists[2] - dists[0]) * 0.5f + params->shiftx * scale_diff);
		madd_v3_v3fl(r_co, cam_axis_y, (dists[1] - dists[3]) * 0.5f + params->shifty * scale_diff);
		madd_v3_v3fl(r_co, cam_axis_z, -(data->dist_to_cam - 1.0f - params->clipsta));

		return true;
	}
	else {
		float plane_isect_1[3], plane_isect_1_no[3], plane_isect_1_other[3];
		float plane_isect_2[3], plane_isect_2_no[3], plane_isect_2_other[3];

		float plane_isect_pt_1[3], plane_isect_pt_2[3];

		/* apply the dist-from-plane's to the transformed plane points */
		for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) {
			mul_v3_v3fl(plane_tx[i], data->normal_tx[i], sqrtf_signed(data->dist_vals_sq[i]));
		}

		if ((!isect_plane_plane_v3(plane_isect_1, plane_isect_1_no,
		                           plane_tx[0], data->normal_tx[0],
		                           plane_tx[2], data->normal_tx[2])) ||
		    (!isect_plane_plane_v3(plane_isect_2, plane_isect_2_no,
		                           plane_tx[1], data->normal_tx[1],
		                           plane_tx[3], data->normal_tx[3])))
		{
			return false;
		}

		add_v3_v3v3(plane_isect_1_other, plane_isect_1, plane_isect_1_no);
		add_v3_v3v3(plane_isect_2_other, plane_isect_2, plane_isect_2_no);

		if (isect_line_line_v3(plane_isect_1, plane_isect_1_other,
		                       plane_isect_2, plane_isect_2_other,
		                       plane_isect_pt_1, plane_isect_pt_2) != 0)
		{
			float cam_plane_no[3];
			float plane_isect_delta[3];
			float plane_isect_delta_len;

			float shift_fac = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y) /
			                  params->lens;

			/* we want (0, 0, -1) transformed by camera_rotmat, this is a quicker shortcut. */
			negate_v3_v3(cam_plane_no, data->camera_rotmat[2]);

			sub_v3_v3v3(plane_isect_delta, plane_isect_pt_2, plane_isect_pt_1);
			plane_isect_delta_len = len_v3(plane_isect_delta);

			if (dot_v3v3(plane_isect_delta, cam_plane_no) > 0.0f) {
				copy_v3_v3(r_co, plane_isect_pt_1);

				/* offset shift */
				normalize_v3(plane_isect_1_no);
				madd_v3_v3fl(r_co, plane_isect_1_no, params->shifty * plane_isect_delta_len * shift_fac);
			}
			else {
				copy_v3_v3(r_co, plane_isect_pt_2);

				/* offset shift */
				normalize_v3(plane_isect_2_no);
				madd_v3_v3fl(r_co, plane_isect_2_no, params->shiftx * plane_isect_delta_len * shift_fac);
			}

			return true;
		}
	}

	return false;
}