Blender V5.0
render/hydra/camera.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "camera.hh"
6
7#include "BKE_camera.h"
8
9#include "DNA_camera_types.h"
10#include "DNA_object_types.h"
11#include "DNA_scene_types.h"
12#include "DNA_screen_types.h"
13#include "DNA_view3d_types.h"
14
16
17#include "hydra/object.hh"
18
20
21static void gf_camera_fill_dof_data(const Object *camera_obj, pxr::GfCamera *gf_camera)
22{
23 if (camera_obj == nullptr || camera_obj->type != OB_CAMERA) {
24 return;
25 }
26
27 const Camera *camera = static_cast<Camera *>(camera_obj->data);
28 if (!(camera->dof.flag & CAM_DOF_ENABLED)) {
29 return;
30 }
31
32 /* World units. Handles DoF object and value. Object takes precedence. */
33 const float focus_distance = BKE_camera_object_dof_distance(camera_obj);
34 gf_camera->SetFocusDistance(focus_distance);
35
36 /*
37 * F-stop is unit-less, however it's a ratio between focal length and aperture diameter.
38 * The aperture must be in the same unit for correctness.
39 * Focal length in GfCamera is defined in tenths of a world unit.
40 *
41 * Following the logic of USD camera data writer:
42 * tenth_unit_to_meters = 1 / 10
43 * tenth_unit_to_millimeters = 1000 * tenth_unit_to_meters = 100
44 * Scene's units scale is not used for camera's focal length.
45 */
46 gf_camera->SetFStop(camera->dof.aperture_fstop * 100.0);
47}
48
49static pxr::GfCamera gf_camera(const CameraParams &params,
50 const pxr::GfVec2i &res,
51 const pxr::GfVec4f &border)
52{
53 pxr::GfCamera camera;
54
55 camera.SetProjection(params.is_ortho ? pxr::GfCamera::Projection::Orthographic :
56 pxr::GfCamera::Projection::Perspective);
57 camera.SetClippingRange(pxr::GfRange1f(params.clip_start, params.clip_end));
58 camera.SetFocalLength(params.lens);
59
60 pxr::GfVec2f b_pos(border[0], border[1]), b_size(border[2], border[3]);
61 float sensor_size = BKE_camera_sensor_size(params.sensor_fit, params.sensor_x, params.sensor_y);
62 pxr::GfVec2f sensor_scale = (BKE_camera_sensor_fit(params.sensor_fit, res[0], res[1]) ==
64 pxr::GfVec2f(1.0f, float(res[1]) / res[0]) :
65 pxr::GfVec2f(float(res[0]) / res[1], 1.0f);
66 pxr::GfVec2f aperture = pxr::GfVec2f((params.is_ortho) ? params.ortho_scale : sensor_size);
67 aperture = pxr::GfCompMult(aperture, sensor_scale);
68 aperture = pxr::GfCompMult(aperture, b_size);
69 aperture *= params.zoom;
70 if (params.is_ortho) {
71 /* Use tenths of a world unit according to USD docs
72 * https://graphics.pixar.com/usd/docs/api/class_gf_camera.html */
73 aperture *= 10.0f;
74 }
75 camera.SetHorizontalAperture(aperture[0]);
76 camera.SetVerticalAperture(aperture[1]);
77
78 pxr::GfVec2f lens_shift = pxr::GfVec2f(params.shiftx, params.shifty);
79 lens_shift = pxr::GfCompDiv(lens_shift, sensor_scale);
80 lens_shift += pxr::GfVec2f(params.offsetx, params.offsety);
81 lens_shift += b_pos + b_size * 0.5f - pxr::GfVec2f(0.5f);
82 lens_shift = pxr::GfCompDiv(lens_shift, b_size);
83 camera.SetHorizontalApertureOffset(lens_shift[0] * aperture[0]);
84 camera.SetVerticalApertureOffset(lens_shift[1] * aperture[1]);
85
86 return camera;
87}
88
89pxr::GfCamera gf_camera(const Depsgraph *depsgraph,
90 const View3D *v3d,
91 const ARegion *region,
92 const pxr::GfVec4f &border)
93{
94 const RegionView3D *region_data = (const RegionView3D *)region->regiondata;
96
100
101 pxr::GfCamera camera = gf_camera(params, pxr::GfVec2i(region->winx, region->winy), border);
102 camera.SetTransform(io::hydra::gf_matrix_from_transform(region_data->viewmat).GetInverse());
103
104 /* Ensure viewport is in active camera view mode. */
105 if (region_data->persp == RV3D_CAMOB) {
106 gf_camera_fill_dof_data(scene->camera, &camera);
107 }
108
109 return camera;
110}
111
112pxr::GfCamera gf_camera(const Object *camera_obj,
113 const pxr::GfVec2i &res,
114 const pxr::GfVec4f &border)
115{
119
120 pxr::GfCamera camera = gf_camera(params, res, border);
121 camera.SetTransform(io::hydra::gf_matrix_from_transform(camera_obj->object_to_world().ptr()));
122
123 gf_camera_fill_dof_data(camera_obj, &camera);
124
125 return camera;
126}
127
128} // namespace blender::render::hydra
Camera data-block and utility functions.
float BKE_camera_sensor_size(int sensor_fit, float sensor_x, float sensor_y)
float BKE_camera_object_dof_distance(const struct Object *ob)
int BKE_camera_sensor_fit(int sensor_fit, float sizex, float sizey)
void BKE_camera_params_init(CameraParams *params)
void BKE_camera_params_from_view3d(CameraParams *params, const struct Depsgraph *depsgraph, const struct View3D *v3d, const struct RegionView3D *rv3d)
void BKE_camera_params_from_object(CameraParams *params, const struct Object *cam_ob)
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
@ CAM_DOF_ENABLED
@ CAMERA_SENSOR_FIT_HOR
Object is a sort of wrapper for general info.
@ OB_CAMERA
@ RV3D_CAMOB
BPy_StructRNA * depsgraph
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
pxr::GfMatrix4d gf_matrix_from_transform(const float m[4][4])
static void gf_camera_fill_dof_data(const Object *camera_obj, pxr::GfCamera *gf_camera)
static pxr::GfCamera gf_camera(const CameraParams &params, const pxr::GfVec2i &res, const pxr::GfVec4f &border)
void * regiondata
struct CameraDOFSettings dof
float viewmat[4][4]
struct Object * camera