Blender V4.3
hydra/camera.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2022 NVIDIA Corporation
2 * SPDX-FileCopyrightText: 2022 Blender Foundation
3 *
4 * SPDX-License-Identifier: Apache-2.0 */
5
6#include "hydra/camera.h"
7#include "hydra/session.h"
8#include "scene/camera.h"
9
10#include <pxr/base/gf/frustum.h>
11#include <pxr/imaging/hd/sceneDelegate.h>
12#include <pxr/usd/usdGeom/tokens.h>
13
15
16extern Transform convert_transform(const GfMatrix4d &matrix);
17Transform convert_camera_transform(const GfMatrix4d &matrix, float metersPerUnit)
18{
19 Transform t = convert_transform(matrix);
20 // Flip Z axis
21 t.x.z *= -1.0f;
22 t.y.z *= -1.0f;
23 t.z.z *= -1.0f;
24 // Scale translation
25 t.x.w *= metersPerUnit;
26 t.y.w *= metersPerUnit;
27 t.z.w *= metersPerUnit;
28 return t;
29}
30
31#if PXR_VERSION < 2102
32// clang-format off
34 (projection)
35 (orthographic)
36);
37// clang-format on
38#endif
39
40HdCyclesCamera::HdCyclesCamera(const SdfPath &sprimId) : HdCamera(sprimId)
41{
42#if PXR_VERSION >= 2102
43 // Synchronize default values
44 _horizontalAperture = _data.GetHorizontalAperture() * GfCamera::APERTURE_UNIT;
45 _verticalAperture = _data.GetVerticalAperture() * GfCamera::APERTURE_UNIT;
46 _horizontalApertureOffset = _data.GetHorizontalApertureOffset() * GfCamera::APERTURE_UNIT;
47 _verticalApertureOffset = _data.GetVerticalApertureOffset() * GfCamera::APERTURE_UNIT;
48 _focalLength = _data.GetFocalLength() * GfCamera::FOCAL_LENGTH_UNIT;
49 _clippingRange = _data.GetClippingRange();
50 _fStop = _data.GetFStop();
51 _focusDistance = _data.GetFocusDistance();
52#endif
53}
54
56
58{
59 return DirtyBits::AllDirty;
60}
61
62void HdCyclesCamera::Sync(HdSceneDelegate *sceneDelegate,
63 HdRenderParam *renderParam,
64 HdDirtyBits *dirtyBits)
65{
66 if (*dirtyBits == DirtyBits::Clean) {
67 return;
68 }
69
70 VtValue value;
71 const SdfPath &id = GetId();
72
73#if PXR_VERSION >= 2102
74 if (*dirtyBits & DirtyBits::DirtyTransform) {
75 sceneDelegate->SampleTransform(id, &_transformSamples);
76
77 bool transform_found = false;
78 for (size_t i = 0; i < _transformSamples.count; ++i) {
79 if (_transformSamples.times[i] == 0.0f) {
80 _transform = _transformSamples.values[i];
81 _data.SetTransform(_transform);
82 transform_found = true;
83 break;
84 }
85 }
86
87 if (!transform_found && _transformSamples.count) {
88 _transform = _transformSamples.values[0];
89 _data.SetTransform(_transform);
90 }
91 }
92#else
93 if (*dirtyBits & DirtyBits::DirtyViewMatrix) {
94 sceneDelegate->SampleTransform(id, &_transformSamples);
95
96 value = sceneDelegate->GetCameraParamValue(id, HdCameraTokens->worldToViewMatrix);
97 if (!value.IsEmpty()) {
98 _worldToViewMatrix = value.Get<GfMatrix4d>();
99 _worldToViewInverseMatrix = _worldToViewMatrix.GetInverse();
100 _data.SetTransform(_worldToViewInverseMatrix);
101 }
102 }
103#endif
104
105#if PXR_VERSION < 2111
106 if (*dirtyBits & DirtyBits::DirtyProjMatrix) {
107 value = sceneDelegate->GetCameraParamValue(id, HdCameraTokens->projectionMatrix);
108 if (!value.IsEmpty()) {
109 _projectionMatrix = value.Get<GfMatrix4d>();
110 const float focalLength = _data.GetFocalLength(); // Get default focal length
111# if PXR_VERSION >= 2102
112 _data.SetFromViewAndProjectionMatrix(GetViewMatrix(), _projectionMatrix, focalLength);
113# else
114 if (_projectionMatrix[2][3] < -0.5) {
115 _data.SetProjection(GfCamera::Perspective);
116
117 const float horizontalAperture = (2.0 * focalLength) / _projectionMatrix[0][0];
118 _data.SetHorizontalAperture(horizontalAperture);
119 _data.SetHorizontalApertureOffset(0.5 * horizontalAperture * _projectionMatrix[2][0]);
120 const float verticalAperture = (2.0 * focalLength) / _projectionMatrix[1][1];
121 _data.SetVerticalAperture(verticalAperture);
122 _data.SetVerticalApertureOffset(0.5 * verticalAperture * _projectionMatrix[2][1]);
123
124 _data.SetClippingRange(
125 GfRange1f(_projectionMatrix[3][2] / (_projectionMatrix[2][2] - 1.0),
126 _projectionMatrix[3][2] / (_projectionMatrix[2][2] + 1.0)));
127 }
128 else {
129 _data.SetProjection(GfCamera::Orthographic);
130
131 const float horizontalAperture = (2.0 / GfCamera::APERTURE_UNIT) / _projectionMatrix[0][0];
132 _data.SetHorizontalAperture(horizontalAperture);
133 _data.SetHorizontalApertureOffset(-0.5 * horizontalAperture * _projectionMatrix[3][0]);
134 const float verticalAperture = (2.0 / GfCamera::APERTURE_UNIT) / _projectionMatrix[1][1];
135 _data.SetVerticalAperture(verticalAperture);
136 _data.SetVerticalApertureOffset(-0.5 * verticalAperture * _projectionMatrix[3][1]);
137
138 const double nearMinusFarHalf = 1.0 / _projectionMatrix[2][2];
139 const double nearPlusFarHalf = nearMinusFarHalf * _projectionMatrix[3][2];
140 _data.SetClippingRange(
141 GfRange1f(nearPlusFarHalf + nearMinusFarHalf, nearPlusFarHalf - nearMinusFarHalf));
142 }
143# endif
144 }
145 }
146#endif
147
148 if (*dirtyBits & DirtyBits::DirtyWindowPolicy) {
149 value = sceneDelegate->GetCameraParamValue(id, HdCameraTokens->windowPolicy);
150 if (!value.IsEmpty()) {
151 _windowPolicy = value.Get<CameraUtilConformWindowPolicy>();
152 }
153 }
154
155 if (*dirtyBits & DirtyBits::DirtyClipPlanes) {
156 value = sceneDelegate->GetCameraParamValue(id, HdCameraTokens->clipPlanes);
157 if (!value.IsEmpty()) {
158 _clipPlanes = value.Get<std::vector<GfVec4d>>();
159 }
160 }
161
162 if (*dirtyBits & DirtyBits::DirtyParams) {
163#if PXR_VERSION >= 2102
164 value = sceneDelegate->GetCameraParamValue(id, HdCameraTokens->projection);
165 if (!value.IsEmpty()) {
166 _projection = value.Get<Projection>();
167 _data.SetProjection(_projection != Orthographic ? GfCamera::Perspective :
168 GfCamera::Orthographic);
169 }
170#else
171 value = sceneDelegate->GetCameraParamValue(id, _tokens->projection);
172 if (!value.IsEmpty()) {
173 _data.SetProjection(value.Get<TfToken>() != _tokens->orthographic ? GfCamera::Perspective :
174 GfCamera::Orthographic);
175 }
176#endif
177
178 value = sceneDelegate->GetCameraParamValue(id, HdCameraTokens->horizontalAperture);
179 if (!value.IsEmpty()) {
180 const auto horizontalAperture = value.Get<float>();
181#if PXR_VERSION >= 2102
182 _horizontalAperture = horizontalAperture;
183#endif
184 _data.SetHorizontalAperture(horizontalAperture / GfCamera::APERTURE_UNIT);
185 }
186
187 value = sceneDelegate->GetCameraParamValue(id, HdCameraTokens->verticalAperture);
188 if (!value.IsEmpty()) {
189 const auto verticalAperture = value.Get<float>();
190#if PXR_VERSION >= 2102
191 _verticalAperture = verticalAperture;
192#endif
193 _data.SetVerticalAperture(verticalAperture / GfCamera::APERTURE_UNIT);
194 }
195
196 value = sceneDelegate->GetCameraParamValue(id, HdCameraTokens->horizontalApertureOffset);
197 if (!value.IsEmpty()) {
198 const auto horizontalApertureOffset = value.Get<float>();
199#if PXR_VERSION >= 2102
200 _horizontalApertureOffset = horizontalApertureOffset;
201#endif
202 _data.SetHorizontalApertureOffset(horizontalApertureOffset / GfCamera::APERTURE_UNIT);
203 }
204
205 value = sceneDelegate->GetCameraParamValue(id, HdCameraTokens->verticalApertureOffset);
206 if (!value.IsEmpty()) {
207 const auto verticalApertureOffset = value.Get<float>();
208#if PXR_VERSION >= 2102
209 _verticalApertureOffset = verticalApertureOffset;
210#endif
211 _data.SetVerticalApertureOffset(verticalApertureOffset / GfCamera::APERTURE_UNIT);
212 }
213
214 value = sceneDelegate->GetCameraParamValue(id, HdCameraTokens->focalLength);
215 if (!value.IsEmpty()) {
216 const auto focalLength = value.Get<float>();
217#if PXR_VERSION >= 2102
218 _focalLength = focalLength;
219#endif
220 _data.SetFocalLength(focalLength / GfCamera::FOCAL_LENGTH_UNIT);
221 }
222
223 value = sceneDelegate->GetCameraParamValue(id, HdCameraTokens->clippingRange);
224 if (!value.IsEmpty()) {
225 const auto clippingRange = value.Get<GfRange1f>();
226#if PXR_VERSION >= 2102
227 _clippingRange = clippingRange;
228#endif
229 _data.SetClippingRange(clippingRange);
230 }
231
232 value = sceneDelegate->GetCameraParamValue(id, HdCameraTokens->fStop);
233 if (!value.IsEmpty()) {
234 const auto fStop = value.Get<float>();
235#if PXR_VERSION >= 2102
236 _fStop = fStop;
237#endif
238 _data.SetFStop(fStop);
239 }
240
241 value = sceneDelegate->GetCameraParamValue(id, HdCameraTokens->focusDistance);
242 if (!value.IsEmpty()) {
243 const auto focusDistance = value.Get<float>();
244#if PXR_VERSION >= 2102
245 _focusDistance = focusDistance;
246#endif
247 _data.SetFocusDistance(focusDistance);
248 }
249 }
250
251 *dirtyBits = DirtyBits::Clean;
252}
253
254void HdCyclesCamera::Finalize(HdRenderParam *renderParam)
255{
256 HdCamera::Finalize(renderParam);
257}
258
259void HdCyclesCamera::ApplyCameraSettings(HdRenderParam *renderParam, Camera *cam) const
260{
261 ApplyCameraSettings(renderParam, _data, _windowPolicy, cam);
262
263 const float metersPerUnit = static_cast<HdCyclesSession *>(renderParam)->GetStageMetersPerUnit();
264
265 array<Transform> motion(_transformSamples.count);
266 for (size_t i = 0; i < _transformSamples.count; ++i) {
267 motion[i] = convert_camera_transform(_transformSamples.values[i], metersPerUnit);
268 }
269 cam->set_motion(motion);
270}
271
272void HdCyclesCamera::ApplyCameraSettings(HdRenderParam *renderParam,
273 const GfCamera &dataUnconformedWindow,
274 CameraUtilConformWindowPolicy windowPolicy,
275 Camera *cam)
276{
277 const float width = cam->get_full_width();
278 const float height = cam->get_full_height();
279
280 auto data = dataUnconformedWindow;
281 CameraUtilConformWindow(&data, windowPolicy, width / height);
282
283 if (data.GetProjection() == GfCamera::Orthographic) {
284 cam->set_camera_type(CAMERA_ORTHOGRAPHIC);
285 }
286 else {
287 cam->set_camera_type(CAMERA_PERSPECTIVE);
288 }
289
290 const float metersPerUnit = static_cast<HdCyclesSession *>(renderParam)->GetStageMetersPerUnit();
291
292 auto viewplane = data.GetFrustum().GetWindow();
293 auto focalLength = 1.0f;
294 if (data.GetProjection() == GfCamera::Perspective) {
295 viewplane *= 2.0 / viewplane.GetSize()[1]; // Normalize viewplane
296 focalLength = data.GetFocalLength() * GfCamera::FOCAL_LENGTH_UNIT * metersPerUnit;
297
298 cam->set_fov(GfDegreesToRadians(data.GetFieldOfView(GfCamera::FOVVertical)));
299 }
300
301 cam->set_sensorwidth(data.GetHorizontalAperture() * GfCamera::APERTURE_UNIT * metersPerUnit);
302 cam->set_sensorheight(data.GetVerticalAperture() * GfCamera::APERTURE_UNIT * metersPerUnit);
303
304 cam->set_nearclip(data.GetClippingRange().GetMin() * metersPerUnit);
305 cam->set_farclip(data.GetClippingRange().GetMax() * metersPerUnit);
306
307 cam->set_viewplane_left(viewplane.GetMin()[0]);
308 cam->set_viewplane_right(viewplane.GetMax()[0]);
309 cam->set_viewplane_bottom(viewplane.GetMin()[1]);
310 cam->set_viewplane_top(viewplane.GetMax()[1]);
311
312 if (data.GetFStop() != 0.0f) {
313 cam->set_focaldistance(data.GetFocusDistance() * metersPerUnit);
314 cam->set_aperturesize(focalLength / (2.0f * data.GetFStop()));
315 }
316
317 cam->set_matrix(convert_camera_transform(data.GetTransform(), metersPerUnit));
318}
319
320void HdCyclesCamera::ApplyCameraSettings(HdRenderParam *renderParam,
321 const GfMatrix4d &worldToViewMatrix,
322 const GfMatrix4d &projectionMatrix,
323 const std::vector<GfVec4d> &clipPlanes,
324 Camera *cam)
325{
326#if PXR_VERSION >= 2102
327 GfCamera data;
328 data.SetFromViewAndProjectionMatrix(worldToViewMatrix, projectionMatrix);
329
330 ApplyCameraSettings(renderParam, data, CameraUtilFit, cam);
331#else
332 TF_CODING_ERROR("Not implemented");
333#endif
334}
335
void ApplyCameraSettings(PXR_NS::HdRenderParam *renderParam, CCL_NS::Camera *targetCamera) const
PXR_NS::HdDirtyBits GetInitialDirtyBitsMask() const override
void Sync(PXR_NS::HdSceneDelegate *sceneDelegate, PXR_NS::HdRenderParam *renderParam, PXR_NS::HdDirtyBits *dirtyBits) override
HdCyclesCamera(const PXR_NS::SdfPath &sprimId)
void Finalize(PXR_NS::HdRenderParam *renderParam) override
~HdCyclesCamera() override
#define Projection
Definition gpu_matrix.cc:53
Transform convert_camera_transform(const GfMatrix4d &matrix, float metersPerUnit)
TF_DEFINE_PRIVATE_TOKENS(_tokens,(projection)(orthographic))
HDCYCLES_NAMESPACE_OPEN_SCOPE Transform convert_transform(const GfMatrix4d &matrix)
#define HDCYCLES_NAMESPACE_CLOSE_SCOPE
@ CAMERA_PERSPECTIVE
@ CAMERA_ORTHOGRAPHIC
float4 y
Definition transform.h:24
float4 x
Definition transform.h:24
float4 z
Definition transform.h:24