This document is for a version of USD that is under development. See this page for the current release.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
frustum.h
Go to the documentation of this file.
1//
2// Copyright 2016 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_BASE_GF_FRUSTUM_H
8#define PXR_BASE_GF_FRUSTUM_H
9
12
13#include "pxr/pxr.h"
14#include "pxr/base/gf/bbox3d.h"
16#include "pxr/base/gf/plane.h"
17#include "pxr/base/gf/ray.h"
18#include "pxr/base/gf/range1d.h"
19#include "pxr/base/gf/range2d.h"
21#include "pxr/base/gf/vec2d.h"
22#include "pxr/base/gf/vec3d.h"
23#include "pxr/base/gf/api.h"
24#include "pxr/base/tf/hash.h"
25
26#include <array>
27#include <atomic>
28#include <iosfwd>
29#include <vector>
30
31PXR_NAMESPACE_OPEN_SCOPE
32
71class GfFrustum {
72 public:
78 };
79
88 GF_API GfFrustum();
89
92 : _position(o._position)
93 , _rotation(o._rotation)
94 , _window(o._window)
95 , _nearFar(o._nearFar)
96 , _viewDistance(o._viewDistance)
97 , _projectionType(o._projectionType)
98 , _planes(nullptr) {
99 if (auto *planes = o._planes.load()) {
100 _planes = new std::array<GfPlane, 6>(*planes);
101 }
102 }
103
105 GfFrustum(GfFrustum &&o) noexcept
106 : _position(o._position)
107 , _rotation(o._rotation)
108 , _window(o._window)
109 , _nearFar(o._nearFar)
110 , _viewDistance(o._viewDistance)
111 , _projectionType(o._projectionType)
112 , _planes(nullptr) {
113 if (auto *planes =
114 o._planes.exchange(nullptr, std::memory_order_relaxed)) {
115 _planes = planes;
116 }
117 }
118
121 GF_API GfFrustum(const GfVec3d &position, const GfRotation &rotation,
122 const GfRange2d &window, const GfRange1d &nearFar,
123 GfFrustum::ProjectionType projectionType,
124 double viewDistance = 5.0);
125
129 GF_API GfFrustum(const GfMatrix4d &camToWorldXf,
130 const GfRange2d &window, const GfRange1d &nearFar,
131 GfFrustum::ProjectionType projectionType,
132 double viewDistance = 5.0);
133
135 GfFrustum &operator=(GfFrustum const &o) noexcept {
136 if (this == &o) {
137 return *this;
138 }
139 _position = o._position;
140 _rotation = o._rotation;
141 _window = o._window;
142 _nearFar = o._nearFar;
143 _viewDistance = o._viewDistance;
144 _projectionType = o._projectionType;
145 delete _planes.load(std::memory_order_relaxed);
146 if (auto *planes = o._planes.load(std::memory_order_relaxed)) {
147 _planes.store(new std::array<GfPlane, 6>(*planes),
148 std::memory_order_relaxed);
149 }
150 else {
151 _planes.store(nullptr, std::memory_order_relaxed);
152 }
153 return *this;
154 }
155
158 if (this == &o) {
159 return *this;
160 }
161 _position = o._position;
162 _rotation = o._rotation;
163 _window = o._window;
164 _nearFar = o._nearFar;
165 _viewDistance = o._viewDistance;
166 _projectionType = o._projectionType;
167 delete _planes.load(std::memory_order_relaxed);
168 _planes.store(o._planes.load(std::memory_order_relaxed),
169 std::memory_order_relaxed);
170 o._planes.store(nullptr, std::memory_order_relaxed);
171 return *this;
172 }
173
174 friend inline size_t hash_value(const GfFrustum &f) {
175 return TfHash::Combine(
176 f._position,
177 f._rotation,
178 f._window,
179 f._nearFar,
180 f._viewDistance,
181 f._projectionType
182 );
183 }
184
185 // Equality operator. true iff all parts match.
186 bool operator ==(const GfFrustum& f) const {
187 if (_position != f._position) return false;
188 if (_rotation != f._rotation) return false;
189 if (_window != f._window) return false;
190 if (_nearFar != f._nearFar) return false;
191 if (_viewDistance != f._viewDistance) return false;
192 if (_projectionType != f._projectionType) return false;
193
194 return true;
195 }
196
197 // Inequality operator. true iff not equality.
198 bool operator !=(const GfFrustum& f) const {
199 return !(*this == f);
200 }
201
203 GF_API ~GfFrustum();
204
209
211 void SetPosition(const GfVec3d &position) {
212 _position = position;
213 _DirtyFrustumPlanes();
214 }
215
217 const GfVec3d & GetPosition() const {
218 return _position;
219 }
220
224 void SetRotation(const GfRotation &rotation) {
225 _rotation = rotation;
226 _DirtyFrustumPlanes();
227 }
228
231 const GfRotation & GetRotation() const {
232 return _rotation;
233 }
234
240 GF_API void SetPositionAndRotationFromMatrix(const GfMatrix4d &camToWorldXf);
241
244 void SetWindow(const GfRange2d &window) {
245 _window = window;
246 _DirtyFrustumPlanes();
247 }
248
250 const GfRange2d & GetWindow() const {
251 return _window;
252 }
253
255 static double GetReferencePlaneDepth() {
256 return 1.0;
257 }
258
260 void SetNearFar(const GfRange1d &nearFar) {
261 _nearFar = nearFar;
262 _DirtyFrustumPlanes();
263 }
264
266 const GfRange1d & GetNearFar() const {
267 return _nearFar;
268 }
269
271 void SetViewDistance(double viewDistance) {
272 _viewDistance = viewDistance;
273 }
274
276 double GetViewDistance() const {
277 return _viewDistance;
278 }
279
282 _projectionType = projectionType;
283 _DirtyFrustumPlanes();
284 }
285
288 return _projectionType;
289 }
290
292
300
318 GF_API void SetPerspective(double fieldOfViewHeight,
319 double aspectRatio,
320 double nearDistance, double farDistance);
321
349 GF_API void SetPerspective(double fieldOfView,
350 bool isFovVertical,
351 double aspectRatio,
352 double nearDistance, double farDistance);
353
357 GF_API bool GetPerspective(double *fieldOfViewHeight,
358 double *aspectRatio,
359 double *nearDistance,
360 double *farDistance) const;
361
365 GF_API bool GetPerspective(bool isFovVertical,
366 double *fieldOfView,
367 double *aspectRatio,
368 double *nearDistance,
369 double *farDistance) const;
370
382 GF_API double GetFOV(bool isFovVertical = false) const;
383
388 GF_API
389 void SetOrthographic(double left, double right,
390 double bottom, double top,
391 double nearPlane, double farPlane);
392
396 GF_API bool GetOrthographic(double *left, double *right,
397 double *bottom, double *top,
398 double *nearPlane, double *farPlane)
399 const;
400
406 GF_API void FitToSphere(const GfVec3d &center,
407 double radius,
408 double slack = 0.0);
409
423 GF_API GfFrustum& Transform(const GfMatrix4d &matrix);
424
428
431 GF_API GfVec3d ComputeUpVector() const;
432
446 GF_API void ComputeViewFrame(GfVec3d *side,
447 GfVec3d *up,
448 GfVec3d *view) const;
449
453
458
463
467
471 GF_API double ComputeAspectRatio() const;
472
483 GF_API
484 std::vector<GfVec3d> ComputeCorners() const;
485
495 GF_API
496 std::vector<GfVec3d> ComputeCornersAtDistance(double d) const;
497
514 GF_API GfFrustum ComputeNarrowedFrustum(const GfVec2d &windowPos,
515 const GfVec2d &size) const;
516
536 GF_API GfFrustum ComputeNarrowedFrustum(const GfVec3d &worldPoint,
537 const GfVec2d &size) const;
538
546 GF_API GfRay ComputeRay(const GfVec2d &windowPos) const;
547
554 GF_API GfRay ComputeRay(const GfVec3d &worldSpacePos) const;
555
562 GF_API GfRay ComputePickRay(const GfVec2d &windowPos) const;
563
566 GF_API GfRay ComputePickRay(const GfVec3d &worldSpacePos) const;
567
569
576
580 GF_API bool Intersects(const GfBBox3d &bbox) const;
581
584 GF_API bool Intersects(const GfVec3d &point) const;
585
588 GF_API bool Intersects(const GfVec3d &p0,
589 const GfVec3d &p1) const;
590
593 GF_API bool Intersects(const GfVec3d &p0,
594 const GfVec3d &p1,
595 const GfVec3d &p2) const;
596
608 GF_API static bool IntersectsViewVolume(const GfBBox3d &bbox,
609 const GfMatrix4d &vpMat);
610
612
613 private:
614 // Dirty the result of _CalculateFrustumPlanes.
615 GF_API void _DirtyFrustumPlanes();
616
617 // Calculates cached frustum planes used for intersection tests.
618 GF_API void _CalculateFrustumPlanes() const;
619
620 // Builds and returns a \c GfRay that can be used for picking. Given an
621 // eye position and direction in camera space, offsets the ray to emanate
622 // from the near plane, then transforms into worldspace
623 GF_API GfRay _ComputePickRayOffsetToNearPlane(
624 const GfVec3d &camSpaceFrom,
625 const GfVec3d &camSpaceDir) const;
626
627 // Returns a frustum that is a narrowed-down version of this frustum. The
628 // new frustum has the same near and far planes, but the other planes are
629 // adjusted to be centered on \p windowPoint with the new width and height
630 // obtained from the existing width and height by multiplying by \p size[0]
631 // and \p size[1], respectively. Finally, the new frustum is clipped
632 // against this frustum so that it is completely contained in the existing
633 // frustum.
634 //
635 // \p windowPoint is given in window coordinates.
636 // \p size is given as a scalar (0 to 1 in both dimensions).
637 //
638 // If the \p size given is outside this range, it may result in returning
639 // a collapsed frustum.
640 //
641 // This method is useful for computing a volume to use for interactive
642 // picking.
643 GfFrustum _ComputeNarrowedFrustumSub(const GfVec2d windowPoint,
644 const GfVec2d &size) const;
645
646 bool _SegmentIntersects(GfVec3d const &p0, uint32_t p0Mask,
647 GfVec3d const &p1, uint32_t p1Mask) const;
648
649 // Position of the frustum in world space.
650 GfVec3d _position;
651
652 // Orientation of the frustum in world space as a rotation to apply to the
653 // -z axis.
654 GfRotation _rotation;
655
656 // Window rectangle in the image plane.
657 GfRange2d _window;
658
659 // Near/far interval.
660 GfRange1d _nearFar;
661
662 // View distance.
663 double _viewDistance;
664
665 // Projection type.
666 ProjectionType _projectionType;
667
668 // Cached planes.
669 // If null, the planes have not been calculated.
670 mutable std::atomic<std::array<GfPlane, 6> *> _planes;
671};
672
680GF_API std::ostream& operator<<(std::ostream& out, const GfFrustum& f);
681
682PXR_NAMESPACE_CLOSE_SCOPE
683
684#endif // PXR_BASE_GF_FRUSTUM_H
Basic type: arbitrarily oriented 3D bounding box.
Definition: bbox3d.h:67
Basic type: View frustum.
Definition: frustum.h:71
GF_API GfRay ComputeRay(const GfVec3d &worldSpacePos) const
Builds and returns a GfRay that connects the viewpoint to the given 3d point in worldspace.
static double GetReferencePlaneDepth()
Returns the depth of the reference plane.
Definition: frustum.h:255
GF_API std::vector< GfVec3d > ComputeCornersAtDistance(double d) const
Returns the world-space corners of the intersection of the frustum with a plane parallel to the near/...
GF_API double ComputeAspectRatio() const
Returns the aspect ratio of the frustum, defined as the width of the window divided by the height.
GfFrustum & operator=(GfFrustum &&o) noexcept
Move assignment.
Definition: frustum.h:157
GF_API void SetPerspective(double fieldOfView, bool isFovVertical, double aspectRatio, double nearDistance, double farDistance)
Sets up the frustum in a manner similar to gluPerspective().
GF_API GfRay ComputePickRay(const GfVec2d &windowPos) const
Builds and returns a GfRay that can be used for picking at the given normalized (-1 to +1 in both dim...
void SetViewDistance(double viewDistance)
Sets the view distance.
Definition: frustum.h:271
GfFrustum & operator=(GfFrustum const &o) noexcept
Copy assignment.
Definition: frustum.h:135
void SetNearFar(const GfRange1d &nearFar)
Sets the near/far interval.
Definition: frustum.h:260
const GfRange2d & GetWindow() const
Returns the window rectangle in the reference plane.
Definition: frustum.h:250
GF_API GfFrustum ComputeNarrowedFrustum(const GfVec3d &worldPoint, const GfVec2d &size) const
Returns a frustum that is a narrowed-down version of this frustum.
GF_API ~GfFrustum()
Destructor.
GF_API void SetPerspective(double fieldOfViewHeight, double aspectRatio, double nearDistance, double farDistance)
Sets up the frustum in a manner similar to gluPerspective().
const GfRange1d & GetNearFar() const
Returns the near/far interval.
Definition: frustum.h:266
GF_API GfFrustum()
This constructor creates an instance with default viewing parameters:
GF_API bool Intersects(const GfVec3d &point) const
Returns true if the given point is inside or intersecting the frustum.
void SetProjectionType(GfFrustum::ProjectionType projectionType)
Sets the projection type.
Definition: frustum.h:281
GF_API double GetFOV(bool isFovVertical=false) const
Returns the horizontal or vertical fov of the frustum.
double GetViewDistance() const
Returns the view distance.
Definition: frustum.h:276
GfFrustum::ProjectionType GetProjectionType() const
Returns the projection type.
Definition: frustum.h:287
GF_API GfFrustum ComputeNarrowedFrustum(const GfVec2d &windowPos, const GfVec2d &size) const
Returns a frustum that is a narrowed-down version of this frustum.
GF_API bool GetOrthographic(double *left, double *right, double *bottom, double *top, double *nearPlane, double *farPlane) const
Returns the current frustum in the format used by SetOrthographic().
GF_API bool Intersects(const GfBBox3d &bbox) const
Returns true if the given axis-aligned bbox is inside or intersecting the frustum.
void SetPosition(const GfVec3d &position)
Sets the position of the frustum in world space.
Definition: frustum.h:211
GF_API bool GetPerspective(bool isFovVertical, double *fieldOfView, double *aspectRatio, double *nearDistance, double *farDistance) const
Returns the current frustum in the format used by SetPerspective().
GF_API GfVec3d ComputeUpVector() const
Returns the normalized world-space up vector, which is computed by rotating the y axis by the frustum...
static GF_API bool IntersectsViewVolume(const GfBBox3d &bbox, const GfMatrix4d &vpMat)
Returns true if the bbox volume intersects the view volume given by the view-projection matrix,...
GF_API void SetOrthographic(double left, double right, double bottom, double top, double nearPlane, double farPlane)
Sets up the frustum in a manner similar to glOrtho().
GF_API GfFrustum(const GfMatrix4d &camToWorldXf, const GfRange2d &window, const GfRange1d &nearFar, GfFrustum::ProjectionType projectionType, double viewDistance=5.0)
This constructor creates an instance from a camera matrix (always of a y-Up camera,...
GfFrustum(GfFrustum const &o)
Copy constructor.
Definition: frustum.h:91
GF_API bool Intersects(const GfVec3d &p0, const GfVec3d &p1) const
Returns true if the line segment formed by the given points is inside or intersecting the frustum.
GF_API GfRay ComputePickRay(const GfVec3d &worldSpacePos) const
Builds and returns a GfRay that can be used for picking that connects the viewpoint to the given 3d p...
GF_API std::vector< GfVec3d > ComputeCorners() const
Returns the world-space corners of the frustum as a vector of 8 points, ordered as:
const GfRotation & GetRotation() const
Returns the orientation of the frustum in world space as a rotation to apply to the -z axis.
Definition: frustum.h:231
GF_API GfMatrix4d ComputeViewMatrix() const
Returns a matrix that represents the viewing transformation for this frustum.
GF_API bool GetPerspective(double *fieldOfViewHeight, double *aspectRatio, double *nearDistance, double *farDistance) const
Returns the current frustum in the format used by SetPerspective().
GF_API GfVec3d ComputeViewDirection() const
Returns the normalized world-space view direction vector, which is computed by rotating the -z axis b...
GF_API bool Intersects(const GfVec3d &p0, const GfVec3d &p1, const GfVec3d &p2) const
Returns true if the triangle formed by the given points is inside or intersecting the frustum.
GF_API GfMatrix4d ComputeProjectionMatrix() const
Returns a GL-style projection matrix corresponding to the frustum's projection.
GF_API void SetPositionAndRotationFromMatrix(const GfMatrix4d &camToWorldXf)
Sets the position and rotation of the frustum from a camera matrix (always from a y-Up camera).
void SetWindow(const GfRange2d &window)
Sets the window rectangle in the reference plane that defines the left, right, top,...
Definition: frustum.h:244
GfFrustum(GfFrustum &&o) noexcept
Move constructor.
Definition: frustum.h:105
GF_API GfVec3d ComputeLookAtPoint() const
Computes and returns the world-space look-at point from the eye point (position), view direction (rot...
void SetRotation(const GfRotation &rotation)
Sets the orientation of the frustum in world space as a rotation to apply to the default frame: looki...
Definition: frustum.h:224
GF_API GfFrustum(const GfVec3d &position, const GfRotation &rotation, const GfRange2d &window, const GfRange1d &nearFar, GfFrustum::ProjectionType projectionType, double viewDistance=5.0)
This constructor creates an instance with the given viewing parameters.
GF_API void ComputeViewFrame(GfVec3d *side, GfVec3d *up, GfVec3d *view) const
Computes the view frame defined by this frustum.
GF_API GfFrustum & Transform(const GfMatrix4d &matrix)
Transforms the frustum by the given matrix.
GF_API GfMatrix4d ComputeViewInverse() const
Returns a matrix that represents the inverse viewing transformation for this frustum.
ProjectionType
This enum is used to determine the type of projection represented by a frustum.
Definition: frustum.h:75
@ Orthographic
Orthographic projection.
Definition: frustum.h:76
@ Perspective
Perspective projection.
Definition: frustum.h:77
GF_API GfRay ComputeRay(const GfVec2d &windowPos) const
Builds and returns a GfRay that starts at the viewpoint and extends through the given windowPos given...
const GfVec3d & GetPosition() const
Returns the position of the frustum in world space.
Definition: frustum.h:217
GF_API void FitToSphere(const GfVec3d &center, double radius, double slack=0.0)
Modifies the frustum to tightly enclose a sphere with the given center and radius,...
Stores a 4x4 matrix of double elements.
Definition: matrix4d.h:71
Basic type: 1-dimensional floating point range.
Definition: range1d.h:45
Basic type: 2-dimensional floating point range.
Definition: range2d.h:47
Basic type: Ray used for intersection testing.
Definition: ray.h:44
Basic type: 3-space rotation specification.
Definition: rotation.h:37
Basic type for a vector of 2 double components.
Definition: vec2d.h:46
Basic type for a vector of 3 double components.
Definition: vec3d.h:46
static size_t Combine(Args &&... args)
Produce a hash code by combining the hash codes of several objects.
Definition: hash.h:475
GF_API std::ostream & operator<<(std::ostream &, const GfBBox3d &)
Output a GfBBox3d using the format [(range) matrix zeroArea].