Skip to content

Commit bad759c

Browse files
authored
Fix camera parameter translations and simplify code (#302)
* Fix translation of focus distance * Simplify translation of camera lens and aperture parameters * Add support for depthOfField attribute
1 parent 737806e commit bad759c

File tree

1 file changed

+42
-65
lines changed

1 file changed

+42
-65
lines changed

lib/mayaHydra/hydraExtensions/adapters/cameraAdapter.cpp

Lines changed: 42 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ PXR_NAMESPACE_OPEN_SCOPE
3131

3232
namespace {
3333

34+
TF_DEFINE_PRIVATE_TOKENS(
35+
_tokens,
36+
(depthOfField)
37+
);
38+
3439
TF_REGISTRY_FUNCTION(TfType)
3540
{
3641
TfType::Define<MayaHydraCameraAdapter, TfType::Bases<MayaHydraShapeAdapter>>();
@@ -143,48 +148,22 @@ VtValue MayaHydraCameraAdapter::Get(const TfToken& key) { return MayaHydraShapeA
143148

144149
VtValue MayaHydraCameraAdapter::GetCameraParamValue(const TfToken& paramName)
145150
{
146-
constexpr double mayaInchToHydraCentimeter = 0.254;
147-
constexpr double mayaInchToHydraMillimeter = 0.0254;
148-
constexpr double mayaFocaLenToHydra = 0.01;
151+
constexpr double inchToMM = 25.4;
149152

150153
MStatus status;
151154

152155
auto convertFit = [&](const MFnCamera& camera) -> CameraUtilConformWindowPolicy {
153156
const auto mayaFit = camera.filmFit(&status);
154-
if (mayaFit == MFnCamera::kHorizontalFilmFit)
155-
return CameraUtilConformWindowPolicy::CameraUtilMatchHorizontally;
156-
if (mayaFit == MFnCamera::kVerticalFilmFit)
157-
return CameraUtilConformWindowPolicy::CameraUtilMatchVertically;
158-
159-
const auto fitMatcher = camera.horizontalFilmAperture() > camera.verticalFilmAperture()
160-
? MFnCamera::kOverscanFilmFit
161-
: MFnCamera::kFillFilmFit;
162-
return mayaFit == fitMatcher ? CameraUtilConformWindowPolicy::CameraUtilMatchHorizontally
163-
: CameraUtilConformWindowPolicy::CameraUtilMatchVertically;
164-
};
165-
166-
auto apertureConvert = [&](const MFnCamera& camera, double glApertureX, double glApertureY) {
167-
const auto usdFit = convertFit(camera);
168-
const double aperture = usdFit == CameraUtilConformWindowPolicy::CameraUtilMatchHorizontally
169-
? camera.horizontalFilmAperture()
170-
: camera.verticalFilmAperture();
171-
const double glAperture
172-
= usdFit == CameraUtilConformWindowPolicy::CameraUtilMatchHorizontally ? glApertureX
173-
: glApertureY;
174-
return (0.02 / aperture) * (aperture / glAperture);
175-
};
176-
177-
auto viewParameters = [&](const MFnCamera& camera,
178-
const GfVec4d* viewport,
179-
double& apertureX,
180-
double& apertureY,
181-
double& offsetX,
182-
double& offsetY) -> MStatus {
183-
double aspectRatio = viewport
184-
? ((*viewport)[2] - (*viewport)[0]) / ((*viewport)[3] - (*viewport)[1])
185-
: camera.aspectRatio();
186-
return camera.getViewParameters(
187-
aspectRatio, apertureX, apertureY, offsetX, offsetY, true, false, true);
157+
switch (mayaFit) {
158+
case MFnCamera::kFillFilmFit:
159+
return CameraUtilConformWindowPolicy::CameraUtilCrop;
160+
case MFnCamera::kHorizontalFilmFit:
161+
return CameraUtilConformWindowPolicy::CameraUtilMatchHorizontally;
162+
case MFnCamera::kVerticalFilmFit:
163+
return CameraUtilConformWindowPolicy::CameraUtilMatchVertically;
164+
default:
165+
return CameraUtilConformWindowPolicy::CameraUtilFit;
166+
}
188167
};
189168

190169
auto hadError = [&](MStatus& status) -> bool {
@@ -233,23 +212,13 @@ VtValue MayaHydraCameraAdapter::GetCameraParamValue(const TfToken& paramName)
233212
auto focusDistance = camera.focusDistance(&status);
234213
if (hadError(status))
235214
return {};
236-
return VtValue(float(focusDistance * mayaInchToHydraCentimeter));
215+
return VtValue(float(focusDistance));
237216
}
238217
if (paramName == HdCameraTokens->focalLength) {
239-
const double aspectRatio = _viewport
240-
? (((*_viewport)[2] - (*_viewport)[0]) / ((*_viewport)[3] - (*_viewport)[1]))
241-
: camera.aspectRatio();
242-
243-
double left, right, bottom, top;
244-
status = camera.getViewingFrustum(aspectRatio, left, right, bottom, top, true, false, true);
245-
246-
const double cameraNear = camera.nearClippingPlane();
247-
248-
const double focalLen
249-
= (convertFit(camera) == CameraUtilConformWindowPolicy::CameraUtilMatchVertically)
250-
? (2.0 * cameraNear) / (top - bottom)
251-
: (2.0 * cameraNear) / (right - left);
252-
return VtValue(float(focalLen * mayaFocaLenToHydra));
218+
auto focalLength = camera.focalLength(&status);
219+
if (hadError(status))
220+
return {};
221+
return VtValue(float(focalLength)); /// focalLength is in mm, so no conversion needed
253222
}
254223
if (paramName == HdCameraTokens->clippingRange) {
255224
const double cameraNear = camera.nearClippingPlane();
@@ -266,32 +235,35 @@ VtValue MayaHydraCameraAdapter::GetCameraParamValue(const TfToken& paramName)
266235
return VtValue(float(fStop));
267236
}
268237
if (paramName == HdCameraTokens->horizontalAperture) {
269-
double apertureX, apertureY, offsetX, offsetY;
270-
status = viewParameters(camera, _viewport.get(), apertureX, apertureY, offsetX, offsetY);
238+
// Lens squeeze ratio applies horizontally only.
239+
const double horizontalAperture = camera.horizontalFilmAperture(&status) * camera.lensSqueezeRatio(&status);
271240
if (hadError(status))
272241
return {};
273-
return VtValue(float(apertureX * apertureConvert(camera, apertureX, apertureY)));
242+
return VtValue(float(horizontalAperture * inchToMM));
274243
}
275244
if (paramName == HdCameraTokens->verticalAperture) {
276-
double apertureX, apertureY, offsetX, offsetY;
277-
status = viewParameters(camera, _viewport.get(), apertureX, apertureY, offsetX, offsetY);
245+
const double verticalAperture = camera.verticalFilmAperture();
278246
if (hadError(status))
279247
return {};
280-
return VtValue(float(apertureY * apertureConvert(camera, apertureX, apertureY)));
248+
return VtValue(float(verticalAperture * inchToMM));
281249
}
282250
if (paramName == HdCameraTokens->horizontalApertureOffset) {
283-
double apertureX, apertureY, offsetX, offsetY;
284-
status = viewParameters(camera, _viewport.get(), apertureX, apertureY, offsetX, offsetY);
251+
// Film offset and shake (when enabled) have the same effect on film back
252+
const double horizontalApertureOffset =
253+
(camera.shakeEnabled(&status) ? camera.horizontalFilmOffset(&status) + camera.horizontalShake(&status)
254+
: camera.horizontalFilmOffset(&status));
285255
if (hadError(status))
286256
return {};
287-
return VtValue(float(offsetX * mayaInchToHydraMillimeter));
257+
return VtValue(float(horizontalApertureOffset * inchToMM));
288258
}
289259
if (paramName == HdCameraTokens->verticalApertureOffset) {
290-
double apertureX, apertureY, offsetX, offsetY;
291-
status = viewParameters(camera, _viewport.get(), apertureX, apertureY, offsetX, offsetY);
260+
// Film offset and shake (when enabled) have the same effect on film back
261+
const double verticalApertureOffset =
262+
(camera.shakeEnabled(&status) ? camera.verticalFilmOffset(&status) + camera.verticalShake(&status)
263+
: camera.verticalFilmOffset(&status));
292264
if (hadError(status))
293265
return {};
294-
return VtValue(float(offsetY * mayaInchToHydraMillimeter));
266+
return VtValue(float(verticalApertureOffset * inchToMM));
295267
}
296268
if (paramName == HdCameraTokens->windowPolicy) {
297269
const auto windowPolicy = convertFit(camera);
@@ -306,7 +278,12 @@ VtValue MayaHydraCameraAdapter::GetCameraParamValue(const TfToken& paramName)
306278
return VtValue(HdCamera::Perspective);
307279
}
308280
}
309-
281+
if (paramName == _tokens->depthOfField) {
282+
const bool depthOfField = camera.isDepthOfField(&status);
283+
if (hadError(status))
284+
return {};
285+
return VtValue(depthOfField);
286+
}
310287
return {};
311288
}
312289

0 commit comments

Comments
 (0)