Loading...
Searching...
No Matches
frustum.h
Go to the documentation of this file.
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_FRUSTUM_H
25#define PXR_BASE_GF_FRUSTUM_H
26
29
30#include "pxr/pxr.h"
31#include "pxr/base/gf/bbox3d.h"
33#include "pxr/base/gf/plane.h"
34#include "pxr/base/gf/ray.h"
35#include "pxr/base/gf/range1d.h"
36#include "pxr/base/gf/range2d.h"
38#include "pxr/base/gf/vec2d.h"
39#include "pxr/base/gf/vec3d.h"
40#include "pxr/base/gf/api.h"
41#include "pxr/base/tf/hash.h"
42
43#include <array>
44#include <atomic>
45#include <iosfwd>
46#include <vector>
47
48PXR_NAMESPACE_OPEN_SCOPE
49
88class GfFrustum {
89 public:
95 };
96
105 GF_API GfFrustum();
106
109 : _position(o._position)
110 , _rotation(o._rotation)
111 , _window(o._window)
112 , _nearFar(o._nearFar)
113 , _viewDistance(o._viewDistance)
114 , _projectionType(o._projectionType)
115 , _planes(nullptr) {
116 if (auto *planes = o._planes.load()) {
117 _planes = new std::array<GfPlane, 6>(*planes);
118 }
119 }
120
122 GfFrustum(GfFrustum &&o) noexcept
123 : _position(o._position)
124 , _rotation(o._rotation)
125 , _window(o._window)
126 , _nearFar(o._nearFar)
127 , _viewDistance(o._viewDistance)
128 , _projectionType(o._projectionType)
129 , _planes(nullptr) {
130 if (auto *planes =
131 o._planes.exchange(nullptr, std::memory_order_relaxed)) {
132 _planes = planes;
133 }
134 }
135
138 GF_API GfFrustum(const GfVec3d &position, const GfRotation &rotation,
139 const GfRange2d &window, const GfRange1d &nearFar,
140 GfFrustum::ProjectionType projectionType,
141 double viewDistance = 5.0);
142
146 GF_API GfFrustum(const GfMatrix4d &camToWorldXf,
147 const GfRange2d &window, const GfRange1d &nearFar,
148 GfFrustum::ProjectionType projectionType,
149 double viewDistance = 5.0);
150
152 GfFrustum &operator=(GfFrustum const &o) noexcept {
153 if (this == &o) {
154 return *this;
155 }
156 _position = o._position;
157 _rotation = o._rotation;
158 _window = o._window;
159 _nearFar = o._nearFar;
160 _viewDistance = o._viewDistance;
161 _projectionType = o._projectionType;
162 delete _planes.load(std::memory_order_relaxed);
163 if (auto *planes = o._planes.load(std::memory_order_relaxed)) {
164 _planes.store(new std::array<GfPlane, 6>(*planes),
165 std::memory_order_relaxed);
166 }
167 else {
168 _planes.store(nullptr, std::memory_order_relaxed);
169 }
170 return *this;
171 }
172
175 if (this == &o) {
176 return *this;
177 }
178 _position = o._position;
179 _rotation = o._rotation;
180 _window = o._window;
181 _nearFar = o._nearFar;
182 _viewDistance = o._viewDistance;
183 _projectionType = o._projectionType;
184 delete _planes.load(std::memory_order_relaxed);
185 _planes.store(o._planes.load(std::memory_order_relaxed),
186 std::memory_order_relaxed);
187 o._planes.store(nullptr, std::memory_order_relaxed);
188 return *this;
189 }
190
191 friend inline size_t hash_value(const GfFrustum &f) {
192 return TfHash::Combine(
193 f._position,
194 f._rotation,
195 f._window,
196 f._nearFar,
197 f._viewDistance,
198 f._projectionType
199 );
200 }
201
202 // Equality operator. true iff all parts match.
203 bool operator ==(const GfFrustum& f) const {
204 if (_position != f._position) return false;
205 if (_rotation != f._rotation) return false;
206 if (_window != f._window) return false;
207 if (_nearFar != f._nearFar) return false;
208 if (_viewDistance != f._viewDistance) return false;
209 if (_projectionType != f._projectionType) return false;
210
211 return true;
212 }
213
214 // Inequality operator. true iff not equality.
215 bool operator !=(const GfFrustum& f) const {
216 return !(*this == f);
217 }
218
220 GF_API ~GfFrustum();
221
226
228 void SetPosition(const GfVec3d &position) {
229 _position = position;
230 _DirtyFrustumPlanes();
231 }
232
234 const GfVec3d & GetPosition() const {
235 return _position;
236 }
237
241 void SetRotation(const GfRotation &rotation) {
242 _rotation = rotation;
243 _DirtyFrustumPlanes();
244 }
245
248 const GfRotation & GetRotation() const {
249 return _rotation;
250 }
251
257 GF_API void SetPositionAndRotationFromMatrix(const GfMatrix4d &camToWorldXf);
258
261 void SetWindow(const GfRange2d &window) {
262 _window = window;
263 _DirtyFrustumPlanes();
264 }
265
267 const GfRange2d & GetWindow() const {
268 return _window;
269 }
270
272 static double GetReferencePlaneDepth() {
273 return 1.0;
274 }
275
277 void SetNearFar(const GfRange1d &nearFar) {
278 _nearFar = nearFar;
279 _DirtyFrustumPlanes();
280 }
281
283 const GfRange1d & GetNearFar() const {
284 return _nearFar;
285 }
286
288 void SetViewDistance(double viewDistance) {
289 _viewDistance = viewDistance;
290 }
291
293 double GetViewDistance() const {
294 return _viewDistance;
295 }
296
299 _projectionType = projectionType;
300 _DirtyFrustumPlanes();
301 }
302
305 return _projectionType;
306 }
307
309
317
335 GF_API void SetPerspective(double fieldOfViewHeight,
336 double aspectRatio,
337 double nearDistance, double farDistance);
338
366 GF_API void SetPerspective(double fieldOfView,
367 bool isFovVertical,
368 double aspectRatio,
369 double nearDistance, double farDistance);
370
374 GF_API bool GetPerspective(double *fieldOfViewHeight,
375 double *aspectRatio,
376 double *nearDistance,
377 double *farDistance) const;
378
382 GF_API bool GetPerspective(bool isFovVertical,
383 double *fieldOfView,
384 double *aspectRatio,
385 double *nearDistance,
386 double *farDistance) const;
387
399 GF_API double GetFOV(bool isFovVertical = false);
400
405 GF_API
406 void SetOrthographic(double left, double right,
407 double bottom, double top,
408 double nearPlane, double farPlane);
409
413 GF_API bool GetOrthographic(double *left, double *right,
414 double *bottom, double *top,
415 double *nearPlane, double *farPlane)
416 const;
417
423 GF_API void FitToSphere(const GfVec3d &center,
424 double radius,
425 double slack = 0.0);
426
440 GF_API GfFrustum& Transform(const GfMatrix4d &matrix);
441
445
448 GF_API GfVec3d ComputeUpVector() const;
449
463 GF_API void ComputeViewFrame(GfVec3d *side,
464 GfVec3d *up,
465 GfVec3d *view) const;
466
470
475
480
484
488 GF_API double ComputeAspectRatio() const;
489
500 GF_API
501 std::vector<GfVec3d> ComputeCorners() const;
502
512 GF_API
513 std::vector<GfVec3d> ComputeCornersAtDistance(double d) const;
514
531 GF_API GfFrustum ComputeNarrowedFrustum(const GfVec2d &windowPos,
532 const GfVec2d &size) const;
533
553 GF_API GfFrustum ComputeNarrowedFrustum(const GfVec3d &worldPoint,
554 const GfVec2d &size) const;
555
563 GF_API GfRay ComputeRay(const GfVec2d &windowPos) const;
564
571 GF_API GfRay ComputeRay(const GfVec3d &worldSpacePos) const;
572
579 GF_API GfRay ComputePickRay(const GfVec2d &windowPos) const;
580
583 GF_API GfRay ComputePickRay(const GfVec3d &worldSpacePos) const;
584
586
593
597 GF_API bool Intersects(const GfBBox3d &bbox) const;
598
601 GF_API bool Intersects(const GfVec3d &point) const;
602
605 GF_API bool Intersects(const GfVec3d &p0,
606 const GfVec3d &p1) const;
607
610 GF_API bool Intersects(const GfVec3d &p0,
611 const GfVec3d &p1,
612 const GfVec3d &p2) const;
613
625 GF_API static bool IntersectsViewVolume(const GfBBox3d &bbox,
626 const GfMatrix4d &vpMat);
627
629
630 private:
631 // Dirty the result of _CalculateFrustumPlanes.
632 GF_API void _DirtyFrustumPlanes();
633
634 // Calculates cached frustum planes used for intersection tests.
635 GF_API void _CalculateFrustumPlanes() const;
636
637 // Builds and returns a \c GfRay that can be used for picking. Given an
638 // eye position and direction in camera space, offsets the ray to emanate
639 // from the near plane, then transforms into worldspace
640 GF_API GfRay _ComputePickRayOffsetToNearPlane(
641 const GfVec3d &camSpaceFrom,
642 const GfVec3d &camSpaceDir) const;
643
644 // Returns a frustum that is a narrowed-down version of this frustum. The
645 // new frustum has the same near and far planes, but the other planes are
646 // adjusted to be centered on \p windowPoint with the new width and height
647 // obtained from the existing width and height by multiplying by \p size[0]
648 // and \p size[1], respectively. Finally, the new frustum is clipped
649 // against this frustum so that it is completely contained in the existing
650 // frustum.
651 //
652 // \p windowPoint is given in window coordinates.
653 // \p size is given as a scalar (0 to 1 in both dimensions).
654 //
655 // If the \p size given is outside this range, it may result in returning
656 // a collapsed frustum.
657 //
658 // This method is useful for computing a volume to use for interactive
659 // picking.
660 GfFrustum _ComputeNarrowedFrustumSub(const GfVec2d windowPoint,
661 const GfVec2d &size) const;
662
663 bool _SegmentIntersects(GfVec3d const &p0, uint32_t p0Mask,
664 GfVec3d const &p1, uint32_t p1Mask) const;
665
666 // Position of the frustum in world space.
667 GfVec3d _position;
668
669 // Orientation of the frustum in world space as a rotation to apply to the
670 // -z axis.
671 GfRotation _rotation;
672
673 // Window rectangle in the image plane.
674 GfRange2d _window;
675
676 // Near/far interval.
677 GfRange1d _nearFar;
678
679 // View distance.
680 double _viewDistance;
681
682 // Projection type.
683 ProjectionType _projectionType;
684
685 // Cached planes.
686 // If null, the planes have not been calculated.
687 mutable std::atomic<std::array<GfPlane, 6> *> _planes;
688};
689
697GF_API std::ostream& operator<<(std::ostream& out, const GfFrustum& f);
698
699PXR_NAMESPACE_CLOSE_SCOPE
700
701#endif // PXR_BASE_GF_FRUSTUM_H
Basic type: arbitrarily oriented 3D bounding box.
Definition: bbox3d.h:84
Basic type: View frustum.
Definition: frustum.h:88
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:272
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:174
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:288
GfFrustum & operator=(GfFrustum const &o) noexcept
Copy assignment.
Definition: frustum.h:152
void SetNearFar(const GfRange1d &nearFar)
Sets the near/far interval.
Definition: frustum.h:277
const GfRange2d & GetWindow() const
Returns the window rectangle in the reference plane.
Definition: frustum.h:267
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:283
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:298
double GetViewDistance() const
Returns the view distance.
Definition: frustum.h:293
GfFrustum::ProjectionType GetProjectionType() const
Returns the projection type.
Definition: frustum.h:304
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:228
GF_API double GetFOV(bool isFovVertical=false)
Returns the horizontal or vertical fov of the frustum.
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:108
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:248
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:261
GfFrustum(GfFrustum &&o) noexcept
Move constructor.
Definition: frustum.h:122
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:241
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:92
@ Orthographic
Orthographic projection.
Definition: frustum.h:93
@ Perspective
Perspective projection.
Definition: frustum.h:94
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:234
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:88
Basic type: 1-dimensional floating point range.
Definition: range1d.h:62
Basic type: 2-dimensional floating point range.
Definition: range2d.h:64
Basic type: Ray used for intersection testing.
Definition: ray.h:61
Basic type: 3-space rotation specification.
Definition: rotation.h:54
Basic type for a vector of 2 double components.
Definition: vec2d.h:63
Basic type for a vector of 3 double components.
Definition: vec3d.h:63
static size_t Combine(Args &&... args)
Produce a hash code by combining the hash codes of several objects.
Definition: hash.h:492
GF_API std::ostream & operator<<(std::ostream &, const GfBBox3d &)
Output a GfBBox3d using the format [(range) matrix zeroArea].