Hydra: Use BKE_camera_params API to simplify camera code and share more with rest of Blender #114370

Merged
Brecht Van Lommel merged 20 commits from DagerD/blender:hydra-camera-refactoring into main 2023-11-15 19:03:31 +01:00
3 changed files with 50 additions and 74 deletions
Showing only changes of commit ddc281efe0 - Show all commits

View File

@ -4,6 +4,8 @@
#include "camera.h"
#include "BKE_camera.h"
#include "DNA_camera_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@ -22,9 +24,8 @@ static pxr::GfCamera set_gf_camera(bool is_ortho,
{
pxr::GfCamera gf_camera = pxr::GfCamera();
pxr::GfCamera::Projection projection = is_ortho ? pxr::GfCamera::Projection::Orthographic :
pxr::GfCamera::Projection::Perspective;
gf_camera.SetProjection(projection);
gf_camera.SetProjection(is_ortho ? pxr::GfCamera::Projection::Orthographic :
pxr::GfCamera::Projection::Perspective);
gf_camera.SetHorizontalAperture(aperture[0]);
gf_camera.SetVerticalAperture(aperture[1]);
gf_camera.SetHorizontalApertureOffset(l_shift[0] * aperture[0]);
@ -39,7 +40,7 @@ pxr::GfCamera gf_camera(const Depsgraph *depsgraph,
const View3D *v3d,
const ARegion *region,
const RenderData *rd,
pxr::GfVec4f tile)
const pxr::GfVec4f &border)
{
CameraParams camera_params;
const RegionView3D *region_data = (const RegionView3D *)region->regiondata;
@ -52,7 +53,6 @@ pxr::GfCamera gf_camera(const Depsgraph *depsgraph,
camera_sensor_size *= 2.0f;
float ratio = float(region->winx) / region->winy;
DagerD marked this conversation as resolved Outdated

We could use this:
clip_range_ = pxr::GfRange1f(camera_params_.clip_start, camera_params_.clip_end);

instead of this:

float o_depth = v3d->clip_end;

clip_range_ = pxr::GfRange1f(-o_depth * 0.5, o_depth * 0.5);
We could use this: `clip_range_ = pxr::GfRange1f(camera_params_.clip_start, camera_params_.clip_end);` instead of this: ``` float o_depth = v3d->clip_end; clip_range_ = pxr::GfRange1f(-o_depth * 0.5, o_depth * 0.5); ```
int mode;
pxr::GfRange1f clip_range;
pxr::GfVec2f lens_shift;
pxr::GfVec2f sensor_size;
@ -61,8 +61,7 @@ pxr::GfCamera gf_camera(const Depsgraph *depsgraph,
clip_range = pxr::GfRange1f(camera_params.clip_start, camera_params.clip_end);
switch (region_data->persp) {
case RV3D_PERSP:
mode = CAM_PERSP;
case RV3D_PERSP: {
lens_shift = pxr::GfVec2f(camera_params.shiftx, camera_params.shifty);
if (ratio > 1.0f) {
sensor_size = pxr::GfVec2f(camera_sensor_size, camera_sensor_size / ratio);
@ -71,8 +70,8 @@ pxr::GfCamera gf_camera(const Depsgraph *depsgraph,
sensor_size = pxr::GfVec2f(camera_sensor_size * ratio, camera_sensor_size);
}
break;
}
case RV3D_ORTHO: {
mode = CAM_ORTHO;
lens_shift = pxr::GfVec2f(camera_params.shiftx, camera_params.shifty);
float o_size = region_data->dist * camera_sensor_size / camera_params.lens;
if (ratio > 1.0f) {
@ -107,11 +106,9 @@ pxr::GfCamera gf_camera(const Depsgraph *depsgraph,
}
const Camera *camera = (const Camera *)v3d->camera->data;
switch (camera->type) {
case CAM_PANO:
case CAM_PERSP:
mode = camera->type == CAM_PERSP ? CAM_PERSP : CAM_PANO;
switch (sensor_fit) {
case CAMERA_SENSOR_FIT_VERT:
sensor_size = pxr::GfVec2f(camera_params.sensor_y * ratio, camera_params.sensor_y);
@ -131,8 +128,8 @@ pxr::GfCamera gf_camera(const Depsgraph *depsgraph,
BLI_assert_unreachable();
}
break;
case CAM_ORTHO:
mode = CAM_ORTHO;
switch (sensor_fit) {
case CAMERA_SENSOR_FIT_VERT:
ortho_size = pxr::GfVec2f(camera_params.ortho_scale * ratio,
@ -156,18 +153,19 @@ pxr::GfCamera gf_camera(const Depsgraph *depsgraph,
BLI_assert_unreachable();
}
break;
default:
BLI_assert_unreachable();
}
/* This formula was taken from previous plugin with corresponded comment.
* See blender/intern/cycles/blender/blender_camera.cpp:blender_camera_from_view (look
* for 1.41421f). */
float zoom = 4.0 / pow((pow(2.0, 0.5) + region_data->camzoom / 50.0), 2);
/* This formula was taken from blender/intern/cycles/blender/camera.cpp:blender_camera_from_view
* as magic zoom formula. */
float zoom = 2.0f / (float(M_SQRT2) + region_data->camzoom / 50.0f);
zoom *= zoom;
/* Updating l_shift due to viewport zoom and view_camera_offset
/* Updating lens_shift due to viewport zoom and view_camera_offset
* view_camera_offset should be multiplied by 2. */
lens_shift = pxr::GfVec2f((lens_shift[0] + camera_params.offsetx * 2) / zoom,
(lens_shift[1] + camera_params.offsety * 2) / zoom);
lens_shift += pxr::GfVec2f(camera_params.offsetx, camera_params.offsety) * 2;
lens_shift /= zoom;
if (camera_params.is_ortho) {
ortho_size *= zoom;
}
@ -180,34 +178,26 @@ pxr::GfCamera gf_camera(const Depsgraph *depsgraph,
BLI_assert_unreachable();
}
if (mode == CAM_PANO) {
CLOG_WARN(LOG_HYDRA_SCENE, "Unsupported camera type: %d, perspective will be used", mode);
}
float t_pos[2] = {tile[0], tile[1]}, t_size[2] = {tile[2], tile[3]};
lens_shift = {(lens_shift[0] + t_pos[0] + t_size[0] * 0.5f - 0.5f) / t_size[0],
(lens_shift[1] + t_pos[1] + t_size[1] * 0.5f - 0.5f) / t_size[1]};
pxr::GfVec2f b_pos(border[0], border[1]), b_size(border[2], border[3]);
lens_shift += b_pos + b_size * 0.5f - pxr::GfVec2f(0.5f);
lens_shift = pxr::GfCompDiv(lens_shift, b_size);
pxr::GfVec2f aperture;
if (camera_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[0] = ortho_size[0] * t_size[0] * 10;
aperture[1] = ortho_size[1] * t_size[1] * 10;
aperture = pxr::GfCompMult(ortho_size, b_size) * 10;
}
else {
aperture[0] = sensor_size[0] * t_size[0];
aperture[1] = sensor_size[1] * t_size[1];
aperture = pxr::GfCompMult(sensor_size, b_size);
}
return set_gf_camera(camera_params.is_ortho, transform, aperture, lens_shift, clip_range);
}
pxr::GfCamera gf_camera(const Object *camera_obj,
const RenderData *rd,
pxr::GfVec2i res,
pxr::GfVec4f tile)
const pxr::GfVec2i &res,
const pxr::GfVec4f &border)
{
const Camera *camera = (const Camera *)camera_obj->data;
@ -220,7 +210,6 @@ pxr::GfCamera gf_camera(const Object *camera_obj,
float ratio = float(res[0]) / res[1];
int mode;
pxr::GfVec2f lens_shift;
pxr::GfVec2f aperture;
int sensor_fit = BKE_camera_sensor_fit(
@ -245,16 +234,13 @@ pxr::GfCamera gf_camera(const Object *camera_obj,
BLI_assert_unreachable();
}
float t_pos[2] = {tile[0], tile[1]};
float t_size[2] = {tile[2], tile[3]};
lens_shift = pxr::GfVec2f(
lens_shift[0] / t_size[0] + (t_pos[0] + t_size[0] * 0.5 - 0.5) / t_size[0],
lens_shift[1] / t_size[1] + (t_pos[1] + t_size[1] * 0.5 - 0.5) / t_size[1]);
pxr::GfVec2f b_pos(border[0], border[1]), b_size(border[2], border[3]);
lens_shift += b_pos + b_size * 0.5f - pxr::GfVec2f(0.5f);
lens_shift = pxr::GfCompDiv(lens_shift, b_size);
switch (camera->type) {
case CAM_PANO:
case CAM_PERSP:
mode = camera->type == CAM_PERSP ? CAM_PERSP : CAM_PANO;
switch (sensor_fit) {
case CAMERA_SENSOR_FIT_VERT:
aperture = pxr::GfVec2f(camera_params.sensor_y * ratio, camera_params.sensor_y);
@ -273,10 +259,10 @@ pxr::GfCamera gf_camera(const Object *camera_obj,
default:
BLI_assert_unreachable();
}
aperture = pxr::GfVec2f(aperture[0] * t_size[0], aperture[1] * t_size[1]);
aperture = pxr::GfCompMult(aperture, b_size);
break;
case CAM_ORTHO:
mode = CAM_ORTHO;
switch (sensor_fit) {
case CAMERA_SENSOR_FIT_VERT:
aperture = pxr::GfVec2f(camera_params.ortho_scale * ratio, camera_params.ortho_scale);
@ -295,8 +281,9 @@ pxr::GfCamera gf_camera(const Object *camera_obj,
default:
BLI_assert_unreachable();
}
aperture = pxr::GfVec2f(aperture[0] * t_size[0] * 10, aperture[1] * t_size[1] * 10);
aperture = pxr::GfCompMult(aperture, b_size) * 10;
break;
default:
BLI_assert_unreachable();
}

View File

@ -4,13 +4,9 @@
#pragma once
#include <tuple>
#include <pxr/base/gf/camera.h>
#include <pxr/base/gf/vec2f.h>
#include "BKE_camera.h"
struct ARegion;
struct Object;
struct View3D;
@ -23,10 +19,11 @@ pxr::GfCamera gf_camera(const Depsgraph *depsgraph,
const View3D *v3d,
const ARegion *region,
const RenderData *rd,
pxr::GfVec4f tile);
const pxr::GfVec4f &border);
pxr::GfCamera gf_camera(const Object *camera_obj,
const RenderData *rd,
pxr::GfVec2i res,
pxr::GfVec4f tile);
const pxr::GfVec2i &res,
const pxr::GfVec4f &border);
} // namespace blender::io::hydra

View File

@ -33,20 +33,18 @@
namespace blender::render::hydra {
struct ViewSettings {
int screen_width;
int screen_height;
pxr::GfVec4i border;
pxr::GfCamera gf_camera;
ViewSettings(bContext *context);
int width();
int height();
pxr::GfCamera gf_camera();
int screen_width;
int screen_height;
pxr::GfVec4i border;
bContext *ctx;
};
ViewSettings::ViewSettings(bContext *context) : ctx(context)
ViewSettings::ViewSettings(bContext *context)
{
View3D *view3d = CTX_wm_view3d(context);
RegionView3D *region_data = static_cast<RegionView3D *>(CTX_wm_region_data(context));
@ -119,6 +117,15 @@ ViewSettings::ViewSettings(bContext *context) : ctx(context)
}
border = pxr::GfVec4i(x1, y1, x2, y2);
gf_camera = io::hydra::gf_camera(CTX_data_ensure_evaluated_depsgraph(context),
view3d,
region,
&scene->r,
pxr::GfVec4f(float(border[0]) / screen_width,
float(border[1]) / screen_height,
float(width()) / screen_width,
float(height()) / screen_height));
}
int ViewSettings::width()
@ -131,20 +138,6 @@ int ViewSettings::height()
return border[3] - border[1];
}
pxr::GfCamera ViewSettings::gf_camera()
{
pxr::GfVec4f tile = pxr::GfVec4f(float(border[0]) / screen_width,
float(border[1]) / screen_height,
float(width()) / screen_width,
float(height()) / screen_height);
return io::hydra::gf_camera(CTX_data_ensure_evaluated_depsgraph(ctx),
CTX_wm_view3d(ctx),
CTX_wm_region(ctx),
&CTX_data_scene(ctx)->r,
tile);
}
DrawTexture::DrawTexture()
{
float coords[8] = {0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0};
@ -219,8 +212,7 @@ void ViewportEngine::render()
return;
};
pxr::GfCamera gf_camera = view_settings.gf_camera();
free_camera_delegate_->SetCamera(gf_camera);
free_camera_delegate_->SetCamera(view_settings.gf_camera);
pxr::GfVec4d viewport(0.0, 0.0, view_settings.width(), view_settings.height());
render_task_delegate_->set_viewport(viewport);