Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/cycles/blender/blender_camera.cpp192
-rw-r--r--intern/cycles/render/camera.cpp30
-rw-r--r--intern/cycles/render/camera.h5
-rw-r--r--intern/cycles/util/util_boundbox.h71
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__ */