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 #ifndef PXR_BASE_GF_CAMERA_H
25 #define PXR_BASE_GF_CAMERA_H
26 
27 /// \file gf/camera.h
28 /// \ingroup group_gf_BasicGeometry
29 
30 #include "pxr/pxr.h"
31 #include "pxr/base/gf/matrix4d.h"
32 #include "pxr/base/gf/range1f.h"
33 #include "pxr/base/gf/vec4f.h"
34 #include "pxr/base/gf/api.h"
35 
36 #include <vector>
37 
38 PXR_NAMESPACE_OPEN_SCOPE
39 
40 class GfFrustum;
41 
42 /// \class GfCamera
43 /// \ingroup group_gf_BasicGeometry
44 /// \brief Object-based representation of a camera.
45 ///
46 /// This class provides a thin wrapper on the camera data model,
47 /// with a small number of computations.
48 ///
49 class GfCamera
50 {
51 public:
52     /// Projection type.
53     enum Projection {
54         Perspective = 0,
55         Orthographic,
56     };
57 
58     /// Direction used for Field of View or orthographic size
59     enum FOVDirection {
60         FOVHorizontal = 0,
61         FOVVertical
62     };
63 
64     /// The unit for horizontal and vertical aperture is one tenth of the
65     /// world unit. Thus, if the world unit is assumed to be cm, the horizontal
66     /// and vertical aperture unit is mm.
67     GF_API static const double APERTURE_UNIT;
68     /// The unit for focal length. Similar to APERTURE_UNIT.
69     GF_API static const double FOCAL_LENGTH_UNIT;
70 
71     /// Default horizontal and vertical aperture, based on a 35mm
72     /// (non-anamorphic) projector aperture (0.825 x 0602 inches, converted to
73     /// mm).
74     GF_API static const double DEFAULT_HORIZONTAL_APERTURE;
75     GF_API static const double DEFAULT_VERTICAL_APERTURE;
76 
77 public:
78     GF_API GfCamera(
79         const GfMatrix4d &transform = GfMatrix4d(1.0),
80         Projection projection = Perspective,
81         float horizontalAperture = DEFAULT_HORIZONTAL_APERTURE,
82         float verticalAperture = DEFAULT_VERTICAL_APERTURE,
83         float horizontalApertureOffset = 0.0,
84         float verticalApertureOffset = 0.0,
85         float focalLength = 50.0,
86         const GfRange1f &clippingRange = GfRange1f(1, 1000000),
87         const std::vector<GfVec4f> &clippingPlanes = std::vector<GfVec4f>(),
88         float fStop = 0.0,
89         float focusDistance = 0.0);
90 
91     /// Sets the transform of the filmback in world space to \p val.
92     GF_API void SetTransform(const GfMatrix4d &val);
93 
94     /// Sets the projection type.
95     GF_API void SetProjection(const Projection &val);
96 
97     /// \name Physics based camera setup
98 
99     /// These are the values actually stored in the class and they correspond
100     /// to measurements of an actual physical camera (in mm).
101     /// Together with the clipping range, they determine the camera frustum.
102 
103     /// @{
104 
105     /// Sets the focal length in tenths of a world unit (e.g., mm if the world
106     /// unit is assumed to be cm).
107     GF_API void SetFocalLength(const float val);
108 
109     /// Sets the width of the projector aperture in tenths of a world unit
110     /// (e.g., mm if the world unit is assumed to be cm).
111     GF_API void SetHorizontalAperture(const float val);
112 
113     /// Sets the height of the projector aperture in tenths of a world unit
114     /// (e.g., mm if the world unit is assumed to be cm).
115     GF_API void SetVerticalAperture(const float val);
116 
117     /// Sets the horizontal offset of the projector aperture in tenths of a
118     /// world unit (e.g., mm if the world unit is assumed to be cm).
119     GF_API void SetHorizontalApertureOffset(const float val);
120 
121     /// Sets the vertical offset of the projector aperture in tenths of a
122     /// world unit (e.g., mm if the world unit is assumed to be cm).
123     GF_API void SetVerticalApertureOffset(const float val);
124     /// @}
125 
126     /// \name Frustum geometry setup
127     /// @{
128 
129     /// Sets the frustum to be projective with the given \p aspectRatio
130     /// and horizontal, respectively, vertical field of view \p fieldOfView
131     /// (similar to gluPerspective when direction = FOVVertical).
132     ///
133     /// Do not pass values for \p horionztalAperture unless you care about
134     /// DepthOfField.
135 
136     GF_API void SetPerspectiveFromAspectRatioAndFieldOfView(
137         float aspectRatio,
138         float fieldOfView,
139         FOVDirection direction,
140         float horizontalAperture = DEFAULT_HORIZONTAL_APERTURE);
141 
142     /// Sets the frustum to be orthographic such that it has the given
143     /// \p aspectRatio and such that the orthographic width, respectively,
144     /// orthographic height (in cm) is equal to \p orthographicSize
145     /// (depending on direction).
146 
147     GF_API void SetOrthographicFromAspectRatioAndSize(
148         float aspectRatio, float orthographicSize, FOVDirection direction);
149 
150     /// Sets the camera from a view and projection matrix.
151     ///
152     /// Note that the projection matrix does only determine the ratio
153     /// of aperture to focal length, so there is a choice which defaults
154     /// to 50mm (or more accurately, 50 tenths of a world unit).
155 
156     GF_API void SetFromViewAndProjectionMatrix(
157         const GfMatrix4d &viewMatrix, const GfMatrix4d &projMatix,
158         const float focalLength = 50.0);
159 
160     /// @}
161 
162     /// Sets the clipping range in world units.
163     GF_API void SetClippingRange(const GfRange1f &val);
164 
165     /// Sets additional arbitrarily oriented clipping planes.
166     /// A vector (a,b,c,d) encodes a clipping plane that clips off points
167     /// (x,y,z) with
168     ///
169     ///        a * x + b * y + c * z + d * 1 < 0
170     ///
171     /// where (x,y,z) are the coordinates in the camera's space.
172     GF_API void SetClippingPlanes(const std::vector<GfVec4f> &val);
173 
174     /// Sets the lens aperture, unitless.
175     GF_API void SetFStop(const float val);
176 
177     /// Sets the focus distance in world units.
178     GF_API void SetFocusDistance(const float val);
179 
180     /// Returns the transform of the filmback in world space.  This is
181     /// exactly the transform specified via SetTransform().
182     GF_API GfMatrix4d GetTransform() const;
183 
184     /// Returns the projection type.
185     GF_API Projection GetProjection() const;
186 
187     /// Returns the width of the projector aperture in tenths of a world unit
188     /// (e.g., mm if the world unit is assumed to be cm).
189     GF_API float GetHorizontalAperture() const;
190 
191     /// Returns the height of the projector aperture in tenths of a world unit
192     /// (e.g., mm if the world unit is assumed to be cm).
193     GF_API float GetVerticalAperture() const;
194 
195     /// Returns the horizontal offset of the projector aperture in tenths of a
196     /// world unit (e.g., mm if the world unit is assumed to be cm).
197     /// In particular, an offset is necessary when writing out a stereo camera
198     /// with finite convergence distance as two cameras.
199     GF_API float GetHorizontalApertureOffset() const;
200 
201     /// Returns the vertical offset of the projector aperture in tenths of a
202     /// world unit (e.g., mm if the world unit is assumed to be cm).
203     GF_API float GetVerticalApertureOffset() const;
204 
205     /// Returns the projector aperture aspect ratio.
206     GF_API float GetAspectRatio() const;
207 
208     /// Returns the focal length in tenths of a world unit (e.g., mm if the
209     /// world unit is assumed to be cm).
210     GF_API float GetFocalLength() const;
211 
212     /// Returns the horizontal or vertical field of view in degrees.
213     GF_API float GetFieldOfView(FOVDirection direction) const;
214 
215     /// Returns the clipping range in world units.
216     GF_API GfRange1f GetClippingRange() const;
217 
218     /// Returns additional clipping planes.
219     GF_API const std::vector<GfVec4f> &GetClippingPlanes() const;
220 
221     /// Returns the computed, world-space camera frustum.  The frustum
222     /// will always be that of a Y-up, -Z-looking camera.
223     GF_API GfFrustum GetFrustum() const;
224 
225     /// Returns the lens aperture.
226     GF_API float GetFStop() const;
227 
228     /// Returns the focus distance in world units.
229     GF_API float GetFocusDistance() const;
230 
231     /// Equality operator. true iff all parts match.
232     GF_API bool operator==(const GfCamera& other) const;
233 
234     // Inequality operator. true iff not equality.
235     GF_API bool operator!=(const GfCamera& other) const;
236 
237 private:
238     // frustum
239     GfMatrix4d              _transform;
240     Projection              _projection;
241     float                   _horizontalAperture;
242     float                   _verticalAperture;
243     float                   _horizontalApertureOffset;
244     float                   _verticalApertureOffset;
245     float                   _focalLength;
246     GfRange1f               _clippingRange;
247     std::vector<GfVec4f>    _clippingPlanes;
248 
249     // focus
250     float                   _fStop;
251     float                   _focusDistance;
252 };
253 
254 PXR_NAMESPACE_CLOSE_SCOPE
255 
256 #endif // PXR_BASE_GF_CAMERA_H
257