1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 //    names, trademarks, service marks, or product names of the Licensor
11 //    and its affiliates, except as required to comply with Section 4(c) of
12 //    the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 //     http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #include "pxr/usd/usdGeom/camera.h"
25 #include "pxr/usd/usd/schemaRegistry.h"
26 #include "pxr/usd/usd/typed.h"
27 
28 #include "pxr/usd/sdf/types.h"
29 #include "pxr/usd/sdf/assetPath.h"
30 
31 PXR_NAMESPACE_OPEN_SCOPE
32 
33 // Register the schema with the TfType system.
TF_REGISTRY_FUNCTION(TfType)34 TF_REGISTRY_FUNCTION(TfType)
35 {
36     TfType::Define<UsdGeomCamera,
37         TfType::Bases< UsdGeomXformable > >();
38 
39     // Register the usd prim typename as an alias under UsdSchemaBase. This
40     // enables one to call
41     // TfType::Find<UsdSchemaBase>().FindDerivedByName("Camera")
42     // to find TfType<UsdGeomCamera>, which is how IsA queries are
43     // answered.
44     TfType::AddAlias<UsdSchemaBase, UsdGeomCamera>("Camera");
45 }
46 
47 /* virtual */
~UsdGeomCamera()48 UsdGeomCamera::~UsdGeomCamera()
49 {
50 }
51 
52 /* static */
53 UsdGeomCamera
Get(const UsdStagePtr & stage,const SdfPath & path)54 UsdGeomCamera::Get(const UsdStagePtr &stage, const SdfPath &path)
55 {
56     if (!stage) {
57         TF_CODING_ERROR("Invalid stage");
58         return UsdGeomCamera();
59     }
60     return UsdGeomCamera(stage->GetPrimAtPath(path));
61 }
62 
63 /* static */
64 UsdGeomCamera
Define(const UsdStagePtr & stage,const SdfPath & path)65 UsdGeomCamera::Define(
66     const UsdStagePtr &stage, const SdfPath &path)
67 {
68     static TfToken usdPrimTypeName("Camera");
69     if (!stage) {
70         TF_CODING_ERROR("Invalid stage");
71         return UsdGeomCamera();
72     }
73     return UsdGeomCamera(
74         stage->DefinePrim(path, usdPrimTypeName));
75 }
76 
77 /* virtual */
_GetSchemaKind() const78 UsdSchemaKind UsdGeomCamera::_GetSchemaKind() const
79 {
80     return UsdGeomCamera::schemaKind;
81 }
82 
83 /* static */
84 const TfType &
_GetStaticTfType()85 UsdGeomCamera::_GetStaticTfType()
86 {
87     static TfType tfType = TfType::Find<UsdGeomCamera>();
88     return tfType;
89 }
90 
91 /* static */
92 bool
_IsTypedSchema()93 UsdGeomCamera::_IsTypedSchema()
94 {
95     static bool isTyped = _GetStaticTfType().IsA<UsdTyped>();
96     return isTyped;
97 }
98 
99 /* virtual */
100 const TfType &
_GetTfType() const101 UsdGeomCamera::_GetTfType() const
102 {
103     return _GetStaticTfType();
104 }
105 
106 UsdAttribute
GetProjectionAttr() const107 UsdGeomCamera::GetProjectionAttr() const
108 {
109     return GetPrim().GetAttribute(UsdGeomTokens->projection);
110 }
111 
112 UsdAttribute
CreateProjectionAttr(VtValue const & defaultValue,bool writeSparsely) const113 UsdGeomCamera::CreateProjectionAttr(VtValue const &defaultValue, bool writeSparsely) const
114 {
115     return UsdSchemaBase::_CreateAttr(UsdGeomTokens->projection,
116                        SdfValueTypeNames->Token,
117                        /* custom = */ false,
118                        SdfVariabilityVarying,
119                        defaultValue,
120                        writeSparsely);
121 }
122 
123 UsdAttribute
GetHorizontalApertureAttr() const124 UsdGeomCamera::GetHorizontalApertureAttr() const
125 {
126     return GetPrim().GetAttribute(UsdGeomTokens->horizontalAperture);
127 }
128 
129 UsdAttribute
CreateHorizontalApertureAttr(VtValue const & defaultValue,bool writeSparsely) const130 UsdGeomCamera::CreateHorizontalApertureAttr(VtValue const &defaultValue, bool writeSparsely) const
131 {
132     return UsdSchemaBase::_CreateAttr(UsdGeomTokens->horizontalAperture,
133                        SdfValueTypeNames->Float,
134                        /* custom = */ false,
135                        SdfVariabilityVarying,
136                        defaultValue,
137                        writeSparsely);
138 }
139 
140 UsdAttribute
GetVerticalApertureAttr() const141 UsdGeomCamera::GetVerticalApertureAttr() const
142 {
143     return GetPrim().GetAttribute(UsdGeomTokens->verticalAperture);
144 }
145 
146 UsdAttribute
CreateVerticalApertureAttr(VtValue const & defaultValue,bool writeSparsely) const147 UsdGeomCamera::CreateVerticalApertureAttr(VtValue const &defaultValue, bool writeSparsely) const
148 {
149     return UsdSchemaBase::_CreateAttr(UsdGeomTokens->verticalAperture,
150                        SdfValueTypeNames->Float,
151                        /* custom = */ false,
152                        SdfVariabilityVarying,
153                        defaultValue,
154                        writeSparsely);
155 }
156 
157 UsdAttribute
GetHorizontalApertureOffsetAttr() const158 UsdGeomCamera::GetHorizontalApertureOffsetAttr() const
159 {
160     return GetPrim().GetAttribute(UsdGeomTokens->horizontalApertureOffset);
161 }
162 
163 UsdAttribute
CreateHorizontalApertureOffsetAttr(VtValue const & defaultValue,bool writeSparsely) const164 UsdGeomCamera::CreateHorizontalApertureOffsetAttr(VtValue const &defaultValue, bool writeSparsely) const
165 {
166     return UsdSchemaBase::_CreateAttr(UsdGeomTokens->horizontalApertureOffset,
167                        SdfValueTypeNames->Float,
168                        /* custom = */ false,
169                        SdfVariabilityVarying,
170                        defaultValue,
171                        writeSparsely);
172 }
173 
174 UsdAttribute
GetVerticalApertureOffsetAttr() const175 UsdGeomCamera::GetVerticalApertureOffsetAttr() const
176 {
177     return GetPrim().GetAttribute(UsdGeomTokens->verticalApertureOffset);
178 }
179 
180 UsdAttribute
CreateVerticalApertureOffsetAttr(VtValue const & defaultValue,bool writeSparsely) const181 UsdGeomCamera::CreateVerticalApertureOffsetAttr(VtValue const &defaultValue, bool writeSparsely) const
182 {
183     return UsdSchemaBase::_CreateAttr(UsdGeomTokens->verticalApertureOffset,
184                        SdfValueTypeNames->Float,
185                        /* custom = */ false,
186                        SdfVariabilityVarying,
187                        defaultValue,
188                        writeSparsely);
189 }
190 
191 UsdAttribute
GetFocalLengthAttr() const192 UsdGeomCamera::GetFocalLengthAttr() const
193 {
194     return GetPrim().GetAttribute(UsdGeomTokens->focalLength);
195 }
196 
197 UsdAttribute
CreateFocalLengthAttr(VtValue const & defaultValue,bool writeSparsely) const198 UsdGeomCamera::CreateFocalLengthAttr(VtValue const &defaultValue, bool writeSparsely) const
199 {
200     return UsdSchemaBase::_CreateAttr(UsdGeomTokens->focalLength,
201                        SdfValueTypeNames->Float,
202                        /* custom = */ false,
203                        SdfVariabilityVarying,
204                        defaultValue,
205                        writeSparsely);
206 }
207 
208 UsdAttribute
GetClippingRangeAttr() const209 UsdGeomCamera::GetClippingRangeAttr() const
210 {
211     return GetPrim().GetAttribute(UsdGeomTokens->clippingRange);
212 }
213 
214 UsdAttribute
CreateClippingRangeAttr(VtValue const & defaultValue,bool writeSparsely) const215 UsdGeomCamera::CreateClippingRangeAttr(VtValue const &defaultValue, bool writeSparsely) const
216 {
217     return UsdSchemaBase::_CreateAttr(UsdGeomTokens->clippingRange,
218                        SdfValueTypeNames->Float2,
219                        /* custom = */ false,
220                        SdfVariabilityVarying,
221                        defaultValue,
222                        writeSparsely);
223 }
224 
225 UsdAttribute
GetClippingPlanesAttr() const226 UsdGeomCamera::GetClippingPlanesAttr() const
227 {
228     return GetPrim().GetAttribute(UsdGeomTokens->clippingPlanes);
229 }
230 
231 UsdAttribute
CreateClippingPlanesAttr(VtValue const & defaultValue,bool writeSparsely) const232 UsdGeomCamera::CreateClippingPlanesAttr(VtValue const &defaultValue, bool writeSparsely) const
233 {
234     return UsdSchemaBase::_CreateAttr(UsdGeomTokens->clippingPlanes,
235                        SdfValueTypeNames->Float4Array,
236                        /* custom = */ false,
237                        SdfVariabilityVarying,
238                        defaultValue,
239                        writeSparsely);
240 }
241 
242 UsdAttribute
GetFStopAttr() const243 UsdGeomCamera::GetFStopAttr() const
244 {
245     return GetPrim().GetAttribute(UsdGeomTokens->fStop);
246 }
247 
248 UsdAttribute
CreateFStopAttr(VtValue const & defaultValue,bool writeSparsely) const249 UsdGeomCamera::CreateFStopAttr(VtValue const &defaultValue, bool writeSparsely) const
250 {
251     return UsdSchemaBase::_CreateAttr(UsdGeomTokens->fStop,
252                        SdfValueTypeNames->Float,
253                        /* custom = */ false,
254                        SdfVariabilityVarying,
255                        defaultValue,
256                        writeSparsely);
257 }
258 
259 UsdAttribute
GetFocusDistanceAttr() const260 UsdGeomCamera::GetFocusDistanceAttr() const
261 {
262     return GetPrim().GetAttribute(UsdGeomTokens->focusDistance);
263 }
264 
265 UsdAttribute
CreateFocusDistanceAttr(VtValue const & defaultValue,bool writeSparsely) const266 UsdGeomCamera::CreateFocusDistanceAttr(VtValue const &defaultValue, bool writeSparsely) const
267 {
268     return UsdSchemaBase::_CreateAttr(UsdGeomTokens->focusDistance,
269                        SdfValueTypeNames->Float,
270                        /* custom = */ false,
271                        SdfVariabilityVarying,
272                        defaultValue,
273                        writeSparsely);
274 }
275 
276 UsdAttribute
GetStereoRoleAttr() const277 UsdGeomCamera::GetStereoRoleAttr() const
278 {
279     return GetPrim().GetAttribute(UsdGeomTokens->stereoRole);
280 }
281 
282 UsdAttribute
CreateStereoRoleAttr(VtValue const & defaultValue,bool writeSparsely) const283 UsdGeomCamera::CreateStereoRoleAttr(VtValue const &defaultValue, bool writeSparsely) const
284 {
285     return UsdSchemaBase::_CreateAttr(UsdGeomTokens->stereoRole,
286                        SdfValueTypeNames->Token,
287                        /* custom = */ false,
288                        SdfVariabilityUniform,
289                        defaultValue,
290                        writeSparsely);
291 }
292 
293 UsdAttribute
GetShutterOpenAttr() const294 UsdGeomCamera::GetShutterOpenAttr() const
295 {
296     return GetPrim().GetAttribute(UsdGeomTokens->shutterOpen);
297 }
298 
299 UsdAttribute
CreateShutterOpenAttr(VtValue const & defaultValue,bool writeSparsely) const300 UsdGeomCamera::CreateShutterOpenAttr(VtValue const &defaultValue, bool writeSparsely) const
301 {
302     return UsdSchemaBase::_CreateAttr(UsdGeomTokens->shutterOpen,
303                        SdfValueTypeNames->Double,
304                        /* custom = */ false,
305                        SdfVariabilityVarying,
306                        defaultValue,
307                        writeSparsely);
308 }
309 
310 UsdAttribute
GetShutterCloseAttr() const311 UsdGeomCamera::GetShutterCloseAttr() const
312 {
313     return GetPrim().GetAttribute(UsdGeomTokens->shutterClose);
314 }
315 
316 UsdAttribute
CreateShutterCloseAttr(VtValue const & defaultValue,bool writeSparsely) const317 UsdGeomCamera::CreateShutterCloseAttr(VtValue const &defaultValue, bool writeSparsely) const
318 {
319     return UsdSchemaBase::_CreateAttr(UsdGeomTokens->shutterClose,
320                        SdfValueTypeNames->Double,
321                        /* custom = */ false,
322                        SdfVariabilityVarying,
323                        defaultValue,
324                        writeSparsely);
325 }
326 
327 UsdAttribute
GetExposureAttr() const328 UsdGeomCamera::GetExposureAttr() const
329 {
330     return GetPrim().GetAttribute(UsdGeomTokens->exposure);
331 }
332 
333 UsdAttribute
CreateExposureAttr(VtValue const & defaultValue,bool writeSparsely) const334 UsdGeomCamera::CreateExposureAttr(VtValue const &defaultValue, bool writeSparsely) const
335 {
336     return UsdSchemaBase::_CreateAttr(UsdGeomTokens->exposure,
337                        SdfValueTypeNames->Float,
338                        /* custom = */ false,
339                        SdfVariabilityVarying,
340                        defaultValue,
341                        writeSparsely);
342 }
343 
344 namespace {
345 static inline TfTokenVector
_ConcatenateAttributeNames(const TfTokenVector & left,const TfTokenVector & right)346 _ConcatenateAttributeNames(const TfTokenVector& left,const TfTokenVector& right)
347 {
348     TfTokenVector result;
349     result.reserve(left.size() + right.size());
350     result.insert(result.end(), left.begin(), left.end());
351     result.insert(result.end(), right.begin(), right.end());
352     return result;
353 }
354 }
355 
356 /*static*/
357 const TfTokenVector&
GetSchemaAttributeNames(bool includeInherited)358 UsdGeomCamera::GetSchemaAttributeNames(bool includeInherited)
359 {
360     static TfTokenVector localNames = {
361         UsdGeomTokens->projection,
362         UsdGeomTokens->horizontalAperture,
363         UsdGeomTokens->verticalAperture,
364         UsdGeomTokens->horizontalApertureOffset,
365         UsdGeomTokens->verticalApertureOffset,
366         UsdGeomTokens->focalLength,
367         UsdGeomTokens->clippingRange,
368         UsdGeomTokens->clippingPlanes,
369         UsdGeomTokens->fStop,
370         UsdGeomTokens->focusDistance,
371         UsdGeomTokens->stereoRole,
372         UsdGeomTokens->shutterOpen,
373         UsdGeomTokens->shutterClose,
374         UsdGeomTokens->exposure,
375     };
376     static TfTokenVector allNames =
377         _ConcatenateAttributeNames(
378             UsdGeomXformable::GetSchemaAttributeNames(true),
379             localNames);
380 
381     if (includeInherited)
382         return allNames;
383     else
384         return localNames;
385 }
386 
387 PXR_NAMESPACE_CLOSE_SCOPE
388 
389 // ===================================================================== //
390 // Feel free to add custom code below this line. It will be preserved by
391 // the code generator.
392 //
393 // Just remember to wrap code in the appropriate delimiters:
394 // 'PXR_NAMESPACE_OPEN_SCOPE', 'PXR_NAMESPACE_CLOSE_SCOPE'.
395 // ===================================================================== //
396 // --(BEGIN CUSTOM CODE)--
397 
398 PXR_NAMESPACE_OPEN_SCOPE
399 
400 template<class T>
_GetValue(const UsdPrim & prim,const TfToken & name,const UsdTimeCode & time)401 static boost::optional<T> _GetValue(const UsdPrim &prim,
402                                     const TfToken &name,
403                                     const UsdTimeCode &time)
404 {
405     const UsdAttribute attr = prim.GetAttribute(name);
406     if (!attr) {
407         TF_WARN("%s attribute on prim %s missing.",
408                 name.GetText(), prim.GetPath().GetText());
409         return boost::none;
410     }
411 
412     T value;
413     if (!attr.Get(&value, time)) {
414         TF_WARN("Failed to extract value from attribute %s at <%s>.",
415                 name.GetText(), attr.GetPath().GetText());
416         return boost::none;
417     }
418 
419     return value;
420 }
421 
422 static
423 GfCamera::Projection
_TokenToProjection(const TfToken & token)424 _TokenToProjection(const TfToken &token)
425 {
426     if (token == UsdGeomTokens->orthographic) {
427         return GfCamera::Orthographic;
428     }
429 
430     if (token != UsdGeomTokens->perspective) {
431         TF_WARN("Unknown projection type %s", token.GetText());
432     }
433 
434     return GfCamera::Perspective;
435 }
436 
437 static
438 TfToken
_ProjectionToToken(GfCamera::Projection projection)439 _ProjectionToToken(GfCamera::Projection projection)
440 {
441     switch(projection) {
442     case GfCamera::Perspective:
443         return UsdGeomTokens->perspective;
444     case GfCamera::Orthographic:
445         return UsdGeomTokens->orthographic;
446     default:
447         TF_WARN("Unknown projection type %d", projection);
448         return TfToken();
449     }
450 }
451 
452 
453 static
454 GfRange1f
_Vec2fToRange1f(const GfVec2f & vec)455 _Vec2fToRange1f(const GfVec2f &vec)
456 {
457     return GfRange1f(vec[0], vec[1]);
458 }
459 
460 static
461 GfVec2f
_Range1fToVec2f(const GfRange1f & range)462 _Range1fToVec2f(const GfRange1f &range)
463 {
464     return GfVec2f(range.GetMin(), range.GetMax());
465 }
466 
467 static
468 std::vector<GfVec4f>
_VtArrayVec4fToVector(const VtArray<GfVec4f> & array)469 _VtArrayVec4fToVector(const VtArray<GfVec4f> &array)
470 {
471     return std::vector<GfVec4f>(array.begin(), array.end());
472 }
473 
474 static
475 VtArray<GfVec4f>
_VectorVec4fToVtArray(const std::vector<GfVec4f> & vec)476 _VectorVec4fToVtArray(const std::vector<GfVec4f> &vec)
477 {
478     VtArray<GfVec4f> result;
479     result.assign(vec.begin(), vec.end());
480     return result;
481 }
482 
483 GfCamera
GetCamera(const UsdTimeCode & time) const484 UsdGeomCamera::GetCamera(const UsdTimeCode &time) const
485 {
486     GfCamera camera;
487 
488     camera.SetTransform(
489         ComputeLocalToWorldTransform(time));
490 
491     if (const boost::optional<TfToken> projection = _GetValue<TfToken>(
492             GetPrim(), UsdGeomTokens->projection, time)) {
493         camera.SetProjection(_TokenToProjection(*projection));
494     }
495 
496     if (const boost::optional<float> horizontalAperture = _GetValue<float>(
497             GetPrim(), UsdGeomTokens->horizontalAperture, time)) {
498         camera.SetHorizontalAperture(*horizontalAperture);
499     }
500 
501     if (const boost::optional<float> verticalAperture = _GetValue<float>(
502             GetPrim(), UsdGeomTokens->verticalAperture, time)) {
503         camera.SetVerticalAperture(*verticalAperture);
504     }
505 
506     if (const boost::optional<float> horizontalApertureOffset =
507         _GetValue<float>(
508             GetPrim(), UsdGeomTokens->horizontalApertureOffset, time)) {
509         camera.SetHorizontalApertureOffset(*horizontalApertureOffset);
510     }
511 
512     if (const boost::optional<float> verticalApertureOffset = _GetValue<float>(
513             GetPrim(), UsdGeomTokens->verticalApertureOffset, time)) {
514         camera.SetVerticalApertureOffset(*verticalApertureOffset);
515     }
516 
517     if (const boost::optional<float> focalLength = _GetValue<float>(
518             GetPrim(), UsdGeomTokens->focalLength, time)) {
519         camera.SetFocalLength(*focalLength);
520     }
521 
522     if (const boost::optional<GfVec2f> clippingRange = _GetValue<GfVec2f>(
523             GetPrim(), UsdGeomTokens->clippingRange, time)) {
524         camera.SetClippingRange(_Vec2fToRange1f(*clippingRange));
525     }
526 
527     if (const boost::optional<VtArray<GfVec4f> > clippingPlanes =
528         _GetValue<VtArray<GfVec4f> >(
529             GetPrim(), UsdGeomTokens->clippingPlanes, time)) {
530 
531         camera.SetClippingPlanes(_VtArrayVec4fToVector(*clippingPlanes));
532     }
533 
534     if (const boost::optional<float> fStop = _GetValue<float>(
535             GetPrim(), UsdGeomTokens->fStop, time)) {
536         camera.SetFStop(*fStop);
537     }
538 
539     if (const boost::optional<float> focusDistance = _GetValue<float>(
540             GetPrim(), UsdGeomTokens->focusDistance, time)) {
541         camera.SetFocusDistance(*focusDistance);
542     }
543 
544     return camera;
545 }
546 
547 void
SetFromCamera(const GfCamera & camera,const UsdTimeCode & time)548 UsdGeomCamera::SetFromCamera(const GfCamera &camera, const UsdTimeCode &time)
549 {
550     const GfMatrix4d parentToWorldInverse =
551         ComputeParentToWorldTransform(time).GetInverse();
552 
553     const GfMatrix4d camMatrix = camera.GetTransform() * parentToWorldInverse;
554 
555     MakeMatrixXform().Set(camMatrix, time);
556     GetProjectionAttr().Set(_ProjectionToToken(camera.GetProjection()), time);
557     GetHorizontalApertureAttr().Set(camera.GetHorizontalAperture(), time);
558     GetVerticalApertureAttr().Set(camera.GetVerticalAperture(), time);
559     GetHorizontalApertureOffsetAttr().Set(
560         camera.GetHorizontalApertureOffset(), time);
561     GetVerticalApertureOffsetAttr().Set(
562         camera.GetVerticalApertureOffset(), time);
563     GetFocalLengthAttr().Set(camera.GetFocalLength(), time);
564     GetClippingRangeAttr().Set(
565         _Range1fToVec2f(camera.GetClippingRange()), time);
566 
567     GetClippingPlanesAttr().Set(
568         _VectorVec4fToVtArray(camera.GetClippingPlanes()), time);
569 
570     GetFStopAttr().Set(camera.GetFStop(), time);
571     GetFocusDistanceAttr().Set(camera.GetFocusDistance(), time);
572 }
573 
574 PXR_NAMESPACE_CLOSE_SCOPE
575