Changeset View
Changeset View
Standalone View
Standalone View
source/blender/usd/intern/usd_writer_camera.cc
- This file was added.
| /* | |||||
| * 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" | |||||
| } | |||||
| USDCameraWriter::USDCameraWriter(const USDExporterContext &ctx) : USDAbstractWriter(ctx) | |||||
| { | |||||
| } | |||||
| bool USDCameraWriter::is_supported(const Object *object) const | |||||
| { | |||||
| Camera *camera = static_cast<Camera *>(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); | |||||
| } | |||||
| } | |||||