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/app/cycles_xml.cpp4
-rw-r--r--intern/cycles/blender/addon/__init__.py1
-rw-r--r--intern/cycles/blender/blender_camera.cpp45
-rw-r--r--intern/cycles/blender/blender_session.cpp9
-rw-r--r--intern/cycles/blender/blender_sync.h3
-rw-r--r--intern/cycles/kernel/kernel_camera.h56
-rw-r--r--intern/cycles/kernel/kernel_projection.h26
-rw-r--r--intern/cycles/kernel/kernel_types.h5
-rw-r--r--intern/cycles/render/camera.cpp48
-rw-r--r--intern/cycles/render/camera.h13
-rw-r--r--release/scripts/startup/bl_ui/properties_data_camera.py14
-rw-r--r--source/blender/blenkernel/BKE_camera.h1
-rw-r--r--source/blender/blenkernel/BKE_scene.h1
-rw-r--r--source/blender/blenkernel/intern/camera.c23
-rw-r--r--source/blender/blenkernel/intern/scene.c6
-rw-r--r--source/blender/makesdna/DNA_camera_types.h8
-rw-r--r--source/blender/makesrna/intern/rna_camera.c7
-rw-r--r--source/blender/makesrna/intern/rna_render.c16
-rw-r--r--source/blender/makesrna/intern/rna_scene.c11
-rw-r--r--source/blender/render/extern/include/RE_engine.h7
-rw-r--r--source/blender/render/intern/source/external_engine.c26
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c6
22 files changed, 289 insertions, 47 deletions
diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp
index dd1dae121b1..a8f90c7e6d4 100644
--- a/intern/cycles/app/cycles_xml.cpp
+++ b/intern/cycles/app/cycles_xml.cpp
@@ -359,6 +359,10 @@ static void xml_read_camera(const XMLReadState& state, pugi::xml_node node)
xml_read_float(&cam->fisheye_fov, node, "fisheye_fov");
xml_read_float(&cam->fisheye_lens, node, "fisheye_lens");
+ xml_read_float(&cam->use_spherical_stereo, node, "use_spherical_stereo");
+ xml_read_float(&cam->interocular_distance, node, "interocular_distance");
+ xml_read_float(&cam->convergence_distance, node, "convergence_distance");
+
xml_read_float(&cam->sensorwidth, node, "sensorwidth");
xml_read_float(&cam->sensorheight, node, "sensorheight");
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py
index 150b4e75581..29388317873 100644
--- a/intern/cycles/blender/addon/__init__.py
+++ b/intern/cycles/blender/addon/__init__.py
@@ -43,6 +43,7 @@ class CyclesRender(bpy.types.RenderEngine):
bl_use_preview = True
bl_use_exclude_layers = True
bl_use_save_buffers = True
+ bl_use_spherical_stereo = True
def __init__(self):
self.session = None
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index cdbee52bfa9..2a7c1d3d943 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -62,6 +62,9 @@ struct BlenderCamera {
float latitude_max;
float longitude_min;
float longitude_max;
+ bool use_spherical_stereo;
+ float interocular_distance;
+ float convergence_distance;
enum { AUTO, HORIZONTAL, VERTICAL } sensor_fit;
float sensor_width;
@@ -110,7 +113,8 @@ static void blender_camera_init(BlenderCamera *bcam,
static float blender_camera_focal_distance(BL::RenderEngine& b_engine,
BL::Object& b_ob,
- BL::Camera& b_camera)
+ BL::Camera& b_camera,
+ BlenderCamera *bcam)
{
BL::Object b_dof_object = b_camera.dof_object();
@@ -119,8 +123,8 @@ static float blender_camera_focal_distance(BL::RenderEngine& b_engine,
/* for dof object, return distance along camera Z direction */
BL::Array<float, 16> b_ob_matrix;
- b_engine.camera_model_matrix(b_ob, b_ob_matrix);
- Transform obmat = get_transform(b_ob_matrix);
+ b_engine.camera_model_matrix(b_ob, bcam->use_spherical_stereo, b_ob_matrix);
+ Transform obmat = transform_clear_scale(get_transform(b_ob_matrix));
Transform dofmat = get_transform(b_dof_object.matrix_world());
float3 view_dir = normalize(transform_get_column(&obmat, 2));
float3 dof_dir = transform_get_column(&obmat, 3) - transform_get_column(&dofmat, 3);
@@ -170,6 +174,10 @@ static void blender_camera_from_object(BlenderCamera *bcam,
bcam->longitude_min = RNA_float_get(&ccamera, "longitude_min");
bcam->longitude_max = RNA_float_get(&ccamera, "longitude_max");
+ bcam->interocular_distance = b_camera.stereo().interocular_distance();
+ bcam->convergence_distance = b_camera.stereo().convergence_distance();
+ bcam->use_spherical_stereo = b_engine.use_spherical_stereo(b_ob);
+
bcam->ortho_scale = b_camera.ortho_scale();
bcam->lens = b_camera.lens();
@@ -192,10 +200,10 @@ static void blender_camera_from_object(BlenderCamera *bcam,
bcam->apertureblades = RNA_int_get(&ccamera, "aperture_blades");
bcam->aperturerotation = RNA_float_get(&ccamera, "aperture_rotation");
- bcam->focaldistance = blender_camera_focal_distance(b_engine, b_ob, b_camera);
+ bcam->focaldistance = blender_camera_focal_distance(b_engine, b_ob, b_camera, bcam);
bcam->aperture_ratio = RNA_float_get(&ccamera, "aperture_ratio");
- bcam->shift.x = b_engine.camera_shift_x(b_ob);
+ bcam->shift.x = b_engine.camera_shift_x(b_ob, bcam->use_spherical_stereo);
bcam->shift.y = b_camera.shift_y();
bcam->sensor_width = b_camera.sensor_width();
@@ -337,7 +345,7 @@ static void blender_camera_viewplane(BlenderCamera *bcam,
}
}
-static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int height)
+static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int height, const char *viewname)
{
/* copy camera to compare later */
Camera prevcam = *cam;
@@ -394,6 +402,20 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
cam->longitude_min = bcam->longitude_min;
cam->longitude_max = bcam->longitude_max;
+ /* panorama stereo */
+ cam->interocular_distance = bcam->interocular_distance;
+ cam->convergence_distance = bcam->convergence_distance;
+ cam->use_spherical_stereo = bcam->use_spherical_stereo;
+
+ if(cam->use_spherical_stereo) {
+ if(strcmp(viewname, "left") == 0)
+ cam->stereo_eye = Camera::STEREO_LEFT;
+ else if(strcmp(viewname, "right") == 0)
+ cam->stereo_eye = Camera::STEREO_RIGHT;
+ else
+ cam->stereo_eye = Camera::STEREO_NONE;
+ }
+
/* anamorphic lens bokeh */
cam->aperture_ratio = bcam->aperture_ratio;
@@ -435,7 +457,8 @@ 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)
+ int width, int height,
+ const char *viewname)
{
BlenderCamera bcam;
blender_camera_init(&bcam, b_render);
@@ -478,13 +501,13 @@ void BlenderSync::sync_camera(BL::RenderSettings& b_render,
if(b_ob) {
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);
+ b_engine.camera_model_matrix(b_ob, bcam.use_spherical_stereo, b_ob_matrix);
bcam.matrix = get_transform(b_ob_matrix);
}
/* sync */
Camera *cam = scene->camera;
- blender_camera_sync(cam, &bcam, width, height);
+ blender_camera_sync(cam, &bcam, width, height, viewname);
}
void BlenderSync::sync_camera_motion(BL::RenderSettings& b_render,
@@ -497,7 +520,7 @@ void BlenderSync::sync_camera_motion(BL::RenderSettings& b_render,
Camera *cam = scene->camera;
BL::Array<float, 16> b_ob_matrix;
- b_engine.camera_model_matrix(b_ob, b_ob_matrix);
+ b_engine.camera_model_matrix(b_ob, cam->use_spherical_stereo, b_ob_matrix);
Transform tfm = get_transform(b_ob_matrix);
tfm = blender_camera_matrix(tfm, cam->type, cam->panorama_type);
@@ -766,7 +789,7 @@ void BlenderSync::sync_view(BL::SpaceView3D& b_v3d,
b_v3d,
b_rv3d,
width, height);
- blender_camera_sync(scene->camera, &bcam, width, height);
+ blender_camera_sync(scene->camera, &bcam, width, height, "");
}
BufferParams BlenderSync::get_buffer_params(BL::RenderSettings& b_render,
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index f1b524f7b44..1f85feb0b7d 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -153,7 +153,6 @@ void BlenderSession::create_session()
* do some basic syncing here, no objects or materials for speed */
sync->sync_render_layers(b_v3d, NULL);
sync->sync_integrator();
- sync->sync_camera(b_render, b_camera_override, width, height);
}
/* set buffer parameters */
@@ -206,10 +205,8 @@ void BlenderSession::reset_session(BL::BlendData& b_data_, BL::Scene& b_scene_)
/* for final render we will do full data sync per render layer, only
* do some basic syncing here, no objects or materials for speed */
- BL::Object b_camera_override(b_engine.camera_override());
sync->sync_render_layers(b_v3d, NULL);
sync->sync_integrator();
- sync->sync_camera(b_render, b_camera_override, width, height);
BL::SpaceView3D b_null_space_view3d(PointerRNA_NULL);
BL::RegionView3D b_null_region_view3d(PointerRNA_NULL);
@@ -502,7 +499,7 @@ void BlenderSession::render()
/* update scene */
BL::Object b_camera_override(b_engine.camera_override());
- sync->sync_camera(b_render, b_camera_override, width, height);
+ sync->sync_camera(b_render, b_camera_override, width, height, b_rview_name.c_str());
sync->sync_data(b_render,
b_v3d,
b_camera_override,
@@ -642,7 +639,7 @@ void BlenderSession::bake(BL::Object& b_object,
/* update scene */
BL::Object b_camera_override(b_engine.camera_override());
- sync->sync_camera(b_render, b_camera_override, width, height);
+ sync->sync_camera(b_render, b_camera_override, width, height, "");
sync->sync_data(b_render,
b_v3d,
b_camera_override,
@@ -808,7 +805,7 @@ void BlenderSession::synchronize()
if(b_rv3d)
sync->sync_view(b_v3d, b_rv3d, width, height);
else
- sync->sync_camera(b_render, b_camera_override, width, height);
+ sync->sync_camera(b_render, b_camera_override, width, height, "");
/* unlock */
session->scene->mutex.unlock();
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index d3edfcb657f..92250ffeefc 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -69,7 +69,8 @@ public:
void sync_integrator();
void sync_camera(BL::RenderSettings& b_render,
BL::Object& b_override,
- int width, int height);
+ int width, int height,
+ const char *viewname);
void sync_view(BL::SpaceView3D& b_v3d,
BL::RegionView3D& b_rv3d,
int width, int height);
diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h
index fd1d854a0ff..0947946e63d 100644
--- a/intern/cycles/kernel/kernel_camera.h
+++ b/intern/cycles/kernel/kernel_camera.h
@@ -105,18 +105,32 @@ ccl_device void camera_sample_perspective(KernelGlobals *kg, float raster_x, flo
}
#endif
- ray->P = transform_point(&cameratoworld, ray->P);
- ray->D = transform_direction(&cameratoworld, ray->D);
+ float3 tP = transform_point(&cameratoworld, ray->P);
+ float3 tD = transform_direction(&cameratoworld, ray->D);
+ ray->P = spherical_stereo_position(kg, tD, tP);
+ ray->D = spherical_stereo_direction(kg, tD, tP, ray->P);
ray->D = normalize(ray->D);
#ifdef __RAY_DIFFERENTIALS__
/* ray differential */
- float3 Ddiff = transform_direction(&cameratoworld, Pcamera);
-
ray->dP = differential3_zero();
- ray->dD.dx = normalize(Ddiff + float4_to_float3(kernel_data.cam.dx)) - normalize(Ddiff);
- ray->dD.dy = normalize(Ddiff + float4_to_float3(kernel_data.cam.dy)) - normalize(Ddiff);
+ tP = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f));
+ tD = transform_direction(&cameratoworld, tP);
+ float3 Pdiff = spherical_stereo_position(kg, tD, tP);
+ float3 Ddiff = normalize(spherical_stereo_direction(kg, tD, tP, Pdiff));
+
+ tP = transform_perspective(&rastertocamera, make_float3(raster_x + 1.0f, raster_y, 0.0f));
+ tD = transform_direction(&cameratoworld, tP);
+ Pcamera = spherical_stereo_position(kg, tD, tP);
+ ray->dD.dx = normalize(spherical_stereo_direction(kg, tD, tP, Pcamera)) - Ddiff;
+ ray->dP.dx = Pcamera - Pdiff;
+
+ tP = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y + 1.0f, 0.0f));
+ tD = transform_direction(&cameratoworld, tP);
+ Pcamera = spherical_stereo_position(kg, tD, tP);
+ ray->dD.dy = normalize(spherical_stereo_direction(kg, tD, tP, Pcamera)) - Ddiff;
+ /* dP.dy is zero, since the omnidirectional panorama only shift the eyes horizontally */
#endif
#ifdef __CAMERA_CLIPPING__
@@ -259,22 +273,32 @@ ccl_device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float
}
#endif
- ray->P = transform_point(&cameratoworld, ray->P);
- ray->D = transform_direction(&cameratoworld, ray->D);
+ float3 tP = transform_point(&cameratoworld, ray->P);
+ float3 tD = transform_direction(&cameratoworld, ray->D);
+ ray->P = spherical_stereo_position(kg, tD, tP);
+ ray->D = spherical_stereo_direction(kg, tD, tP, ray->P);
ray->D = normalize(ray->D);
#ifdef __RAY_DIFFERENTIALS__
/* ray differential */
ray->dP = differential3_zero();
- Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f));
- float3 Ddiff = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y)));
-
- Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x + 1.0f, raster_y, 0.0f));
- ray->dD.dx = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))) - Ddiff;
-
- Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y + 1.0f, 0.0f));
- ray->dD.dy = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))) - Ddiff;
+ tP = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f));
+ tD = transform_direction(&cameratoworld, panorama_to_direction(kg, tP.x, tP.y));
+ float3 Pdiff = spherical_stereo_position(kg, tD, tP);
+ float3 Ddiff = normalize(spherical_stereo_direction(kg, tD, tP, Pdiff));
+
+ tP = transform_perspective(&rastertocamera, make_float3(raster_x + 1.0f, raster_y, 0.0f));
+ tD = transform_direction(&cameratoworld, panorama_to_direction(kg, tP.x, tP.y));
+ Pcamera = spherical_stereo_position(kg, tD, tP);
+ ray->dD.dx = normalize(spherical_stereo_direction(kg, tD, tP, Pcamera)) - Ddiff;
+ ray->dP.dx = Pcamera - Pdiff;
+
+ tP = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y + 1.0f, 0.0f));
+ tD = transform_direction(&cameratoworld, panorama_to_direction(kg, tP.x, tP.y));
+ Pcamera = spherical_stereo_position(kg, tD, tP);
+ ray->dD.dy = normalize(spherical_stereo_direction(kg, tD, tP, Pcamera)) - Ddiff;
+ /* dP.dy is zero, since the omnidirectional panorama only shift the eyes horizontally */
#endif
}
diff --git a/intern/cycles/kernel/kernel_projection.h b/intern/cycles/kernel/kernel_projection.h
index 62922df3286..fa06b937e61 100644
--- a/intern/cycles/kernel/kernel_projection.h
+++ b/intern/cycles/kernel/kernel_projection.h
@@ -222,6 +222,32 @@ ccl_device float2 direction_to_panorama(KernelGlobals *kg, float3 dir)
}
}
+ccl_device float3 spherical_stereo_position(KernelGlobals *kg, float3 dir, float3 pos)
+{
+ float3 up, side;
+
+ /* Interocular_offset of zero means either non stereo, or stereo without spherical stereo. */
+
+ up = make_float3(0.0f, 0.0f, 1.0f);
+ side = normalize(cross(dir, up));
+
+ return pos + (side * kernel_data.cam.interocular_offset);
+}
+
+ccl_device float3 spherical_stereo_direction(KernelGlobals *kg, float3 dir, float3 pos, float3 newpos)
+{
+ float3 screenpos, dirnew;
+
+ /* Interocular_distance of zero means either no stereo, or stereo without spherical stereo. */
+ if(kernel_data.cam.interocular_offset == 0.0f)
+ return dir;
+
+ screenpos = pos + (normalize(dir) * kernel_data.cam.convergence_distance);
+ dirnew = screenpos - newpos;
+
+ return dirnew;
+}
+
CCL_NAMESPACE_END
#endif /* __KERNEL_PROJECTION_CL__ */
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index bdd17c66c0f..c5edc16f196 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -901,6 +901,11 @@ typedef struct KernelCamera {
float fisheye_lens;
float4 equirectangular_range;
+ /* stereo */
+ int pad1, pad2;
+ float interocular_offset;
+ float convergence_distance;
+
/* matrices */
Transform cameratoworld;
Transform rastertocamera;
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index 9c17a11e0f1..0e343822223 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -73,6 +73,9 @@ Camera::Camera()
longitude_max = M_PI_F;
fov = M_PI_4_F;
fov_pre = fov_post = fov;
+ stereo_eye = STEREO_NONE;
+ interocular_distance = 0.065f;
+ convergence_distance = 30.0f * 0.065f;
sensorwidth = 0.036f;
sensorheight = 0.024f;
@@ -341,6 +344,21 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
kcam->equirectangular_range = make_float4(longitude_min - longitude_max, -longitude_min,
latitude_min - latitude_max, -latitude_min + M_PI_2_F);
+ switch(stereo_eye) {
+ case STEREO_LEFT:
+ kcam->interocular_offset = -interocular_distance * 0.5f;
+ break;
+ case STEREO_RIGHT:
+ kcam->interocular_offset = interocular_distance * 0.5f;
+ break;
+ case STEREO_NONE:
+ default:
+ kcam->interocular_offset = 0.0f;
+ break;
+ }
+
+ kcam->convergence_distance = convergence_distance;
+
/* sensor size */
kcam->sensorwidth = sensorwidth;
kcam->sensorheight = sensorheight;
@@ -427,7 +445,8 @@ bool Camera::modified(const Camera& cam)
(latitude_min == cam.latitude_min) &&
(latitude_max == cam.latitude_max) &&
(longitude_min == cam.longitude_min) &&
- (longitude_max == cam.longitude_max));
+ (longitude_max == cam.longitude_max) &&
+ (stereo_eye == cam.stereo_eye));
}
bool Camera::motion_modified(const Camera& cam)
@@ -480,9 +499,30 @@ BoundBox Camera::viewplane_bounds_get()
BoundBox bounds = BoundBox::empty;
if(type == CAMERA_PANORAMA) {
- bounds.grow(make_float3(cameratoworld.x.w,
- cameratoworld.y.w,
- cameratoworld.z.w));
+ if(use_spherical_stereo == false) {
+ bounds.grow(make_float3(cameratoworld.x.w,
+ cameratoworld.y.w,
+ cameratoworld.z.w));
+ }
+ else {
+ float half_eye_distance = interocular_distance * 0.5f;
+
+ bounds.grow(make_float3(cameratoworld.x.w + half_eye_distance,
+ cameratoworld.y.w,
+ cameratoworld.z.w));
+
+ bounds.grow(make_float3(cameratoworld.z.w,
+ cameratoworld.y.w + half_eye_distance,
+ cameratoworld.z.w));
+
+ bounds.grow(make_float3(cameratoworld.x.w - half_eye_distance,
+ cameratoworld.y.w,
+ cameratoworld.z.w));
+
+ bounds.grow(make_float3(cameratoworld.x.w,
+ cameratoworld.y.w - half_eye_distance,
+ cameratoworld.z.w));
+ }
}
else {
bounds.grow(transform_raster_to_world(0.0f, 0.0f));
diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h
index 6771ecc8f23..6fbb1dc3bc8 100644
--- a/intern/cycles/render/camera.h
+++ b/intern/cycles/render/camera.h
@@ -59,6 +59,13 @@ public:
ROLLING_SHUTTER_NUM_TYPES,
};
+ /* Stereo Type */
+ enum StereoEye {
+ STEREO_NONE,
+ STEREO_LEFT,
+ STEREO_RIGHT,
+ };
+
/* motion blur */
float shuttertime;
MotionPosition motion_position;
@@ -92,6 +99,12 @@ public:
float longitude_min;
float longitude_max;
+ /* panorama stereo */
+ StereoEye stereo_eye;
+ bool use_spherical_stereo;
+ float interocular_distance;
+ float convergence_distance;
+
/* anamorphic lens bokeh */
float aperture_ratio;
diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py
index 108e8bdfc74..58a4820e27a 100644
--- a/release/scripts/startup/bl_ui/properties_data_camera.py
+++ b/release/scripts/startup/bl_ui/properties_data_camera.py
@@ -147,8 +147,12 @@ class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
- # render = context.scene.render
+ render = context.scene.render
st = context.camera.stereo
+ cam = context.camera
+
+ is_spherical_stereo = cam.type != 'ORTHO' and render.use_spherical_stereo
+ use_spherical_stereo = is_spherical_stereo and st.use_spherical_stereo
col = layout.column()
col.row().prop(st, "convergence_mode", expand=True)
@@ -159,8 +163,14 @@ class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel):
col.prop(st, "interocular_distance")
+ if is_spherical_stereo:
+ col.separator()
+ col.prop(st, "use_spherical_stereo")
+
col.label(text="Pivot:")
- col.row().prop(st, "pivot", expand=True)
+ row = col.row()
+ row.active = not use_spherical_stereo
+ row.prop(st, "pivot", expand=True)
class DATA_PT_camera(CameraButtonsPanel, Panel):
diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h
index 118153a9163..d13a711c589 100644
--- a/source/blender/blenkernel/BKE_camera.h
+++ b/source/blender/blenkernel/BKE_camera.h
@@ -144,6 +144,7 @@ void BKE_camera_multiview_view_matrix(struct RenderData *rd, struct Ob
void BKE_camera_multiview_model_matrix(struct RenderData *rd, struct Object *camera, const char *viewname, float r_modelmat[4][4]);
float BKE_camera_multiview_shift_x(struct RenderData *rd, struct Object *camera, const char *viewname);
void BKE_camera_multiview_params(struct RenderData *rd, struct CameraParams *params, struct Object *camera, const char *viewname);
+bool BKE_camera_multiview_spherical_stereo(struct RenderData *rd, struct Object *camera);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 2eac5b6ce5e..a4c44b9934e 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -135,6 +135,7 @@ float get_render_aosss_error(const struct RenderData *r, float error);
bool BKE_scene_use_new_shading_nodes(const struct Scene *scene);
bool BKE_scene_use_shading_nodes_custom(struct Scene *scene);
+bool BKE_scene_use_spherical_stereo(struct Scene *scene);
bool BKE_scene_uses_blender_internal(const struct Scene *scene);
bool BKE_scene_uses_blender_game(const struct Scene *scene);
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 73b1f0e53f6..6fd756e2788 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -845,6 +845,29 @@ void BKE_camera_multiview_model_matrix(RenderData *rd, Object *camera, const cha
normalize_m4(r_modelmat);
}
+bool BKE_camera_multiview_spherical_stereo(RenderData *rd, Object *camera)
+{
+ Camera *cam;
+ const bool is_multiview = (rd && rd->scemode & R_MULTIVIEW) != 0;
+
+ if (!is_multiview)
+ return false;
+
+ if (camera->type != OB_CAMERA)
+ return false;
+ else
+ cam = camera->data;
+
+ if ((rd->views_format == SCE_VIEWS_FORMAT_STEREO_3D) &&
+ ELEM(cam->type, CAM_PANO, CAM_PERSP) &&
+ ((cam->stereo.flag & CAM_S3D_SPHERICAL) != 0))
+ {
+ return true;
+ }
+
+ return false;
+}
+
static Object *camera_multiview_advanced(Scene *scene, Object *camera, const char *suffix)
{
SceneRenderView *srv;
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 3ce000abcfb..6b297a143d6 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -2192,6 +2192,12 @@ bool BKE_scene_use_shading_nodes_custom(Scene *scene)
return (type && type->flag & RE_USE_SHADING_NODES_CUSTOM);
}
+bool BKE_scene_use_spherical_stereo(Scene *scene)
+{
+ RenderEngineType *type = RE_engines_find(scene->r.engine);
+ return (type && type->flag & RE_USE_SPHERICAL_STEREO);
+}
+
bool BKE_scene_uses_blender_internal(const Scene *scene)
{
return STREQ(scene->r.engine, RE_engine_id_BLENDER_RENDER);
diff --git a/source/blender/makesdna/DNA_camera_types.h b/source/blender/makesdna/DNA_camera_types.h
index c45322b818f..7f2e1aaadf9 100644
--- a/source/blender/makesdna/DNA_camera_types.h
+++ b/source/blender/makesdna/DNA_camera_types.h
@@ -51,7 +51,8 @@ typedef struct CameraStereoSettings {
float convergence_distance;
short convergence_mode;
short pivot;
- short pad, pad2;
+ short flag;
+ short pad;
} CameraStereoSettings;
typedef struct Camera {
@@ -148,6 +149,11 @@ enum {
CAM_S3D_PIVOT_CENTER = 2,
};
+/* stereo->flag */
+enum {
+ CAM_S3D_SPHERICAL = (1 << 0),
+};
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/makesrna/intern/rna_camera.c b/source/blender/makesrna/intern/rna_camera.c
index 341cbb70d64..e3f27625356 100644
--- a/source/blender/makesrna/intern/rna_camera.c
+++ b/source/blender/makesrna/intern/rna_camera.c
@@ -144,6 +144,13 @@ static void rna_def_camera_stereo_data(BlenderRNA *brna)
"The converge point for the stereo cameras "
"(often the distance between a projector and the projection screen)");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+
+ prop = RNA_def_property(srna, "use_spherical_stereo", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", CAM_S3D_SPHERICAL);
+ RNA_def_property_ui_text(prop, "Spherical Stereo",
+ "Render every pixel rotating the camera around the "
+ "middle of the interocular distance");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
}
void RNA_def_camera(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index 6fce93dd9f6..84382704b2b 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -522,6 +522,10 @@ static void rna_def_render_engine(BlenderRNA *brna)
prop = RNA_def_boolean(func, "do_break", 0, "Break", "");
RNA_def_function_return(func, prop);
+ func = RNA_def_function(srna, "active_view_get", "RE_engine_active_view_get");
+ prop = RNA_def_string(func, "view", NULL, 0, "View", "Single view active");
+ RNA_def_function_return(func, prop);
+
func = RNA_def_function(srna, "active_view_set", "RE_engine_active_view_set");
RNA_def_string(func, "view", NULL, 0, "View", "Single view to set as active"); /* NULL ok here */
RNA_def_property_flag(prop, PROP_REQUIRED);
@@ -529,15 +533,23 @@ static void rna_def_render_engine(BlenderRNA *brna)
func = RNA_def_function(srna, "camera_shift_x", "RE_engine_get_camera_shift_x");
prop = RNA_def_pointer(func, "camera", "Object", "", "");
RNA_def_property_flag(prop, PROP_REQUIRED);
+ prop = RNA_def_boolean(func, "use_spherical_stereo", 0, "Spherical Stereo", "");
prop = RNA_def_float(func, "shift_x", 0.0f, 0.0f, FLT_MAX, "Shift X", "", 0.0f, FLT_MAX);
RNA_def_function_return(func, prop);
func = RNA_def_function(srna, "camera_model_matrix", "RE_engine_get_camera_model_matrix");
prop = RNA_def_pointer(func, "camera", "Object", "", "");
RNA_def_property_flag(prop, PROP_REQUIRED);
+ prop = RNA_def_boolean(func, "use_spherical_stereo", 0, "Spherical Stereo", "");
prop = RNA_def_float_matrix(func, "r_model_matrix", 4, 4, NULL, 0.0f, 0.0f, "Model Matrix", "Normalized camera model matrix", 0.0f, 0.0f);
RNA_def_property_flag(prop, PROP_REQUIRED);
+ func = RNA_def_function(srna, "use_spherical_stereo", "RE_engine_get_spherical_stereo");
+ prop = RNA_def_pointer(func, "camera", "Object", "", "");
+ RNA_def_property_flag(prop, PROP_REQUIRED);
+ prop = RNA_def_boolean(func, "use_spherical_stereo", 0, "Spherical Stereo", "");
+ RNA_def_function_return(func, prop);
+
func = RNA_def_function(srna, "update_stats", "RE_engine_update_stats");
RNA_def_function_ui_description(func, "Update and signal to redraw render status text");
prop = RNA_def_string(func, "stats", NULL, 0, "Stats", "");
@@ -667,6 +679,10 @@ static void rna_def_render_engine(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "type->flag", RE_USE_SAVE_BUFFERS);
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+ prop = RNA_def_property(srna, "bl_use_spherical_stereo", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "type->flag", RE_USE_SPHERICAL_STEREO);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+
RNA_define_verify_sdna(1);
}
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 7505dc28210..412c0bc0f96 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -1470,6 +1470,12 @@ static int rna_RenderSettings_use_shading_nodes_get(PointerRNA *ptr)
return BKE_scene_use_new_shading_nodes(scene);
}
+static int rna_RenderSettings_use_spherical_stereo_get(PointerRNA *ptr)
+{
+ Scene *scene = (Scene *)ptr->id.data;
+ return BKE_scene_use_spherical_stereo(scene);
+}
+
static int rna_RenderSettings_use_game_engine_get(PointerRNA *ptr)
{
RenderData *rd = (RenderData *)ptr->data;
@@ -5945,6 +5951,11 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Use Shading Nodes", "Active render engine uses new shading nodes system");
+ prop = RNA_def_property(srna, "use_spherical_stereo", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_use_spherical_stereo_get", NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Use Spherical Stereo", "Active render engine supports spherical stereo rendering");
+
prop = RNA_def_property(srna, "use_game_engine", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_use_game_engine_get", NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index d08b637454b..f83a210275f 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -62,6 +62,7 @@ struct BakePixel;
#define RE_USE_SAVE_BUFFERS 64
#define RE_USE_TEXTURE_PREVIEW 128
#define RE_USE_SHADING_NODES_CUSTOM 256
+#define RE_USE_SPHERICAL_STEREO 512
/* RenderEngine.flag */
#define RE_ENGINE_ANIMATION 1
@@ -140,9 +141,11 @@ struct RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y,
void RE_engine_update_result(RenderEngine *engine, struct RenderResult *result);
void RE_engine_end_result(RenderEngine *engine, struct RenderResult *result, int cancel, int merge_results);
+const char *RE_engine_active_view_get(RenderEngine *engine);
void RE_engine_active_view_set(RenderEngine *engine, const char *viewname);
-float RE_engine_get_camera_shift_x(RenderEngine *engine, struct Object *camera);
-void RE_engine_get_camera_model_matrix(RenderEngine *engine, struct Object *camera, float *r_modelmat);
+float RE_engine_get_camera_shift_x(RenderEngine *engine, struct Object *camera, int use_spherical_stereo);
+void RE_engine_get_camera_model_matrix(RenderEngine *engine, struct Object *camera, int use_spherical_stereo, float *r_modelmat);
+int RE_engine_get_spherical_stereo(RenderEngine *engine, struct Object *camera);
int RE_engine_test_break(RenderEngine *engine);
void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char *info);
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index b31760c34dd..fd9d95c63b6 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -372,24 +372,46 @@ void RE_engine_set_error_message(RenderEngine *engine, const char *msg)
}
}
+const char *RE_engine_active_view_get(RenderEngine *engine)
+{
+ Render *re = engine->re;
+ return RE_GetActiveRenderView(re);
+}
+
void RE_engine_active_view_set(RenderEngine *engine, const char *viewname)
{
Render *re = engine->re;
RE_SetActiveRenderView(re, viewname);
}
-float RE_engine_get_camera_shift_x(RenderEngine *engine, Object *camera)
+float RE_engine_get_camera_shift_x(RenderEngine *engine, Object *camera, int use_spherical_stereo)
{
Render *re = engine->re;
+
+ /* when using spherical stereo, get camera shift without multiview, leaving stereo to be handled by the engine */
+ if (use_spherical_stereo)
+ re = NULL;
+
return BKE_camera_multiview_shift_x(re ? &re->r : NULL, camera, re->viewname);
}
-void RE_engine_get_camera_model_matrix(RenderEngine *engine, Object *camera, float *r_modelmat)
+void RE_engine_get_camera_model_matrix(RenderEngine *engine, Object *camera, int use_spherical_stereo, float *r_modelmat)
{
Render *re = engine->re;
+
+ /* when using spherical stereo, get model matrix without multiview, leaving stereo to be handled by the engine */
+ if (use_spherical_stereo)
+ re = NULL;
+
BKE_camera_multiview_model_matrix(re ? &re->r : NULL, camera, re->viewname, (float (*)[4])r_modelmat);
}
+int RE_engine_get_spherical_stereo(RenderEngine *engine, Object *camera)
+{
+ Render *re = engine->re;
+ return BKE_camera_multiview_spherical_stereo(re ? &re->r : NULL, camera) ? 1 : 0;
+}
+
rcti* RE_engine_get_current_tiles(Render *re, int *r_total_tiles, bool *r_needs_free)
{
static rcti tiles_static[BLENDER_MAX_THREADS];
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index e96e866245a..bbf0ffa4cd4 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -230,9 +230,11 @@ void RE_texture_rng_init() RET_NONE
void RE_texture_rng_exit() RET_NONE
bool RE_layers_have_name(struct RenderResult *result) {STUB_ASSERT(0); return 0;}
+const char *RE_engine_active_view_get(struct RenderEngine *engine) RET_NULL
void RE_engine_active_view_set(struct RenderEngine *engine, const char *viewname) {STUB_ASSERT(0);}
-void RE_engine_get_camera_model_matrix(struct RenderEngine *engine, struct Object *camera, float *r_modelmat) {STUB_ASSERT(0);}
-float RE_engine_get_camera_shift_x(struct RenderEngine *engine, struct Object *camera) RET_ZERO
+void RE_engine_get_camera_model_matrix(struct RenderEngine *engine, struct Object *camera, int use_spherical_stereo, float *r_modelmat) {STUB_ASSERT(0);}
+float RE_engine_get_camera_shift_x(struct RenderEngine *engine, struct Object *camera, int use_spherical_stereo) RET_ZERO
+int RE_engine_get_spherical_stereo(struct RenderEngine *engine, struct Object *camera) RET_ZERO
void RE_SetActiveRenderView(struct Render *re, const char *viewname) {STUB_ASSERT(0);}
struct RenderPass *RE_pass_find_by_type(volatile struct RenderLayer *rl, int passtype, const char *viewname) RET_NULL