Loading...
Searching...
No Matches
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:487
GF_API std::ostream & operator<<(std::ostream &, const GfBBox3d &)
Output a GfBBox3d using the format [(range) matrix zeroArea].