diff options
author | Dalai Felinto <dfelinto@gmail.com> | 2015-09-24 18:24:20 +0300 |
---|---|---|
committer | Dalai Felinto <dfelinto@gmail.com> | 2015-09-24 18:24:20 +0300 |
commit | 27b3ea622f8bd313a8e2827dfec752bf2125566c (patch) | |
tree | f212e49d224ce8e1cfc3b17a64ae524711494391 /intern/cycles/blender/blender_camera.cpp | |
parent | 372dff8d1dc7e24d4b2cd37de245588ecfce8bfa (diff) | |
parent | de80e687689032cb85179a1f7e89750573631d5d (diff) |
Merge remote-tracking branch 'origin/master' into cycles_camera_nodescycles_camera_nodes
Note: the branch currently crashes in blender_camera_nodes.cpp:
BL::NodeTree b_ntree = b_data.node_groups[nodes_tree_name];
The crash was introduced in:
cb7cf523e5c000609f32a382e2c0fcc57f635a42
Conflicts:
intern/cycles/SConscript
intern/cycles/blender/addon/__init__.py
intern/cycles/blender/addon/properties.py
intern/cycles/blender/blender_camera.cpp
intern/cycles/kernel/kernel_types.h
intern/cycles/kernel/svm/svm.h
intern/cycles/kernel/svm/svm_types.h
intern/cycles/render/camera.cpp
intern/cycles/render/camera.h
Diffstat (limited to 'intern/cycles/blender/blender_camera.cpp')
-rw-r--r-- | intern/cycles/blender/blender_camera.cpp | 305 |
1 files changed, 219 insertions, 86 deletions
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp index d26317b6e32..d45dc62a1e0 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -11,7 +11,7 @@ * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and - * limitations under the License + * limitations under the License. */ #include "camera.h" @@ -20,6 +20,8 @@ #include "blender_sync.h" #include "blender_util.h" +#include "util_logging.h" + CCL_NAMESPACE_BEGIN /* Blender Camera Intermediate: we first convert both the offline and 3d view @@ -51,6 +53,10 @@ struct BlenderCamera { PanoramaType panorama_type; float fisheye_fov; float fisheye_lens; + float latitude_min; + float latitude_max; + float longitude_min; + float longitude_max; enum { AUTO, HORIZONTAL, VERTICAL } sensor_fit; float sensor_width; @@ -61,11 +67,12 @@ struct BlenderCamera { BoundBox2D border; BoundBox2D pano_viewplane; + BoundBox2D viewport_camera_border; Transform matrix; }; -static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings b_render, BL::Scene b_scene) +static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings b_render) { memset(bcam, 0, sizeof(BlenderCamera)); @@ -80,13 +87,15 @@ static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings b_render bcam->border.top = 1.0f; bcam->pano_viewplane.right = 1.0f; bcam->pano_viewplane.top = 1.0f; + bcam->viewport_camera_border.right = 1.0f; + bcam->viewport_camera_border.top = 1.0f; /* render resolution */ bcam->full_width = render_resolution_x(b_render); bcam->full_height = render_resolution_y(b_render); } -static float blender_camera_focal_distance(BL::Object b_ob, BL::Camera b_camera) +static float blender_camera_focal_distance(BL::RenderEngine b_engine, BL::Object b_ob, BL::Camera b_camera) { BL::Object b_dof_object = b_camera.dof_object(); @@ -94,14 +103,16 @@ static float blender_camera_focal_distance(BL::Object b_ob, BL::Camera b_camera) return b_camera.dof_distance(); /* for dof object, return distance along camera Z direction */ - Transform obmat = transform_clear_scale(get_transform(b_ob.matrix_world())); + BL::Array<float, 16> b_ob_matrix; + b_engine.camera_model_matrix(b_ob, b_ob_matrix); + Transform obmat = get_transform(b_ob_matrix); Transform dofmat = get_transform(b_dof_object.matrix_world()); - Transform mat = transform_inverse(obmat) * dofmat; - - return fabsf(transform_get_column(&mat, 3).z); + float3 view_dir = normalize(transform_get_column(&obmat, 2)); + float3 dof_dir = transform_get_column(&obmat, 3) - transform_get_column(&dofmat, 3); + return fabsf(dot(view_dir, dof_dir)); } -static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob, bool skip_panorama = false) +static void blender_camera_from_object(BlenderCamera *bcam, BL::RenderEngine b_engine, BL::Object b_ob, bool skip_panorama = false) { BL::ID b_ob_data = b_ob.data(); @@ -137,6 +148,9 @@ static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob, boo case 2: bcam->panorama_type = PANORAMA_FISHEYE_EQUISOLID; break; + case 3: + bcam->panorama_type = PANORAMA_MIRRORBALL; + break; case 0: default: bcam->panorama_type = PANORAMA_EQUIRECTANGULAR; @@ -145,6 +159,10 @@ static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob, boo bcam->fisheye_fov = RNA_float_get(&ccamera, "fisheye_fov"); bcam->fisheye_lens = RNA_float_get(&ccamera, "fisheye_lens"); + bcam->latitude_min = RNA_float_get(&ccamera, "latitude_min"); + bcam->latitude_max = RNA_float_get(&ccamera, "latitude_max"); + bcam->longitude_min = RNA_float_get(&ccamera, "longitude_min"); + bcam->longitude_max = RNA_float_get(&ccamera, "longitude_max"); bcam->ortho_scale = b_camera.ortho_scale(); @@ -168,10 +186,10 @@ static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob, boo bcam->apertureblades = RNA_int_get(&ccamera, "aperture_blades"); bcam->aperturerotation = RNA_float_get(&ccamera, "aperture_rotation"); - bcam->focaldistance = blender_camera_focal_distance(b_ob, b_camera); + bcam->focaldistance = blender_camera_focal_distance(b_engine, b_ob, b_camera); bcam->aperture_ratio = RNA_float_get(&ccamera, "aperture_ratio"); - bcam->shift.x = b_camera.shift_x(); + bcam->shift.x = b_engine.camera_shift_x(b_ob); bcam->shift.y = b_camera.shift_y(); bcam->sensor_width = b_camera.sensor_width(); @@ -189,19 +207,34 @@ static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob, boo } } -static Transform blender_camera_matrix(const Transform& tfm, CameraType type) +static Transform blender_camera_matrix(const Transform& tfm, + const CameraType type, + const PanoramaType panorama_type) { Transform result; if(type == CAMERA_PANORAMA) { - /* make it so environment camera needs to be pointed in the direction - * of the positive x-axis to match an environment texture, this way - * it is looking at the center of the texture */ - result = tfm * - make_transform( 0.0f, -1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - -1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f); + if(panorama_type == PANORAMA_MIRRORBALL) { + /* Mirror ball camera is looking into the negative Y direction + * which matches texture mirror ball mapping. + */ + result = tfm * + make_transform(1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f); + } + else { + /* Make it so environment camera needs to be pointed in the direction + * of the positive x-axis to match an environment texture, this way + * it is looking at the center of the texture + */ + result = tfm * + make_transform( 0.0f, -1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + -1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f); + } } else { /* note the blender camera points along the negative z-axis */ @@ -211,8 +244,11 @@ static Transform blender_camera_matrix(const Transform& tfm, CameraType type) return transform_clear_scale(result); } -static void blender_camera_viewplane(BlenderCamera *bcam, int width, int height, - BoundBox2D *viewplane, float *aspectratio, float *sensor_size) +static void blender_camera_viewplane(BlenderCamera *bcam, + int width, int height, + BoundBox2D *viewplane, + float *aspectratio, + float *sensor_size) { /* dimensions */ float xratio = (float)width*bcam->pixelaspect.x; @@ -225,24 +261,34 @@ static void blender_camera_viewplane(BlenderCamera *bcam, int width, int height, /* sensor fitting */ if(bcam->sensor_fit == BlenderCamera::AUTO) { horizontal_fit = (xratio > yratio); - *sensor_size = bcam->sensor_width; + if(sensor_size != NULL) { + *sensor_size = bcam->sensor_width; + } } else if(bcam->sensor_fit == BlenderCamera::HORIZONTAL) { horizontal_fit = true; - *sensor_size = bcam->sensor_width; + if(sensor_size != NULL) { + *sensor_size = bcam->sensor_width; + } } else { horizontal_fit = false; - *sensor_size = bcam->sensor_height; + if(sensor_size != NULL) { + *sensor_size = bcam->sensor_height; + } } if(horizontal_fit) { - *aspectratio = xratio/yratio; + if(aspectratio != NULL) { + *aspectratio = xratio/yratio; + } xaspect = *aspectratio; yaspect = 1.0f; } else { - *aspectratio = yratio/xratio; + if(aspectratio != NULL) { + *aspectratio = yratio/xratio; + } xaspect = 1.0f; yaspect = *aspectratio; } @@ -251,31 +297,37 @@ static void blender_camera_viewplane(BlenderCamera *bcam, int width, int height, if(bcam->type == CAMERA_ORTHOGRAPHIC) { xaspect = xaspect*bcam->ortho_scale/(*aspectratio*2.0f); yaspect = yaspect*bcam->ortho_scale/(*aspectratio*2.0f); - *aspectratio = bcam->ortho_scale/2.0f; + if(aspectratio != NULL) { + *aspectratio = bcam->ortho_scale/2.0f; + } } if(bcam->type == CAMERA_PANORAMA) { /* set viewplane */ - *viewplane = bcam->pano_viewplane; + if(viewplane != NULL) { + *viewplane = bcam->pano_viewplane; + } } else { /* set viewplane */ - viewplane->left = -xaspect; - viewplane->right = xaspect; - viewplane->bottom = -yaspect; - viewplane->top = yaspect; - - /* zoom for 3d camera view */ - *viewplane = (*viewplane) * bcam->zoom; - - /* modify viewplane with camera shift and 3d camera view offset */ - float dx = 2.0f*(*aspectratio*bcam->shift.x + bcam->offset.x*xaspect*2.0f); - float dy = 2.0f*(*aspectratio*bcam->shift.y + bcam->offset.y*yaspect*2.0f); - - viewplane->left += dx; - viewplane->right += dx; - viewplane->bottom += dy; - viewplane->top += dy; + if(viewplane != NULL) { + viewplane->left = -xaspect; + viewplane->right = xaspect; + viewplane->bottom = -yaspect; + viewplane->top = yaspect; + + /* zoom for 3d camera view */ + *viewplane = (*viewplane) * bcam->zoom; + + /* modify viewplane with camera shift and 3d camera view offset */ + float dx = 2.0f*(*aspectratio*bcam->shift.x + bcam->offset.x*xaspect*2.0f); + float dy = 2.0f*(*aspectratio*bcam->shift.y + bcam->offset.y*yaspect*2.0f); + + viewplane->left += dx; + viewplane->right += dx; + viewplane->bottom += dy; + viewplane->top += dy; + } } } @@ -292,7 +344,7 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int &cam->viewplane, &aspectratio, &sensor_size); /* panorama sensor */ - if (bcam->type == CAMERA_PANORAMA && bcam->panorama_type == PANORAMA_FISHEYE_EQUISOLID) { + if(bcam->type == CAMERA_PANORAMA && bcam->panorama_type == PANORAMA_FISHEYE_EQUISOLID) { float fit_xratio = (float)bcam->full_width*bcam->pixelaspect.x; float fit_yratio = (float)bcam->full_height*bcam->pixelaspect.y; bool horizontal_fit; @@ -336,6 +388,11 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int cam->panorama_type = bcam->panorama_type; cam->fisheye_fov = bcam->fisheye_fov; cam->fisheye_lens = bcam->fisheye_lens; + cam->latitude_min = bcam->latitude_min; + cam->latitude_max = bcam->latitude_max; + + cam->longitude_min = bcam->longitude_min; + cam->longitude_max = bcam->longitude_max; /* anamorphic lens bokeh */ cam->aperture_ratio = bcam->aperture_ratio; @@ -348,14 +405,20 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int cam->bladesrotation = bcam->aperturerotation; /* transform */ - cam->matrix = blender_camera_matrix(bcam->matrix, bcam->type); + cam->matrix = blender_camera_matrix(bcam->matrix, + bcam->type, + bcam->panorama_type); cam->motion.pre = cam->matrix; cam->motion.post = cam->matrix; cam->use_motion = false; + cam->use_perspective_motion = false; cam->shuttertime = bcam->shuttertime; + cam->fov_pre = cam->fov; + cam->fov_post = cam->fov; /* border */ cam->border = bcam->border; + cam->viewport_camera_border = bcam->viewport_camera_border; /* set update flag */ if(cam->modified(prevcam)) @@ -367,7 +430,7 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int void BlenderSync::sync_camera(BL::RenderSettings b_render, BL::Object b_override, int width, int height) { BlenderCamera bcam; - blender_camera_init(&bcam, b_render, b_scene); + blender_camera_init(&bcam, b_render); /* pixel aspect */ bcam.pixelaspect.x = b_render.pixel_aspect_x(); @@ -389,25 +452,34 @@ void BlenderSync::sync_camera(BL::RenderSettings b_render, BL::Object b_override b_ob = b_override; if(b_ob) { - blender_camera_from_object(&bcam, b_ob); - bcam.matrix = get_transform(b_ob.matrix_world()); + BL::Array<float, 16> b_ob_matrix; + blender_camera_from_object(&bcam, b_engine, b_ob); + b_engine.camera_model_matrix(b_ob, b_ob_matrix); + bcam.matrix = get_transform(b_ob_matrix); } /* sync */ Camera *cam = scene->camera; blender_camera_sync(cam, &bcam, width, height); sync_camera_nodes(b_ob); - scene->camera->use_camera_in_volume = experimental; } -void BlenderSync::sync_camera_motion(BL::Object b_ob, float motion_time) +void BlenderSync::sync_camera_motion(BL::RenderSettings b_render, + BL::Object b_ob, + int width, int height, + float motion_time) { - Camera *cam = scene->camera; + if(!b_ob) + return; - Transform tfm = get_transform(b_ob.matrix_world()); - tfm = blender_camera_matrix(tfm, cam->type); + Camera *cam = scene->camera; + BL::Array<float, 16> b_ob_matrix; + b_engine.camera_model_matrix(b_ob, b_ob_matrix); + Transform tfm = get_transform(b_ob_matrix); + tfm = blender_camera_matrix(tfm, cam->type, cam->panorama_type); if(tfm != cam->matrix) { + VLOG(1) << "Camera " << b_ob.name() << " motion detected."; if(motion_time == -1.0f) { cam->motion.pre = tfm; cam->use_motion = true; @@ -417,14 +489,39 @@ void BlenderSync::sync_camera_motion(BL::Object b_ob, float motion_time) cam->use_motion = true; } } + + if(cam->type == CAMERA_PERSPECTIVE) { + BlenderCamera bcam; + float aspectratio, sensor_size; + blender_camera_init(&bcam, b_render); + blender_camera_from_object(&bcam, b_engine, b_ob); + blender_camera_viewplane(&bcam, + width, height, + NULL, + &aspectratio, + &sensor_size); + /* TODO(sergey): De-duplicate calculation with camera sync. */ + float fov = 2.0f * atanf((0.5f * sensor_size) / bcam.lens / aspectratio); + if(fov != cam->fov) { + VLOG(1) << "Camera " << b_ob.name() << " FOV change detected."; + if(motion_time == -1.0f) { + cam->fov_pre = fov; + cam->use_perspective_motion = true; + } + else if(motion_time == 1.0f) { + cam->fov_post = fov; + cam->use_perspective_motion = true; + } + } + } } /* Sync 3D View Camera */ -static void blender_camera_view_subset(BL::RenderSettings b_render, BL::Scene b_scene, BL::Object b_ob, BL::SpaceView3D b_v3d, +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, BL::RegionView3D b_rv3d, int width, int height, BoundBox2D *view_box, BoundBox2D *cam_box); -static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height, bool skip_panorama = false) +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) { /* 3d view parameters */ bcam->nearclip = b_v3d.clip_start(); @@ -437,13 +534,13 @@ static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL: BL::Object b_ob = (b_v3d.lock_camera_and_layers())? b_scene.camera(): b_v3d.camera(); if(b_ob) { - blender_camera_from_object(bcam, b_ob, skip_panorama); + blender_camera_from_object(bcam, b_engine, b_ob, skip_panorama); if(!skip_panorama && bcam->type == CAMERA_PANORAMA) { /* in panorama camera view, we map viewplane to camera border */ BoundBox2D view_box, cam_box; - blender_camera_view_subset(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); bcam->pano_viewplane = view_box.make_relative_to(cam_box); @@ -481,7 +578,7 @@ static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL: bcam->matrix = transform_inverse(get_transform(b_rv3d.view_matrix())); } -static void blender_camera_view_subset(BL::RenderSettings b_render, BL::Scene b_scene, BL::Object b_ob, BL::SpaceView3D b_v3d, +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, BL::RegionView3D b_rv3d, int width, int height, BoundBox2D *view_box, BoundBox2D *cam_box) { BoundBox2D cam, view; @@ -489,16 +586,16 @@ static void blender_camera_view_subset(BL::RenderSettings b_render, BL::Scene b_ /* get viewport viewplane */ BlenderCamera view_bcam; - blender_camera_init(&view_bcam, b_render, b_scene); - blender_camera_from_view(&view_bcam, b_scene, b_v3d, b_rv3d, width, height, true); + blender_camera_init(&view_bcam, b_render); + blender_camera_from_view(&view_bcam, b_engine, b_scene, b_v3d, b_rv3d, width, height, true); blender_camera_viewplane(&view_bcam, width, height, &view, &view_aspect, &sensor_size); /* get camera viewplane */ BlenderCamera cam_bcam; - blender_camera_init(&cam_bcam, b_render, b_scene); - blender_camera_from_object(&cam_bcam, b_ob, true); + blender_camera_init(&cam_bcam, b_render); + blender_camera_from_object(&cam_bcam, b_engine, b_ob, true); blender_camera_viewplane(&cam_bcam, cam_bcam.full_width, cam_bcam.full_height, &cam, &cam_aspect, &sensor_size); @@ -508,7 +605,27 @@ static void blender_camera_view_subset(BL::RenderSettings b_render, BL::Scene b_ *cam_box = cam * (1.0f/cam_aspect); } -static void blender_camera_border(BlenderCamera *bcam, BL::RenderSettings b_render, BL::Scene b_scene, BL::SpaceView3D b_v3d, +static void blender_camera_border_subset(BL::RenderEngine b_engine, + BL::RenderSettings b_render, + BL::Scene b_scene, + BL::SpaceView3D b_v3d, + BL::RegionView3D b_rv3d, + BL::Object b_ob, + int width, int height, + const BoundBox2D &border, + BoundBox2D *result) +{ + /* Determine camera viewport subset. */ + BoundBox2D view_box, cam_box; + blender_camera_view_subset(b_engine, b_render, b_scene, b_ob, b_v3d, b_rv3d, width, height, + &view_box, &cam_box); + + /* Determine viewport subset matching given border. */ + cam_box = cam_box.make_relative_to(view_box); + *result = cam_box.subset(border); +} + +static void blender_camera_border(BlenderCamera *bcam, BL::RenderEngine b_engine, BL::RenderSettings b_render, BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height) { bool is_camera_view; @@ -526,47 +643,61 @@ static void blender_camera_border(BlenderCamera *bcam, BL::RenderSettings b_rend bcam->border.right = b_v3d.render_border_max_x(); bcam->border.bottom = b_v3d.render_border_min_y(); bcam->border.top = b_v3d.render_border_max_y(); - - return; } - } - else if(!b_render.use_border()) return; + } BL::Object b_ob = (b_v3d.lock_camera_and_layers())? b_scene.camera(): b_v3d.camera(); if(!b_ob) return; + /* Determine camera border inside the viewport. */ + BoundBox2D full_border; + blender_camera_border_subset(b_engine, + b_render, + b_scene, + b_v3d, + b_rv3d, + b_ob, + width, height, + full_border, + &bcam->viewport_camera_border); + + if(!b_render.use_border()) { + return; + } + bcam->border.left = b_render.border_min_x(); bcam->border.right = b_render.border_max_x(); bcam->border.bottom = b_render.border_min_y(); bcam->border.top = b_render.border_max_y(); - /* determine camera viewport subset */ - BoundBox2D view_box, cam_box; - - blender_camera_view_subset(b_render, b_scene, b_ob, b_v3d, b_rv3d, width, height, - &view_box, &cam_box); - - /* determine viewport subset matching camera border */ - cam_box = cam_box.make_relative_to(view_box); - bcam->border = cam_box.subset(bcam->border).clamp(); + /* Determine viewport subset matching camera border. */ + blender_camera_border_subset(b_engine, + b_render, + b_scene, + b_v3d, + b_rv3d, + b_ob, + width, height, + bcam->border, + &bcam->border); + bcam->border.clamp(); } void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height) { BlenderCamera bcam; - blender_camera_init(&bcam, b_scene.render(), b_scene); - blender_camera_from_view(&bcam, b_scene, b_v3d, b_rv3d, width, height); - blender_camera_border(&bcam, b_scene.render(), b_scene, b_v3d, b_rv3d, width, height); + blender_camera_init(&bcam, b_scene.render()); + blender_camera_from_view(&bcam, b_engine, b_scene, b_v3d, b_rv3d, width, height); + blender_camera_border(&bcam, b_engine, b_scene.render(), b_scene, b_v3d, b_rv3d, width, height); blender_camera_sync(scene->camera, &bcam, width, height); sync_view_nodes(b_rv3d); - scene->camera->use_camera_in_volume = experimental; } -BufferParams BlenderSync::get_buffer_params(BL::RenderSettings b_render, BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, Camera *cam, int width, int height) +BufferParams BlenderSync::get_buffer_params(BL::RenderSettings b_render, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, Camera *cam, int width, int height) { BufferParams params; bool use_border = false; @@ -581,10 +712,12 @@ BufferParams BlenderSync::get_buffer_params(BL::RenderSettings b_render, BL::Sce if(use_border) { /* border render */ - params.full_x = (int)(cam->border.left * (float)width); - params.full_y = (int)(cam->border.bottom * (float)height); - params.width = (int)(cam->border.right * (float)width) - params.full_x; - params.height = (int)(cam->border.top * (float)height) - params.full_y; + /* the viewport may offset the border outside the view */ + BoundBox2D border = cam->border.clamp(); + params.full_x = (int)(border.left * (float)width); + params.full_y = (int)(border.bottom * (float)height); + params.width = (int)(border.right * (float)width) - params.full_x; + params.height = (int)(border.top * (float)height) - params.full_y; /* survive in case border goes out of view or becomes too small */ params.width = max(params.width, 1); |