Changeset View
Standalone View
intern/cycles/blender/blender_camera.cpp
| Show First 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | struct BlenderCamera { | ||||
| PanoramaType panorama_type; | PanoramaType panorama_type; | ||||
| float fisheye_fov; | float fisheye_fov; | ||||
| float fisheye_lens; | float fisheye_lens; | ||||
| float latitude_min; | float latitude_min; | ||||
| float latitude_max; | float latitude_max; | ||||
| float longitude_min; | float longitude_min; | ||||
| float longitude_max; | float longitude_max; | ||||
| bool use_spherical_stereo; | |||||
| float interocular_distance; | |||||
| float convergence_distance; | |||||
| enum { AUTO, HORIZONTAL, VERTICAL } sensor_fit; | enum { AUTO, HORIZONTAL, VERTICAL } sensor_fit; | ||||
| float sensor_width; | float sensor_width; | ||||
| float sensor_height; | float sensor_height; | ||||
| int full_width; | int full_width; | ||||
| int full_height; | int full_height; | ||||
| Show All 22 Lines | static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings b_render) | ||||
| bcam->viewport_camera_border.right = 1.0f; | bcam->viewport_camera_border.right = 1.0f; | ||||
| bcam->viewport_camera_border.top = 1.0f; | bcam->viewport_camera_border.top = 1.0f; | ||||
| /* render resolution */ | /* render resolution */ | ||||
| bcam->full_width = render_resolution_x(b_render); | bcam->full_width = render_resolution_x(b_render); | ||||
| bcam->full_height = render_resolution_y(b_render); | bcam->full_height = render_resolution_y(b_render); | ||||
| } | } | ||||
| static float blender_camera_focal_distance(BL::RenderEngine b_engine, BL::Object b_ob, BL::Camera b_camera) | static float camera_shift_x(BL::RenderEngine b_engine, BL::Object b_ob, BL::Camera b_camera, bool use_spherical_stereo) | ||||
| { | |||||
| if(use_spherical_stereo) | |||||
sergey: Guess this is because `b_engine.camera_shift_x` applies offset for an eye? Worth mentioning… | |||||
| return b_camera.shift_x(); | |||||
| else | |||||
| return b_engine.camera_shift_x(b_ob); | |||||
| } | |||||
| static void camera_model_matrix(BL::RenderEngine b_engine, BL::Object b_ob, bool use_spherical_stereo, | |||||
Not Done Inline ActionsSame as above. sergey: Same as above. | |||||
| BL::Array<float, 16> &r_matrix) | |||||
| { | |||||
| if(use_spherical_stereo) | |||||
Not Done Inline ActionsSeems phab got confused here with comments.. Still think we can make more clear Py-API for such things, but at least please bother explaining why it's special case here as well ;) sergey: Seems phab got confused here with comments..
Still think we can make more clear Py-API for… | |||||
| memcpy(r_matrix, b_ob.matrix_world(), sizeof(float)*16); | |||||
| else | |||||
| b_engine.camera_model_matrix(b_ob, r_matrix); | |||||
| } | |||||
| static float blender_camera_focal_distance(BL::RenderEngine b_engine, BL::Object b_ob, BL::Camera b_camera, bool use_spherical_stereo) | |||||
Not Done Inline ActionsWhy exactly we need to have special handling of those two functions? Something tells me it's better idea to make it so camera's RNA API will be giving you proper shift/matrix depending on it's settings? Might be missing something tho.. sergey: Why exactly we need to have special handling of those two functions? Something tells me it's… | |||||
Not Done Inline ActionsThe RNA API (b_engine.camera_shift_x) is not aware of this special case of stereo (since Blender Internal doesn't support it). dfelinto: The RNA API (b_engine.camera_shift_x) is not aware of this special case of stereo (since… | |||||
Not Done Inline ActionsThink it's more clear to pass bcam and access to bcam->use_spherical_stereo. So if shift/matrix will ever depend on more settings you don't need to pass them sergey: Think it's more clear to pass `bcam` and access to `bcam->use_spherical_stereo`. So if… | |||||
Not Done Inline ActionsSame. sergey: Same. | |||||
| { | { | ||||
| BL::Object b_dof_object = b_camera.dof_object(); | BL::Object b_dof_object = b_camera.dof_object(); | ||||
| if(!b_dof_object) | if(!b_dof_object) | ||||
| return b_camera.dof_distance(); | return b_camera.dof_distance(); | ||||
| /* for dof object, return distance along camera Z direction */ | /* for dof object, return distance along camera Z direction */ | ||||
| BL::Array<float, 16> b_ob_matrix; | BL::Array<float, 16> b_ob_matrix; | ||||
| b_engine.camera_model_matrix(b_ob, b_ob_matrix); | camera_model_matrix(b_engine, b_ob, use_spherical_stereo, b_ob_matrix); | ||||
| Transform obmat = get_transform(b_ob_matrix); | Transform obmat = transform_clear_scale(get_transform(b_ob_matrix)); | ||||
| Transform dofmat = get_transform(b_dof_object.matrix_world()); | Transform dofmat = get_transform(b_dof_object.matrix_world()); | ||||
| Transform mat = transform_inverse(obmat) * dofmat; | Transform mat = transform_inverse(obmat) * dofmat; | ||||
| return fabsf(transform_get_column(&mat, 3).z); | return fabsf(transform_get_column(&mat, 3).z); | ||||
| } | } | ||||
| static void blender_camera_from_object(BlenderCamera *bcam, BL::RenderEngine b_engine, BL::Object b_ob, bool skip_panorama = false) | static bool blender_camera_use_spherical_stereo(BL::RenderSettings b_render, BlenderCamera *bcam, PointerRNA *ccamera) | ||||
| { | |||||
| if(b_render.use_multiview() && | |||||
| b_render.views_format() == 0 && /* STEREO_3D */ | |||||
Not Done Inline ActionsUse RenderSettings::view_format_STEREO_3D instead of 0. sergey: Use `RenderSettings::view_format_STEREO_3D` instead of 0. | |||||
Not Done Inline Actionsdone dfelinto: done | |||||
| bcam->type == CAMERA_PANORAMA && | |||||
| RNA_boolean_get(ccamera, "use_spherical_stereo")) | |||||
| { | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| static void blender_camera_from_object(BlenderCamera *bcam, BL::RenderEngine b_engine, BL::RenderSettings b_render, | |||||
| BL::Object b_ob, bool skip_panorama = false) | |||||
| { | { | ||||
| BL::ID b_ob_data = b_ob.data(); | BL::ID b_ob_data = b_ob.data(); | ||||
| if(b_ob_data.is_a(&RNA_Camera)) { | if(b_ob_data.is_a(&RNA_Camera)) { | ||||
| BL::Camera b_camera(b_ob_data); | BL::Camera b_camera(b_ob_data); | ||||
| PointerRNA ccamera = RNA_pointer_get(&b_camera.ptr, "cycles"); | PointerRNA ccamera = RNA_pointer_get(&b_camera.ptr, "cycles"); | ||||
| bcam->nearclip = b_camera.clip_start(); | bcam->nearclip = b_camera.clip_start(); | ||||
| Show All 32 Lines | if(b_ob_data.is_a(&RNA_Camera)) { | ||||
| bcam->fisheye_fov = RNA_float_get(&ccamera, "fisheye_fov"); | bcam->fisheye_fov = RNA_float_get(&ccamera, "fisheye_fov"); | ||||
| bcam->fisheye_lens = RNA_float_get(&ccamera, "fisheye_lens"); | bcam->fisheye_lens = RNA_float_get(&ccamera, "fisheye_lens"); | ||||
| bcam->latitude_min = RNA_float_get(&ccamera, "latitude_min"); | bcam->latitude_min = RNA_float_get(&ccamera, "latitude_min"); | ||||
| bcam->latitude_max = RNA_float_get(&ccamera, "latitude_max"); | bcam->latitude_max = RNA_float_get(&ccamera, "latitude_max"); | ||||
| bcam->longitude_min = RNA_float_get(&ccamera, "longitude_min"); | bcam->longitude_min = RNA_float_get(&ccamera, "longitude_min"); | ||||
| bcam->longitude_max = RNA_float_get(&ccamera, "longitude_max"); | bcam->longitude_max = RNA_float_get(&ccamera, "longitude_max"); | ||||
| bcam->interocular_distance = b_camera.stereo().interocular_distance(); | |||||
| bcam->convergence_distance = b_camera.stereo().convergence_distance(); | |||||
| bcam->use_spherical_stereo = blender_camera_use_spherical_stereo(b_render, bcam, &ccamera); | |||||
| bcam->ortho_scale = b_camera.ortho_scale(); | bcam->ortho_scale = b_camera.ortho_scale(); | ||||
| bcam->lens = b_camera.lens(); | bcam->lens = b_camera.lens(); | ||||
| /* allow f/stop number to change aperture_size but still | /* allow f/stop number to change aperture_size but still | ||||
| * give manual control over aperture radius */ | * give manual control over aperture radius */ | ||||
| int aperture_type = RNA_enum_get(&ccamera, "aperture_type"); | int aperture_type = RNA_enum_get(&ccamera, "aperture_type"); | ||||
| if(aperture_type == 1) { | if(aperture_type == 1) { | ||||
| float fstop = RNA_float_get(&ccamera, "aperture_fstop"); | float fstop = RNA_float_get(&ccamera, "aperture_fstop"); | ||||
| fstop = max(fstop, 1e-5f); | fstop = max(fstop, 1e-5f); | ||||
| if(bcam->type == CAMERA_ORTHOGRAPHIC) | if(bcam->type == CAMERA_ORTHOGRAPHIC) | ||||
| bcam->aperturesize = 1.0f/(2.0f*fstop); | bcam->aperturesize = 1.0f/(2.0f*fstop); | ||||
| else | else | ||||
| bcam->aperturesize = (bcam->lens*1e-3f)/(2.0f*fstop); | bcam->aperturesize = (bcam->lens*1e-3f)/(2.0f*fstop); | ||||
| } | } | ||||
| else | else | ||||
| bcam->aperturesize = RNA_float_get(&ccamera, "aperture_size"); | bcam->aperturesize = RNA_float_get(&ccamera, "aperture_size"); | ||||
| bcam->apertureblades = RNA_int_get(&ccamera, "aperture_blades"); | bcam->apertureblades = RNA_int_get(&ccamera, "aperture_blades"); | ||||
| bcam->aperturerotation = RNA_float_get(&ccamera, "aperture_rotation"); | bcam->aperturerotation = RNA_float_get(&ccamera, "aperture_rotation"); | ||||
| bcam->focaldistance = blender_camera_focal_distance(b_engine, b_ob, b_camera); | bcam->focaldistance = blender_camera_focal_distance(b_engine, b_ob, b_camera, bcam->use_spherical_stereo); | ||||
| bcam->aperture_ratio = RNA_float_get(&ccamera, "aperture_ratio"); | bcam->aperture_ratio = RNA_float_get(&ccamera, "aperture_ratio"); | ||||
| bcam->shift.x = b_engine.camera_shift_x(b_ob); | bcam->shift.x = camera_shift_x(b_engine, b_ob, b_camera, bcam->use_spherical_stereo); | ||||
| bcam->shift.y = b_camera.shift_y(); | bcam->shift.y = b_camera.shift_y(); | ||||
| bcam->sensor_width = b_camera.sensor_width(); | bcam->sensor_width = b_camera.sensor_width(); | ||||
| bcam->sensor_height = b_camera.sensor_height(); | bcam->sensor_height = b_camera.sensor_height(); | ||||
| if(b_camera.sensor_fit() == BL::Camera::sensor_fit_AUTO) | if(b_camera.sensor_fit() == BL::Camera::sensor_fit_AUTO) | ||||
| bcam->sensor_fit = BlenderCamera::AUTO; | bcam->sensor_fit = BlenderCamera::AUTO; | ||||
| else if(b_camera.sensor_fit() == BL::Camera::sensor_fit_HORIZONTAL) | else if(b_camera.sensor_fit() == BL::Camera::sensor_fit_HORIZONTAL) | ||||
| ▲ Show 20 Lines • Show All 148 Lines • ▼ Show 20 Lines | static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int height) | ||||
| cam->fisheye_fov = bcam->fisheye_fov; | cam->fisheye_fov = bcam->fisheye_fov; | ||||
| cam->fisheye_lens = bcam->fisheye_lens; | cam->fisheye_lens = bcam->fisheye_lens; | ||||
| cam->latitude_min = bcam->latitude_min; | cam->latitude_min = bcam->latitude_min; | ||||
| cam->latitude_max = bcam->latitude_max; | cam->latitude_max = bcam->latitude_max; | ||||
| cam->longitude_min = bcam->longitude_min; | cam->longitude_min = bcam->longitude_min; | ||||
| cam->longitude_max = bcam->longitude_max; | cam->longitude_max = bcam->longitude_max; | ||||
| /* panorama stereo */ | |||||
| cam->use_spherical_stereo = bcam->use_spherical_stereo; | |||||
| cam->interocular_distance = bcam->interocular_distance; | |||||
| cam->convergence_distance = bcam->convergence_distance; | |||||
| /* anamorphic lens bokeh */ | /* anamorphic lens bokeh */ | ||||
| cam->aperture_ratio = bcam->aperture_ratio; | cam->aperture_ratio = bcam->aperture_ratio; | ||||
Not Done Inline ActionsThink we can avoid exposing eyes to the underlying camera classes. See comments below in the kernel. sergey: Think we can avoid exposing eyes to the underlying camera classes. See comments below in the… | |||||
| /* perspective */ | /* perspective */ | ||||
| cam->fov = 2.0f * atanf((0.5f * sensor_size) / bcam->lens / aspectratio); | cam->fov = 2.0f * atanf((0.5f * sensor_size) / bcam->lens / aspectratio); | ||||
| cam->focaldistance = bcam->focaldistance; | cam->focaldistance = bcam->focaldistance; | ||||
| cam->aperturesize = bcam->aperturesize; | cam->aperturesize = bcam->aperturesize; | ||||
| cam->blades = bcam->apertureblades; | cam->blades = bcam->apertureblades; | ||||
| cam->bladesrotation = bcam->aperturerotation; | cam->bladesrotation = bcam->aperturerotation; | ||||
| /* transform */ | /* transform */ | ||||
| Show All 35 Lines | void BlenderSync::sync_camera(BL::RenderSettings b_render, BL::Object b_override, int width, int height) | ||||
| /* camera object */ | /* camera object */ | ||||
| BL::Object b_ob = b_scene.camera(); | BL::Object b_ob = b_scene.camera(); | ||||
| if(b_override) | if(b_override) | ||||
| b_ob = b_override; | b_ob = b_override; | ||||
| if(b_ob) { | if(b_ob) { | ||||
| BL::Array<float, 16> b_ob_matrix; | BL::Array<float, 16> b_ob_matrix; | ||||
| blender_camera_from_object(&bcam, b_engine, b_ob); | blender_camera_from_object(&bcam, b_engine, b_render, b_ob); | ||||
| b_engine.camera_model_matrix(b_ob, b_ob_matrix); | camera_model_matrix(b_engine, b_ob, bcam.use_spherical_stereo, b_ob_matrix); | ||||
| bcam.matrix = get_transform(b_ob_matrix); | bcam.matrix = get_transform(b_ob_matrix); | ||||
| } | } | ||||
| /* sync */ | /* sync */ | ||||
| Camera *cam = scene->camera; | Camera *cam = scene->camera; | ||||
| blender_camera_sync(cam, &bcam, width, height); | blender_camera_sync(cam, &bcam, width, height); | ||||
| /* multiview panorama */ | |||||
| if(cam->use_spherical_stereo) { | |||||
| const char *active_view = b_engine.active_view_get(); | |||||
Not Done Inline ActionsSome API questions. Is it always limited to "left" and "right"? Is there some non-string constants to distinguish those two? sergey: Some API questions.
Is it always limited to "left" and "right"? Is there some non-string… | |||||
Not Done Inline ActionsIt is always limited to "left" and "right", and we have the constants in Blender (STEREO_LEFT_NAME/STEREO_RIGHT_NAME). I wasn't sure how to proceed here (whether to expose the Blender constants to Cycles, or to re-define them here) dfelinto: It is always limited to "left" and "right", and we have the constants in Blender… | |||||
Not Done Inline ActionsThat's a bit weird:
So seems would have some redundant updates. sergey: That's a bit weird:
- Cycles sets current view to the render engine, so in theory it knows… | |||||
| if(strcmp(active_view, "left") == 0) | |||||
Not Done Inline ActionsWould it make sense to have some sort of view.type which could be {VIEW_LEFT, VIEW_RIGHT, VIEW_CUSTOM}? sergey: Would it make sense to have some sort of `view.type` which could be `{VIEW_LEFT, VIEW_RIGHT… | |||||
| cam->stereo_eye = STEREO_LEFT; | |||||
| else if(strcmp(active_view, "right") == 0) | |||||
| cam->stereo_eye = STEREO_RIGHT; | |||||
| else | |||||
| cam->stereo_eye = STEREO_NONE; | |||||
| } | |||||
| /* force update to update the kernel camera */ | |||||
Not Done Inline ActionsThat' wrong. Camera is to be tagged for update only if it was modified, which is already checked in blender_camera_sync. So my guess this code belongs to other place of the file and no force tag is needed. sergey: That' wrong. Camera is to be tagged for update only if it was modified, which is already… | |||||
| cam->tag_update(); | |||||
| } | } | ||||
| void BlenderSync::sync_camera_motion(BL::Object b_ob, float motion_time) | void BlenderSync::sync_camera_motion(BL::Object b_ob, float motion_time) | ||||
| { | { | ||||
| Camera *cam = scene->camera; | Camera *cam = scene->camera; | ||||
| BL::Array<float, 16> b_ob_matrix; | BL::Array<float, 16> b_ob_matrix; | ||||
| b_engine.camera_model_matrix(b_ob, b_ob_matrix); | camera_model_matrix(b_engine, b_ob, cam->use_spherical_stereo, b_ob_matrix); | ||||
| Transform tfm = get_transform(b_ob_matrix); | Transform tfm = get_transform(b_ob_matrix); | ||||
| tfm = blender_camera_matrix(tfm, cam->type); | tfm = blender_camera_matrix(tfm, cam->type); | ||||
| if(tfm != cam->matrix) { | if(tfm != cam->matrix) { | ||||
| VLOG(1) << "Camera " << b_ob.name() << " motion detected."; | VLOG(1) << "Camera " << b_ob.name() << " motion detected."; | ||||
| if(motion_time == -1.0f) { | if(motion_time == -1.0f) { | ||||
| cam->motion.pre = tfm; | cam->motion.pre = tfm; | ||||
| cam->use_motion = true; | cam->use_motion = true; | ||||
| Show All 18 Lines | static void blender_camera_from_view(BlenderCamera *bcam, BL::RenderEngine b_engine, BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height, bool skip_panorama = false) | ||||
| bcam->lens = b_v3d.lens(); | bcam->lens = b_v3d.lens(); | ||||
| bcam->shuttertime = b_scene.render().motion_blur_shutter(); | bcam->shuttertime = b_scene.render().motion_blur_shutter(); | ||||
| if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA) { | if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA) { | ||||
| /* camera view */ | /* camera view */ | ||||
| BL::Object b_ob = (b_v3d.lock_camera_and_layers())? b_scene.camera(): b_v3d.camera(); | BL::Object b_ob = (b_v3d.lock_camera_and_layers())? b_scene.camera(): b_v3d.camera(); | ||||
| if(b_ob) { | if(b_ob) { | ||||
| blender_camera_from_object(bcam, b_engine, b_ob, skip_panorama); | blender_camera_from_object(bcam, b_engine, b_scene.render(), b_ob, skip_panorama); | ||||
| if(!skip_panorama && bcam->type == CAMERA_PANORAMA) { | if(!skip_panorama && bcam->type == CAMERA_PANORAMA) { | ||||
| /* in panorama camera view, we map viewplane to camera border */ | /* in panorama camera view, we map viewplane to camera border */ | ||||
| BoundBox2D view_box, cam_box; | BoundBox2D view_box, cam_box; | ||||
| blender_camera_view_subset(b_engine, b_scene.render(), b_scene, b_ob, b_v3d, b_rv3d, width, height, | blender_camera_view_subset(b_engine, b_scene.render(), b_scene, b_ob, b_v3d, b_rv3d, width, height, | ||||
| &view_box, &cam_box); | &view_box, &cam_box); | ||||
| ▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | static void blender_camera_view_subset(BL::RenderEngine b_engine, BL::RenderSettings b_render, BL::Scene b_scene, BL::Object b_ob, BL::SpaceView3D b_v3d, | ||||
| blender_camera_from_view(&view_bcam, b_engine, b_scene, b_v3d, b_rv3d, width, height, true); | blender_camera_from_view(&view_bcam, b_engine, b_scene, b_v3d, b_rv3d, width, height, true); | ||||
| blender_camera_viewplane(&view_bcam, width, height, | blender_camera_viewplane(&view_bcam, width, height, | ||||
| &view, &view_aspect, &sensor_size); | &view, &view_aspect, &sensor_size); | ||||
| /* get camera viewplane */ | /* get camera viewplane */ | ||||
| BlenderCamera cam_bcam; | BlenderCamera cam_bcam; | ||||
| blender_camera_init(&cam_bcam, b_render); | blender_camera_init(&cam_bcam, b_render); | ||||
| blender_camera_from_object(&cam_bcam, b_engine, b_ob, true); | blender_camera_from_object(&cam_bcam, b_engine, b_render, b_ob, true); | ||||
| blender_camera_viewplane(&cam_bcam, cam_bcam.full_width, cam_bcam.full_height, | blender_camera_viewplane(&cam_bcam, cam_bcam.full_width, cam_bcam.full_height, | ||||
| &cam, &cam_aspect, &sensor_size); | &cam, &cam_aspect, &sensor_size); | ||||
| /* return */ | /* return */ | ||||
| *view_box = view * (1.0f/view_aspect); | *view_box = view * (1.0f/view_aspect); | ||||
| *cam_box = cam * (1.0f/cam_aspect); | *cam_box = cam * (1.0f/cam_aspect); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 128 Lines • Show Last 20 Lines | |||||
Guess this is because b_engine.camera_shift_x applies offset for an eye? Worth mentioning this in the comment.