Add Chromium-only Blender WebEngine parity work
This commit is contained in:
137
blender-5.2.0/source/blender/render/hydra/camera.cc
Normal file
137
blender-5.2.0/source/blender/render/hydra/camera.cc
Normal file
@@ -0,0 +1,137 @@
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "camera.hh"
|
||||
|
||||
#include "BKE_camera.h"
|
||||
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
|
||||
#include "DEG_depsgraph_query.hh"
|
||||
|
||||
namespace blender::render::hydra {
|
||||
|
||||
static pxr::GfMatrix4d gf_matrix_from_transform(const float m[4][4])
|
||||
{
|
||||
pxr::GfMatrix4d ret;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
ret[i][j] = m[i][j];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void gf_camera_fill_dof_data(const Object *camera_obj, pxr::GfCamera *gf_camera)
|
||||
{
|
||||
if (camera_obj == nullptr || camera_obj->type != OB_CAMERA) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Camera *camera = id_cast<Camera *>(camera_obj->data);
|
||||
if (!(camera->dof.flag & CAM_DOF_ENABLED)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* World units. Handles DoF object and value. Object takes precedence. */
|
||||
const float focus_distance = BKE_camera_object_dof_distance(camera_obj);
|
||||
gf_camera->SetFocusDistance(focus_distance);
|
||||
|
||||
/*
|
||||
* F-stop is unit-less, however it's a ratio between focal length and aperture diameter.
|
||||
* The aperture must be in the same unit for correctness.
|
||||
* Focal length in GfCamera is defined in tenths of a world unit.
|
||||
*
|
||||
* Following the logic of USD camera data writer:
|
||||
* tenth_unit_to_meters = 1 / 10
|
||||
* tenth_unit_to_millimeters = 1000 * tenth_unit_to_meters = 100
|
||||
* Scene's units scale is not used for camera's focal length.
|
||||
*/
|
||||
gf_camera->SetFStop(camera->dof.aperture_fstop * 100.0);
|
||||
}
|
||||
|
||||
static pxr::GfCamera gf_camera(const CameraParams ¶ms,
|
||||
const pxr::GfVec2i &res,
|
||||
const pxr::GfVec4f &border)
|
||||
{
|
||||
pxr::GfCamera camera;
|
||||
|
||||
camera.SetProjection(params.is_ortho ? pxr::GfCamera::Projection::Orthographic :
|
||||
pxr::GfCamera::Projection::Perspective);
|
||||
camera.SetClippingRange(pxr::GfRange1f(params.clip_start, params.clip_end));
|
||||
camera.SetFocalLength(params.lens);
|
||||
|
||||
pxr::GfVec2f b_pos(border[0], border[1]), b_size(border[2], border[3]);
|
||||
float sensor_size = BKE_camera_sensor_size(params.sensor_fit, params.sensor_x, params.sensor_y);
|
||||
pxr::GfVec2f sensor_scale = (BKE_camera_sensor_fit(params.sensor_fit, res[0], res[1]) ==
|
||||
CAMERA_SENSOR_FIT_HOR) ?
|
||||
pxr::GfVec2f(1.0f, float(res[1]) / res[0]) :
|
||||
pxr::GfVec2f(float(res[0]) / res[1], 1.0f);
|
||||
pxr::GfVec2f aperture = pxr::GfVec2f((params.is_ortho) ? params.ortho_scale : sensor_size);
|
||||
aperture = pxr::GfCompMult(aperture, sensor_scale);
|
||||
aperture = pxr::GfCompMult(aperture, b_size);
|
||||
aperture *= params.zoom;
|
||||
if (params.is_ortho) {
|
||||
/* Use tenths of a world unit according to USD docs
|
||||
* https://graphics.pixar.com/usd/docs/api/class_gf_camera.html */
|
||||
aperture *= 10.0f;
|
||||
}
|
||||
camera.SetHorizontalAperture(aperture[0]);
|
||||
camera.SetVerticalAperture(aperture[1]);
|
||||
|
||||
pxr::GfVec2f lens_shift = pxr::GfVec2f(params.shiftx, params.shifty);
|
||||
lens_shift = pxr::GfCompDiv(lens_shift, sensor_scale);
|
||||
lens_shift += pxr::GfVec2f(params.offsetx, params.offsety);
|
||||
lens_shift += b_pos + b_size * 0.5f - pxr::GfVec2f(0.5f);
|
||||
lens_shift = pxr::GfCompDiv(lens_shift, b_size);
|
||||
camera.SetHorizontalApertureOffset(lens_shift[0] * aperture[0]);
|
||||
camera.SetVerticalApertureOffset(lens_shift[1] * aperture[1]);
|
||||
|
||||
return camera;
|
||||
}
|
||||
|
||||
pxr::GfCamera gf_camera(const Depsgraph *depsgraph,
|
||||
const View3D *v3d,
|
||||
const ARegion *region,
|
||||
const pxr::GfVec4f &border)
|
||||
{
|
||||
const RegionView3D *region_data = static_cast<const RegionView3D *>(region->regiondata);
|
||||
const Scene *scene = DEG_get_evaluated_scene(depsgraph);
|
||||
|
||||
CameraParams params;
|
||||
BKE_camera_params_init(¶ms);
|
||||
BKE_camera_params_from_view3d(¶ms, depsgraph, v3d, region_data);
|
||||
|
||||
pxr::GfCamera camera = gf_camera(params, pxr::GfVec2i(region->winx, region->winy), border);
|
||||
camera.SetTransform(gf_matrix_from_transform(region_data->viewmat).GetInverse());
|
||||
|
||||
/* Ensure viewport is in active camera view mode. */
|
||||
if (region_data->persp == RV3D_CAMOB) {
|
||||
gf_camera_fill_dof_data(scene->camera, &camera);
|
||||
}
|
||||
|
||||
return camera;
|
||||
}
|
||||
|
||||
pxr::GfCamera gf_camera(const Object *camera_obj,
|
||||
const pxr::GfVec2i &res,
|
||||
const pxr::GfVec4f &border)
|
||||
{
|
||||
CameraParams params;
|
||||
BKE_camera_params_init(¶ms);
|
||||
BKE_camera_params_from_object(¶ms, camera_obj);
|
||||
|
||||
pxr::GfCamera camera = gf_camera(params, res, border);
|
||||
camera.SetTransform(gf_matrix_from_transform(camera_obj->object_to_world().ptr()));
|
||||
|
||||
gf_camera_fill_dof_data(camera_obj, &camera);
|
||||
|
||||
return camera;
|
||||
}
|
||||
|
||||
} // namespace blender::render::hydra
|
||||
Reference in New Issue
Block a user