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:
Diffstat (limited to 'intern/cycles/blender/blender_camera.cpp')
-rw-r--r--intern/cycles/blender/blender_camera.cpp290
1 files changed, 290 insertions, 0 deletions
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
new file mode 100644
index 00000000000..2a2c2a7c643
--- /dev/null
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -0,0 +1,290 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "camera.h"
+#include "scene.h"
+
+#include "blender_sync.h"
+#include "blender_util.h"
+
+CCL_NAMESPACE_BEGIN
+
+/* Blender Camera Intermediate: we first convert both the offline and 3d view
+ * render camera to this, and from there convert to our native camera format. */
+
+struct BlenderCamera {
+ float nearclip;
+ float farclip;
+
+ bool ortho;
+ float ortho_scale;
+
+ float lens;
+
+ float aperturesize;
+ uint apertureblades;
+ float aperturerotation;
+ float focaldistance;
+
+ float2 shift;
+ float2 offset;
+ float zoom;
+
+ float2 pixelaspect;
+
+ enum { AUTO, HORIZONTAL, VERTICAL } sensor_fit;
+ float sensor_width;
+ float sensor_height;
+
+ Transform matrix;
+};
+
+static void blender_camera_init(BlenderCamera *bcam)
+{
+ memset(bcam, 0, sizeof(BlenderCamera));
+
+ bcam->zoom = 1.0f;
+ bcam->pixelaspect = make_float2(1.0f, 1.0f);
+ bcam->sensor_width = 32.0f;
+ bcam->sensor_height = 18.0f;
+ bcam->sensor_fit = BlenderCamera::AUTO;
+}
+
+static float blender_camera_focal_distance(BL::Object b_ob, BL::Camera b_camera)
+{
+ BL::Object b_dof_object = b_camera.dof_object();
+
+ if(!b_dof_object)
+ return b_camera.dof_distance();
+
+ /* for dof object, return distance along camera direction. this is
+ * compatible with blender, but does it fit our dof model? */
+ Transform obmat = get_transform(b_ob.matrix_world());
+ Transform dofmat = get_transform(b_dof_object.matrix_world());
+
+ float3 cam_p = transform_get_column(&obmat, 3);
+ float3 cam_dir = normalize(transform_get_column(&obmat, 2));
+ float3 dof_p = transform_get_column(&dofmat, 3);
+ float3 proj_p = dot(dof_p, cam_dir) * cam_dir;
+
+ return len(proj_p - cam_p);
+}
+
+static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob)
+{
+ BL::ID b_ob_data = b_ob.data();
+
+ if(b_ob_data.is_a(&RNA_Camera)) {
+ BL::Camera b_camera(b_ob_data);
+ PointerRNA ccamera = RNA_pointer_get(&b_camera.ptr, "cycles");
+
+ bcam->nearclip = b_camera.clip_start();
+ bcam->farclip = b_camera.clip_end();
+
+ bcam->ortho = (b_camera.type() == BL::Camera::type_ORTHO);
+ bcam->ortho_scale = b_camera.ortho_scale();
+
+ bcam->lens = b_camera.lens();
+ bcam->aperturesize = RNA_float_get(&ccamera, "aperture_size");
+ bcam->apertureblades = RNA_int_get(&ccamera, "aperture_blades");
+ bcam->aperturerotation = RNA_float_get(&ccamera, "aperture_rotation");
+ bcam->focaldistance = blender_camera_focal_distance(b_ob, b_camera);
+
+ bcam->shift.x = b_camera.shift_x();
+ bcam->shift.y = b_camera.shift_y();
+
+ bcam->sensor_width = b_camera.sensor_width();
+ bcam->sensor_height = b_camera.sensor_height();
+
+ if(b_camera.sensor_fit() == BL::Camera::sensor_fit_AUTO)
+ bcam->sensor_fit = BlenderCamera::AUTO;
+ else if(b_camera.sensor_fit() == BL::Camera::sensor_fit_HORIZONTAL)
+ bcam->sensor_fit = BlenderCamera::HORIZONTAL;
+ else
+ bcam->sensor_fit = BlenderCamera::VERTICAL;
+ }
+ else {
+ /* from lamp not implemented yet */
+ }
+}
+
+static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int height)
+{
+ /* copy camera to compare later */
+ Camera prevcam = *cam;
+
+ /* dimensions */
+ float xratio = width*bcam->pixelaspect.x;
+ float yratio = height*bcam->pixelaspect.y;
+
+ /* compute x/y aspect and ratio */
+ float aspectratio, xaspect, yaspect;
+
+ /* sensor fitting */
+ bool horizontal_fit;
+ float sensor_size;
+
+ if(bcam->sensor_fit == BlenderCamera::AUTO) {
+ horizontal_fit = (xratio > yratio);
+ sensor_size = bcam->sensor_width;
+ }
+ else if(bcam->sensor_fit == BlenderCamera::HORIZONTAL) {
+ horizontal_fit = true;
+ sensor_size = bcam->sensor_width;
+ }
+ else {
+ horizontal_fit = false;
+ sensor_size = bcam->sensor_height;
+ }
+
+ if(horizontal_fit) {
+ aspectratio= xratio/yratio;
+ xaspect= aspectratio;
+ yaspect= 1.0f;
+ }
+ else {
+ aspectratio= yratio/xratio;
+ xaspect= 1.0f;
+ yaspect= aspectratio;
+ }
+
+ /* modify aspect for orthographic scale */
+ if(bcam->ortho) {
+ xaspect = xaspect*bcam->ortho_scale/(aspectratio*2.0f);
+ yaspect = yaspect*bcam->ortho_scale/(aspectratio*2.0f);
+ aspectratio = bcam->ortho_scale/2.0f;
+ }
+
+ /* set viewplane */
+ cam->left = -xaspect;
+ cam->right = xaspect;
+ cam->bottom = -yaspect;
+ cam->top = yaspect;
+
+ /* zoom for 3d camera view */
+ cam->left *= bcam->zoom;
+ cam->right *= bcam->zoom;
+ cam->bottom *= bcam->zoom;
+ cam->top *= 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);
+
+ cam->left += dx;
+ cam->right += dx;
+ cam->bottom += dy;
+ cam->top += dy;
+
+ /* clipping distances */
+ cam->nearclip = bcam->nearclip;
+ cam->farclip = bcam->farclip;
+
+ /* orthographic */
+ cam->ortho = bcam->ortho;
+
+ /* perspective */
+ cam->fov = 2.0f*atan((0.5f*sensor_size)/bcam->lens/aspectratio);
+ cam->focaldistance = bcam->focaldistance;
+ cam->aperturesize = bcam->aperturesize;
+ cam->blades = bcam->apertureblades;
+ cam->bladesrotation = bcam->aperturerotation;
+
+ /* transform, note the blender camera points along the negative z-axis */
+ cam->matrix = bcam->matrix * transform_scale(1.0f, 1.0f, -1.0f);
+
+ /* set update flag */
+ if(cam->modified(prevcam))
+ cam->tag_update();
+}
+
+/* Sync Render Camera */
+
+void BlenderSync::sync_camera(int width, int height)
+{
+ BlenderCamera bcam;
+ blender_camera_init(&bcam);
+
+ /* pixel aspect */
+ BL::RenderSettings r = b_scene.render();
+
+ bcam.pixelaspect.x = r.pixel_aspect_x();
+ bcam.pixelaspect.y = r.pixel_aspect_y();
+
+ /* camera object */
+ BL::Object b_ob = b_scene.camera();
+
+ if(b_ob) {
+ blender_camera_from_object(&bcam, b_ob);
+ bcam.matrix = get_transform(b_ob.matrix_world());
+ }
+
+ /* sync */
+ Camera *cam = scene->camera;
+ blender_camera_sync(cam, &bcam, width, height);
+}
+
+/* Sync 3D View Camera */
+
+void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height)
+{
+ BlenderCamera bcam;
+ blender_camera_init(&bcam);
+
+ /* 3d view parameters */
+ bcam.nearclip = b_v3d.clip_start();
+ bcam.farclip = b_v3d.clip_end();
+ bcam.lens = b_v3d.lens();
+
+ if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA) {
+ /* camera view */
+ BL::Object b_ob = b_scene.camera();
+
+ if(b_ob) {
+ blender_camera_from_object(&bcam, b_ob);
+
+ /* 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) {
+ /* orthographic view */
+ bcam.farclip *= 0.5;
+ bcam.nearclip = -bcam.farclip;
+
+ bcam.ortho = true;
+ bcam.ortho_scale = b_rv3d.view_distance();
+ }
+
+ bcam.zoom *= 2.0f;
+
+ /* 3d view transform */
+ bcam.matrix = transform_inverse(get_transform(b_rv3d.view_matrix()));
+
+ /* sync */
+ blender_camera_sync(scene->camera, &bcam, width, height);
+}
+
+CCL_NAMESPACE_END
+