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); } }
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)); } }
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; } }
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); }
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); }
/** * 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(¶ms); params.clipsta = v3d->near; params.clipend = v3d->far; BKE_camera_params_from_object(¶ms, 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; }
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; }
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(¶ms->viewplane) / BLI_rctf_size_y(¶ms->viewplane)); } else { scale_diff = (dists[0] + dists[2]) * (BLI_rctf_size_y(¶ms->viewplane) / BLI_rctf_size_x(¶ms->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; }