Blender  V2.93
blender_camera.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "render/camera.h"
18 #include "render/scene.h"
19 
20 #include "blender/blender_sync.h"
21 #include "blender/blender_util.h"
22 
23 #include "util/util_logging.h"
24 
26 
27 /* Blender Camera Intermediate: we first convert both the offline and 3d view
28  * render camera to this, and from there convert to our native camera format. */
29 
30 struct BlenderCamera {
31  float nearclip;
32  float farclip;
33 
35  float ortho_scale;
36 
37  float lens;
38  float shuttertime;
41 
44 
45  float aperturesize;
49 
52  float zoom;
53 
55 
57 
59  float fisheye_fov;
60  float fisheye_lens;
61  float latitude_min;
62  float latitude_max;
71 
73  float sensor_width;
75 
78 
81 
85 
87 
89 
91 };
92 
93 static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings &b_render)
94 {
95  memset((void *)bcam, 0, sizeof(BlenderCamera));
96 
97  bcam->nearclip = 1e-5f;
98  bcam->farclip = 1e5f;
99 
100  bcam->type = CAMERA_PERSPECTIVE;
101  bcam->ortho_scale = 1.0f;
102 
103  bcam->lens = 50.0f;
104  bcam->shuttertime = 1.0f;
105 
107  bcam->rolling_shutter_duration = 0.1f;
108 
109  bcam->aperturesize = 0.0f;
110  bcam->apertureblades = 0;
111  bcam->aperturerotation = 0.0f;
112  bcam->focaldistance = 10.0f;
113 
114  bcam->zoom = 1.0f;
115  bcam->pixelaspect = one_float2();
116  bcam->aperture_ratio = 1.0f;
117 
118  bcam->sensor_width = 36.0f;
119  bcam->sensor_height = 24.0f;
122  bcam->border.right = 1.0f;
123  bcam->border.top = 1.0f;
124  bcam->pano_viewplane.right = 1.0f;
125  bcam->pano_viewplane.top = 1.0f;
126  bcam->viewport_camera_border.right = 1.0f;
127  bcam->viewport_camera_border.top = 1.0f;
128  bcam->offscreen_dicing_scale = 1.0f;
129  bcam->matrix = transform_identity();
130 
131  /* render resolution */
132  bcam->render_width = render_resolution_x(b_render);
133  bcam->render_height = render_resolution_y(b_render);
134  bcam->full_width = bcam->render_width;
135  bcam->full_height = bcam->render_height;
136 }
137 
139  BL::Object &b_ob,
140  BL::Camera &b_camera,
141  BlenderCamera *bcam)
142 {
143  BL::Object b_dof_object = b_camera.dof().focus_object();
144 
145  if (!b_dof_object)
146  return b_camera.dof().focus_distance();
147 
148  /* for dof object, return distance along camera Z direction */
149  BL::Array<float, 16> b_ob_matrix;
150  b_engine.camera_model_matrix(b_ob, bcam->use_spherical_stereo, b_ob_matrix);
151  Transform obmat = transform_clear_scale(get_transform(b_ob_matrix));
152  Transform dofmat = get_transform(b_dof_object.matrix_world());
153  float3 view_dir = normalize(transform_get_column(&obmat, 2));
154  float3 dof_dir = transform_get_column(&obmat, 3) - transform_get_column(&dofmat, 3);
155  return fabsf(dot(view_dir, dof_dir));
156 }
157 
159  BL::RenderEngine &b_engine,
160  BL::Object &b_ob,
161  bool skip_panorama = false)
162 {
163  BL::ID b_ob_data = b_ob.data();
164 
165  if (b_ob_data.is_a(&RNA_Camera)) {
166  BL::Camera b_camera(b_ob_data);
167  PointerRNA ccamera = RNA_pointer_get(&b_camera.ptr, "cycles");
168 
169  bcam->nearclip = b_camera.clip_start();
170  bcam->farclip = b_camera.clip_end();
171 
172  switch (b_camera.type()) {
173  case BL::Camera::type_ORTHO:
174  bcam->type = CAMERA_ORTHOGRAPHIC;
175  break;
176  case BL::Camera::type_PANO:
177  if (!skip_panorama)
178  bcam->type = CAMERA_PANORAMA;
179  else
180  bcam->type = CAMERA_PERSPECTIVE;
181  break;
182  case BL::Camera::type_PERSP:
183  default:
184  bcam->type = CAMERA_PERSPECTIVE;
185  break;
186  }
187 
189  ccamera, "panorama_type", PANORAMA_NUM_TYPES, PANORAMA_EQUIRECTANGULAR);
190 
191  bcam->fisheye_fov = RNA_float_get(&ccamera, "fisheye_fov");
192  bcam->fisheye_lens = RNA_float_get(&ccamera, "fisheye_lens");
193  bcam->latitude_min = RNA_float_get(&ccamera, "latitude_min");
194  bcam->latitude_max = RNA_float_get(&ccamera, "latitude_max");
195  bcam->longitude_min = RNA_float_get(&ccamera, "longitude_min");
196  bcam->longitude_max = RNA_float_get(&ccamera, "longitude_max");
197 
198  bcam->interocular_distance = b_camera.stereo().interocular_distance();
199  if (b_camera.stereo().convergence_mode() == BL::CameraStereoData::convergence_mode_PARALLEL) {
200  bcam->convergence_distance = FLT_MAX;
201  }
202  else {
203  bcam->convergence_distance = b_camera.stereo().convergence_distance();
204  }
205  bcam->use_spherical_stereo = b_engine.use_spherical_stereo(b_ob);
206 
207  bcam->use_pole_merge = b_camera.stereo().use_pole_merge();
208  bcam->pole_merge_angle_from = b_camera.stereo().pole_merge_angle_from();
209  bcam->pole_merge_angle_to = b_camera.stereo().pole_merge_angle_to();
210 
211  bcam->ortho_scale = b_camera.ortho_scale();
212 
213  bcam->lens = b_camera.lens();
214 
215  if (b_camera.dof().use_dof()) {
216  /* allow f/stop number to change aperture_size but still
217  * give manual control over aperture radius */
218  float fstop = b_camera.dof().aperture_fstop();
219  fstop = max(fstop, 1e-5f);
220 
221  if (bcam->type == CAMERA_ORTHOGRAPHIC)
222  bcam->aperturesize = 1.0f / (2.0f * fstop);
223  else
224  bcam->aperturesize = (bcam->lens * 1e-3f) / (2.0f * fstop);
225 
226  bcam->apertureblades = b_camera.dof().aperture_blades();
227  bcam->aperturerotation = b_camera.dof().aperture_rotation();
228  bcam->focaldistance = blender_camera_focal_distance(b_engine, b_ob, b_camera, bcam);
229  bcam->aperture_ratio = b_camera.dof().aperture_ratio();
230  }
231  else {
232  /* DOF is turned of for the camera. */
233  bcam->aperturesize = 0.0f;
234  bcam->apertureblades = 0;
235  bcam->aperturerotation = 0.0f;
236  bcam->focaldistance = 0.0f;
237  bcam->aperture_ratio = 1.0f;
238  }
239 
240  bcam->shift.x = b_engine.camera_shift_x(b_ob, bcam->use_spherical_stereo);
241  bcam->shift.y = b_camera.shift_y();
242 
243  bcam->sensor_width = b_camera.sensor_width();
244  bcam->sensor_height = b_camera.sensor_height();
245 
246  if (b_camera.sensor_fit() == BL::Camera::sensor_fit_AUTO)
248  else if (b_camera.sensor_fit() == BL::Camera::sensor_fit_HORIZONTAL)
250  else
252  }
253  else if (b_ob_data.is_a(&RNA_Light)) {
254  /* Can also look through spot light. */
255  BL::SpotLight b_light(b_ob_data);
256  float lens = 16.0f / tanf(b_light.spot_size() * 0.5f);
257  if (lens > 0.0f) {
258  bcam->lens = lens;
259  }
260  }
261 
262  bcam->motion_steps = object_motion_steps(b_ob, b_ob);
263 }
264 
266  const CameraType type,
267  const PanoramaType panorama_type)
268 {
270 
271  if (type == CAMERA_PANORAMA) {
272  if (panorama_type == PANORAMA_MIRRORBALL) {
273  /* Mirror ball camera is looking into the negative Y direction
274  * which matches texture mirror ball mapping.
275  */
276  result = tfm * make_transform(
277  1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
278  }
279  else {
280  /* Make it so environment camera needs to be pointed in the direction
281  * of the positive x-axis to match an environment texture, this way
282  * it is looking at the center of the texture
283  */
284  result = tfm * make_transform(
285  0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f);
286  }
287  }
288  else {
289  /* note the blender camera points along the negative z-axis */
290  result = tfm * transform_scale(1.0f, 1.0f, -1.0f);
291  }
292 
294 }
295 
297  int width,
298  int height,
299  BoundBox2D *viewplane,
300  float *aspectratio,
301  float *sensor_size)
302 {
303  /* dimensions */
304  float xratio = (float)width * bcam->pixelaspect.x;
305  float yratio = (float)height * bcam->pixelaspect.y;
306 
307  /* compute x/y aspect and ratio */
308  float xaspect, yaspect;
309  bool horizontal_fit;
310 
311  /* sensor fitting */
312  if (bcam->sensor_fit == BlenderCamera::AUTO) {
313  horizontal_fit = (xratio > yratio);
314  if (sensor_size != NULL) {
315  *sensor_size = bcam->sensor_width;
316  }
317  }
318  else if (bcam->sensor_fit == BlenderCamera::HORIZONTAL) {
319  horizontal_fit = true;
320  if (sensor_size != NULL) {
321  *sensor_size = bcam->sensor_width;
322  }
323  }
324  else {
325  horizontal_fit = false;
326  if (sensor_size != NULL) {
327  *sensor_size = bcam->sensor_height;
328  }
329  }
330 
331  if (horizontal_fit) {
332  if (aspectratio != NULL) {
333  *aspectratio = xratio / yratio;
334  }
335  xaspect = *aspectratio;
336  yaspect = 1.0f;
337  }
338  else {
339  if (aspectratio != NULL) {
340  *aspectratio = yratio / xratio;
341  }
342  xaspect = 1.0f;
343  yaspect = *aspectratio;
344  }
345 
346  /* modify aspect for orthographic scale */
347  if (bcam->type == CAMERA_ORTHOGRAPHIC) {
348  xaspect = xaspect * bcam->ortho_scale / (*aspectratio * 2.0f);
349  yaspect = yaspect * bcam->ortho_scale / (*aspectratio * 2.0f);
350  if (aspectratio != NULL) {
351  *aspectratio = bcam->ortho_scale / 2.0f;
352  }
353  }
354 
355  if (bcam->type == CAMERA_PANORAMA) {
356  /* set viewplane */
357  if (viewplane != NULL) {
358  *viewplane = bcam->pano_viewplane;
359  }
360  }
361  else {
362  /* set viewplane */
363  if (viewplane != NULL) {
364  viewplane->left = -xaspect;
365  viewplane->right = xaspect;
366  viewplane->bottom = -yaspect;
367  viewplane->top = yaspect;
368 
369  /* zoom for 3d camera view */
370  *viewplane = (*viewplane) * bcam->zoom;
371 
372  /* modify viewplane with camera shift and 3d camera view offset */
373  float dx = 2.0f * (*aspectratio * bcam->shift.x + bcam->offset.x * xaspect * 2.0f);
374  float dy = 2.0f * (*aspectratio * bcam->shift.y + bcam->offset.y * yaspect * 2.0f);
375 
376  viewplane->left += dx;
377  viewplane->right += dx;
378  viewplane->bottom += dy;
379  viewplane->top += dy;
380  }
381  }
382 }
383 
384 static void blender_camera_sync(Camera *cam,
385  BlenderCamera *bcam,
386  int width,
387  int height,
388  const char *viewname,
389  PointerRNA *cscene)
390 {
391  float aspectratio, sensor_size;
392 
393  /* viewplane */
394  BoundBox2D viewplane;
395  blender_camera_viewplane(bcam, width, height, &viewplane, &aspectratio, &sensor_size);
396 
397  cam->set_viewplane_left(viewplane.left);
398  cam->set_viewplane_right(viewplane.right);
399  cam->set_viewplane_top(viewplane.top);
400  cam->set_viewplane_bottom(viewplane.bottom);
401 
402  cam->set_full_width(width);
403  cam->set_full_height(height);
404 
405  /* panorama sensor */
407  float fit_xratio = (float)bcam->render_width * bcam->pixelaspect.x;
408  float fit_yratio = (float)bcam->render_height * bcam->pixelaspect.y;
409  bool horizontal_fit;
410  float sensor_size;
411 
412  if (bcam->sensor_fit == BlenderCamera::AUTO) {
413  horizontal_fit = (fit_xratio > fit_yratio);
414  sensor_size = bcam->sensor_width;
415  }
416  else if (bcam->sensor_fit == BlenderCamera::HORIZONTAL) {
417  horizontal_fit = true;
418  sensor_size = bcam->sensor_width;
419  }
420  else { /* vertical */
421  horizontal_fit = false;
422  sensor_size = bcam->sensor_height;
423  }
424 
425  if (horizontal_fit) {
426  cam->set_sensorwidth(sensor_size);
427  cam->set_sensorheight(sensor_size * fit_yratio / fit_xratio);
428  }
429  else {
430  cam->set_sensorwidth(sensor_size * fit_xratio / fit_yratio);
431  cam->set_sensorheight(sensor_size);
432  }
433  }
434 
435  /* clipping distances */
436  cam->set_nearclip(bcam->nearclip);
437  cam->set_farclip(bcam->farclip);
438 
439  /* type */
440  cam->set_camera_type(bcam->type);
441 
442  /* panorama */
443  cam->set_panorama_type(bcam->panorama_type);
444  cam->set_fisheye_fov(bcam->fisheye_fov);
445  cam->set_fisheye_lens(bcam->fisheye_lens);
446  cam->set_latitude_min(bcam->latitude_min);
447  cam->set_latitude_max(bcam->latitude_max);
448 
449  cam->set_longitude_min(bcam->longitude_min);
450  cam->set_longitude_max(bcam->longitude_max);
451 
452  /* panorama stereo */
453  cam->set_interocular_distance(bcam->interocular_distance);
454  cam->set_convergence_distance(bcam->convergence_distance);
455  cam->set_use_spherical_stereo(bcam->use_spherical_stereo);
456 
457  if (cam->get_use_spherical_stereo()) {
458  if (strcmp(viewname, "left") == 0)
459  cam->set_stereo_eye(Camera::STEREO_LEFT);
460  else if (strcmp(viewname, "right") == 0)
461  cam->set_stereo_eye(Camera::STEREO_RIGHT);
462  else
463  cam->set_stereo_eye(Camera::STEREO_NONE);
464  }
465 
466  cam->set_use_pole_merge(bcam->use_pole_merge);
467  cam->set_pole_merge_angle_from(bcam->pole_merge_angle_from);
468  cam->set_pole_merge_angle_to(bcam->pole_merge_angle_to);
469 
470  /* anamorphic lens bokeh */
471  cam->set_aperture_ratio(bcam->aperture_ratio);
472 
473  /* perspective */
474  cam->set_fov(2.0f * atanf((0.5f * sensor_size) / bcam->lens / aspectratio));
475  cam->set_focaldistance(bcam->focaldistance);
476  cam->set_aperturesize(bcam->aperturesize);
477  cam->set_blades(bcam->apertureblades);
478  cam->set_bladesrotation(bcam->aperturerotation);
479 
480  /* transform */
481  cam->set_matrix(blender_camera_matrix(bcam->matrix, bcam->type, bcam->panorama_type));
482 
483  array<Transform> motion;
484  motion.resize(bcam->motion_steps, cam->get_matrix());
485  cam->set_motion(motion);
486  cam->set_use_perspective_motion(false);
487 
488  cam->set_shuttertime(bcam->shuttertime);
489  cam->set_fov_pre(cam->get_fov());
490  cam->set_fov_post(cam->get_fov());
491  cam->set_motion_position(bcam->motion_position);
492 
493  cam->set_rolling_shutter_type(bcam->rolling_shutter_type);
494  cam->set_rolling_shutter_duration(bcam->rolling_shutter_duration);
495 
496  cam->set_shutter_curve(bcam->shutter_curve);
497 
498  /* border */
499  cam->set_border_left(bcam->border.left);
500  cam->set_border_right(bcam->border.right);
501  cam->set_border_top(bcam->border.top);
502  cam->set_border_bottom(bcam->border.bottom);
503 
504  cam->set_viewport_camera_border_left(bcam->viewport_camera_border.left);
505  cam->set_viewport_camera_border_right(bcam->viewport_camera_border.right);
506  cam->set_viewport_camera_border_top(bcam->viewport_camera_border.top);
507  cam->set_viewport_camera_border_bottom(bcam->viewport_camera_border.bottom);
508 
509  bcam->offscreen_dicing_scale = RNA_float_get(cscene, "offscreen_dicing_scale");
510  cam->set_offscreen_dicing_scale(bcam->offscreen_dicing_scale);
511 }
512 
513 /* Sync Render Camera */
514 
515 void BlenderSync::sync_camera(BL::RenderSettings &b_render,
516  BL::Object &b_override,
517  int width,
518  int height,
519  const char *viewname)
520 {
521  BlenderCamera bcam;
522  blender_camera_init(&bcam, b_render);
523 
524  /* pixel aspect */
525  bcam.pixelaspect.x = b_render.pixel_aspect_x();
526  bcam.pixelaspect.y = b_render.pixel_aspect_y();
527  bcam.shuttertime = b_render.motion_blur_shutter();
528 
529  BL::CurveMapping b_shutter_curve(b_render.motion_blur_shutter_curve());
530  curvemapping_to_array(b_shutter_curve, bcam.shutter_curve, RAMP_TABLE_SIZE);
531 
532  PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
534  "motion_blur_position",
538  cscene,
539  "rolling_shutter_type",
542  bcam.rolling_shutter_duration = RNA_float_get(&cscene, "rolling_shutter_duration");
543 
544  /* border */
545  if (b_render.use_border()) {
546  bcam.border.left = b_render.border_min_x();
547  bcam.border.right = b_render.border_max_x();
548  bcam.border.bottom = b_render.border_min_y();
549  bcam.border.top = b_render.border_max_y();
550  }
551 
552  /* camera object */
553  BL::Object b_ob = b_scene.camera();
554 
555  if (b_override)
556  b_ob = b_override;
557 
558  if (b_ob) {
559  BL::Array<float, 16> b_ob_matrix;
560  blender_camera_from_object(&bcam, b_engine, b_ob);
561  b_engine.camera_model_matrix(b_ob, bcam.use_spherical_stereo, b_ob_matrix);
562  bcam.matrix = get_transform(b_ob_matrix);
563  }
564 
565  /* sync */
566  Camera *cam = scene->camera;
567  blender_camera_sync(cam, &bcam, width, height, viewname, &cscene);
568 
569  /* dicing camera */
570  b_ob = BL::Object(RNA_pointer_get(&cscene, "dicing_camera"));
571  if (b_ob) {
572  BL::Array<float, 16> b_ob_matrix;
573  blender_camera_from_object(&bcam, b_engine, b_ob);
574  b_engine.camera_model_matrix(b_ob, bcam.use_spherical_stereo, b_ob_matrix);
575  bcam.matrix = get_transform(b_ob_matrix);
576 
577  blender_camera_sync(scene->dicing_camera, &bcam, width, height, viewname, &cscene);
578  }
579  else {
580  *scene->dicing_camera = *cam;
581  }
582 }
583 
584 void BlenderSync::sync_camera_motion(
585  BL::RenderSettings &b_render, BL::Object &b_ob, int width, int height, float motion_time)
586 {
587  if (!b_ob)
588  return;
589 
590  Camera *cam = scene->camera;
591  BL::Array<float, 16> b_ob_matrix;
592  b_engine.camera_model_matrix(b_ob, cam->get_use_spherical_stereo(), b_ob_matrix);
593  Transform tfm = get_transform(b_ob_matrix);
594  tfm = blender_camera_matrix(tfm, cam->get_camera_type(), cam->get_panorama_type());
595 
596  if (motion_time == 0.0f) {
597  /* When motion blur is not centered in frame, cam->matrix gets reset. */
598  cam->set_matrix(tfm);
599  }
600 
601  /* Set transform in motion array. */
602  int motion_step = cam->motion_step(motion_time);
603  if (motion_step >= 0) {
604  array<Transform> motion = cam->get_motion();
605  motion[motion_step] = tfm;
606  cam->set_motion(motion);
607  }
608 
609  if (cam->get_camera_type() == CAMERA_PERSPECTIVE) {
610  BlenderCamera bcam;
611  float aspectratio, sensor_size;
612  blender_camera_init(&bcam, b_render);
613 
614  /* TODO(sergey): Consider making it a part of blender_camera_init(). */
615  bcam.pixelaspect.x = b_render.pixel_aspect_x();
616  bcam.pixelaspect.y = b_render.pixel_aspect_y();
617 
618  blender_camera_from_object(&bcam, b_engine, b_ob);
619  blender_camera_viewplane(&bcam, width, height, NULL, &aspectratio, &sensor_size);
620  /* TODO(sergey): De-duplicate calculation with camera sync. */
621  float fov = 2.0f * atanf((0.5f * sensor_size) / bcam.lens / aspectratio);
622  if (fov != cam->get_fov()) {
623  VLOG(1) << "Camera " << b_ob.name() << " FOV change detected.";
624  if (motion_time == 0.0f) {
625  cam->set_fov(fov);
626  }
627  else if (motion_time == -1.0f) {
628  cam->set_fov_pre(fov);
629  cam->set_use_perspective_motion(true);
630  }
631  else if (motion_time == 1.0f) {
632  cam->set_fov_post(fov);
633  cam->set_use_perspective_motion(true);
634  }
635  }
636  }
637 }
638 
639 /* Sync 3D View Camera */
640 
641 static void blender_camera_view_subset(BL::RenderEngine &b_engine,
642  BL::RenderSettings &b_render,
643  BL::Scene &b_scene,
644  BL::Object &b_ob,
645  BL::SpaceView3D &b_v3d,
646  BL::RegionView3D &b_rv3d,
647  int width,
648  int height,
649  BoundBox2D *view_box,
650  BoundBox2D *cam_box);
651 
653  BL::RenderEngine &b_engine,
654  BL::Scene &b_scene,
655  BL::SpaceView3D &b_v3d,
656  BL::RegionView3D &b_rv3d,
657  int width,
658  int height,
659  bool skip_panorama = false)
660 {
661  /* 3d view parameters */
662  bcam->nearclip = b_v3d.clip_start();
663  bcam->farclip = b_v3d.clip_end();
664  bcam->lens = b_v3d.lens();
665  bcam->shuttertime = b_scene.render().motion_blur_shutter();
666 
667  BL::CurveMapping b_shutter_curve(b_scene.render().motion_blur_shutter_curve());
668  curvemapping_to_array(b_shutter_curve, bcam->shutter_curve, RAMP_TABLE_SIZE);
669 
670  if (b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA) {
671  /* camera view */
672  BL::Object b_ob = (b_v3d.use_local_camera()) ? b_v3d.camera() : b_scene.camera();
673 
674  if (b_ob) {
675  blender_camera_from_object(bcam, b_engine, b_ob, skip_panorama);
676 
677  if (!skip_panorama && bcam->type == CAMERA_PANORAMA) {
678  /* in panorama camera view, we map viewplane to camera border */
679  BoundBox2D view_box, cam_box;
680 
681  BL::RenderSettings b_render_settings(b_scene.render());
683  b_render_settings,
684  b_scene,
685  b_ob,
686  b_v3d,
687  b_rv3d,
688  width,
689  height,
690  &view_box,
691  &cam_box);
692 
693  bcam->pano_viewplane = view_box.make_relative_to(cam_box);
694  }
695  else {
696  /* magic zoom formula */
697  bcam->zoom = (float)b_rv3d.view_camera_zoom();
698  bcam->zoom = (1.41421f + bcam->zoom / 50.0f);
699  bcam->zoom *= bcam->zoom;
700  bcam->zoom = 2.0f / bcam->zoom;
701 
702  /* offset */
703  bcam->offset = get_float2(b_rv3d.view_camera_offset());
704  }
705  }
706  }
707  else if (b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_ORTHO) {
708  /* orthographic view */
709  bcam->farclip *= 0.5f;
710  bcam->nearclip = -bcam->farclip;
711 
712  float sensor_size;
713  if (bcam->sensor_fit == BlenderCamera::VERTICAL)
714  sensor_size = bcam->sensor_height;
715  else
716  sensor_size = bcam->sensor_width;
717 
718  bcam->type = CAMERA_ORTHOGRAPHIC;
719  bcam->ortho_scale = b_rv3d.view_distance() * sensor_size / b_v3d.lens();
720  }
721 
722  bcam->zoom *= 2.0f;
723 
724  /* 3d view transform */
725  bcam->matrix = transform_inverse(get_transform(b_rv3d.view_matrix()));
726 
727  /* dimensions */
728  bcam->full_width = width;
729  bcam->full_height = height;
730 }
731 
733  BL::RenderSettings &b_render,
734  BL::Scene &b_scene,
735  BL::Object &b_ob,
736  BL::SpaceView3D &b_v3d,
737  BL::RegionView3D &b_rv3d,
738  int width,
739  int height,
740  BoundBox2D *view_box,
741  BoundBox2D *cam_box)
742 {
743  BoundBox2D cam, view;
744  float view_aspect, cam_aspect, sensor_size;
745 
746  /* Get viewport viewplane. */
747  BlenderCamera view_bcam;
748  blender_camera_init(&view_bcam, b_render);
749  blender_camera_from_view(&view_bcam, b_engine, b_scene, b_v3d, b_rv3d, width, height, true);
750 
751  blender_camera_viewplane(&view_bcam, width, height, &view, &view_aspect, &sensor_size);
752 
753  /* Get camera viewplane. */
754  BlenderCamera cam_bcam;
755  blender_camera_init(&cam_bcam, b_render);
756  blender_camera_from_object(&cam_bcam, b_engine, b_ob, true);
757 
758  /* Camera border is affect by aspect, viewport is not. */
759  cam_bcam.pixelaspect.x = b_render.pixel_aspect_x();
760  cam_bcam.pixelaspect.y = b_render.pixel_aspect_y();
761 
763  &cam_bcam, cam_bcam.full_width, cam_bcam.full_height, &cam, &cam_aspect, &sensor_size);
764 
765  /* Return */
766  *view_box = view * (1.0f / view_aspect);
767  *cam_box = cam * (1.0f / cam_aspect);
768 }
769 
771  BL::RenderSettings &b_render,
772  BL::Scene &b_scene,
773  BL::SpaceView3D &b_v3d,
774  BL::RegionView3D &b_rv3d,
775  BL::Object &b_ob,
776  int width,
777  int height,
778  const BoundBox2D &border,
780 {
781  /* Determine camera viewport subset. */
782  BoundBox2D view_box, cam_box;
784  b_engine, b_render, b_scene, b_ob, b_v3d, b_rv3d, width, height, &view_box, &cam_box);
785 
786  /* Determine viewport subset matching given border. */
787  cam_box = cam_box.make_relative_to(view_box);
788  *result = cam_box.subset(border);
789 }
790 
792  BL::RenderEngine &b_engine,
793  BL::RenderSettings &b_render,
794  BL::Scene &b_scene,
795  BL::SpaceView3D &b_v3d,
796  BL::RegionView3D &b_rv3d,
797  int width,
798  int height)
799 {
800  bool is_camera_view;
801 
802  /* camera view? */
803  is_camera_view = b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA;
804 
805  if (!is_camera_view) {
806  /* for non-camera view check whether render border is enabled for viewport
807  * and if so use border from 3d viewport
808  * assume viewport has got correctly clamped border already
809  */
810  if (b_v3d.use_render_border()) {
811  bcam->border.left = b_v3d.render_border_min_x();
812  bcam->border.right = b_v3d.render_border_max_x();
813  bcam->border.bottom = b_v3d.render_border_min_y();
814  bcam->border.top = b_v3d.render_border_max_y();
815  }
816  return;
817  }
818 
819  BL::Object b_ob = (b_v3d.use_local_camera()) ? b_v3d.camera() : b_scene.camera();
820 
821  if (!b_ob)
822  return;
823 
824  /* Determine camera border inside the viewport. */
825  BoundBox2D full_border;
827  b_render,
828  b_scene,
829  b_v3d,
830  b_rv3d,
831  b_ob,
832  width,
833  height,
834  full_border,
835  &bcam->viewport_camera_border);
836 
837  if (!b_render.use_border()) {
838  return;
839  }
840 
841  bcam->border.left = b_render.border_min_x();
842  bcam->border.right = b_render.border_max_x();
843  bcam->border.bottom = b_render.border_min_y();
844  bcam->border.top = b_render.border_max_y();
845 
846  /* Determine viewport subset matching camera border. */
848  b_render,
849  b_scene,
850  b_v3d,
851  b_rv3d,
852  b_ob,
853  width,
854  height,
855  bcam->border,
856  &bcam->border);
857  bcam->border = bcam->border.clamp();
858 }
859 
860 void BlenderSync::sync_view(BL::SpaceView3D &b_v3d,
861  BL::RegionView3D &b_rv3d,
862  int width,
863  int height)
864 {
865  BlenderCamera bcam;
866  BL::RenderSettings b_render_settings(b_scene.render());
867  blender_camera_init(&bcam, b_render_settings);
868  blender_camera_from_view(&bcam, b_engine, b_scene, b_v3d, b_rv3d, width, height);
869  blender_camera_border(&bcam, b_engine, b_render_settings, b_scene, b_v3d, b_rv3d, width, height);
870  PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
871  blender_camera_sync(scene->camera, &bcam, width, height, "", &cscene);
872 
873  /* dicing camera */
874  BL::Object b_ob = BL::Object(RNA_pointer_get(&cscene, "dicing_camera"));
875  if (b_ob) {
876  BL::Array<float, 16> b_ob_matrix;
877  blender_camera_from_object(&bcam, b_engine, b_ob);
878  b_engine.camera_model_matrix(b_ob, bcam.use_spherical_stereo, b_ob_matrix);
879  bcam.matrix = get_transform(b_ob_matrix);
880 
881  blender_camera_sync(scene->dicing_camera, &bcam, width, height, "", &cscene);
882  }
883  else {
884  *scene->dicing_camera = *scene->camera;
885  }
886 }
887 
888 BufferParams BlenderSync::get_buffer_params(BL::RenderSettings &b_render,
889  BL::SpaceView3D &b_v3d,
890  BL::RegionView3D &b_rv3d,
891  Camera *cam,
892  int width,
893  int height,
894  const bool use_denoiser)
895 {
897  bool use_border = false;
898 
899  params.full_width = width;
900  params.full_height = height;
901 
902  if (b_v3d && b_rv3d && b_rv3d.view_perspective() != BL::RegionView3D::view_perspective_CAMERA)
903  use_border = b_v3d.use_render_border();
904  else
905  use_border = b_render.use_border();
906 
907  if (use_border) {
908  /* border render */
909  /* the viewport may offset the border outside the view */
910  BoundBox2D border = cam->border.clamp();
911  params.full_x = (int)(border.left * (float)width);
912  params.full_y = (int)(border.bottom * (float)height);
913  params.width = (int)(border.right * (float)width) - params.full_x;
914  params.height = (int)(border.top * (float)height) - params.full_y;
915 
916  /* survive in case border goes out of view or becomes too small */
917  params.width = max(params.width, 1);
918  params.height = max(params.height, 1);
919  }
920  else {
921  params.width = width;
922  params.height = height;
923  }
924 
925  PassType display_pass = update_viewport_display_passes(b_v3d, params.passes);
926 
927  /* Can only denoise the combined image pass */
928  params.denoising_data_pass = display_pass == PASS_COMBINED && use_denoiser;
929 
930  return params;
931 }
932 
typedef float(TangentPoint)[2]
unsigned int uint
Definition: BLI_sys_types.h:83
struct ID ID
struct Camera Camera
struct CurveMapping CurveMapping
struct Object Object
struct Scene Scene
struct RegionView3D RegionView3D
static AppView * view
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
struct RenderEngine RenderEngine
StructRNA RNA_Light
StructRNA RNA_Camera
static void blender_camera_border(BlenderCamera *bcam, BL::RenderEngine &b_engine, BL::RenderSettings &b_render, BL::Scene &b_scene, BL::SpaceView3D &b_v3d, BL::RegionView3D &b_rv3d, int width, int height)
static float blender_camera_focal_distance(BL::RenderEngine &b_engine, BL::Object &b_ob, BL::Camera &b_camera, BlenderCamera *bcam)
static void blender_camera_view_subset(BL::RenderEngine &b_engine, BL::RenderSettings &b_render, 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_border_subset(BL::RenderEngine &b_engine, BL::RenderSettings &b_render, BL::Scene &b_scene, BL::SpaceView3D &b_v3d, BL::RegionView3D &b_rv3d, BL::Object &b_ob, int width, int height, const BoundBox2D &border, BoundBox2D *result)
static void blender_camera_from_view(BlenderCamera *bcam, BL::RenderEngine &b_engine, BL::Scene &b_scene, BL::SpaceView3D &b_v3d, BL::RegionView3D &b_rv3d, int width, int height, bool skip_panorama=false)
static void blender_camera_from_object(BlenderCamera *bcam, BL::RenderEngine &b_engine, BL::Object &b_ob, bool skip_panorama=false)
static void blender_camera_viewplane(BlenderCamera *bcam, int width, int height, BoundBox2D *viewplane, float *aspectratio, float *sensor_size)
static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int height, const char *viewname, PointerRNA *cscene)
static Transform blender_camera_matrix(const Transform &tfm, const CameraType type, const PanoramaType panorama_type)
static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings &b_render)
static uint object_motion_steps(BL::Object &b_parent, BL::Object &b_ob, const int max_steps=INT_MAX)
Definition: blender_util.h:489
static int render_resolution_x(BL::RenderSettings &b_render)
Definition: blender_util.h:227
static void curvemapping_to_array(BL::CurveMapping &cumap, array< float > &data, int size)
Definition: blender_util.h:158
static int render_resolution_y(BL::RenderSettings &b_render)
Definition: blender_util.h:232
static int get_enum(PointerRNA &ptr, const char *name, int num_values=-1, int default_value=-1)
Definition: blender_util.h:386
static float2 get_float2(const BL::Array< float, 2 > &array)
Definition: blender_util.h:290
static Transform get_transform(const BL::Array< float, 16 > &array)
Definition: blender_util.h:277
PassType update_viewport_display_passes(BL::SpaceView3D &b_v3d, vector< Pass > &passes)
static BufferParams get_buffer_params(BL::RenderSettings &b_render, BL::SpaceView3D &b_v3d, BL::RegionView3D &b_rv3d, Camera *cam, int width, int height, const bool use_denoiser)
void sync_camera(BL::RenderSettings &b_render, BL::Object &b_override, int width, int height, const char *viewname)
void sync_view(BL::SpaceView3D &b_v3d, BL::RegionView3D &b_rv3d, int width, int height)
BoundBox2D clamp(float mn=0.0f, float mx=1.0f)
BoundBox2D make_relative_to(const BoundBox2D &other) const
BoundBox2D subset(const BoundBox2D &other) const
T * resize(size_t newsize)
Definition: util_array.h:150
IconTextureDrawCall border
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define tanf(x)
#define CCL_NAMESPACE_END
#define atanf(x)
#define fabsf(x)
PassType
Definition: kernel_types.h:347
@ PASS_COMBINED
Definition: kernel_types.h:351
#define RAMP_TABLE_SIZE
Definition: kernel_types.h:46
PanoramaType
Definition: kernel_types.h:614
@ PANORAMA_MIRRORBALL
Definition: kernel_types.h:618
@ PANORAMA_FISHEYE_EQUISOLID
Definition: kernel_types.h:617
@ PANORAMA_NUM_TYPES
Definition: kernel_types.h:620
@ PANORAMA_EQUIRECTANGULAR
Definition: kernel_types.h:615
CameraType
Definition: kernel_types.h:610
@ CAMERA_PERSPECTIVE
Definition: kernel_types.h:610
@ CAMERA_PANORAMA
Definition: kernel_types.h:610
@ CAMERA_ORTHOGRAPHIC
Definition: kernel_types.h:610
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6562
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6355
float rolling_shutter_duration
Camera::MotionPosition motion_position
enum BlenderCamera::@1186 sensor_fit
CameraType type
array< float > shutter_curve
Transform matrix
float offscreen_dicing_scale
BoundBox2D pano_viewplane
Camera::RollingShutterType rolling_shutter_type
BoundBox2D border
float convergence_distance
float pole_merge_angle_from
PanoramaType panorama_type
float pole_merge_angle_to
float interocular_distance
BoundBox2D viewport_camera_border
RollingShutterType
Definition: camera.h:59
@ ROLLING_SHUTTER_NUM_TYPES
Definition: camera.h:65
@ ROLLING_SHUTTER_NONE
Definition: camera.h:61
MotionPosition
Definition: camera.h:47
@ MOTION_NUM_POSITIONS
Definition: camera.h:55
@ MOTION_POSITION_CENTER
Definition: camera.h:51
BoundBox2D border
Definition: camera.h:142
int motion_step(float time) const
Definition: camera.cpp:807
@ STEREO_LEFT
Definition: camera.h:71
@ STEREO_NONE
Definition: camera.h:70
@ STEREO_RIGHT
Definition: camera.h:72
Camera * dicing_camera
Definition: scene.h:227
struct Object * camera
float max
#define VLOG(severity)
Definition: util_logging.h:50
ccl_device_inline float2 one_float2()
ccl_device_inline float2 normalize(const float2 &a)
ccl_device_inline float dot(const float2 &a, const float2 &b)
Transform transform_inverse(const Transform &tfm)
ccl_device_inline Transform transform_identity()
ccl_device_inline float3 transform_get_column(const Transform *t, int column)
ccl_device_inline Transform make_transform(float a, float b, float c, float d, float e, float f, float g, float h, float i, float j, float k, float l)
ccl_device_inline Transform transform_scale(float3 s)
ccl_device_inline Transform transform_clear_scale(const Transform &tfm)