10 #ifndef INCLUDED_IMATHFRUSTUM_H
11 #define INCLUDED_IMATHFRUSTUM_H
22 IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
121 IMATH_CONSTEXPR14
T aspectExc() const;
128 IMATH_CONSTEXPR14
Matrix44<
T> projectionMatrixExc() const;
140 set (
T nearPlane,
T farPlane,
T left,
T right,
T top,
T bottom,
bool ortho = false) IMATH_NOEXCEPT;
149 void setExc (
T nearPlane,
T farPlane,
T fovx,
T fovy,
T aspect);
174 window (
T left,
T right,
T top,
T bottom) const IMATH_NOEXCEPT;
189 IMATH_CONSTEXPR14
Vec2<
T> projectPointToScreenExc (const
Vec3<
T>&) const;
194 long max) const IMATH_NOEXCEPT;
196 IMATH_CONSTEXPR14
T ZToDepthExc (
long zval,
long min,
long max) const;
199 IMATH_HOSTDEVICE IMATH_CONSTEXPR14
T normalizedZToDepth (
T zval) const IMATH_NOEXCEPT;
203 IMATH_CONSTEXPR14
T normalizedZToDepthExc (
T zval) const;
207 DepthToZ (
T depth,
long zmin,
long zmax) const IMATH_NOEXCEPT;
210 IMATH_CONSTEXPR14
long DepthToZExc (
T depth,
long zmin,
long zmax) const;
216 IMATH_CONSTEXPR14
T worldRadiusExc (const
Vec3<
T>& p,
T radius) const;
222 IMATH_CONSTEXPR14
T screenRadiusExc (const
Vec3<
T>& p,
T radius) const;
233 localToScreen (const
Vec2<
T>&) const IMATH_NOEXCEPT;
237 IMATH_CONSTEXPR14
Vec2<
T> localToScreenExc (const
Vec2<
T>&) const;
256 set (
T (0.1),
T (1000.0),
T (-1.0),
T (1.0),
T (1.0),
T (-1.0),
false);
267 set (
n,
f, l,
r,
t,
b, o);
273 set (nearPlane, farPlane, fovx, fovy, aspect);
283 _nearPlane =
f._nearPlane;
284 _farPlane =
f._farPlane;
289 _orthographic =
f._orthographic;
295 constexpr
inline bool
298 return _nearPlane == src._nearPlane && _farPlane == src._farPlane && _left == src._left &&
299 _right == src._right && _top == src._top && _bottom == src._bottom &&
300 _orthographic == src._orthographic;
304 constexpr
inline bool
357 _orthographic = ortho;
364 if (fovx !=
T (0) && fovy !=
T (0))
365 throw std::domain_error (
"fovx and fovy cannot both be non-zero.");
367 const T two =
static_cast<T> (2);
371 _right = nearPlane *
std::tan (fovx / two);
373 _top = ((_right - _left) / aspect) / two;
378 _top = nearPlane *
std::tan (fovy / two);
380 _right = (_top - _bottom) * aspect / two;
383 _nearPlane = nearPlane;
384 _farPlane = farPlane;
385 _orthographic =
false;
392 const T two =
static_cast<T> (2);
396 _right = nearPlane *
std::tan (fovx / two);
398 _top = ((_right - _left) / aspect) / two;
403 _top = nearPlane *
std::tan (fovy / two);
405 _right = (_top - _bottom) * aspect / two;
408 _nearPlane = nearPlane;
409 _farPlane = farPlane;
410 _orthographic =
false;
428 IMATH_CONSTEXPR14
inline T
431 T rightMinusLeft = _right - _left;
432 T topMinusBottom = _top - _bottom;
436 throw std::domain_error (
"Bad viewing frustum: "
437 "aspect ratio cannot be computed.");
440 return rightMinusLeft / topMinusBottom;
444 IMATH_CONSTEXPR14
inline T
447 T rightMinusLeft = _right - _left;
448 T topMinusBottom = _top - _bottom;
449 return rightMinusLeft / topMinusBottom;
456 T rightPlusLeft = _right + _left;
457 T rightMinusLeft = _right - _left;
459 T topPlusBottom = _top + _bottom;
460 T topMinusBottom = _top - _bottom;
462 T farPlusNear = _farPlane + _nearPlane;
463 T farMinusNear = _farPlane - _nearPlane;
465 if ((
abs (rightMinusLeft) <
T (1) &&
467 (
abs (topMinusBottom) <
T (1) &&
471 throw std::domain_error (
"Bad viewing frustum: "
472 "projection matrix cannot be computed.");
477 T tx = -rightPlusLeft / rightMinusLeft;
478 T ty = -topPlusBottom / topMinusBottom;
479 T tz = -farPlusNear / farMinusNear;
485 throw std::domain_error (
"Bad viewing frustum: "
486 "projection matrix cannot be computed.");
489 T A =
T (2) / rightMinusLeft;
490 T B =
T (2) / topMinusBottom;
491 T C =
T (-2) / farMinusNear;
493 return Matrix44<T> (
A, 0, 0, 0, 0,
B, 0, 0, 0, 0, C, 0, tx, ty, tz, 1.f);
497 T A = rightPlusLeft / rightMinusLeft;
498 T B = topPlusBottom / topMinusBottom;
499 T C = -farPlusNear / farMinusNear;
501 T farTimesNear =
T (-2) * _farPlane * _nearPlane;
504 throw std::domain_error (
"Bad viewing frustum: "
505 "projection matrix cannot be computed.");
508 T D = farTimesNear / farMinusNear;
510 T twoTimesNear =
T (2) * _nearPlane;
512 if ((
abs (rightMinusLeft) <
T (1) &&
514 (
abs (topMinusBottom) <
T (1) &&
517 throw std::domain_error (
"Bad viewing frustum: "
518 "projection matrix cannot be computed.");
521 T E = twoTimesNear / rightMinusLeft;
522 T F = twoTimesNear / topMinusBottom;
524 return Matrix44<T> (E, 0, 0, 0, 0, F, 0, 0,
A,
B, C, -1, 0, 0, D, 0);
532 T rightPlusLeft = _right + _left;
533 T rightMinusLeft = _right - _left;
535 T topPlusBottom = _top + _bottom;
536 T topMinusBottom = _top - _bottom;
538 T farPlusNear = _farPlane + _nearPlane;
539 T farMinusNear = _farPlane - _nearPlane;
543 T tx = -rightPlusLeft / rightMinusLeft;
544 T ty = -topPlusBottom / topMinusBottom;
545 T tz = -farPlusNear / farMinusNear;
547 T A =
T (2) / rightMinusLeft;
548 T B =
T (2) / topMinusBottom;
549 T C =
T (-2) / farMinusNear;
551 return Matrix44<T> (
A, 0, 0, 0, 0,
B, 0, 0, 0, 0, C, 0, tx, ty, tz, 1.f);
555 T A = rightPlusLeft / rightMinusLeft;
556 T B = topPlusBottom / topMinusBottom;
557 T C = -farPlusNear / farMinusNear;
559 T farTimesNear =
T (-2) * _farPlane * _nearPlane;
561 T D = farTimesNear / farMinusNear;
563 T twoTimesNear =
T (2) * _nearPlane;
565 T E = twoTimesNear / rightMinusLeft;
566 T F = twoTimesNear / topMinusBottom;
568 return Matrix44<T> (E, 0, 0, 0, 0, F, 0, 0,
A,
B, C, -1, 0, 0, D, 0);
573 constexpr
inline bool
576 return (_nearPlane == _farPlane) || (_left == _right) || (_top == _bottom);
588 return Frustum<T> (_nearPlane, _farPlane, bl.
x, tr.
x, tr.
y, bl.
y, _orthographic);
595 return Vec2<T> (_left + (_right - _left) * (1.
f +
s.x) / 2.f,
596 _bottom + (_top - _bottom) * (1.
f +
s.y) / 2.f);
600 IMATH_CONSTEXPR14
inline Vec2<T>
603 T leftPlusRight = _left -
T (2) * p.
x + _right;
604 T leftMinusRight = _left - _right;
605 T bottomPlusTop = _bottom -
T (2) * p.
y + _top;
606 T bottomMinusTop = _bottom - _top;
608 if ((
abs (leftMinusRight) <
T (1) &&
610 (
abs (bottomMinusTop) <
T (1) &&
613 throw std::domain_error (
"Bad viewing frustum: "
614 "local-to-screen transformation cannot be computed");
617 return Vec2<T> (leftPlusRight / leftMinusRight, bottomPlusTop / bottomMinusTop);
621 IMATH_CONSTEXPR14
inline Vec2<T>
624 T leftPlusRight = _left -
T (2) * p.x + _right;
625 T leftMinusRight = _left - _right;
626 T bottomPlusTop = _bottom -
T (2) * p.y + _top;
627 T bottomMinusTop = _bottom - _top;
629 return Vec2<T> (leftPlusRight / leftMinusRight, bottomPlusTop / bottomMinusTop);
636 Vec2<T> point = screenToLocal (p);
647 if (orthographic() || point.
z ==
T (0))
648 return localToScreenExc (
Vec2<T> (point.
x, point.
y));
650 return localToScreenExc (
651 Vec2<T> (point.
x * _nearPlane / -point.
z, point.
y * _nearPlane / -point.
z));
658 if (orthographic() || point.z ==
T (0))
659 return localToScreen (
Vec2<T> (point.x, point.y));
661 return localToScreen (
662 Vec2<T> (point.x * _nearPlane / -point.z, point.y * _nearPlane / -point.z));
669 int zdiff = zmax - zmin;
673 throw std::domain_error (
"Bad call to Frustum::ZToDepth: zmax == zmin");
679 T fzval = (
T (zval) -
T (zmin)) /
T (zdiff);
680 return normalizedZToDepthExc (fzval);
687 int zdiff = zmax - zmin;
692 T fzval = (
T (zval) -
T (zmin)) /
T (zdiff);
693 return normalizedZToDepth (fzval);
700 T Zp = zval *
T (2) -
T (1);
704 return -(Zp * (_farPlane - _nearPlane) + (_farPlane + _nearPlane)) / T (2);
708 T farTimesNear = 2 * _farPlane * _nearPlane;
709 T farMinusNear = Zp * (_farPlane - _nearPlane) - _farPlane - _nearPlane;
713 throw std::domain_error (
"Frustum::normalizedZToDepth cannot be computed: "
714 "near and far clipping planes of the viewing frustum "
715 "may be too close to each other");
718 return farTimesNear / farMinusNear;
726 T Zp = zval *
T (2) -
T (1);
730 return -(Zp * (_farPlane - _nearPlane) + (_farPlane + _nearPlane)) / T (2);
734 T farTimesNear = 2 * _farPlane * _nearPlane;
735 T farMinusNear = Zp * (_farPlane - _nearPlane) - _farPlane - _nearPlane;
737 return farTimesNear / farMinusNear;
742 IMATH_CONSTEXPR14
long
745 long zdiff = zmax - zmin;
746 T farMinusNear = _farPlane - _nearPlane;
750 T farPlusNear =
T (2) * depth + _farPlane + _nearPlane;
754 throw std::domain_error (
"Bad viewing frustum: "
755 "near and far clipping planes "
756 "are too close to each other");
759 T Zp = -farPlusNear / farMinusNear;
760 return long (0.5 * (Zp + 1) * zdiff) + zmin;
766 T farTimesNear =
T (2) * _farPlane * _nearPlane;
769 throw std::domain_error (
"Bad call to DepthToZ function: "
770 "value of `depth' is too small");
773 T farPlusNear = farTimesNear / depth + _farPlane + _nearPlane;
776 throw std::domain_error (
"Bad viewing frustum: "
777 "near and far clipping planes "
778 "are too close to each other");
781 T Zp = farPlusNear / farMinusNear;
782 return long (0.5 * (Zp + 1) * zdiff) + zmin;
787 IMATH_CONSTEXPR14
long
790 long zdiff = zmax - zmin;
791 T farMinusNear = _farPlane - _nearPlane;
795 T farPlusNear =
T (2) *
depth + _farPlane + _nearPlane;
797 T Zp = -farPlusNear / farMinusNear;
798 return long (0.5 * (Zp + 1) * zdiff) + zmin;
804 T farTimesNear =
T (2) * _farPlane * _nearPlane;
806 T farPlusNear = farTimesNear /
depth + _farPlane + _nearPlane;
808 T Zp = farPlusNear / farMinusNear;
809 return long (0.5 * (Zp + 1) * zdiff) + zmin;
829 return radius * (-_nearPlane / p.
z);
833 throw std::domain_error (
"Bad call to Frustum::screenRadius: "
834 "magnitude of `p' is too small");
837 return radius * (-_nearPlane / p.
z);
854 return radius * (-_nearPlane / p.z);
863 return radius * (p.
z / -_nearPlane);
867 throw std::domain_error (
"Bad viewing frustum: "
868 "near clipping plane is too close to zero");
876 return radius * (p.z / -_nearPlane);
890 Vec3<T> a (_left, _bottom, -_nearPlane);
891 Vec3<T> b (_left, _top, -_nearPlane);
892 Vec3<T> c (_right, _top, -_nearPlane);
893 Vec3<T> d (_right, _bottom, -_nearPlane);
903 p[0].set (
Vec3<T> (0, 1, 0), _top);
904 p[1].set (
Vec3<T> (1, 0, 0), _right);
905 p[2].set (
Vec3<T> (0, -1, 0), -_bottom);
906 p[3].set (
Vec3<T> (-1, 0, 0), -_left);
908 p[4].set (
Vec3<T> (0, 0, 1), -_nearPlane);
909 p[5].set (
Vec3<T> (0, 0, -1), _farPlane);
927 double s = _farPlane / double (_nearPlane);
928 T farLeft = (
T) (s * _left);
929 T farRight = (
T) (s * _right);
930 T farTop = (
T) (s * _top);
931 T farBottom = (
T) (s * _bottom);
964 IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
966 #if defined _WIN32 || defined _WIN64
975 #endif // INCLUDED_IMATHFRUSTUM_H
IMATH_HOSTDEVICE constexpr T hither() const IMATH_NOEXCEPT
Return the near clipping plane.
SYS_API double atan2(double y, double x)
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.
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
SYS_API double tan(double x)
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.
LeafData & operator=(const LeafData &)=delete
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.
IMATH_HOSTDEVICE constexpr bool orthographic() const IMATH_NOEXCEPT
Return true if the frustum is orthographic, false if perspective.
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.
bool operator!=(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
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.