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.cpp102
-rw-r--r--intern/cycles/blender/blender_object.cpp17
-rw-r--r--intern/cycles/blender/blender_session.cpp28
-rw-r--r--intern/cycles/blender/blender_sync.cpp13
-rw-r--r--intern/cycles/blender/blender_sync.h18
-rw-r--r--intern/cycles/kernel/kernel_camera.h25
-rw-r--r--intern/cycles/kernel/kernel_types.h8
-rw-r--r--intern/cycles/render/camera.cpp24
-rw-r--r--intern/cycles/render/camera.h4
-rw-r--r--intern/cycles/util/util_transform.h5
10 files changed, 202 insertions, 42 deletions
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index 90b42ea4ec2..18e9aa8bc17 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -244,8 +244,11 @@ static Transform blender_camera_matrix(const Transform& tfm,
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;
@@ -258,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;
}
@@ -284,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;
+ }
}
}
@@ -386,7 +405,10 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
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;
@@ -435,7 +457,10 @@ void BlenderSync::sync_camera(BL::RenderSettings b_render, BL::Object b_override
blender_camera_sync(cam, &bcam, width, height);
}
-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;
BL::Array<float, 16> b_ob_matrix;
@@ -454,6 +479,31 @@ 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 */
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 35ba450be41..432c4aaa078 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -659,7 +659,11 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time)
mesh_motion_synced.clear();
}
-void BlenderSync::sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override, void **python_thread_state)
+void BlenderSync::sync_motion(BL::RenderSettings b_render,
+ BL::SpaceView3D b_v3d,
+ BL::Object b_override,
+ int width, int height,
+ void **python_thread_state)
{
if(scene->need_motion() == Scene::MOTION_NONE)
return;
@@ -679,6 +683,9 @@ void BlenderSync::sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override, void
/* note iteration over motion_times set happens in sorted order */
foreach(float relative_time, motion_times) {
+ VLOG(1) << "Synchronizing motion for the relative time "
+ << relative_time << ".";
+
/* fixed shutter time to get previous and next frame for motion pass */
float shuttertime;
@@ -698,8 +705,12 @@ void BlenderSync::sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override, void
python_thread_state_save(python_thread_state);
/* sync camera, only supports two times at the moment */
- if(relative_time == -1.0f || relative_time == 1.0f)
- sync_camera_motion(b_cam, relative_time);
+ if(relative_time == -1.0f || relative_time == 1.0f) {
+ sync_camera_motion(b_render,
+ b_cam,
+ width, height,
+ relative_time);
+ }
/* sync object */
sync_objects(b_v3d, relative_time);
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index e1d5e1310d5..8903801d38d 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -122,7 +122,12 @@ void BlenderSession::create_session()
if(session_pause == false) {
/* full data sync */
sync->sync_view(b_v3d, b_rv3d, width, height);
- sync->sync_data(b_v3d, b_engine.camera_override(), &python_thread_state);
+ sync->sync_data(b_render,
+ b_v3d,
+ b_engine.camera_override(),
+ width, height,
+ &python_thread_state,
+ b_rlay_name.c_str());
}
}
else {
@@ -477,7 +482,12 @@ void BlenderSession::render()
/* update scene */
sync->sync_camera(b_render, b_engine.camera_override(), width, height);
- sync->sync_data(b_v3d, b_engine.camera_override(), &python_thread_state, b_rlay_name.c_str());
+ sync->sync_data(b_render,
+ b_v3d,
+ b_engine.camera_override(),
+ width, height,
+ &python_thread_state,
+ b_rlay_name.c_str());
/* update number of samples per layer */
int samples = sync->get_layer_samples();
@@ -570,7 +580,12 @@ void BlenderSession::bake(BL::Object b_object, const string& pass_type, const in
/* update scene */
sync->sync_camera(b_render, b_engine.camera_override(), width, height);
- sync->sync_data(b_v3d, b_engine.camera_override(), &python_thread_state);
+ sync->sync_data(b_render,
+ b_v3d,
+ b_engine.camera_override(),
+ width, height,
+ &python_thread_state,
+ b_rlay_name.c_str());
/* get buffer parameters */
SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
@@ -712,7 +727,12 @@ void BlenderSession::synchronize()
}
/* data and camera synchronize */
- sync->sync_data(b_v3d, b_engine.camera_override(), &python_thread_state);
+ sync->sync_data(b_render,
+ b_v3d,
+ b_engine.camera_override(),
+ width, height,
+ &python_thread_state,
+ b_rlay_name.c_str());
if(b_rv3d)
sync->sync_view(b_v3d, b_rv3d, width, height);
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index c5fb7925306..8888d219aac 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -145,7 +145,12 @@ bool BlenderSync::sync_recalc()
return recalc;
}
-void BlenderSync::sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, void **python_thread_state, const char *layer)
+void BlenderSync::sync_data(BL::RenderSettings b_render,
+ BL::SpaceView3D b_v3d,
+ BL::Object b_override,
+ int width, int height,
+ void **python_thread_state,
+ const char *layer)
{
sync_render_layers(b_v3d, layer);
sync_integrator();
@@ -157,7 +162,11 @@ void BlenderSync::sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, void *
mesh_synced.clear(); /* use for objects and motion sync */
sync_objects(b_v3d);
- sync_motion(b_v3d, b_override, python_thread_state);
+ sync_motion(b_render,
+ b_v3d,
+ b_override,
+ width, height,
+ python_thread_state);
mesh_synced.clear();
}
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index b8bd14c0f71..efc6ae94542 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -53,7 +53,12 @@ public:
/* sync */
bool sync_recalc();
- void sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, void **python_thread_state, const char *layer = 0);
+ void sync_data(BL::RenderSettings b_render,
+ BL::SpaceView3D b_v3d,
+ BL::Object b_override,
+ int width, int height,
+ void **python_thread_state,
+ const char *layer = 0);
void sync_render_layers(BL::SpaceView3D b_v3d, const char *layer);
void sync_integrator();
void sync_camera(BL::RenderSettings b_render, BL::Object b_override, int width, int height);
@@ -75,7 +80,11 @@ private:
void sync_lamps(bool update_all);
void sync_materials(bool update_all);
void sync_objects(BL::SpaceView3D b_v3d, float motion_time = 0.0f);
- void sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override, void **python_thread_state);
+ void sync_motion(BL::RenderSettings b_render,
+ BL::SpaceView3D b_v3d,
+ BL::Object b_override,
+ int width, int height,
+ void **python_thread_state);
void sync_film();
void sync_view();
void sync_world(bool update_all);
@@ -98,7 +107,10 @@ private:
void sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::Object b_ob, Transform& tfm, bool *use_portal);
void sync_background_light(bool use_portal);
void sync_mesh_motion(BL::Object b_ob, Object *object, float motion_time);
- void sync_camera_motion(BL::Object b_ob, float motion_time);
+ void sync_camera_motion(BL::RenderSettings b_render,
+ BL::Object b_ob,
+ int width, int height,
+ float motion_time);
/* particles */
bool sync_dupli_particle(BL::Object b_ob, BL::DupliObject b_dup, Object *object);
diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h
index 3ce5134181a..67651f96544 100644
--- a/intern/cycles/kernel/kernel_camera.h
+++ b/intern/cycles/kernel/kernel_camera.h
@@ -43,7 +43,30 @@ ccl_device void camera_sample_perspective(KernelGlobals *kg, float raster_x, flo
{
/* create ray form raster position */
Transform rastertocamera = kernel_data.cam.rastertocamera;
- float3 Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f));
+ float3 raster = make_float3(raster_x, raster_y, 0.0f);
+ float3 Pcamera = transform_perspective(&rastertocamera, raster);
+
+#ifdef __CAMERA_MOTION__
+ if(kernel_data.cam.have_perspective_motion) {
+ /* TODO(sergey): Currently we interpolate projected coordinate which
+ * gives nice looking result and which is simple, but is in fact a bit
+ * different comparing to constructing projective matrix from an
+ * interpolated field of view.
+ */
+ if(ray->time < 0.5f) {
+ Transform rastertocamera_pre = kernel_data.cam.perspective_motion.pre;
+ float3 Pcamera_pre =
+ transform_perspective(&rastertocamera_pre, raster);
+ Pcamera = interp(Pcamera_pre, Pcamera, ray->time * 2.0f);
+ }
+ else {
+ Transform rastertocamera_post = kernel_data.cam.perspective_motion.post;
+ float3 Pcamera_post =
+ transform_perspective(&rastertocamera_post, raster);
+ Pcamera = interp(Pcamera, Pcamera_post, (ray->time - 0.5f) * 2.0f);
+ }
+ }
+#endif
ray->P = make_float3(0.0f, 0.0f, 0.0f);
ray->D = Pcamera;
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 46e5d6b2a31..ba8cba1dc83 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -778,7 +778,7 @@ typedef struct KernelCamera {
/* motion blur */
float shuttertime;
- int have_motion;
+ int have_motion, have_perspective_motion;
/* clipping */
float nearclip;
@@ -796,7 +796,6 @@ typedef struct KernelCamera {
float inv_aperture_ratio;
int is_inside_volume;
- int pad2;
/* more matrices */
Transform screentoworld;
@@ -810,6 +809,11 @@ typedef struct KernelCamera {
Transform worldtocamera;
MotionTransform motion;
+
+ /* Denotes changes in the projective matrix, namely in rastertocamera.
+ * Used for camera zoom motion blur,
+ */
+ PerspectiveMotionTransform perspective_motion;
} KernelCamera;
typedef struct KernelFilm {
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index 89505221862..df2a1d348d6 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -40,6 +40,7 @@ Camera::Camera()
motion.pre = transform_identity();
motion.post = transform_identity();
use_motion = false;
+ use_perspective_motion = false;
aperture_ratio = 1.0f;
@@ -170,6 +171,23 @@ void Camera::update()
dx = transform_direction(&cameratoworld, dx);
dy = transform_direction(&cameratoworld, dy);
+ /* TODO(sergey): Support other types of camera. */
+ if(type == CAMERA_PERSPECTIVE) {
+ /* TODO(sergey): Move to an utility function and de-duplicate with
+ * calculation above.
+ */
+ Transform screentocamera_pre =
+ transform_inverse(transform_perspective(fov_pre,
+ nearclip,
+ farclip));
+ Transform screentocamera_post =
+ transform_inverse(transform_perspective(fov_post,
+ nearclip,
+ farclip));
+ perspective_motion.pre = screentocamera_pre * rastertoscreen;
+ perspective_motion.post = screentocamera_post * rastertoscreen;
+ }
+
need_update = false;
need_device_update = true;
need_flags_update = true;
@@ -205,8 +223,10 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
/* camera motion */
kcam->have_motion = 0;
+ kcam->have_perspective_motion = 0;
if(need_motion == Scene::MOTION_PASS) {
+ /* TODO(sergey): Support perspective (zoom, fov) motion. */
if(type == CAMERA_PANORAMA) {
if(use_motion) {
kcam->motion.pre = transform_inverse(motion.pre);
@@ -234,6 +254,10 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
transform_motion_decompose((DecompMotionTransform*)&kcam->motion, &motion, &matrix);
kcam->have_motion = 1;
}
+ if(use_perspective_motion) {
+ kcam->perspective_motion = perspective_motion;
+ kcam->have_perspective_motion = 1;
+ }
}
#endif
diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h
index 3efbe904e2f..1bedb051112 100644
--- a/intern/cycles/render/camera.h
+++ b/intern/cycles/render/camera.h
@@ -83,7 +83,9 @@ public:
/* motion */
MotionTransform motion;
- bool use_motion;
+ bool use_motion, use_perspective_motion;
+ float fov_pre, fov_post;
+ PerspectiveMotionTransform perspective_motion;
/* computed camera parameters */
Transform screentoworld;
diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h
index 0b87db0a379..ba8d04b5c16 100644
--- a/intern/cycles/util/util_transform.h
+++ b/intern/cycles/util/util_transform.h
@@ -55,6 +55,11 @@ typedef struct DecompMotionTransform {
float4 post_x, post_y;
} DecompMotionTransform;
+typedef struct PerspectiveMotionTransform {
+ Transform pre;
+ Transform post;
+} PerspectiveMotionTransform;
+
/* Functions */
ccl_device_inline float3 transform_perspective(const Transform *t, const float3 a)