This rescales the whole scene by its root transform to match the same visual size while not forcing the user to wait for scale to be applied to each object. This is requested by studios whose main applications / USD scenes are in CM, because referencing and payloading scenes from disparate scales can cause issues at resolution time. If "Apply Unit Scale Conversion" is unchecked on import, the user now has the ability to bring the objects in with a scale factor of 1.0, so that the objects may be edited as if Blender's scene units matches the imported stage's. At export time, a "Stage Meters Per Unit" value can be chosen from a list of common measurements, as well as setting a custom value. Co-authored-by: kiki <charles@skeletalstudios.com> Co-authored-by: Michael Kowalski <makowalski@nvidia.com> Pull Request: https://projects.blender.org/blender/blender/pulls/122804
93 lines
3.6 KiB
C++
93 lines
3.6 KiB
C++
/* SPDX-FileCopyrightText: 2021 Tangent Animation. All rights reserved.
|
|
* SPDX-FileCopyrightText: 2023 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
*
|
|
* Adapted from the Blender Alembic importer implementation. */
|
|
|
|
#include "usd_reader_camera.hh"
|
|
|
|
#include "DNA_camera_types.h"
|
|
#include "DNA_object_types.h"
|
|
|
|
#include "BLI_math_base.h"
|
|
|
|
#include "BKE_camera.h"
|
|
#include "BKE_object.hh"
|
|
|
|
#include <pxr/usd/usdGeom/camera.h>
|
|
|
|
namespace blender::io::usd {
|
|
|
|
void USDCameraReader::create_object(Main *bmain, const double /*motionSampleTime*/)
|
|
{
|
|
Camera *bcam = BKE_camera_add(bmain, name_.c_str());
|
|
|
|
object_ = BKE_object_add_only_object(bmain, OB_CAMERA, name_.c_str());
|
|
object_->data = bcam;
|
|
}
|
|
|
|
void USDCameraReader::read_object_data(Main *bmain, const double motionSampleTime)
|
|
{
|
|
Camera *bcam = (Camera *)object_->data;
|
|
|
|
pxr::VtValue val;
|
|
cam_prim_.GetFocalLengthAttr().Get(&val, motionSampleTime);
|
|
pxr::VtValue verApOffset;
|
|
cam_prim_.GetVerticalApertureOffsetAttr().Get(&verApOffset, motionSampleTime);
|
|
pxr::VtValue horApOffset;
|
|
cam_prim_.GetHorizontalApertureOffsetAttr().Get(&horApOffset, motionSampleTime);
|
|
pxr::VtValue clippingRangeVal;
|
|
cam_prim_.GetClippingRangeAttr().Get(&clippingRangeVal, motionSampleTime);
|
|
pxr::VtValue focalDistanceVal;
|
|
cam_prim_.GetFocusDistanceAttr().Get(&focalDistanceVal, motionSampleTime);
|
|
pxr::VtValue fstopVal;
|
|
cam_prim_.GetFStopAttr().Get(&fstopVal, motionSampleTime);
|
|
pxr::VtValue projectionVal;
|
|
cam_prim_.GetProjectionAttr().Get(&projectionVal, motionSampleTime);
|
|
pxr::VtValue verAp;
|
|
cam_prim_.GetVerticalApertureAttr().Get(&verAp, motionSampleTime);
|
|
pxr::VtValue horAp;
|
|
cam_prim_.GetHorizontalApertureAttr().Get(&horAp, motionSampleTime);
|
|
|
|
/*
|
|
* For USD, these camera properties are in tenths of a world unit.
|
|
* https://graphics.pixar.com/usd/release/api/class_usd_geom_camera.html#UsdGeom_CameraUnits
|
|
*
|
|
* tenth_unit_to_meters = stage_meters_per_unit / 10
|
|
* tenth_unit_to_millimeters = 1000 * unit_to_tenth_unit
|
|
* = 100 * stage_meters_per_unit
|
|
*/
|
|
const double tenth_unit_to_millimeters = 100.0 * settings_->stage_meters_per_unit;
|
|
bcam->lens = val.Get<float>() * tenth_unit_to_millimeters;
|
|
bcam->sensor_x = horAp.Get<float>() * tenth_unit_to_millimeters;
|
|
bcam->sensor_y = verAp.Get<float>() * tenth_unit_to_millimeters;
|
|
|
|
bcam->sensor_fit = bcam->sensor_x >= bcam->sensor_y ? CAMERA_SENSOR_FIT_HOR :
|
|
CAMERA_SENSOR_FIT_VERT;
|
|
|
|
float sensor_size = bcam->sensor_x >= bcam->sensor_y ? bcam->sensor_x : bcam->sensor_y;
|
|
bcam->shiftx = (horApOffset.Get<float>() * tenth_unit_to_millimeters) / sensor_size;
|
|
bcam->shifty = (verApOffset.Get<float>() * tenth_unit_to_millimeters) / sensor_size;
|
|
|
|
bcam->type = (projectionVal.Get<pxr::TfToken>().GetString() == "perspective") ? CAM_PERSP :
|
|
CAM_ORTHO;
|
|
|
|
/* Call UncheckedGet() to silence compiler warnings.
|
|
* Clamp to 1e-6 matching range defined in RNA. */
|
|
bcam->clip_start = max_ff(
|
|
1e-6f, clippingRangeVal.UncheckedGet<pxr::GfVec2f>()[0] * settings_->scene_scale);
|
|
bcam->clip_end = clippingRangeVal.UncheckedGet<pxr::GfVec2f>()[1] * settings_->scene_scale;
|
|
|
|
bcam->dof.focus_distance = focalDistanceVal.Get<float>() * settings_->scene_scale;
|
|
bcam->dof.aperture_fstop = float(fstopVal.Get<float>());
|
|
|
|
if (bcam->type == CAM_ORTHO) {
|
|
bcam->ortho_scale = max_ff(verAp.Get<float>(), horAp.Get<float>());
|
|
}
|
|
|
|
USDXformReader::read_object_data(bmain, motionSampleTime);
|
|
}
|
|
|
|
} // namespace blender::io::usd
|