diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-11-11 02:31:29 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-11-11 02:31:29 +0400 |
commit | 1ca4670267c3709d1c233264012882b4c0902748 (patch) | |
tree | 33e92ccad6818117431588274b3ec27952b753ba /intern | |
parent | 446f70f286154ca248dbdd25ecd68cdb9c6114d5 (diff) |
Cycles: panorama camera in viewport camera view now shows the render mapped
to the camera border rather than the entire viewport.
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/blender/blender_camera.cpp | 192 | ||||
-rw-r--r-- | intern/cycles/render/camera.cpp | 30 | ||||
-rw-r--r-- | intern/cycles/render/camera.h | 5 | ||||
-rw-r--r-- | intern/cycles/util/util_boundbox.h | 71 |
4 files changed, 178 insertions, 120 deletions
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp index af16e210301..61fe7cf254d 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -56,10 +56,8 @@ struct BlenderCamera { float sensor_width; float sensor_height; - float border_left; - float border_right; - float border_bottom; - float border_top; + BoundBox2D border; + BoundBox2D pano_viewplane; Transform matrix; }; @@ -75,8 +73,10 @@ static void blender_camera_init(BlenderCamera *bcam) bcam->sensor_height = 18.0f; bcam->sensor_fit = BlenderCamera::AUTO; bcam->shuttertime = 1.0f; - bcam->border_right = 1.0f; - bcam->border_top = 1.0f; + bcam->border.right = 1.0f; + bcam->border.top = 1.0f; + bcam->pano_viewplane.right = 1.0f; + bcam->pano_viewplane.top = 1.0f; } static float blender_camera_focal_distance(BL::Object b_ob, BL::Camera b_camera) @@ -199,7 +199,7 @@ static Transform blender_camera_matrix(const Transform& tfm, CameraType type) } static void blender_camera_viewplane(BlenderCamera *bcam, int width, int height, - float *left, float *right, float *bottom, float *top, float *aspectratio, float *sensor_size) + BoundBox2D *viewplane, float *aspectratio, float *sensor_size) { /* dimensions */ float xratio = width*bcam->pixelaspect.x; @@ -244,32 +244,26 @@ static void blender_camera_viewplane(BlenderCamera *bcam, int width, int height, if(bcam->type == CAMERA_PANORAMA) { /* set viewplane */ - *left = 0.0f; - *right = 1.0f; - *bottom = 0.0f; - *top = 1.0f; + *viewplane = bcam->pano_viewplane; } else { /* set viewplane */ - *left = -xaspect; - *right = xaspect; - *bottom = -yaspect; - *top = yaspect; + viewplane->left = -xaspect; + viewplane->right = xaspect; + viewplane->bottom = -yaspect; + viewplane->top = yaspect; /* zoom for 3d camera view */ - *left *= bcam->zoom; - *right *= bcam->zoom; - *bottom *= bcam->zoom; - *top *= bcam->zoom; + *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); - *left += dx; - *right += dx; - *bottom += dy; - *top += dy; + viewplane->left += dx; + viewplane->right += dx; + viewplane->bottom += dy; + viewplane->top += dy; } } @@ -281,7 +275,7 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int /* viewplane */ blender_camera_viewplane(bcam, width, height, - &cam->left, &cam->right, &cam->bottom, &cam->top, &aspectratio, &sensor_size); + &cam->viewplane, &aspectratio, &sensor_size); /* sensor */ cam->sensorwidth = bcam->sensor_width; @@ -314,10 +308,7 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int cam->shuttertime = bcam->shuttertime; /* border */ - cam->border_left = bcam->border_left; - cam->border_right = bcam->border_right; - cam->border_bottom = bcam->border_bottom; - cam->border_top = bcam->border_top; + cam->border = bcam->border; /* set update flag */ if(cam->modified(prevcam)) @@ -340,10 +331,10 @@ void BlenderSync::sync_camera(BL::Object b_override, int width, int height) /* border */ if(r.use_border()) { - bcam.border_left = r.border_min_x(); - bcam.border_right = r.border_max_x(); - bcam.border_bottom = r.border_min_y(); - bcam.border_top = r.border_max_y(); + bcam.border.left = r.border_min_x(); + bcam.border.right = r.border_max_x(); + bcam.border.bottom = r.border_min_y(); + bcam.border.top = r.border_max_y(); } /* camera object */ @@ -381,6 +372,9 @@ void BlenderSync::sync_camera_motion(BL::Object b_ob, int motion) /* Sync 3D View Camera */ +static void blender_camera_view_subset(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) { /* 3d view parameters */ @@ -396,14 +390,25 @@ static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL: if(b_ob) { blender_camera_from_object(bcam, b_ob, skip_panorama); - /* magic zoom formula */ - bcam->zoom = (float)b_rv3d.view_camera_zoom(); - bcam->zoom = (1.41421f + bcam->zoom/50.0f); - bcam->zoom *= bcam->zoom; - bcam->zoom = 2.0f/bcam->zoom; - - /* offset */ - bcam->offset = get_float2(b_rv3d.view_camera_offset()); + 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, b_ob, b_v3d, b_rv3d, width, height, + &view_box, &cam_box); + + bcam->pano_viewplane = view_box.make_relative_to(cam_box); + } + else { + /* magic zoom formula */ + bcam->zoom = (float)b_rv3d.view_camera_zoom(); + bcam->zoom = (1.41421f + bcam->zoom/50.0f); + bcam->zoom *= bcam->zoom; + bcam->zoom = 2.0f/bcam->zoom; + + /* offset */ + bcam->offset = get_float2(b_rv3d.view_camera_offset()); + } } } else if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_ORTHO) { @@ -427,6 +432,37 @@ 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::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) +{ + BL::RenderSettings r = b_scene.render(); + BoundBox2D cam, view; + float view_aspect, cam_aspect, sensor_size; + + /* get viewport viewplane */ + BlenderCamera view_bcam; + blender_camera_init(&view_bcam); + blender_camera_from_view(&view_bcam, 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); + blender_camera_from_object(&cam_bcam, b_ob, true); + + width = (int)(r.resolution_x()*r.resolution_percentage()/100); + height = (int)(r.resolution_y()*r.resolution_percentage()/100); + + blender_camera_viewplane(&cam_bcam, width, height, + &cam, &cam_aspect, &sensor_size); + + /* return */ + *view_box = view * (1.0f/view_aspect); + *cam_box = cam * (1.0f/cam_aspect); +} + static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height) { @@ -442,10 +478,10 @@ static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::Sp * assume viewport has got correctly clamped border already */ if(b_v3d.use_render_border()) { - bcam->border_left = b_v3d.render_border_min_x(); - 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(); + bcam->border.left = b_v3d.render_border_min_x(); + 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; } @@ -458,60 +494,20 @@ static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::Sp if(!b_ob) return; - bcam->border_left = r.border_min_x(); - bcam->border_right = r.border_max_x(); - bcam->border_bottom = r.border_min_y(); - bcam->border_top = r.border_max_y(); - - float cam_left, cam_right, cam_bottom, cam_top; - float view_left, view_right, view_bottom, view_top; - float view_aspect, cam_aspect, sensor_size; - - /* get viewport viewplane */ - BlenderCamera view_bcam; - blender_camera_init(&view_bcam); - blender_camera_from_view(&view_bcam, b_scene, b_v3d, b_rv3d, width, height, true); - - blender_camera_viewplane(&view_bcam, width, height, - &view_left, &view_right, &view_bottom, &view_top, &view_aspect, &sensor_size); - - view_left /= view_aspect; - view_right /= view_aspect; - view_bottom /= view_aspect; - view_top /= view_aspect; + bcam->border.left = r.border_min_x(); + bcam->border.right = r.border_max_x(); + bcam->border.bottom = r.border_min_y(); + bcam->border.top = r.border_max_y(); - /* get camera viewplane */ - BlenderCamera cam_bcam; - blender_camera_init(&cam_bcam); - blender_camera_from_object(&cam_bcam, b_ob, true); - - width = (int)(r.resolution_x()*r.resolution_percentage()/100); - height = (int)(r.resolution_y()*r.resolution_percentage()/100); - - blender_camera_viewplane(&cam_bcam, width, height, - &cam_left, &cam_right, &cam_bottom, &cam_top, &cam_aspect, &sensor_size); + /* determine camera viewport subset */ + BoundBox2D view_box, cam_box; - cam_left /= cam_aspect; - cam_right /= cam_aspect; - cam_bottom /= cam_aspect; - cam_top /= cam_aspect; + blender_camera_view_subset(b_scene, b_ob, b_v3d, b_rv3d, width, height, + &view_box, &cam_box); /* determine viewport subset matching camera border */ - float tmp_left = ((cam_left - view_left) / (view_right - view_left)); - float tmp_right = ((cam_right - view_left) / (view_right - view_left)); - float tmp_bottom = ((cam_bottom - view_bottom) / (view_top - view_bottom)); - float tmp_top = ((cam_top - view_bottom) / (view_top - view_bottom)); - - bcam->border_left = tmp_left + bcam->border_left*(tmp_right - tmp_left); - bcam->border_right = tmp_left + bcam->border_right*(tmp_right - tmp_left); - bcam->border_bottom = tmp_bottom + bcam->border_bottom*(tmp_top - tmp_bottom); - bcam->border_top = tmp_bottom + bcam->border_top*(tmp_top - tmp_bottom); - - /* clamp */ - bcam->border_left = clamp(bcam->border_left, 0.0f, 1.0f); - bcam->border_right = clamp(bcam->border_right, 0.0f, 1.0f); - bcam->border_bottom = clamp(bcam->border_bottom, 0.0f, 1.0f); - bcam->border_top = clamp(bcam->border_top, 0.0f, 1.0f); + cam_box = cam_box.make_relative_to(view_box); + bcam->border = cam_box.subset(bcam->border).clamp(); } void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height) @@ -539,10 +535,10 @@ BufferParams BlenderSync::get_buffer_params(BL::Scene b_scene, BL::SpaceView3D b if(use_border) { /* border render */ - params.full_x = cam->border_left*width; - params.full_y = cam->border_bottom*height; - params.width = (int)(cam->border_right*width) - params.full_x; - params.height = (int)(cam->border_top*height) - params.full_y; + params.full_x = cam->border.left*width; + params.full_y = cam->border.bottom*height; + params.width = (int)(cam->border.right*width) - params.full_x; + params.height = (int)(cam->border.top*height) - params.full_y; /* survive in case border goes out of view or becomes too small */ params.width = max(params.width, 1); diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index 649936bec04..308ebd0794a 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -55,15 +55,10 @@ Camera::Camera() width = 1024; height = 512; - left = -((float)width/(float)height); - right = (float)width/(float)height; - bottom = -1.0f; - top = 1.0f; - - border_left = 0.0f; - border_right = 1.0f; - border_bottom = 0.0f; - border_top = 1.0f; + viewplane.left = -((float)width/(float)height); + viewplane.right = (float)width/(float)height; + viewplane.bottom = -1.0f; + viewplane.top = 1.0f; screentoworld = transform_identity(); rastertoworld = transform_identity(); @@ -95,10 +90,11 @@ void Camera::update() /* raster to screen */ Transform screentoraster = ndctoraster; - + screentoraster = ndctoraster * - transform_scale(1.0f/(right - left), 1.0f/(top - bottom), 1.0f) * - transform_translate(-left, -bottom, 0.0f); + transform_scale(1.0f/(viewplane.right - viewplane.left), + 1.0f/(viewplane.top - viewplane.bottom), 1.0f) * + transform_translate(-viewplane.left, -viewplane.bottom, 0.0f); Transform rastertoscreen = transform_inverse(screentoraster); @@ -265,14 +261,8 @@ bool Camera::modified(const Camera& cam) // modified for progressive render // (width == cam.width) && // (height == cam.height) && - (left == cam.left) && - (right == cam.right) && - (bottom == cam.bottom) && - (top == cam.top) && - (border_left == cam.border_left) && - (border_right == cam.border_right) && - (border_bottom == cam.border_bottom) && - (border_top == cam.border_top) && + (viewplane == cam.viewplane) && + (border == cam.border) && (matrix == cam.matrix) && (panorama_type == cam.panorama_type) && (fisheye_fov == cam.fisheye_fov) && diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h index 1407c86e7c2..4c2de7b50b8 100644 --- a/intern/cycles/render/camera.h +++ b/intern/cycles/render/camera.h @@ -21,6 +21,7 @@ #include "kernel_types.h" +#include "util_boundbox.h" #include "util_transform.h" #include "util_types.h" @@ -65,10 +66,10 @@ public: /* screen */ int width, height; - float left, right, bottom, top; + BoundBox2D viewplane; /* border */ - float border_left, border_right, border_bottom, border_top; + BoundBox2D border; /* transformation */ Transform matrix; diff --git a/intern/cycles/util/util_boundbox.h b/intern/cycles/util/util_boundbox.h index b35c4c12bb8..a0cdf1761ad 100644 --- a/intern/cycles/util/util_boundbox.h +++ b/intern/cycles/util/util_boundbox.h @@ -31,6 +31,8 @@ using namespace std; CCL_NAMESPACE_BEGIN +/* 3D BoundBox */ + class BoundBox { public: @@ -160,6 +162,75 @@ __forceinline BoundBox intersect(const BoundBox& a, const BoundBox& b, const Bou return intersect(a, intersect(b, c)); } +/* 2D BoundBox */ + +class BoundBox2D { +public: + float left; + float right; + float bottom; + float top; + + BoundBox2D() + : left(0.0f), right(1.0f), bottom(0.0f), top(1.0f) + { + } + + bool operator==(const BoundBox2D& other) const + { + return (left == other.left && right == other.right && + bottom == other.bottom && top == other.top); + } + + BoundBox2D operator*(float f) const + { + BoundBox2D result; + + result.left = left*f; + result.right = right*f; + result.bottom = bottom*f; + result.top = top*f; + + return result; + } + + BoundBox2D subset(const BoundBox2D& other) const + { + BoundBox2D subset; + + subset.left = left + other.left*(right - left); + subset.right = left + other.right*(right - left); + subset.bottom = bottom + other.bottom*(top - bottom); + subset.top = bottom + other.top*(top - bottom); + + return subset; + } + + BoundBox2D make_relative_to(const BoundBox2D& other) const + { + BoundBox2D result; + + result.left = ((left - other.left) / (other.right - other.left)); + result.right = ((right - other.left) / (other.right - other.left)); + result.bottom = ((bottom - other.bottom) / (other.top - other.bottom)); + result.top = ((top - other.bottom) / (other.top - other.bottom)); + + return result; + } + + BoundBox2D clamp(float mn = 0.0f, float mx = 1.0f) + { + BoundBox2D result; + + result.left = ccl::clamp(left, mn, mx); + result.right = ccl::clamp(right, mn, mx); + result.bottom = ccl::clamp(bottom, mn, mx); + result.top = ccl::clamp(top, mn, mx); + + return result; + } +}; + CCL_NAMESPACE_END #endif /* __UTIL_BOUNDBOX_H__ */ |