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:
79
80 using FrustumPlanes = std::array<GfPlane, 6>;
81
90 GF_API GfFrustum();
91
94 : _position(o._position)
95 , _rotation(o._rotation)
96 , _window(o._window)
97 , _nearFar(o._nearFar)
98 , _viewDistance(o._viewDistance)
99 , _projectionType(o._projectionType)
100 , _planes(nullptr) {
101 if (auto *planes = o._planes.load()) {
102 _planes = new FrustumPlanes(*planes);
103 }
104 }
105
107 GfFrustum(GfFrustum &&o) noexcept
108 : _position(o._position)
109 , _rotation(o._rotation)
110 , _window(o._window)
111 , _nearFar(o._nearFar)
112 , _viewDistance(o._viewDistance)
113 , _projectionType(o._projectionType)
114 , _planes(nullptr) {
115 if (auto *planes =
116 o._planes.exchange(nullptr, std::memory_order_relaxed)) {
117 _planes = planes;
118 }
119 }
120
123 GF_API GfFrustum(const GfVec3d &position, const GfRotation &rotation,
124 const GfRange2d &window, const GfRange1d &nearFar,
125 GfFrustum::ProjectionType projectionType,
126 double viewDistance = 5.0);
127
131 GF_API GfFrustum(const GfMatrix4d &camToWorldXf,
132 const GfRange2d &window, const GfRange1d &nearFar,
133 GfFrustum::ProjectionType projectionType,
134 double viewDistance = 5.0);
135
137 GfFrustum &operator=(GfFrustum const &o) noexcept {
138 if (this == &o) {
139 return *this;
140 }
141 _position = o._position;
142 _rotation = o._rotation;
143 _window = o._window;
144 _nearFar = o._nearFar;
145 _viewDistance = o._viewDistance;
146 _projectionType = o._projectionType;
147 delete _planes.load(std::memory_order_relaxed);
148 if (auto *planes = o._planes.load(std::memory_order_relaxed)) {
149 _planes.store(new FrustumPlanes(*planes),
150 std::memory_order_relaxed);
151 }
152 else {
153 _planes.store(nullptr, std::memory_order_relaxed);
154 }
155 return *this;
156 }
157
160 if (this == &o) {
161 return *this;
162 }
163 _position = o._position;
164 _rotation = o._rotation;
165 _window = o._window;
166 _nearFar = o._nearFar;
167 _viewDistance = o._viewDistance;
168 _projectionType = o._projectionType;
169 delete _planes.load(std::memory_order_relaxed);
170 _planes.store(o._planes.load(std::memory_order_relaxed),
171 std::memory_order_relaxed);
172 o._planes.store(nullptr, std::memory_order_relaxed);
173 return *this;
174 }
175
176 friend inline size_t hash_value(const GfFrustum &f) {
177 return TfHash::Combine(
178 f._position,
179 f._rotation,
180 f._window,
181 f._nearFar,
182 f._viewDistance,
183 f._projectionType
184 );
185 }
186
187 // Equality operator. true iff all parts match.
188 bool operator ==(const GfFrustum& f) const {
189 if (_position != f._position) return false;
190 if (_rotation != f._rotation) return false;
191 if (_window != f._window) return false;
192 if (_nearFar != f._nearFar) return false;
193 if (_viewDistance != f._viewDistance) return false;
194 if (_projectionType != f._projectionType) return false;
195
196 return true;
197 }
198
199 // Inequality operator. true iff not equality.
200 bool operator !=(const GfFrustum& f) const {
201 return !(*this == f);
202 }
203
205 GF_API ~GfFrustum();
206
211
213 void SetPosition(const GfVec3d &position) {
214 _position = position;
215 _DirtyFrustumPlanes();
216 }
217
219 const GfVec3d & GetPosition() const {
220 return _position;
221 }
222
226 void SetRotation(const GfRotation &rotation) {
227 _rotation = rotation;
228 _DirtyFrustumPlanes();
229 }
230
233 const GfRotation & GetRotation() const {
234 return _rotation;
235 }
236
242 GF_API void SetPositionAndRotationFromMatrix(const GfMatrix4d &camToWorldXf);
243
246 void SetWindow(const GfRange2d &window) {
247 _window = window;
248 _DirtyFrustumPlanes();
249 }
250
252 const GfRange2d & GetWindow() const {
253 return _window;
254 }
255
257 static double GetReferencePlaneDepth() {
258 return 1.0;
259 }
260
262 void SetNearFar(const GfRange1d &nearFar) {
263 _nearFar = nearFar;
264 _DirtyFrustumPlanes();
265 }
266
268 const GfRange1d & GetNearFar() const {
269 return _nearFar;
270 }
271
273 void SetViewDistance(double viewDistance) {
274 _viewDistance = viewDistance;
275 }
276
278 double GetViewDistance() const {
279 return _viewDistance;
280 }
281
284 _projectionType = projectionType;
285 _DirtyFrustumPlanes();
286 }
287
290 return _projectionType;
291 }
292
294
302
320 GF_API void SetPerspective(double fieldOfViewHeight,
321 double aspectRatio,
322 double nearDistance, double farDistance);
323
351 GF_API void SetPerspective(double fieldOfView,
352 bool isFovVertical,
353 double aspectRatio,
354 double nearDistance, double farDistance);
355
359 GF_API bool GetPerspective(double *fieldOfViewHeight,
360 double *aspectRatio,
361 double *nearDistance,
362 double *farDistance) const;
363
367 GF_API bool GetPerspective(bool isFovVertical,
368 double *fieldOfView,
369 double *aspectRatio,
370 double *nearDistance,
371 double *farDistance) const;
372
384 GF_API double GetFOV(bool isFovVertical = false) const;
385
390 GF_API
391 void SetOrthographic(double left, double right,
392 double bottom, double top,
393 double nearPlane, double farPlane);
394
398 GF_API bool GetOrthographic(double *left, double *right,
399 double *bottom, double *top,
400 double *nearPlane, double *farPlane)
401 const;
402
408 GF_API void FitToSphere(const GfVec3d &center,
409 double radius,
410 double slack = 0.0);
411
425 GF_API GfFrustum& Transform(const GfMatrix4d &matrix);
426
430
433 GF_API GfVec3d ComputeUpVector() const;
434
448 GF_API void ComputeViewFrame(GfVec3d *side,
449 GfVec3d *up,
450 GfVec3d *view) const;
451
455
460
465
469
473 GF_API double ComputeAspectRatio() const;
474
485 GF_API
486 std::vector<GfVec3d> ComputeCorners() const;
487
497 GF_API
498 std::vector<GfVec3d> ComputeCornersAtDistance(double d) const;
499
508 GF_API
509 FrustumPlanes ComputePlanes() const;
510
527 GF_API GfFrustum ComputeNarrowedFrustum(const GfVec2d &windowPos,
528 const GfVec2d &size) const;
529
549 GF_API GfFrustum ComputeNarrowedFrustum(const GfVec3d &worldPoint,
550 const GfVec2d &size) const;
551
559 GF_API GfRay ComputeRay(const GfVec2d &windowPos) const;
560
567 GF_API GfRay ComputeRay(const GfVec3d &worldSpacePos) const;
568
575 GF_API GfRay ComputePickRay(const GfVec2d &windowPos) const;
576
579 GF_API GfRay ComputePickRay(const GfVec3d &worldSpacePos) const;
580
582
589
593 GF_API bool Intersects(const GfBBox3d &bbox) const;
594
597 GF_API bool Intersects(const GfVec3d &point) const;
598
601 GF_API bool Intersects(const GfVec3d &p0,
602 const GfVec3d &p1) const;
603
606 GF_API bool Intersects(const GfVec3d &p0,
607 const GfVec3d &p1,
608 const GfVec3d &p2) const;
609
621 GF_API static bool IntersectsViewVolume(const GfBBox3d &bbox,
622 const GfMatrix4d &vpMat);
623
625
626 private:
627 // Dirty the result of _CalculateFrustumPlanes.
628 GF_API void _DirtyFrustumPlanes();
629
630 // Calculates cached frustum planes used for intersection tests.
631 GF_API void _CalculateFrustumPlanes() const;
632
633 // Builds and returns a \c GfRay that can be used for picking. Given an
634 // eye position and direction in camera space, offsets the ray to emanate
635 // from the near plane, then transforms into worldspace
636 GF_API GfRay _ComputePickRayOffsetToNearPlane(
637 const GfVec3d &camSpaceFrom,
638 const GfVec3d &camSpaceDir) const;
639
640 // Returns a frustum that is a narrowed-down version of this frustum. The
641 // new frustum has the same near and far planes, but the other planes are
642 // adjusted to be centered on \p windowPoint with the new width and height
643 // obtained from the existing width and height by multiplying by \p size[0]
644 // and \p size[1], respectively. Finally, the new frustum is clipped
645 // against this frustum so that it is completely contained in the existing
646 // frustum.
647 //
648 // \p windowPoint is given in window coordinates.
649 // \p size is given as a scalar (0 to 1 in both dimensions).
650 //
651 // If the \p size given is outside this range, it may result in returning
652 // a collapsed frustum.
653 //
654 // This method is useful for computing a volume to use for interactive
655 // picking.
656 GfFrustum _ComputeNarrowedFrustumSub(const GfVec2d windowPoint,
657 const GfVec2d &size) const;
658
659 bool _SegmentIntersects(GfVec3d const &p0, uint32_t p0Mask,
660 GfVec3d const &p1, uint32_t p1Mask) const;
661
662 // Position of the frustum in world space.
663 GfVec3d _position;
664
665 // Orientation of the frustum in world space as a rotation to apply to the
666 // -z axis.
667 GfRotation _rotation;
668
669 // Window rectangle in the image plane.
670 GfRange2d _window;
671
672 // Near/far interval.
673 GfRange1d _nearFar;
674
675 // View distance.
676 double _viewDistance;
677
678 // Projection type.
679 ProjectionType _projectionType;
680
681 // Cached planes.
682 // If null, the planes have not been calculated.
683 mutable std::atomic<FrustumPlanes *> _planes;
684};
685
693GF_API std::ostream& operator<<(std::ostream& out, const GfFrustum& f);
694
695PXR_NAMESPACE_CLOSE_SCOPE
696
697#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:257
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:159
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:273
GfFrustum & operator=(GfFrustum const &o) noexcept
Copy assignment.
Definition frustum.h:137
void SetNearFar(const GfRange1d &nearFar)
Sets the near/far interval.
Definition frustum.h:262
const GfRange2d & GetWindow() const
Returns the window rectangle in the reference plane.
Definition frustum.h:252
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:268
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:283
GF_API FrustumPlanes ComputePlanes() const
Returns the world-space clipping planes of the frustum as a vector of 6 GfPlane objects,...
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:278
GfFrustum::ProjectionType GetProjectionType() const
Returns the projection type.
Definition frustum.h:289
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:213
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:93
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:233
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:246
GfFrustum(GfFrustum &&o) noexcept
Move constructor.
Definition frustum.h:107
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:226
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:219
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 &out, const GfFrustum &f)
Output a GfFrustum using the format [(position) (rotation) [window] [nearFar] viewDistance type].