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