Blender V5.0
usd_writer_camera.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2019 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
7
8#include <pxr/usd/usdGeom/camera.h>
9#include <pxr/usd/usdGeom/tokens.h>
10
11#include "BKE_camera.h"
12#include "BLI_assert.h"
13
15
16#include "DNA_camera_types.h"
17#include "DNA_scene_types.h"
18
19namespace blender::io::usd {
20
22
24{
25 const Camera *camera = static_cast<const Camera *>(context->object->data);
26 return camera->type == CAM_PERSP;
27}
28
29static void camera_sensor_size_for_render(const Camera *camera,
30 const RenderData *rd,
31 float *r_sensor,
32 float *r_sensor_x,
33 float *r_sensor_y)
34{
35 /* Compute the final image size in pixels. */
36 float sizex = rd->xsch * rd->xasp;
37 float sizey = rd->ysch * rd->yasp;
38
39 int sensor_fit = BKE_camera_sensor_fit(camera->sensor_fit, sizex, sizey);
40 float sensor_size = BKE_camera_sensor_size(
41 camera->sensor_fit, camera->sensor_x, camera->sensor_y);
42 *r_sensor = sensor_size;
43
44 switch (sensor_fit) {
46 *r_sensor_x = sensor_size;
47 *r_sensor_y = sensor_size * sizey / sizex;
48 break;
50 *r_sensor_x = sensor_size * sizex / sizey;
51 *r_sensor_y = sensor_size;
52 break;
54 BLI_assert_msg(0, "Camera fit should be either horizontal or vertical");
55 break;
56 }
57}
58
60{
61 const double meters_per_unit = get_meters_per_unit(usd_export_context_.export_params);
62 const float unit_scale = float(1.0 / meters_per_unit);
63
64 pxr::UsdTimeCode time = get_export_time_code();
65 pxr::UsdGeomCamera usd_camera = pxr::UsdGeomCamera::Define(usd_export_context_.stage,
66 usd_export_context_.usd_path);
67
68 const Camera *camera = static_cast<const Camera *>(context.object->data);
69 const Scene *scene = DEG_get_evaluated_scene(usd_export_context_.depsgraph);
70
71 usd_camera.CreateProjectionAttr().Set(pxr::UsdGeomTokens->perspective);
72
73 /*
74 * For USD, these camera properties are in tenths of a world unit.
75 * https://graphics.pixar.com/usd/release/api/class_usd_geom_camera.html#UsdGeom_CameraUnits
76 *
77 * tenth_unit_to_meters = stage_meters_per_unit / 10
78 * tenth_unit_to_millimeters = 1000 * unit_to_tenth_unit
79 * = 100 * stage_meters_per_unit
80 */
81 const float tenth_unit_to_mm = float(100.0 * meters_per_unit * scene->unit.scale_length);
82
83 float sensor_size, aperture_x, aperture_y;
84 camera_sensor_size_for_render(camera, &scene->r, &sensor_size, &aperture_x, &aperture_y);
85
86 set_attribute(usd_camera.CreateFocalLengthAttr(pxr::VtValue(), true),
87 camera->lens / tenth_unit_to_mm,
88 time,
90 set_attribute(usd_camera.CreateHorizontalApertureAttr(pxr::VtValue(), true),
91 aperture_x / tenth_unit_to_mm,
92 time,
94 set_attribute(usd_camera.CreateVerticalApertureAttr(pxr::VtValue(), true),
95 aperture_y / tenth_unit_to_mm,
96 time,
98 set_attribute(usd_camera.CreateHorizontalApertureOffsetAttr(pxr::VtValue(), true),
99 sensor_size * camera->shiftx / tenth_unit_to_mm,
100 time,
102 set_attribute(usd_camera.CreateVerticalApertureOffsetAttr(pxr::VtValue(), true),
103 sensor_size * camera->shifty / tenth_unit_to_mm,
104 time,
106 set_attribute(usd_camera.CreateClippingRangeAttr(pxr::VtValue(), true),
107 pxr::GfVec2f(camera->clip_start * unit_scale, camera->clip_end * unit_scale),
108 time,
110
111 /* Write DoF-related attributes. */
112 if (camera->dof.flag & CAM_DOF_ENABLED) {
113 const float focus_distance = BKE_camera_object_dof_distance(context.object);
114 set_attribute(usd_camera.CreateFStopAttr(pxr::VtValue(), true),
115 camera->dof.aperture_fstop,
116 time,
118 set_attribute(usd_camera.CreateFocusDistanceAttr(pxr::VtValue(), true),
119 focus_distance * unit_scale,
120 time,
122 }
123 else {
124 set_attribute(usd_camera.CreateFStopAttr(pxr::VtValue(), true), 0.0f, time, usd_value_writer_);
125 }
126
127 auto prim = usd_camera.GetPrim();
128 write_id_properties(prim, camera->id, time);
129}
130
131} // namespace blender::io::usd
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)
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
@ CAM_DOF_ENABLED
@ CAM_PERSP
@ CAMERA_SENSOR_FIT_HOR
@ CAMERA_SENSOR_FIT_AUTO
@ CAMERA_SENSOR_FIT_VERT
pxr::UsdTimeCode get_export_time_code() const
pxr::UsdUtilsSparseValueWriter usd_value_writer_
USDAbstractWriter(const USDExporterContext &usd_export_context)
void write_id_properties(const pxr::UsdPrim &prim, const ID &id, pxr::UsdTimeCode=pxr::UsdTimeCode::Default()) const
const USDExporterContext usd_export_context_
USDCameraWriter(const USDExporterContext &ctx)
bool is_supported(const HierarchyContext *context) const override
void do_write(HierarchyContext &context) override
nullptr float
static void camera_sensor_size_for_render(const Camera *camera, const RenderData *rd, float *r_sensor, float *r_sensor_x, float *r_sensor_y)
void set_attribute(const pxr::UsdAttribute &attr, const USDT value, pxr::UsdTimeCode time, pxr::UsdUtilsSparseValueWriter &value_writer)
double get_meters_per_unit(const USDExportParams &params)
float clip_end
char sensor_fit
float sensor_y
float sensor_x
float clip_start
struct CameraDOFSettings dof
struct RenderData r
struct UnitSettings unit