diff --git a/intern/cycles/blender/camera.cpp b/intern/cycles/blender/camera.cpp index 3fcc893b1b1..d60e2b727a5 100644 --- a/intern/cycles/blender/camera.cpp +++ b/intern/cycles/blender/camera.cpp @@ -329,101 +329,63 @@ static Transform blender_camera_matrix(const Transform &tfm, static void blender_camera_viewplane(BlenderCamera *bcam, const int width, const int height, - BoundBox2D *viewplane, - float *aspectratio, - float *sensor_size) + BoundBox2D &viewplane, + float &aspectratio, + float &sensor_size) { /* dimensions */ const float xratio = (float)width * bcam->pixelaspect.x; const float yratio = (float)height * bcam->pixelaspect.y; /* compute x/y aspect and ratio */ - float xaspect; - float yaspect; + float2 aspect; bool horizontal_fit; /* sensor fitting */ if (bcam->sensor_fit == BlenderCamera::AUTO) { horizontal_fit = (xratio > yratio); - if (sensor_size != nullptr) { - *sensor_size = bcam->sensor_width; - } + sensor_size = bcam->sensor_width; } else if (bcam->sensor_fit == BlenderCamera::HORIZONTAL) { horizontal_fit = true; - if (sensor_size != nullptr) { - *sensor_size = bcam->sensor_width; - } + sensor_size = bcam->sensor_width; } else { horizontal_fit = false; - if (sensor_size != nullptr) { - *sensor_size = bcam->sensor_height; - } + sensor_size = bcam->sensor_height; } if (horizontal_fit) { - if (aspectratio != nullptr) { - *aspectratio = xratio / yratio; - } - xaspect = *aspectratio; - yaspect = 1.0f; + aspectratio = xratio / yratio; + aspect = make_float2(aspectratio, 1.0f); } else { - if (aspectratio != nullptr) { - *aspectratio = yratio / xratio; - } - xaspect = 1.0f; - yaspect = *aspectratio; + aspectratio = yratio / xratio; + aspect = make_float2(1.0f, aspectratio); } /* modify aspect for orthographic scale */ if (bcam->type == CAMERA_ORTHOGRAPHIC) { - xaspect = xaspect * bcam->ortho_scale / (*aspectratio * 2.0f); - yaspect = yaspect * bcam->ortho_scale / (*aspectratio * 2.0f); - if (aspectratio != nullptr) { - *aspectratio = bcam->ortho_scale / 2.0f; - } + aspect *= bcam->ortho_scale / (aspectratio * 2.0f); + aspectratio = bcam->ortho_scale / 2.0f; } if (bcam->type == CAMERA_PANORAMA || bcam->type == CAMERA_CUSTOM) { - /* Set viewplane for panoramic or custom camera. */ - if (viewplane != nullptr) { - *viewplane = bcam->pano_viewplane; - - /* Modify viewplane for camera shift. */ - const float shift_factor = (bcam->pano_aspectratio == 0.0f) ? - 1.0f : - *aspectratio / bcam->pano_aspectratio; - const float dx = bcam->shift.x * shift_factor; - const float dy = bcam->shift.y * shift_factor; - - viewplane->left += dx; - viewplane->right += dx; - viewplane->bottom += dy; - viewplane->top += dy; + /* Account for camera shift. */ + float2 dv = bcam->shift; + if (bcam->pano_aspectratio != 0.0f) { + dv *= aspectratio / bcam->pano_aspectratio; } + + /* Set viewplane for panoramic or custom camera. */ + viewplane = bcam->pano_viewplane.offset(dv); } else { - /* set viewplane */ - if (viewplane != nullptr) { - viewplane->left = -xaspect; - viewplane->right = xaspect; - viewplane->bottom = -yaspect; - viewplane->top = yaspect; + /* Account for camera shift and 3d camera view offset. */ + const float2 dv = 2.0f * (aspectratio * bcam->shift + bcam->offset * aspect * 2.0f); - /* zoom for 3d camera view */ - *viewplane = (*viewplane) * bcam->zoom; - - /* modify viewplane with camera shift and 3d camera view offset */ - const float dx = 2.0f * (*aspectratio * bcam->shift.x + bcam->offset.x * xaspect * 2.0f); - const 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; - } + /* Set viewplane for perspective or orthographic camera. */ + viewplane = (BoundBox2D(aspect) * bcam->zoom).offset(dv); } } @@ -516,7 +478,7 @@ static void blender_camera_sync(Camera *cam, /* viewplane */ BoundBox2D viewplane; - blender_camera_viewplane(bcam, width, height, &viewplane, &aspectratio, &sensor_size); + blender_camera_viewplane(bcam, width, height, viewplane, aspectratio, sensor_size); cam->set_viewplane_left(viewplane.left); cam->set_viewplane_right(viewplane.right); @@ -792,9 +754,11 @@ void BlenderSync::sync_camera_motion(BL::RenderSettings &b_render, bcam.pixelaspect.y = b_render.pixel_aspect_y(); blender_camera_from_object(&bcam, b_engine, b_ob, b_data); + + BoundBox2D viewplane; float aspectratio; float sensor_size; - blender_camera_viewplane(&bcam, width, height, nullptr, &aspectratio, &sensor_size); + blender_camera_viewplane(&bcam, width, height, viewplane, aspectratio, sensor_size); /* TODO(sergey): De-duplicate calculation with camera sync. */ const float fov = 2.0f * atanf((0.5f * sensor_size) / bcam.lens / aspectratio); if (fov != cam->get_fov()) { @@ -825,9 +789,9 @@ static void blender_camera_view_subset(BL::RenderEngine &b_engine, BL::RegionView3D &b_rv3d, const int width, const int height, - BoundBox2D *view_box, - BoundBox2D *cam_box, - float *view_aspect); + BoundBox2D &view_box, + BoundBox2D &cam_box, + float &view_aspect); static void blender_camera_from_view(BlenderCamera *bcam, BL::RenderEngine &b_engine, @@ -871,9 +835,9 @@ static void blender_camera_from_view(BlenderCamera *bcam, b_rv3d, width, height, - &view_box, - &cam_box, - &view_aspect); + view_box, + cam_box, + view_aspect); bcam->pano_viewplane = view_box.make_relative_to(cam_box); bcam->pano_aspectratio = view_aspect; @@ -926,9 +890,9 @@ static void blender_camera_view_subset(BL::RenderEngine &b_engine, BL::RegionView3D &b_rv3d, const int width, const int height, - BoundBox2D *view_box, - BoundBox2D *cam_box, - float *view_aspect) + BoundBox2D &view_box, + BoundBox2D &cam_box, + float &view_aspect) { BoundBox2D cam; BoundBox2D view; @@ -940,7 +904,7 @@ static void blender_camera_view_subset(BL::RenderEngine &b_engine, blender_camera_from_view( &view_bcam, b_engine, b_scene, b_data, b_v3d, b_rv3d, width, height, true); - blender_camera_viewplane(&view_bcam, width, height, &view, view_aspect, &sensor_size); + blender_camera_viewplane(&view_bcam, width, height, view, view_aspect, sensor_size); /* Get camera viewplane. */ BlenderCamera cam_bcam(b_render); @@ -951,11 +915,11 @@ static void blender_camera_view_subset(BL::RenderEngine &b_engine, cam_bcam.pixelaspect.y = b_render.pixel_aspect_y(); blender_camera_viewplane( - &cam_bcam, cam_bcam.full_width, cam_bcam.full_height, &cam, &cam_aspect, &sensor_size); + &cam_bcam, cam_bcam.full_width, cam_bcam.full_height, cam, cam_aspect, sensor_size); /* Return */ - *view_box = view * (1.0f / *view_aspect); - *cam_box = cam * (1.0f / cam_aspect); + view_box = view * (1.0f / view_aspect); + cam_box = cam * (1.0f / cam_aspect); } static void blender_camera_border_subset(BL::RenderEngine &b_engine, @@ -983,9 +947,9 @@ static void blender_camera_border_subset(BL::RenderEngine &b_engine, b_rv3d, width, height, - &view_box, - &cam_box, - &view_aspect); + view_box, + cam_box, + view_aspect); /* Determine viewport subset matching given border. */ cam_box = cam_box.make_relative_to(view_box); diff --git a/intern/cycles/scene/camera.cpp b/intern/cycles/scene/camera.cpp index 1f9e00a5f3e..50f13901c7a 100644 --- a/intern/cycles/scene/camera.cpp +++ b/intern/cycles/scene/camera.cpp @@ -196,24 +196,15 @@ Camera::~Camera() = default; void Camera::compute_auto_viewplane() { if (camera_type == CAMERA_PANORAMA || camera_type == CAMERA_CUSTOM) { - viewplane.left = 0.0f; - viewplane.right = 1.0f; - viewplane.bottom = 0.0f; - viewplane.top = 1.0f; + viewplane = BoundBox2D(); } else { const float aspect = (float)full_width / (float)full_height; if (full_width >= full_height) { - viewplane.left = -aspect; - viewplane.right = aspect; - viewplane.bottom = -1.0f; - viewplane.top = 1.0f; + viewplane = BoundBox2D(make_float2(aspect, 1.0f)); } else { - viewplane.left = -1.0f; - viewplane.right = 1.0f; - viewplane.bottom = -1.0f / aspect; - viewplane.top = 1.0f / aspect; + viewplane = BoundBox2D(make_float2(1.0f, 1.0f / aspect)); } } } diff --git a/intern/cycles/util/boundbox.h b/intern/cycles/util/boundbox.h index 2b5ec9e362d..c7c2b7de2d4 100644 --- a/intern/cycles/util/boundbox.h +++ b/intern/cycles/util/boundbox.h @@ -202,6 +202,11 @@ class BoundBox2D { BoundBox2D() = default; + BoundBox2D(const float2 radius) + : left(-radius.x), right(radius.x), bottom(-radius.y), top(radius.y) + { + } + bool operator==(const BoundBox2D &other) const { return (left == other.left && right == other.right && bottom == other.bottom && @@ -265,6 +270,18 @@ class BoundBox2D { return result; } + + BoundBox2D offset(const float2 offset) const + { + BoundBox2D result; + + result.left = left + offset.x; + result.right = right + offset.x; + result.bottom = bottom + offset.y; + result.top = top + offset.y; + + return result; + } }; CCL_NAMESPACE_END