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