diff options
author | Sybren A. Stüvel <sybren@blender.org> | 2020-03-06 18:19:35 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@blender.org> | 2020-03-06 18:19:45 +0300 |
commit | eb522af4fec58876ac1b0a73ad9bcdae2d82d33f (patch) | |
tree | 485c6a1fb23b5be256757375e2157378d3a5c61b /source/blender/io/usd/intern/usd_writer_camera.cc | |
parent | ff60dd8b18ed00902e5bdfd36882072db7af8735 (diff) |
Cleanup: move Alembic, AVI, Collada, and USD to `source/blender/io`
This moves the `alembic`, `avi`, `collada`, and `usd` modules into a common
`io` directory.
This also cleans up some `#include "../../{somedir}/{somefile}.h"` by
adding `../../io/{somedir}` to `CMakeLists.txt` and then just using
`#include "{somefile}.h"`.
No functional changes.
Diffstat (limited to 'source/blender/io/usd/intern/usd_writer_camera.cc')
-rw-r--r-- | source/blender/io/usd/intern/usd_writer_camera.cc | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/source/blender/io/usd/intern/usd_writer_camera.cc b/source/blender/io/usd/intern/usd_writer_camera.cc new file mode 100644 index 00000000000..9b85d69559c --- /dev/null +++ b/source/blender/io/usd/intern/usd_writer_camera.cc @@ -0,0 +1,111 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2019 Blender Foundation. + * All rights reserved. + */ +#include "usd_writer_camera.h" +#include "usd_hierarchy_iterator.h" + +#include <pxr/usd/usdGeom/camera.h> +#include <pxr/usd/usdGeom/tokens.h> + +extern "C" { +#include "BKE_camera.h" +#include "BLI_assert.h" + +#include "DNA_camera_types.h" +#include "DNA_scene_types.h" +} + +namespace USD { + +USDCameraWriter::USDCameraWriter(const USDExporterContext &ctx) : USDAbstractWriter(ctx) +{ +} + +bool USDCameraWriter::is_supported(const HierarchyContext *context) const +{ + Camera *camera = static_cast<Camera *>(context->object->data); + return camera->type == CAM_PERSP; +} + +static void camera_sensor_size_for_render(const Camera *camera, + const struct RenderData *rd, + float *r_sensor_x, + float *r_sensor_y) +{ + /* Compute the final image size in pixels. */ + float sizex = rd->xsch * rd->xasp; + float sizey = rd->ysch * rd->yasp; + + int sensor_fit = BKE_camera_sensor_fit(camera->sensor_fit, sizex, sizey); + + switch (sensor_fit) { + case CAMERA_SENSOR_FIT_HOR: + *r_sensor_x = camera->sensor_x; + *r_sensor_y = camera->sensor_x * sizey / sizex; + break; + case CAMERA_SENSOR_FIT_VERT: + *r_sensor_x = camera->sensor_y * sizex / sizey; + *r_sensor_y = camera->sensor_y; + break; + case CAMERA_SENSOR_FIT_AUTO: + BLI_assert(!"Camera fit should be either horizontal or vertical"); + break; + } +} + +void USDCameraWriter::do_write(HierarchyContext &context) +{ + pxr::UsdTimeCode timecode = get_export_time_code(); + pxr::UsdGeomCamera usd_camera = pxr::UsdGeomCamera::Define(usd_export_context_.stage, + usd_export_context_.usd_path); + + Camera *camera = static_cast<Camera *>(context.object->data); + Scene *scene = DEG_get_evaluated_scene(usd_export_context_.depsgraph); + + usd_camera.CreateProjectionAttr().Set(pxr::UsdGeomTokens->perspective); + + /* USD stores the focal length in "millimeters or tenths of world units", because at some point + * they decided world units might be centimeters. Quite confusing, as the USD Viewer shows the + * correct FoV when we write millimeters and not "tenths of world units". + */ + usd_camera.CreateFocalLengthAttr().Set(camera->lens, timecode); + + float aperture_x, aperture_y; + camera_sensor_size_for_render(camera, &scene->r, &aperture_x, &aperture_y); + + float film_aspect = aperture_x / aperture_y; + usd_camera.CreateHorizontalApertureAttr().Set(aperture_x, timecode); + usd_camera.CreateVerticalApertureAttr().Set(aperture_y, timecode); + usd_camera.CreateHorizontalApertureOffsetAttr().Set(aperture_x * camera->shiftx, timecode); + usd_camera.CreateVerticalApertureOffsetAttr().Set(aperture_y * camera->shifty * film_aspect, + timecode); + + usd_camera.CreateClippingRangeAttr().Set( + pxr::VtValue(pxr::GfVec2f(camera->clip_start, camera->clip_end)), timecode); + + // Write DoF-related attributes. + if (camera->dof.flag & CAM_DOF_ENABLED) { + usd_camera.CreateFStopAttr().Set(camera->dof.aperture_fstop, timecode); + + float focus_distance = scene->unit.scale_length * + BKE_camera_object_dof_distance(context.object); + usd_camera.CreateFocusDistanceAttr().Set(focus_distance, timecode); + } +} + +} // namespace USD |