Blender V5.0
blenkernel/intern/camera.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstdlib>
10#include <optional>
11
12/* Allow using deprecated functionality for .blend file I/O. */
13#define DNA_DEPRECATED_ALLOW
14
15#include "DNA_ID.h"
16#include "DNA_camera_types.h"
17#include "DNA_defaults.h"
18#include "DNA_light_types.h"
19#include "DNA_object_types.h"
20#include "DNA_scene_types.h"
21#include "DNA_text_types.h"
22#include "DNA_view3d_types.h"
23
24#include "BLI_listbase.h"
25#include "BLI_math_geom.h"
26#include "BLI_math_matrix.h"
27#include "BLI_math_vector.h"
28#include "BLI_rect.h"
29#include "BLI_string.h"
30#include "BLI_utildefines.h"
31
32#include "BKE_action.hh"
33#include "BKE_bpath.hh"
34#include "BKE_camera.h"
35#include "BKE_idprop.hh"
36#include "BKE_idtype.hh"
37#include "BKE_lib_id.hh"
38#include "BKE_lib_query.hh"
39#include "BKE_object.hh"
40#include "BKE_scene.hh"
41#include "BKE_screen.hh"
42
43#include "BLT_translation.hh"
44
46
47#include "MEM_guardedalloc.h"
48
49#include "BLO_read_write.hh"
50
51/* -------------------------------------------------------------------- */
54
55static void camera_init_data(ID *id)
56{
57 Camera *cam = (Camera *)id;
59
61}
62
73static void camera_copy_data(Main * /*bmain*/,
74 std::optional<Library *> /*owner_library*/,
75 ID *id_dst,
76 const ID *id_src,
77 const int flag)
78{
79 Camera *cam_dst = (Camera *)id_dst;
80 const Camera *cam_src = (const Camera *)id_src;
81
82 /* We never handle user-count here for owned data. */
83 const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
84
86 LISTBASE_FOREACH (CameraBGImage *, bgpic_src, &cam_src->bg_images) {
87 CameraBGImage *bgpic_dst = BKE_camera_background_image_copy(bgpic_src, flag_subdata);
88 BLI_addtail(&cam_dst->bg_images, bgpic_dst);
89 }
90
91 if (cam_src->custom_bytecode) {
92 cam_dst->custom_bytecode = static_cast<char *>(MEM_dupallocN(cam_src->custom_bytecode));
93 }
94}
95
97static void camera_free_data(ID *id)
98{
99 Camera *cam = (Camera *)id;
101 if (cam->custom_bytecode) {
103 }
104}
105
123
124static void camera_foreach_path(ID *id, BPathForeachPathData *bpath_data)
125{
126 Camera *camera = reinterpret_cast<Camera *>(id);
127
128 if (camera->custom_filepath[0]) {
130 bpath_data, camera->custom_filepath, sizeof(camera->custom_filepath));
131 }
132}
133
138
140{
141 auto cycles_data_ensure = [](IDProperty *group) {
142 IDProperty *prop = IDP_GetPropertyTypeFromGroup(group, "cycles", IDP_GROUP);
143 if (prop) {
144 return prop;
145 }
146 prop = blender::bke::idprop::create_group("cycles").release();
147 IDP_AddToGroup(group, prop);
148 return prop;
149 };
150
151 auto cycles_property_int_set = [](IDProperty *idprop, const char *name, int value) {
152 if (IDProperty *prop = IDP_GetPropertyTypeFromGroup(idprop, name, IDP_INT)) {
153 IDP_int_set(prop, value);
154 }
155 else {
156 IDP_AddToGroup(idprop, blender::bke::idprop::create(name, value).release());
157 }
158 };
159
160 auto cycles_property_float_set = [](IDProperty *idprop, const char *name, float value) {
162 IDP_float_set(prop, value);
163 }
164 else {
165 IDP_AddToGroup(idprop, blender::bke::idprop::create(name, value).release());
166 }
167 };
168
169 /* For forward compatibility, still write panoramic properties as ID properties for
170 * previous blender versions. */
171 IDProperty *idprop_prev = IDP_ID_system_properties_get(id);
172 /* Make a copy to avoid modifying the original. */
173 IDProperty *idprop_temp = idprop_prev ? IDP_CopyProperty(idprop_prev) :
175
176 Camera *cam = (Camera *)id;
177 IDProperty *cycles_cam = cycles_data_ensure(idprop_temp);
178 cycles_property_int_set(cycles_cam, "panorama_type", cam->panorama_type);
179 cycles_property_float_set(cycles_cam, "fisheye_fov", cam->fisheye_fov);
180 cycles_property_float_set(cycles_cam, "fisheye_lens", cam->fisheye_lens);
181 cycles_property_float_set(cycles_cam, "latitude_min", cam->latitude_min);
182 cycles_property_float_set(cycles_cam, "latitude_max", cam->latitude_max);
183 cycles_property_float_set(cycles_cam, "longitude_min", cam->longitude_min);
184 cycles_property_float_set(cycles_cam, "longitude_max", cam->longitude_max);
185 cycles_property_float_set(cycles_cam, "fisheye_polynomial_k0", cam->fisheye_polynomial_k0);
186 cycles_property_float_set(cycles_cam, "fisheye_polynomial_k1", cam->fisheye_polynomial_k1);
187 cycles_property_float_set(cycles_cam, "fisheye_polynomial_k2", cam->fisheye_polynomial_k2);
188 cycles_property_float_set(cycles_cam, "fisheye_polynomial_k3", cam->fisheye_polynomial_k3);
189 cycles_property_float_set(cycles_cam, "fisheye_polynomial_k4", cam->fisheye_polynomial_k4);
190
191 id->system_properties = idprop_temp;
192
193 return {idprop_prev, idprop_temp};
194}
195
198{
199 id->system_properties = data.idprop_prev;
200 data.idprop_prev = nullptr;
201
202 if (data.idprop_temp) {
203 IDP_FreeProperty(data.idprop_temp);
204 data.idprop_temp = nullptr;
205 }
206}
207
208static void camera_blend_write(BlendWriter *writer, ID *id, const void *id_address)
209{
210 const bool is_undo = BLO_write_is_undo(writer);
211 Camera *cam = (Camera *)id;
212
214 if (!is_undo) {
216 }
217
218 /* write LibData */
219 BLO_write_id_struct(writer, Camera, id_address, &cam->id);
220 BKE_id_blend_write(writer, &cam->id);
221
222 LISTBASE_FOREACH (CameraBGImage *, bgpic, &cam->bg_images) {
223 BLO_write_struct(writer, CameraBGImage, bgpic);
224 }
225
226 if (!is_undo) {
228 }
229
230 if (cam->custom_bytecode) {
231 BLO_write_string(writer, cam->custom_bytecode);
232 }
233}
234
236{
237 Camera *ca = (Camera *)id;
238
240
241 LISTBASE_FOREACH (CameraBGImage *, bgpic, &ca->bg_images) {
242 bgpic->iuser.scene = nullptr;
243
244 /* If linking from a library, clear 'local' library override flag. */
245 if (ID_IS_LINKED(ca)) {
247 }
248 }
249
250 BLO_read_string(reader, &ca->custom_bytecode);
251}
252
254 /*id_code*/ Camera::id_type,
255 /*id_filter*/ FILTER_ID_CA,
256 /*dependencies_id_types*/ FILTER_ID_OB | FILTER_ID_IM,
257 /*main_listbase_index*/ INDEX_ID_CA,
258 /*struct_size*/ sizeof(Camera),
259 /*name*/ "Camera",
260 /*name_plural*/ N_("cameras"),
261 /*translation_context*/ BLT_I18NCONTEXT_ID_CAMERA,
263 /*asset_type_info*/ nullptr,
264
265 /*init_data*/ camera_init_data,
266 /*copy_data*/ camera_copy_data,
267 /*free_data*/ camera_free_data,
268 /*make_local*/ nullptr,
269 /*foreach_id*/ camera_foreach_id,
270 /*foreach_cache*/ nullptr,
271 /*foreach_path*/ camera_foreach_path,
272 /*foreach_working_space_color*/ nullptr,
273 /*owner_pointer_get*/ nullptr,
274
275 /*blend_write*/ camera_blend_write,
276 /*blend_read_data*/ camera_blend_read_data,
277 /*blend_read_after_liblink*/ nullptr,
278
279 /*blend_read_undo_preserve*/ nullptr,
280
281 /*lib_override_apply_post*/ nullptr,
282};
283
285
286/* -------------------------------------------------------------------- */
289
290Camera *BKE_camera_add(Main *bmain, const char *name)
291{
292 Camera *cam;
293
294 cam = BKE_id_new<Camera>(bmain, name);
295
296 return cam;
297}
298
300{
301 const Camera *cam = (const Camera *)ob->data;
302 if (ob->type != OB_CAMERA) {
303 return 0.0f;
304 }
305 if (cam->dof.focus_object) {
306 float view_dir[3], dof_dir[3];
307 normalize_v3_v3(view_dir, ob->object_to_world().ptr()[2]);
309 cam->dof.focus_subtarget);
310 if (pchan) {
311 float posemat[4][4];
312 mul_m4_m4m4(posemat, cam->dof.focus_object->object_to_world().ptr(), pchan->pose_mat);
313 sub_v3_v3v3(dof_dir, ob->object_to_world().location(), posemat[3]);
314 }
315 else {
316 sub_v3_v3v3(dof_dir,
317 ob->object_to_world().location(),
318 cam->dof.focus_object->object_to_world().location());
319 }
320 return fmax(fabsf(dot_v3v3(view_dir, dof_dir)), 1e-5f);
321 }
322 return fmax(cam->dof.focus_distance, 1e-5f);
323}
324
325float BKE_camera_sensor_size(int sensor_fit, float sensor_x, float sensor_y)
326{
327 /* sensor size used to fit to. for auto, sensor_x is both x and y. */
328 if (sensor_fit == CAMERA_SENSOR_FIT_VERT) {
329 return sensor_y;
330 }
331
332 return sensor_x;
333}
334
335int BKE_camera_sensor_fit(int sensor_fit, float sizex, float sizey)
336{
337 if (sensor_fit == CAMERA_SENSOR_FIT_AUTO) {
338 if (sizex >= sizey) {
340 }
341
343 }
344
345 return sensor_fit;
346}
347
349
350/* -------------------------------------------------------------------- */
353
355{
356 memset(params, 0, sizeof(CameraParams));
357
358 /* defaults */
359 params->sensor_x = DEFAULT_SENSOR_WIDTH;
360 params->sensor_y = DEFAULT_SENSOR_HEIGHT;
361 params->sensor_fit = CAMERA_SENSOR_FIT_AUTO;
362
363 params->zoom = 1.0f;
364
365 /* fallback for non camera objects */
366 params->clip_start = 0.1f;
367 params->clip_end = 100.0f;
368}
369
371{
372 if (!cam_ob) {
373 return;
374 }
375
376 if (cam_ob->type == OB_CAMERA) {
377 /* camera object */
378 const Camera *cam = static_cast<const Camera *>(cam_ob->data);
379
380 if (cam->type == CAM_ORTHO) {
381 params->is_ortho = true;
382 }
383 params->lens = cam->lens;
384 params->ortho_scale = cam->ortho_scale;
385
386 params->shiftx = cam->shiftx;
387 params->shifty = cam->shifty;
388
389 params->sensor_x = cam->sensor_x;
390 params->sensor_y = cam->sensor_y;
391 params->sensor_fit = cam->sensor_fit;
392
393 params->clip_start = cam->clip_start;
394 params->clip_end = cam->clip_end;
395 }
396 else if (cam_ob->type == OB_LAMP) {
397 /* light object */
398 Light *la = static_cast<Light *>(cam_ob->data);
399 params->lens = 16.0f / tanf(la->spotsize * 0.5f);
400 if (params->lens == 0.0f) {
401 params->lens = 35.0f;
402 }
403 }
404 else {
405 params->lens = 35.0f;
406 }
407}
408
410 const Depsgraph *depsgraph,
411 const View3D *v3d,
412 const RegionView3D *rv3d)
413{
414 /* common */
415 params->lens = v3d->lens;
416 params->clip_start = v3d->clip_start;
417 params->clip_end = v3d->clip_end;
418
419 if (rv3d->persp == RV3D_CAMOB) {
420 /* camera view */
421 const Object *ob_camera_eval = DEG_get_evaluated(depsgraph, v3d->camera);
422 BKE_camera_params_from_object(params, ob_camera_eval);
423
425
426 params->offsetx = 2.0f * rv3d->camdx * params->zoom;
427 params->offsety = 2.0f * rv3d->camdy * params->zoom;
428
429 params->shiftx *= params->zoom;
430 params->shifty *= params->zoom;
431
433 }
434 else if (rv3d->persp == RV3D_ORTHO) {
435 /* orthographic view */
436 float sensor_size = BKE_camera_sensor_size(
437 params->sensor_fit, params->sensor_x, params->sensor_y);
438 /* Halve, otherwise too extreme low Z-buffer quality. */
439 params->clip_end *= 0.5f;
440 params->clip_start = -params->clip_end;
441
442 params->is_ortho = true;
443 /* make sure any changes to this match ED_view3d_radius_to_dist_ortho() */
444 params->ortho_scale = rv3d->dist * sensor_size / v3d->lens;
446 }
447 else {
448 /* perspective view */
450 }
451}
452
454 CameraParams *params, int winx, int winy, float aspx, float aspy)
455{
456 rctf viewplane;
457 float pixsize, viewfac, sensor_size, dx, dy;
458 int sensor_fit;
459
460 params->ycor = aspy / aspx;
461
462 if (params->is_ortho) {
463 /* orthographic camera */
464 /* scale == 1.0 means exact 1 to 1 mapping */
465 pixsize = params->ortho_scale;
466 }
467 else {
468 /* perspective camera */
469 sensor_size = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y);
470 pixsize = (sensor_size * params->clip_start) / params->lens;
471 }
472
473 /* determine sensor fit */
474 sensor_fit = BKE_camera_sensor_fit(params->sensor_fit, aspx * winx, aspy * winy);
475
476 if (sensor_fit == CAMERA_SENSOR_FIT_HOR) {
477 viewfac = winx;
478 }
479 else {
480 viewfac = params->ycor * winy;
481 }
482
483 pixsize /= viewfac;
484
485 /* extra zoom factor */
486 pixsize *= params->zoom;
487
488 /* compute view plane:
489 * Fully centered, Z-buffer fills in jittered between `-.5` and `+.5`. */
490 viewplane.xmin = -0.5f * float(winx);
491 viewplane.ymin = -0.5f * params->ycor * float(winy);
492 viewplane.xmax = 0.5f * float(winx);
493 viewplane.ymax = 0.5f * params->ycor * float(winy);
494
495 /* lens shift and offset */
496 dx = params->shiftx * viewfac + winx * params->offsetx;
497 dy = params->shifty * viewfac + winy * params->offsety;
498
499 viewplane.xmin += dx;
500 viewplane.ymin += dy;
501 viewplane.xmax += dx;
502 viewplane.ymax += dy;
503
504 /* the window matrix is used for clipping, and not changed during OSA steps */
505 /* using an offset of +0.5 here would give clip errors on edges */
506 BLI_rctf_mul(&viewplane, pixsize);
507
508 /* Used for rendering (offset by near-clip with perspective views), passed to RE_SetPixelSize.
509 * For viewport drawing 'RegionView3D.pixsize'. */
510 params->viewdx = pixsize;
511 params->viewdy = params->ycor * pixsize;
512 params->viewplane = viewplane;
513}
514
515void BKE_camera_params_crop_viewplane(rctf *viewplane, int winx, int winy, const rcti *region)
516{
517 float pix_size_x = BLI_rctf_size_x(viewplane) / winx;
518 float pix_size_y = BLI_rctf_size_y(viewplane) / winy;
519
520 viewplane->xmin += pix_size_x * region->xmin;
521 viewplane->ymin += pix_size_y * region->ymin;
522
523 viewplane->xmax = viewplane->xmin + pix_size_x * BLI_rcti_size_x(region);
524 viewplane->ymax = viewplane->ymin + pix_size_y * BLI_rcti_size_y(region);
525}
526
528{
529 rctf viewplane = params->viewplane;
530
531 /* compute projection matrix */
532 if (params->is_ortho) {
533 orthographic_m4(params->winmat,
534 viewplane.xmin,
535 viewplane.xmax,
536 viewplane.ymin,
537 viewplane.ymax,
538 params->clip_start,
539 params->clip_end);
540 }
541 else {
542 perspective_m4(params->winmat,
543 viewplane.xmin,
544 viewplane.xmax,
545 viewplane.ymin,
546 viewplane.ymax,
547 params->clip_start,
548 params->clip_end);
549 }
550}
551
553
554/* -------------------------------------------------------------------- */
557
559 const Camera *camera,
560 const float drawsize,
561 const bool do_clip,
562 const float scale[3],
563 float r_asp[2],
564 float r_shift[2],
565 float *r_drawsize,
566 float r_vec[4][3])
567{
568 float facx, facy;
569 float depth;
570
571 /* aspect correction */
572 if (scene) {
573 float aspx = float(scene->r.xsch) * scene->r.xasp;
574 float aspy = float(scene->r.ysch) * scene->r.yasp;
575 int sensor_fit = BKE_camera_sensor_fit(camera->sensor_fit, aspx, aspy);
576
577 if (sensor_fit == CAMERA_SENSOR_FIT_HOR) {
578 r_asp[0] = 1.0;
579 r_asp[1] = aspy / aspx;
580 }
581 else {
582 r_asp[0] = aspx / aspy;
583 r_asp[1] = 1.0;
584 }
585 }
586 else {
587 r_asp[0] = 1.0f;
588 r_asp[1] = 1.0f;
589 }
590
591 if (camera->type == CAM_ORTHO) {
592 facx = 0.5f * camera->ortho_scale * r_asp[0] * scale[0];
593 facy = 0.5f * camera->ortho_scale * r_asp[1] * scale[1];
594 r_shift[0] = camera->shiftx * camera->ortho_scale * scale[0];
595 r_shift[1] = camera->shifty * camera->ortho_scale * scale[1];
596 depth = -drawsize * scale[2];
597
598 *r_drawsize = 0.5f * camera->ortho_scale;
599 }
600 else {
601 /* that way it's always visible - clip_start+0.1 */
602 float fac, scale_x, scale_y;
603 float half_sensor = 0.5f * ((camera->sensor_fit == CAMERA_SENSOR_FIT_VERT) ?
604 (camera->sensor_y) :
605 (camera->sensor_x));
606
607 /* fixed size, variable depth (stays a reasonable size in the 3D view) */
608 *r_drawsize = (drawsize / 2.0f) / ((scale[0] + scale[1] + scale[2]) / 3.0f);
609 depth = *r_drawsize * camera->lens / (-half_sensor) * scale[2];
610 fac = *r_drawsize;
611 scale_x = scale[0];
612 scale_y = scale[1];
613
614 facx = fac * r_asp[0] * scale_x;
615 facy = fac * r_asp[1] * scale_y;
616 r_shift[0] = camera->shiftx * fac * 2.0f * scale_x;
617 r_shift[1] = camera->shifty * fac * 2.0f * scale_y;
618 }
619
620 r_vec[0][0] = r_shift[0] + facx;
621 r_vec[0][1] = r_shift[1] + facy;
622 r_vec[0][2] = depth;
623 r_vec[1][0] = r_shift[0] + facx;
624 r_vec[1][1] = r_shift[1] - facy;
625 r_vec[1][2] = depth;
626 r_vec[2][0] = r_shift[0] - facx;
627 r_vec[2][1] = r_shift[1] - facy;
628 r_vec[2][2] = depth;
629 r_vec[3][0] = r_shift[0] - facx;
630 r_vec[3][1] = r_shift[1] + facy;
631 r_vec[3][2] = depth;
632
633 if (do_clip) {
634 /* Ensure the frame isn't behind the near clipping plane, #62814. */
635 float fac = ((camera->clip_start + 0.1f) / -r_vec[0][2]) * scale[2];
636 for (uint i = 0; i < 4; i++) {
637 if (camera->type == CAM_ORTHO) {
638 r_vec[i][2] *= fac;
639 }
640 else {
641 mul_v3_fl(r_vec[i], fac);
642 }
643 }
644 }
645}
646
647void BKE_camera_view_frame(const Scene *scene, const Camera *camera, float r_vec[4][3])
648{
649 float dummy_asp[2];
650 float dummy_shift[2];
651 float dummy_drawsize;
652 const float dummy_scale[3] = {1.0f, 1.0f, 1.0f};
653
655 scene, camera, 1.0, false, dummy_scale, dummy_asp, dummy_shift, &dummy_drawsize, r_vec);
656}
657
659
660/* -------------------------------------------------------------------- */
663
664#define CAMERA_VIEWFRAME_NUM_PLANES 4
665
666#define Y_MIN 0
667#define Y_MAX 1
668#define Z_MIN 2
669#define Z_MAX 3
670
672 float plane_tx[CAMERA_VIEWFRAME_NUM_PLANES][4]; /* 4 planes normalized */
673 float dist_vals[CAMERA_VIEWFRAME_NUM_PLANES]; /* distance (signed) */
674 float camera_no[3];
675 float z_range[2];
677
679
680 /* Not used by callbacks... */
681 float camera_rotmat[3][3];
682};
683
684static void camera_to_frame_view_cb(const float co[3], void *user_data)
685{
687
688 for (uint i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) {
689 const float nd = plane_point_side_v3(data->plane_tx[i], co);
690 CLAMP_MAX(data->dist_vals[i], nd);
691 }
692
693 if (data->do_zrange) {
694 const float d = dot_v3v3(data->camera_no, co);
695 CLAMP_MAX(data->z_range[0], d);
696 CLAMP_MIN(data->z_range[1], d);
697 }
698
699 data->tot++;
700}
701
702static void camera_frame_fit_data_init(const Scene *scene,
703 const Object *ob,
704 const bool do_clip_dists,
707{
708 float camera_rotmat_transposed_inversed[4][4];
709
710 /* setup parameters */
713
714 /* Compute matrix, view-plane, etc. */
715 if (scene) {
717 params, scene->r.xsch, scene->r.ysch, scene->r.xasp, scene->r.yasp);
718 }
719 else {
721 }
723
724 /* initialize callback data */
725 copy_m3_m4(data->camera_rotmat, (float (*)[4])ob->object_to_world().ptr());
726 normalize_m3(data->camera_rotmat);
727 /* To transform a plane which is in its homogeneous representation (4d vector),
728 * we need the inverse of the transpose of the transform matrix... */
729 copy_m4_m3(camera_rotmat_transposed_inversed, data->camera_rotmat);
730 transpose_m4(camera_rotmat_transposed_inversed);
731 invert_m4(camera_rotmat_transposed_inversed);
732
733 /* Extract frustum planes from projection matrix. */
735 data->plane_tx[Y_MIN],
736 data->plane_tx[Y_MAX],
737 data->plane_tx[Z_MIN],
738 data->plane_tx[Z_MAX],
739 nullptr,
740 nullptr);
741
742 /* Rotate planes and get normals from them */
743 for (uint i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) {
744 mul_m4_v4(camera_rotmat_transposed_inversed, data->plane_tx[i]);
745 /* Normalize. */
746 data->plane_tx[i][3] /= normalize_v3(data->plane_tx[i]);
747
748 data->dist_vals[i] = FLT_MAX;
749 }
750
751 data->tot = 0;
752 data->do_zrange = params->is_ortho || do_clip_dists;
753
754 if (data->do_zrange) {
755 /* We want (0, 0, -1) transformed by camera_rotmat, this is a quicker shortcut. */
756 negate_v3_v3(data->camera_no, data->camera_rotmat[2]);
757 data->z_range[0] = FLT_MAX;
758 data->z_range[1] = -FLT_MAX;
759 }
760}
761
764 float r_co[3],
765 float *r_scale,
766 float *r_clip_start,
767 float *r_clip_end)
768{
769 float plane_tx[CAMERA_VIEWFRAME_NUM_PLANES][4];
770
771 if (data->tot <= 1) {
772 return false;
773 }
774
775 if (params->is_ortho) {
776 const float *cam_axis_x = data->camera_rotmat[0];
777 const float *cam_axis_y = data->camera_rotmat[1];
778 const float *cam_axis_z = data->camera_rotmat[2];
779 const float *dists = data->dist_vals;
780 const float dist_span_y = dists[Y_MIN] + dists[Y_MAX];
781 const float dist_span_z = dists[Z_MIN] + dists[Z_MAX];
782 const float dist_mid_y = (dists[Y_MIN] - dists[Y_MAX]) * 0.5f;
783 const float dist_mid_z = (dists[Z_MIN] - dists[Z_MAX]) * 0.5f;
784 const float scale_diff = (dist_span_z < dist_span_y) ?
785 (dist_span_z * (BLI_rctf_size_x(&params->viewplane) /
786 BLI_rctf_size_y(&params->viewplane))) :
787 (dist_span_y * (BLI_rctf_size_y(&params->viewplane) /
788 BLI_rctf_size_x(&params->viewplane)));
789
790 *r_scale = params->ortho_scale - scale_diff;
791
792 zero_v3(r_co);
793 madd_v3_v3fl(r_co, cam_axis_x, dist_mid_y + (params->shiftx * scale_diff));
794 madd_v3_v3fl(r_co, cam_axis_y, dist_mid_z + (params->shifty * scale_diff));
795 madd_v3_v3fl(r_co, cam_axis_z, -(data->z_range[0] - 1.0f - params->clip_start));
796 }
797 else {
798 float plane_isect_1[3], plane_isect_1_no[3], plane_isect_1_other[3];
799 float plane_isect_2[3], plane_isect_2_no[3], plane_isect_2_other[3];
800
801 float plane_isect_pt_1[3], plane_isect_pt_2[3];
802
803 /* apply the dist-from-plane's to the transformed plane points */
804 for (int i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) {
805 float co[3];
806 mul_v3_v3fl(co, data->plane_tx[i], data->dist_vals[i]);
807 plane_from_point_normal_v3(plane_tx[i], co, data->plane_tx[i]);
808 }
809
810 if (!isect_plane_plane_v3(plane_tx[Y_MIN], plane_tx[Y_MAX], plane_isect_1, plane_isect_1_no) ||
811 !isect_plane_plane_v3(plane_tx[Z_MIN], plane_tx[Z_MAX], plane_isect_2, plane_isect_2_no))
812 {
813 return false;
814 }
815
816 add_v3_v3v3(plane_isect_1_other, plane_isect_1, plane_isect_1_no);
817 add_v3_v3v3(plane_isect_2_other, plane_isect_2, plane_isect_2_no);
818
819 if (!isect_line_line_v3(plane_isect_1,
820 plane_isect_1_other,
821 plane_isect_2,
822 plane_isect_2_other,
823 plane_isect_pt_1,
824 plane_isect_pt_2))
825 {
826 return false;
827 }
828
829 float cam_plane_no[3];
830 float plane_isect_delta[3];
831
832 const float shift_fac = BKE_camera_sensor_size(
833 params->sensor_fit, params->sensor_x, params->sensor_y) /
834 params->lens;
835
836 /* we want (0, 0, -1) transformed by camera_rotmat, this is a quicker shortcut. */
837 negate_v3_v3(cam_plane_no, data->camera_rotmat[2]);
838
839 sub_v3_v3v3(plane_isect_delta, plane_isect_pt_2, plane_isect_pt_1);
840 const float plane_isect_delta_len = len_v3(plane_isect_delta);
841
842 if (dot_v3v3(plane_isect_delta, cam_plane_no) > 0.0f) {
843 copy_v3_v3(r_co, plane_isect_pt_1);
844
845 /* offset shift */
846 normalize_v3(plane_isect_1_no);
847 madd_v3_v3fl(r_co, plane_isect_1_no, params->shifty * plane_isect_delta_len * shift_fac);
848 }
849 else {
850 copy_v3_v3(r_co, plane_isect_pt_2);
851
852 /* offset shift */
853 normalize_v3(plane_isect_2_no);
854 madd_v3_v3fl(r_co, plane_isect_2_no, params->shiftx * plane_isect_delta_len * shift_fac);
855 }
856 }
857
858 if (r_clip_start && r_clip_end) {
859 const float z_offs = dot_v3v3(r_co, data->camera_no);
860 *r_clip_start = data->z_range[0] - z_offs;
861 *r_clip_end = data->z_range[1] - z_offs;
862 }
863 return true;
864}
865
866#undef Y_MIN
867#undef Y_MAX
868#undef Z_MIN
869#undef Z_MAX
870
872 const Scene *scene,
873 Object *camera_ob,
874 float r_co[3],
875 float *r_scale,
876 float *r_clip_start,
877 float *r_clip_end)
878{
880 CameraViewFrameData data_cb;
881
882 /* just in case */
883 *r_scale = 1.0f;
884
885 camera_frame_fit_data_init(scene, camera_ob, r_clip_start && r_clip_end, &params, &data_cb);
886
887 /* run callback on all visible points */
889
891 &params, &data_cb, r_co, r_scale, r_clip_start, r_clip_end);
892}
893
895 const float (*cos)[3],
896 int num_cos,
897 Object *camera_ob,
898 float r_co[3],
899 float *r_scale)
900{
902 Object *camera_ob_eval = DEG_get_evaluated(depsgraph, camera_ob);
904 CameraViewFrameData data_cb;
905
906 /* just in case */
907 *r_scale = 1.0f;
908
909 camera_frame_fit_data_init(scene_eval, camera_ob_eval, false, &params, &data_cb);
910
911 /* run callback on all given coordinates */
912 while (num_cos--) {
913 camera_to_frame_view_cb(cos[num_cos], &data_cb);
914 }
915
916 return camera_frame_fit_calc_from_data(&params, &data_cb, r_co, r_scale, nullptr, nullptr);
917}
918
920
921/* -------------------------------------------------------------------- */
924
925static void camera_model_matrix(const Object *camera, float r_modelmat[4][4])
926{
927 copy_m4_m4(r_modelmat, camera->object_to_world().ptr());
928}
929
930static void camera_stereo3d_model_matrix(const Object *camera,
931 const bool is_left,
932 float r_modelmat[4][4])
933{
934 const Camera *data = (const Camera *)camera->data;
935 float interocular_distance, convergence_distance;
936 short convergence_mode, pivot;
937 float sizemat[4][4];
938
939 float fac = 1.0f;
940 float fac_signed;
941
942 interocular_distance = data->stereo.interocular_distance;
943 convergence_distance = data->stereo.convergence_distance;
944 convergence_mode = data->stereo.convergence_mode;
945 pivot = data->stereo.pivot;
946
947 if (((pivot == CAM_S3D_PIVOT_LEFT) && is_left) || ((pivot == CAM_S3D_PIVOT_RIGHT) && !is_left)) {
948 camera_model_matrix(camera, r_modelmat);
949 return;
950 }
951
952 float size[3];
953 mat4_to_size(size, camera->object_to_world().ptr());
954 size_to_mat4(sizemat, size);
955
956 if (pivot == CAM_S3D_PIVOT_CENTER) {
957 fac = 0.5f;
958 }
959
960 fac_signed = is_left ? fac : -fac;
961
962 /* rotation */
963 if (convergence_mode == CAM_S3D_TOE) {
964 float angle;
965 float angle_sin, angle_cos;
966 float toeinmat[4][4];
967 float rotmat[4][4];
968
969 unit_m4(rotmat);
970
971 if (pivot == CAM_S3D_PIVOT_CENTER) {
972 fac = -fac;
973 fac_signed = -fac_signed;
974 }
975
976 angle = atanf((interocular_distance * 0.5f) / convergence_distance) / fac;
977
978 angle_cos = cosf(angle * fac_signed);
979 angle_sin = sinf(angle * fac_signed);
980
981 rotmat[0][0] = angle_cos;
982 rotmat[2][0] = -angle_sin;
983 rotmat[0][2] = angle_sin;
984 rotmat[2][2] = angle_cos;
985
986 if (pivot == CAM_S3D_PIVOT_CENTER) {
987 /* set the rotation */
988 copy_m4_m4(toeinmat, rotmat);
989 /* set the translation */
990 toeinmat[3][0] = interocular_distance * fac_signed;
991
992 /* transform */
993 normalize_m4_m4(r_modelmat, camera->object_to_world().ptr());
994 mul_m4_m4m4(r_modelmat, r_modelmat, toeinmat);
995
996 /* scale back to the original size */
997 mul_m4_m4m4(r_modelmat, r_modelmat, sizemat);
998 }
999 else { /* CAM_S3D_PIVOT_LEFT, CAM_S3D_PIVOT_RIGHT */
1000 /* rotate perpendicular to the interocular line */
1001 normalize_m4_m4(r_modelmat, camera->object_to_world().ptr());
1002 mul_m4_m4m4(r_modelmat, r_modelmat, rotmat);
1003
1004 /* translate along the interocular line */
1005 unit_m4(toeinmat);
1006 toeinmat[3][0] = -interocular_distance * fac_signed;
1007 mul_m4_m4m4(r_modelmat, r_modelmat, toeinmat);
1008
1009 /* rotate to toe-in angle */
1010 mul_m4_m4m4(r_modelmat, r_modelmat, rotmat);
1011
1012 /* scale back to the original size */
1013 mul_m4_m4m4(r_modelmat, r_modelmat, sizemat);
1014 }
1015 }
1016 else {
1017 normalize_m4_m4(r_modelmat, camera->object_to_world().ptr());
1018
1019 /* translate - no rotation in CAM_S3D_OFFAXIS, CAM_S3D_PARALLEL */
1020 translate_m4(r_modelmat, -interocular_distance * fac_signed, 0.0f, 0.0f);
1021
1022 /* scale back to the original size */
1023 mul_m4_m4m4(r_modelmat, r_modelmat, sizemat);
1024 }
1025}
1026
1028 const Object *camera,
1029 const bool is_left,
1030 float r_viewmat[4][4])
1031{
1033 rd, camera, is_left ? STEREO_LEFT_NAME : STEREO_RIGHT_NAME, r_viewmat);
1034 invert_m4(r_viewmat);
1035}
1036
1037/* left is the default */
1038static bool camera_is_left(const char *viewname)
1039{
1040 if (viewname && viewname[0] != '\0') {
1041 return !STREQ(viewname, STEREO_RIGHT_NAME);
1042 }
1043 return true;
1044}
1045
1047 const Object *camera,
1048 const char *viewname,
1049 float r_modelmat[4][4])
1050{
1051 BKE_camera_multiview_model_matrix_scaled(rd, camera, viewname, r_modelmat);
1052 normalize_m4(r_modelmat);
1053}
1054
1056 const Object *camera,
1057 const char *viewname,
1058 float r_modelmat[4][4])
1059{
1060 const bool is_multiview = (rd && rd->scemode & R_MULTIVIEW) != 0;
1061
1062 if (!is_multiview) {
1063 camera_model_matrix(camera, r_modelmat);
1064 }
1065 else if (rd->views_format == SCE_VIEWS_FORMAT_MULTIVIEW) {
1066 camera_model_matrix(camera, r_modelmat);
1067 }
1068 else { /* SCE_VIEWS_SETUP_BASIC */
1069 const bool is_left = camera_is_left(viewname);
1070 camera_stereo3d_model_matrix(camera, is_left, r_modelmat);
1071 }
1072}
1073
1075 const Object *camera,
1076 const char *viewname,
1077 float r_winmat[4][4])
1078{
1080
1081 /* Setup parameters */
1084 BKE_camera_multiview_params(rd, &params, camera, viewname);
1085
1086 /* Compute matrix, view-plane, etc. */
1089
1090 copy_m4_m4(r_winmat, params.winmat);
1091}
1092
1094{
1095 const bool is_multiview = (rd && rd->scemode & R_MULTIVIEW) != 0;
1096
1097 if (!is_multiview) {
1098 return false;
1099 }
1100
1101 if (camera->type != OB_CAMERA) {
1102 return false;
1103 }
1104
1105 const Camera *cam = static_cast<const Camera *>(camera->data);
1106
1109 ((cam->stereo.flag & CAM_S3D_SPHERICAL) != 0))
1110 {
1111 return true;
1112 }
1113
1114 return false;
1115}
1116
1117static Object *camera_multiview_advanced(const Scene *scene, Object *camera, const char *suffix)
1118{
1119 char name[MAX_NAME];
1120 const char *camera_name = camera->id.name + 2;
1121 const int len_name = strlen(camera_name);
1122 int len_suffix_max = -1;
1123
1124 name[0] = '\0';
1125
1126 /* we need to take the better match, thus the len_suffix_max test */
1127 LISTBASE_FOREACH (const SceneRenderView *, srv, &scene->r.views) {
1128 const int len_suffix = strlen(srv->suffix);
1129
1130 if ((len_suffix < len_suffix_max) || (len_name < len_suffix)) {
1131 continue;
1132 }
1133
1134 if (STREQ(camera_name + (len_name - len_suffix), srv->suffix)) {
1135 SNPRINTF(name, "%.*s%s", (len_name - len_suffix), camera_name, suffix);
1136 len_suffix_max = len_suffix;
1137 }
1138 }
1139
1140 if (name[0] != '\0') {
1142 if (ob != nullptr) {
1143 return ob;
1144 }
1145 }
1146
1147 return camera;
1148}
1149
1150Object *BKE_camera_multiview_render(const Scene *scene, Object *camera, const char *viewname)
1151{
1152 const bool is_multiview = (camera != nullptr) && (scene->r.scemode & R_MULTIVIEW) != 0;
1153
1154 if (!is_multiview) {
1155 return camera;
1156 }
1158 return camera;
1159 }
1160 /* SCE_VIEWS_FORMAT_MULTIVIEW */
1161 const char *suffix = BKE_scene_multiview_view_suffix_get(&scene->r, viewname);
1162 return camera_multiview_advanced(scene, camera, suffix);
1163}
1164
1165static float camera_stereo3d_shift_x(const Object *camera, const char *viewname)
1166{
1167 const Camera *data = static_cast<const Camera *>(camera->data);
1168 float shift = data->shiftx;
1169 float interocular_distance, convergence_distance;
1170 short convergence_mode, pivot;
1171 bool is_left = true;
1172
1173 float fac = 1.0f;
1174 float fac_signed;
1175
1176 if (viewname && viewname[0]) {
1177 is_left = STREQ(viewname, STEREO_LEFT_NAME);
1178 }
1179
1180 interocular_distance = data->stereo.interocular_distance;
1181 convergence_distance = data->stereo.convergence_distance;
1182 convergence_mode = data->stereo.convergence_mode;
1183 pivot = data->stereo.pivot;
1184
1185 if (convergence_mode != CAM_S3D_OFFAXIS) {
1186 return shift;
1187 }
1188
1189 if (((pivot == CAM_S3D_PIVOT_LEFT) && is_left) || ((pivot == CAM_S3D_PIVOT_RIGHT) && !is_left)) {
1190 return shift;
1191 }
1192
1193 if (pivot == CAM_S3D_PIVOT_CENTER) {
1194 fac = 0.5f;
1195 }
1196
1197 fac_signed = is_left ? fac : -fac;
1198 shift += ((interocular_distance / data->sensor_x) * (data->lens / convergence_distance)) *
1199 fac_signed;
1200
1201 return shift;
1202}
1203
1205 const Object *camera,
1206 const char *viewname)
1207{
1208 const bool is_multiview = (rd && rd->scemode & R_MULTIVIEW) != 0;
1209 const Camera *data = static_cast<const Camera *>(camera->data);
1210
1211 BLI_assert(camera->type == OB_CAMERA);
1212
1213 if (!is_multiview) {
1214 return data->shiftx;
1215 }
1217 return data->shiftx;
1218 }
1219 if (data->type == CAM_PANO) {
1220 return data->shiftx;
1221 }
1222 /* SCE_VIEWS_SETUP_BASIC */
1223 return camera_stereo3d_shift_x(camera, viewname);
1224}
1225
1228 const Object *camera,
1229 const char *viewname)
1230{
1231 if (camera->type == OB_CAMERA) {
1232 params->shiftx = BKE_camera_multiview_shift_x(rd, camera, viewname);
1233 }
1234}
1235
1237
1238/* -------------------------------------------------------------------- */
1241
1243{
1244 CameraBGImage *bgpic = MEM_callocN<CameraBGImage>("Background Image");
1245
1246 bgpic->scale = 1.0f;
1247 bgpic->alpha = 0.5f;
1248 bgpic->iuser.flag |= IMA_ANIM_ALWAYS;
1251
1252 BLI_addtail(&cam->bg_images, bgpic);
1253
1254 return bgpic;
1255}
1256
1258{
1259 CameraBGImage *bgpic_dst = static_cast<CameraBGImage *>(MEM_dupallocN(bgpic_src));
1260
1261 bgpic_dst->next = bgpic_dst->prev = nullptr;
1262
1263 if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
1264 id_us_plus((ID *)bgpic_dst->ima);
1265 id_us_plus((ID *)bgpic_dst->clip);
1266 }
1267
1270 }
1271
1272 return bgpic_dst;
1273}
1274
1276{
1277 BLI_remlink(&cam->bg_images, bgpic);
1278
1279 MEM_freeN(bgpic);
1280}
1281
1283{
1284 CameraBGImage *bgpic = static_cast<CameraBGImage *>(cam->bg_images.first);
1285
1286 while (bgpic) {
1287 CameraBGImage *next_bgpic = bgpic->next;
1288
1290
1291 bgpic = next_bgpic;
1292 }
1293}
1294
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
bool BKE_bpath_foreach_path_fixed_process(BPathForeachPathData *bpath_data, char *path, size_t path_maxncpy)
Definition bpath.cc:125
Camera data-block and utility functions.
#define CAMERA_PARAM_ZOOM_INIT_PERSP
Definition BKE_camera.h:76
#define CAMERA_PARAM_ZOOM_INIT_CAMOB
Definition BKE_camera.h:75
IDProperty * IDP_ID_system_properties_ensure(ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition idprop.cc:900
IDProperty * IDP_ID_system_properties_get(ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition idprop.cc:895
IDProperty * IDP_GetPropertyTypeFromGroup(const IDProperty *prop, blender::StringRef name, char type) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:768
void IDP_FreeProperty(IDProperty *prop)
Definition idprop.cc:1251
#define IDP_int_set(prop, value)
bool IDP_AddToGroup(IDProperty *group, IDProperty *prop) ATTR_NONNULL()
Definition idprop.cc:717
IDProperty * IDP_CopyProperty(const IDProperty *prop) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:863
#define IDP_float_set(prop, value)
IDTypeInfo IDType_ID_CA
@ IDTYPE_FLAGS_APPEND_IS_REUSABLE
Definition BKE_idtype.hh:47
void id_us_plus(ID *id)
Definition lib_id.cc:358
void * BKE_id_new(Main *bmain, short type, const char *name)
Definition lib_id.cc:1514
@ LIB_ID_COPY_NO_LIB_OVERRIDE_LOCAL_DATA_FLAG
@ LIB_ID_CREATE_NO_USER_REFCOUNT
void BKE_id_blend_write(BlendWriter *writer, ID *id)
Definition lib_id.cc:2631
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(data_, id_super_, cb_flag_)
@ IDWALK_CB_USER
@ IDWALK_CB_NOP
LibraryForeachIDFlag BKE_lib_query_foreachid_process_flags_get(const LibraryForeachIDData *data)
Definition lib_query.cc:129
@ IDWALK_DO_DEPRECATED_POINTERS
General operations, lookup, etc. for blender objects.
void BKE_scene_foreach_display_point(Depsgraph *depsgraph, void(*func_cb)(const float[3], void *), void *user_data)
Object * BKE_scene_object_find_by_name(const Scene *scene, const char *name)
Definition scene.cc:2021
const char * BKE_scene_multiview_view_suffix_get(const RenderData *rd, const char *viewname)
Definition scene.cc:3137
float BKE_screen_view3d_zoom_to_fac(float camzoom)
Definition screen.cc:1039
#define BLI_assert(a)
Definition BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:497
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:131
void orthographic_m4(float mat[4][4], float left, float right, float bottom, float top, float nearClip, float farClip)
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
Definition math_geom.cc:217
int isect_line_line_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3], float r_i1[3], float r_i2[3])
void perspective_m4(float mat[4][4], float left, float right, float bottom, float top, float nearClip, float farClip)
bool isect_plane_plane_v3(const float plane_a[4], const float plane_b[4], float r_isect_co[3], float r_isect_no[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float plane_point_side_v3(const float plane[4], const float co[3])
void planes_from_projmat(const float mat[4][4], float left[4], float right[4], float bottom[4], float top[4], float near[4], float far[4])
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void copy_m3_m4(float m1[3][3], const float m2[4][4])
void normalize_m4_m4(float rmat[4][4], const float mat[4][4]) ATTR_NONNULL()
void copy_m4_m3(float m1[4][4], const float m2[3][3])
void translate_m4(float mat[4][4], float Tx, float Ty, float Tz)
void normalize_m3(float R[3][3]) ATTR_NONNULL()
void size_to_mat4(float R[4][4], const float size[3])
void copy_m4_m4(float m1[4][4], const float m2[4][4])
void mul_m4_v4(const float mat[4][4], float r[4])
bool invert_m4(float mat[4][4])
void mat4_to_size(float size[3], const float M[4][4])
void transpose_m4(float R[4][4])
void normalize_m4(float R[4][4]) ATTR_NONNULL()
void unit_m4(float m[4][4])
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE void zero_v3(float r[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE float normalize_v3(float n[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition BLI_rect.h:198
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition BLI_rect.h:194
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition BLI_rect.h:202
void BLI_rctf_mul(struct rctf *rect, float factor)
Definition rct.cc:588
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition BLI_rect.h:206
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:604
unsigned int uint
#define CLAMP_MAX(a, c)
#define ELEM(...)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define STREQ(a, b)
#define CLAMP_MIN(a, b)
#define BLO_write_id_struct(writer, struct_name, id_address, id)
#define BLO_write_struct(writer, struct_name, data_ptr)
void BLO_read_string(BlendDataReader *reader, char **ptr_p)
Definition readfile.cc:5828
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
#define BLO_read_struct_list(reader, struct_name, list)
bool BLO_write_is_undo(BlendWriter *writer)
#define BLT_I18NCONTEXT_ID_CAMERA
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
ID and Library types, which are fundamental for SDNA.
#define FILTER_ID_OB
Definition DNA_ID.h:1214
#define FILTER_ID_CA
Definition DNA_ID.h:1200
#define ID_IS_LINKED(_id)
Definition DNA_ID.h:694
@ INDEX_ID_CA
Definition DNA_ID.h:1333
#define FILTER_ID_IM
Definition DNA_ID.h:1204
@ IDP_FLOAT
@ IDP_INT
@ IDP_GROUP
@ CAM_S3D_OFFAXIS
@ CAM_S3D_TOE
#define DEFAULT_SENSOR_HEIGHT
@ CAM_S3D_SPHERICAL
@ CAM_PERSP
@ CAM_PANO
@ CAM_CUSTOM
@ CAM_ORTHO
@ CAM_S3D_PIVOT_CENTER
@ CAM_S3D_PIVOT_RIGHT
@ CAM_S3D_PIVOT_LEFT
@ CAMERA_SENSOR_FIT_HOR
@ CAMERA_SENSOR_FIT_AUTO
@ CAMERA_SENSOR_FIT_VERT
#define DEFAULT_SENSOR_WIDTH
@ CAM_BGIMG_FLAG_CAMERA_ASPECT
@ CAM_BGIMG_FLAG_OVERRIDE_LIBRARY_LOCAL
@ CAM_BGIMG_FLAG_EXPANDED
#define DNA_struct_default_get(struct_name)
#define MAX_NAME
Definition DNA_defs.h:50
@ IMA_ANIM_ALWAYS
Object is a sort of wrapper for general info.
@ OB_CAMERA
@ OB_LAMP
#define STEREO_LEFT_NAME
#define STEREO_RIGHT_NAME
@ SCE_VIEWS_FORMAT_STEREO_3D
@ SCE_VIEWS_FORMAT_MULTIVIEW
@ R_MULTIVIEW
@ RV3D_CAMOB
@ RV3D_ORTHO
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:117
Read Guarded memory(de)allocation.
static void camera_blend_read_data(BlendDataReader *reader, ID *id)
static void camera_foreach_id(ID *id, LibraryForeachIDData *data)
float BKE_camera_sensor_size(int sensor_fit, float sensor_x, float sensor_y)
bool BKE_camera_view_frame_fit_to_coords(const Depsgraph *depsgraph, const float(*cos)[3], int num_cos, Object *camera_ob, float r_co[3], float *r_scale)
void BKE_camera_multiview_model_matrix_scaled(const RenderData *rd, const Object *camera, const char *viewname, float r_modelmat[4][4])
bool BKE_camera_view_frame_fit_to_scene(Depsgraph *depsgraph, const Scene *scene, Object *camera_ob, float r_co[3], float *r_scale, float *r_clip_start, float *r_clip_end)
CameraBGImage * BKE_camera_background_image_copy(const CameraBGImage *bgpic_src, const int flag)
#define Z_MAX
static bool camera_frame_fit_calc_from_data(CameraParams *params, CameraViewFrameData *data, float r_co[3], float *r_scale, float *r_clip_start, float *r_clip_end)
static void camera_frame_fit_data_init(const Scene *scene, const Object *ob, const bool do_clip_dists, CameraParams *params, CameraViewFrameData *data)
static bool camera_is_left(const char *viewname)
CameraBGImage * BKE_camera_background_image_new(Camera *cam)
void BKE_camera_multiview_params(const RenderData *rd, CameraParams *params, const Object *camera, const char *viewname)
#define CAMERA_VIEWFRAME_NUM_PLANES
void BKE_camera_multiview_view_matrix(const RenderData *rd, const Object *camera, const bool is_left, float r_viewmat[4][4])
static void camera_stereo3d_model_matrix(const Object *camera, const bool is_left, float r_modelmat[4][4])
static void camera_model_matrix(const Object *camera, float r_modelmat[4][4])
static void camera_copy_data(Main *, std::optional< Library * >, ID *id_dst, const ID *id_src, const int flag)
#define Y_MIN
void BKE_camera_params_from_object(CameraParams *params, const Object *cam_ob)
void BKE_camera_view_frame(const Scene *scene, const Camera *camera, float r_vec[4][3])
static float camera_stereo3d_shift_x(const Object *camera, const char *viewname)
#define Y_MAX
void BKE_camera_params_from_view3d(CameraParams *params, const Depsgraph *depsgraph, const View3D *v3d, const RegionView3D *rv3d)
int BKE_camera_sensor_fit(int sensor_fit, float sizex, float sizey)
void BKE_camera_params_init(CameraParams *params)
static void camera_to_frame_view_cb(const float co[3], void *user_data)
void BKE_camera_view_frame_ex(const Scene *scene, const Camera *camera, const float drawsize, const bool do_clip, const float scale[3], float r_asp[2], float r_shift[2], float *r_drawsize, float r_vec[4][3])
void BKE_camera_params_crop_viewplane(rctf *viewplane, int winx, int winy, const rcti *region)
Camera * BKE_camera_add(Main *bmain, const char *name)
#define Z_MIN
float BKE_camera_object_dof_distance(const Object *ob)
void BKE_camera_params_compute_viewplane(CameraParams *params, int winx, int winy, float aspx, float aspy)
void BKE_camera_multiview_model_matrix(const RenderData *rd, const Object *camera, const char *viewname, float r_modelmat[4][4])
void BKE_camera_multiview_window_matrix(const RenderData *rd, const Object *camera, const char *viewname, float r_winmat[4][4])
void BKE_camera_background_image_remove(Camera *cam, CameraBGImage *bgpic)
static CameraCyclesCompatibilityData camera_write_cycles_compatibility_data_create(ID *id)
void BKE_camera_background_image_clear(Camera *cam)
void BKE_camera_params_compute_matrix(CameraParams *params)
static void camera_blend_write(BlendWriter *writer, ID *id, const void *id_address)
bool BKE_camera_multiview_spherical_stereo(const RenderData *rd, const Object *camera)
static void camera_free_data(ID *id)
static void camera_foreach_path(ID *id, BPathForeachPathData *bpath_data)
static void camera_init_data(ID *id)
static Object * camera_multiview_advanced(const Scene *scene, Object *camera, const char *suffix)
static void camera_write_cycles_compatibility_data_clear(ID *id, CameraCyclesCompatibilityData &data)
Object * BKE_camera_multiview_render(const Scene *scene, Object *camera, const char *viewname)
float BKE_camera_multiview_shift_x(const RenderData *rd, const Object *camera, const char *viewname)
BMesh const char void * data
BPy_StructRNA * depsgraph
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
nullptr float
static float is_left(const float2 &p0, const float2 &p1, const float2 &p2)
#define cos
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void * MEM_dupallocN(const void *vmemh)
Definition mallocn.cc:143
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
std::unique_ptr< IDProperty, IDPropertyDeleter > create(StringRef prop_name, int32_t value, eIDPropertyFlag flags={})
Allocate a new IDProperty of type IDP_INT, set its name and value.
std::unique_ptr< IDProperty, IDPropertyDeleter > create_group(StringRef prop_name, eIDPropertyFlag flags={})
Allocate a new IDProperty of type IDP_GROUP.
const char * name
#define fabsf
#define atanf
#define sinf
#define tanf
#define cosf
#define FLT_MAX
Definition stdcycles.h:14
struct CameraBGImage * next
struct CameraBGImage * prev
struct MovieClip * clip
struct ImageUser iuser
struct Image * ima
struct Object * focus_object
float plane_tx[CAMERA_VIEWFRAME_NUM_PLANES][4]
float dist_vals[CAMERA_VIEWFRAME_NUM_PLANES]
float clip_end
char panorama_type
char sensor_fit
float sensor_y
float latitude_max
float fisheye_polynomial_k3
float longitude_max
struct ListBase bg_images
char * custom_bytecode
float fisheye_polynomial_k1
float latitude_min
float fisheye_polynomial_k2
struct Text * custom_shader
struct CameraStereoSettings stereo
char custom_filepath[1024]
float fisheye_fov
float fisheye_polynomial_k0
float fisheye_polynomial_k4
float sensor_x
float clip_start
float fisheye_lens
float longitude_min
struct CameraDOFSettings dof
float ortho_scale
Definition DNA_ID.h:414
char name[258]
Definition DNA_ID.h:432
float spotsize
void * first
struct bPose * pose
struct RenderData r
struct Object * camera
float clip_start
float pose_mat[4][4]
float xmax
float xmin
float ymax
float ymin
int ymin
int xmin
i
Definition text_draw.cc:230
#define N_(msgid)
uint8_t flag
Definition wm_window.cc:145