10 #ifndef INCLUDED_IMATHFRUSTUM_H
11 #define INCLUDED_IMATHFRUSTUM_H
22 IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
64 bool ortho = false) IMATH_NOEXCEPT;
68 Frustum (
T nearPlane,
T farPlane,
T fovx,
T fovy,
T aspect) IMATH_NOEXCEPT;
71 virtual ~
Frustum () IMATH_NOEXCEPT;
75 operator= (const
Frustum&) IMATH_NOEXCEPT;
84 operator== (const
Frustum<
T>&
src) const IMATH_NOEXCEPT;
88 operator!= (const
Frustum<
T>&
src) const IMATH_NOEXCEPT;
154 IMATH_CONSTEXPR14
T aspectExc () const;
158 projectionMatrix () const IMATH_NOEXCEPT;
162 IMATH_CONSTEXPR14
Matrix44<
T> projectionMatrixExc () const;
180 bool ortho = false) IMATH_NOEXCEPT;
185 set (
T nearPlane,
T farPlane,
T fovx,
T fovy,
T aspect) IMATH_NOEXCEPT;
190 void setExc (
T nearPlane,
T farPlane,
T fovx,
T fovy,
T aspect);
194 modifyNearAndFar (
T nearPlane,
T farPlane) IMATH_NOEXCEPT;
217 window (
T left,
T right,
T top,
T bottom) const IMATH_NOEXCEPT;
226 projectScreenToRay (const
Vec2<
T>&) const IMATH_NOEXCEPT;
230 projectPointToScreen (const
Vec3<
T>&) const IMATH_NOEXCEPT;
234 IMATH_CONSTEXPR14
Vec2<
T> projectPointToScreenExc (const
Vec3<
T>&) const;
238 ZToDepth (
long zval,
long min,
long max) const IMATH_NOEXCEPT;
240 IMATH_CONSTEXPR14
T ZToDepthExc (
long zval,
long min,
long max) const;
244 normalizedZToDepth (
T zval) const IMATH_NOEXCEPT;
248 IMATH_CONSTEXPR14
T normalizedZToDepthExc (
T zval) const;
252 DepthToZ (
T depth,
long zmin,
long zmax) const IMATH_NOEXCEPT;
255 IMATH_CONSTEXPR14
long DepthToZExc (
T depth,
long zmin,
long zmax) const;
259 worldRadius (const
Vec3<
T>& p,
T radius) const IMATH_NOEXCEPT;
262 IMATH_CONSTEXPR14
T worldRadiusExc (const
Vec3<
T>& p,
T radius) const;
266 screenRadius (const
Vec3<
T>& p,
T radius) const IMATH_NOEXCEPT;
269 IMATH_CONSTEXPR14
T screenRadiusExc (const
Vec3<
T>& p,
T radius) const;
276 screenToLocal (const
Vec2<
T>&) const IMATH_NOEXCEPT;
280 localToScreen (const
Vec2<
T>&) const IMATH_NOEXCEPT;
284 IMATH_CONSTEXPR14
Vec2<
T> localToScreenExc (const
Vec2<
T>&) const;
303 set (
T (0.1),
T (1000.0),
T (-1.0),
T (1.0),
T (1.0),
T (-1.0),
false);
323 set (nearPlane, farPlane, fovx, fovy, aspect);
333 _nearPlane =
f._nearPlane;
334 _farPlane =
f._farPlane;
339 _orthographic =
f._orthographic;
345 constexpr
inline bool
348 return _nearPlane ==
src._nearPlane && _farPlane ==
src._farPlane &&
349 _left ==
src._left && _right ==
src._right && _top ==
src._top &&
350 _bottom ==
src._bottom && _orthographic ==
src._orthographic;
354 constexpr
inline bool
377 if (_orthographic) { _nearPlane =
n; }
406 _orthographic = ortho;
413 if (fovx !=
T (0) && fovy !=
T (0))
414 throw std::domain_error (
"fovx and fovy cannot both be non-zero.");
416 const T two =
static_cast<T> (2);
420 _right = nearPlane * std::tan (fovx / two);
422 _top = ((_right - _left) / aspect) / two;
427 _top = nearPlane * std::tan (fovy / two);
429 _right = (_top - _bottom) * aspect / two;
432 _nearPlane = nearPlane;
433 _farPlane = farPlane;
434 _orthographic =
false;
442 const T two =
static_cast<T> (2);
446 _right = nearPlane * std::tan (fovx / two);
448 _top = ((_right - _left) / aspect) / two;
453 _top = nearPlane * std::tan (fovy / two);
455 _right = (_top - _bottom) * aspect / two;
458 _nearPlane = nearPlane;
459 _farPlane = farPlane;
460 _orthographic =
false;
467 return std::atan2 (_right, _nearPlane) - std::atan2 (_left, _nearPlane);
474 return std::atan2 (_top, _nearPlane) - std::atan2 (_bottom, _nearPlane);
478 IMATH_CONSTEXPR14
inline T
481 T rightMinusLeft = _right - _left;
482 T topMinusBottom = _top - _bottom;
484 if (
abs (topMinusBottom) <
T (1) &&
485 abs (rightMinusLeft) >
488 throw std::domain_error (
"Bad viewing frustum: "
489 "aspect ratio cannot be computed.");
492 return rightMinusLeft / topMinusBottom;
496 IMATH_CONSTEXPR14
inline T
499 T rightMinusLeft = _right - _left;
500 T topMinusBottom = _top - _bottom;
501 return rightMinusLeft / topMinusBottom;
508 T rightPlusLeft = _right + _left;
509 T rightMinusLeft = _right - _left;
511 T topPlusBottom = _top + _bottom;
512 T topMinusBottom = _top - _bottom;
514 T farPlusNear = _farPlane + _nearPlane;
515 T farMinusNear = _farPlane - _nearPlane;
517 if ((
abs (rightMinusLeft) <
T (1) &&
518 abs (rightPlusLeft) >
520 (
abs (topMinusBottom) <
T (1) &&
521 abs (topPlusBottom) >
523 (
abs (farMinusNear) < 1 &&
527 throw std::domain_error (
"Bad viewing frustum: "
528 "projection matrix cannot be computed.");
533 T tx = -rightPlusLeft / rightMinusLeft;
534 T ty = -topPlusBottom / topMinusBottom;
535 T tz = -farPlusNear / farMinusNear;
537 if ((
abs (rightMinusLeft) <
T (1) &&
539 (
abs (topMinusBottom) <
T (1) &&
541 (
abs (farMinusNear) <
T (1) &&
544 throw std::domain_error (
"Bad viewing frustum: "
545 "projection matrix cannot be computed.");
548 T A =
T (2) / rightMinusLeft;
549 T B =
T (2) / topMinusBottom;
550 T C =
T (-2) / farMinusNear;
553 A, 0, 0, 0, 0,
B, 0, 0, 0, 0, C, 0, tx, ty, tz, 1.f);
557 T A = rightPlusLeft / rightMinusLeft;
558 T B = topPlusBottom / topMinusBottom;
559 T C = -farPlusNear / farMinusNear;
561 T farTimesNear =
T (-2) * _farPlane * _nearPlane;
562 if (
abs (farMinusNear) <
T (1) &&
567 throw std::domain_error (
"Bad viewing frustum: "
568 "projection matrix cannot be computed.");
571 T D = farTimesNear / farMinusNear;
573 T twoTimesNear =
T (2) * _nearPlane;
575 if ((
abs (rightMinusLeft) <
T (1) &&
578 (
abs (topMinusBottom) <
T (1) &&
583 throw std::domain_error (
"Bad viewing frustum: "
584 "projection matrix cannot be computed.");
587 T E = twoTimesNear / rightMinusLeft;
588 T F = twoTimesNear / topMinusBottom;
590 return Matrix44<T> (E, 0, 0, 0, 0, F, 0, 0,
A,
B, C, -1, 0, 0, D, 0);
598 T rightPlusLeft = _right + _left;
599 T rightMinusLeft = _right - _left;
601 T topPlusBottom = _top + _bottom;
602 T topMinusBottom = _top - _bottom;
604 T farPlusNear = _farPlane + _nearPlane;
605 T farMinusNear = _farPlane - _nearPlane;
609 T tx = -rightPlusLeft / rightMinusLeft;
610 T ty = -topPlusBottom / topMinusBottom;
611 T tz = -farPlusNear / farMinusNear;
613 T A =
T (2) / rightMinusLeft;
614 T B =
T (2) / topMinusBottom;
615 T C =
T (-2) / farMinusNear;
618 A, 0, 0, 0, 0,
B, 0, 0, 0, 0, C, 0, tx, ty, tz, 1.f);
622 T A = rightPlusLeft / rightMinusLeft;
623 T B = topPlusBottom / topMinusBottom;
624 T C = -farPlusNear / farMinusNear;
626 T farTimesNear =
T (-2) * _farPlane * _nearPlane;
628 T D = farTimesNear / farMinusNear;
630 T twoTimesNear =
T (2) * _nearPlane;
632 T E = twoTimesNear / rightMinusLeft;
633 T F = twoTimesNear / topMinusBottom;
635 return Matrix44<T> (E, 0, 0, 0, 0, F, 0, 0,
A,
B, C, -1, 0, 0, D, 0);
640 constexpr
inline bool
643 return (_nearPlane == _farPlane) || (_left == _right) || (_top == _bottom);
656 _nearPlane, _farPlane, bl.
x, tr.
x, tr.
y, bl.
y, _orthographic);
664 _left + (_right - _left) * (1.
f +
s.x) / 2.f,
665 _bottom + (_top - _bottom) * (1.
f +
s.y) / 2.f);
669 IMATH_CONSTEXPR14
inline Vec2<T>
672 T leftPlusRight = _left -
T (2) * p.
x + _right;
673 T leftMinusRight = _left - _right;
674 T bottomPlusTop = _bottom -
T (2) * p.
y + _top;
675 T bottomMinusTop = _bottom - _top;
677 if ((
abs (leftMinusRight) <
T (1) &&
678 abs (leftPlusRight) >
680 (
abs (bottomMinusTop) <
T (1) &&
681 abs (bottomPlusTop) >
684 throw std::domain_error (
685 "Bad viewing frustum: "
686 "local-to-screen transformation cannot be computed");
690 leftPlusRight / leftMinusRight, bottomPlusTop / bottomMinusTop);
694 IMATH_CONSTEXPR14
inline Vec2<T>
697 T leftPlusRight = _left -
T (2) * p.x + _right;
698 T leftMinusRight = _left - _right;
699 T bottomPlusTop = _bottom -
T (2) * p.y + _top;
700 T bottomMinusTop = _bottom - _top;
703 leftPlusRight / leftMinusRight, bottomPlusTop / bottomMinusTop);
710 Vec2<T> point = screenToLocal (p);
716 Vec3<T> (0, 0, 0), Vec3<T> (point.
x, point.
y, -_nearPlane));
723 if (orthographic () || point.
z ==
T (0))
724 return localToScreenExc (
Vec2<T> (point.
x, point.
y));
726 return localToScreenExc (
Vec2<T> (
727 point.
x * _nearPlane / -point.
z, point.
y * _nearPlane / -point.
z));
734 if (orthographic () || point.z ==
T (0))
735 return localToScreen (
Vec2<T> (point.x, point.y));
737 return localToScreen (
Vec2<T> (
738 point.x * _nearPlane / -point.z, point.y * _nearPlane / -point.z));
745 int zdiff = zmax - zmin;
749 throw std::domain_error (
"Bad call to Frustum::ZToDepth: zmax == zmin");
752 if (zval > zmax + 1) zval -= zdiff;
754 T fzval = (
T (zval) -
T (zmin)) /
T (zdiff);
755 return normalizedZToDepthExc (fzval);
762 int zdiff = zmax - zmin;
764 if (zval > zmax + 1) zval -= zdiff;
766 T fzval = (
T (zval) -
T (zmin)) /
T (zdiff);
767 return normalizedZToDepth (fzval);
774 T Zp = zval *
T (2) -
T (1);
778 return -(Zp * (_farPlane - _nearPlane) + (_farPlane + _nearPlane)) /
783 T farTimesNear = 2 * _farPlane * _nearPlane;
784 T farMinusNear = Zp * (_farPlane - _nearPlane) - _farPlane - _nearPlane;
786 if (
abs (farMinusNear) < 1 &&
790 throw std::domain_error (
791 "Frustum::normalizedZToDepth cannot be computed: "
792 "near and far clipping planes of the viewing frustum "
793 "may be too close to each other");
796 return farTimesNear / farMinusNear;
804 T Zp = zval *
T (2) -
T (1);
808 return -(Zp * (_farPlane - _nearPlane) + (_farPlane + _nearPlane)) /
813 T farTimesNear = 2 * _farPlane * _nearPlane;
814 T farMinusNear = Zp * (_farPlane - _nearPlane) - _farPlane - _nearPlane;
816 return farTimesNear / farMinusNear;
821 IMATH_CONSTEXPR14
long
824 long zdiff = zmax - zmin;
825 T farMinusNear = _farPlane - _nearPlane;
829 T farPlusNear =
T (2) * depth + _farPlane + _nearPlane;
831 if (
abs (farMinusNear) <
T (1) &&
835 throw std::domain_error (
"Bad viewing frustum: "
836 "near and far clipping planes "
837 "are too close to each other");
840 T Zp = -farPlusNear / farMinusNear;
841 return long (0.5 * (Zp + 1) * zdiff) + zmin;
847 T farTimesNear =
T (2) * _farPlane * _nearPlane;
848 if (
abs (depth) <
T (1) &&
851 throw std::domain_error (
"Bad call to DepthToZ function: "
852 "value of `depth' is too small");
855 T farPlusNear = farTimesNear / depth + _farPlane + _nearPlane;
856 if (
abs (farMinusNear) <
T (1) &&
860 throw std::domain_error (
"Bad viewing frustum: "
861 "near and far clipping planes "
862 "are too close to each other");
865 T Zp = farPlusNear / farMinusNear;
866 return long (0.5 * (Zp + 1) * zdiff) + zmin;
871 IMATH_CONSTEXPR14
long
874 long zdiff = zmax - zmin;
875 T farMinusNear = _farPlane - _nearPlane;
879 T farPlusNear =
T (2) *
depth + _farPlane + _nearPlane;
881 T Zp = -farPlusNear / farMinusNear;
882 return long (0.5 * (Zp + 1) * zdiff) + zmin;
888 T farTimesNear =
T (2) * _farPlane * _nearPlane;
890 T farPlusNear = farTimesNear /
depth + _farPlane + _nearPlane;
892 T Zp = farPlusNear / farMinusNear;
893 return long (0.5 * (Zp + 1) * zdiff) + zmin;
911 if (
abs (p.
z) >
T (1) ||
914 return radius * (-_nearPlane / p.
z);
918 throw std::domain_error (
"Bad call to Frustum::screenRadius: "
919 "magnitude of `p' is too small");
922 return radius * (-_nearPlane / p.
z);
939 return radius * (-_nearPlane / p.z);
946 if (
abs (-_nearPlane) >
T (1) ||
949 return radius * (p.
z / -_nearPlane);
953 throw std::domain_error (
"Bad viewing frustum: "
954 "near clipping plane is too close to zero");
962 return radius * (p.z / -_nearPlane);
976 Vec3<T> a (_left, _bottom, -_nearPlane);
977 Vec3<T> b (_left, _top, -_nearPlane);
978 Vec3<T> c (_right, _top, -_nearPlane);
979 Vec3<T> d (_right, _bottom, -_nearPlane);
989 p[0].set (
Vec3<T> (0, 1, 0), _top);
990 p[1].set (
Vec3<T> (1, 0, 0), _right);
991 p[2].set (
Vec3<T> (0, -1, 0), -_bottom);
992 p[3].set (
Vec3<T> (-1, 0, 0), -_left);
994 p[4].set (
Vec3<T> (0, 0, 1), -_nearPlane);
995 p[5].set (
Vec3<T> (0, 0, -1), _farPlane);
1013 double s = _farPlane / double (_nearPlane);
1014 T farLeft = (
T) (s * _left);
1015 T farRight = (
T) (s * _right);
1016 T farTop = (
T) (s * _top);
1017 T farBottom = (
T) (s * _bottom);
1050 IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
1052 #if defined _WIN32 || defined _WIN64
1061 #endif // INCLUDED_IMATHFRUSTUM_H
IMATH_HOSTDEVICE constexpr T hither() const IMATH_NOEXCEPT
Return the near clipping plane.
IMATH_CONSTEXPR14 T screenRadiusExc(const Vec3< T > &p, T radius) const
Compute screen radius. Throw an exception on error.
IMATH_HOSTDEVICE constexpr bool operator!=(const Frustum< T > &src) const IMATH_NOEXCEPT
Inequality.
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersect(const Line3< T > &line, Vec3< T > &intersection) const IMATH_NOEXCEPT
*get result *(waiting if necessary)*A common idiom is to fire a bunch of sub tasks at the and then *wait for them to all complete We provide a helper class
IMATH_HOSTDEVICE void set(T nearPlane, T farPlane, T left, T right, T top, T bottom, bool ortho=false) IMATH_NOEXCEPT
Set functions change the entire state of the Frustum.
IMATH_HOSTDEVICE void setOrthographic(bool) IMATH_NOEXCEPT
Set the ortographic state.
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec2< T > localToScreen(const Vec2< T > &) const IMATH_NOEXCEPT
Map point from local space to screen space.
IMATH_HOSTDEVICE constexpr T fovx() const IMATH_NOEXCEPT
Return the field of view in X.
GLboolean GLboolean GLboolean GLboolean a
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 const Frustum & operator=(const Frustum &) IMATH_NOEXCEPT
Component-wise assignment.
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
IMATH_HOSTDEVICE constexpr bool operator==(const Frustum< T > &src) const IMATH_NOEXCEPT
Equality.
IMATH_CONSTEXPR14 T normalizedZToDepthExc(T zval) const
IMATH_HOSTDEVICE constexpr bool degenerate() const IMATH_NOEXCEPT
Return true if the frustum is degenerate.
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Vec2< T > projectPointToScreen(const Vec3< T > &) const IMATH_NOEXCEPT
Project a 3D point into screen coordinates.
bool operator==(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
IMATH_HOSTDEVICE constexpr T left() const IMATH_NOEXCEPT
Return the left of the frustum.
constexpr auto set(type rhs) -> int
IMATH_HOSTDEVICE constexpr T nearPlane() const IMATH_NOEXCEPT
Return the near clipping plane.
IMATH_HOSTDEVICE constexpr Vec2< T > screenToLocal(const Vec2< T > &) const IMATH_NOEXCEPT
Map point from screen space to local space.
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 IMATH_HOSTDEVICE Frustum< T > window(T left, T right, T top, T bottom) const IMATH_NOEXCEPT
Frustum< double > Frustumd
Frustum of type double.
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T normalizedZToDepth(T zval) const IMATH_NOEXCEPT
Map a normalized z value to its depth in the frustum.
Frustum< float > Frustumf
Frustum of type float.
IMATH_CONSTEXPR14 Vec2< T > localToScreenExc(const Vec2< T > &) const
IMATH_HOSTDEVICE constexpr T bottom() const IMATH_NOEXCEPT
Return the bottom of the frustum.
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Frustum() IMATH_NOEXCEPT
GLboolean GLboolean GLboolean b
IMATH_CONSTEXPR14 long DepthToZExc(T depth, long zmin, long zmax) const
Map depth to z value. Throw an exception on error.
IMATH_CONSTEXPR14 Matrix44< T > projectionMatrixExc() const
GLint GLint GLsizei GLsizei GLsizei depth
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T screenRadius(const Vec3< T > &p, T radius) const IMATH_NOEXCEPT
Compute screen radius.
IMATH_HOSTDEVICE void planes(Plane3< T > p[6]) const IMATH_NOEXCEPT
GLfloat GLfloat GLfloat GLfloat h
IMATH_CONSTEXPR14 Vec2< T > projectPointToScreenExc(const Vec3< T > &) const
IMATH_HOSTDEVICE constexpr T top() const IMATH_NOEXCEPT
Return the top of the frustum.
IMATH_HOSTDEVICE constexpr T yon() const IMATH_NOEXCEPT
Return the far clipping plane.
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Line3< T > projectScreenToRay(const Vec2< T > &) const IMATH_NOEXCEPT
Project a point in screen spaced to 3d ray.
#define IMATH_EXPORT_TEMPLATE_TYPE
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 long DepthToZ(T depth, long zmin, long zmax) const IMATH_NOEXCEPT
Map depth to z value.
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T ZToDepth(long zval, long min, long max) const IMATH_NOEXCEPT
Map a z value to its depth in the frustum.
GLdouble GLdouble GLdouble top
IMATH_HOSTDEVICE constexpr T fovy() const IMATH_NOEXCEPT
Return the field of view in Y.
IMATH_CONSTEXPR14 T aspectExc() const
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER IMATH_HOSTDEVICE constexpr T abs(T a) IMATH_NOEXCEPT
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 Matrix44< T > projectionMatrix() const IMATH_NOEXCEPT
Return the project matrix that the frustum defines.
virtual ~Frustum() IMATH_NOEXCEPT
Destructor.
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T aspect() const IMATH_NOEXCEPT
Return the aspect ratio.
IMATH_CONSTEXPR14 T worldRadiusExc(const Vec3< T > &p, T radius) const
Compute worldRadius. Throw an exception on error.
IMATH_HOSTDEVICE void modifyNearAndFar(T nearPlane, T farPlane) IMATH_NOEXCEPT
Set the near and far clipping planes.
IMATH_HOSTDEVICE constexpr T right() const IMATH_NOEXCEPT
Return the right of the frustum.
void setExc(T nearPlane, T farPlane, T fovx, T fovy, T aspect)
IMATH_HOSTDEVICE constexpr T farPlane() const IMATH_NOEXCEPT
Return the far clipping plane.
IMATH_CONSTEXPR14 T ZToDepthExc(long zval, long min, long max) const
Map a z value to its depth in the frustum.
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 T worldRadius(const Vec3< T > &p, T radius) const IMATH_NOEXCEPT
Compute worldRadius.