18 #ifndef ION_MATH_FIELDOFVIEW_H_
19 #define ION_MATH_FIELDOFVIEW_H_
53 const T& bottom,
const T& top);
134 void Print(std::ostream& out)
const;
137 void Read(std::istream& in);
145 return AreEqual(fov0, fov1);
149 return !AreEqual(fov0, fov1);
157 static bool ComputeHalfAnglesForTotalFovAndOpticalCenter1d(
158 const Angle<T> total_fov,
const T optical_center_ndc,
167 static void ComputeHalfAnglesForCenteredFovAndOpticalCenter1d(
168 const Angle<T> centered_fov,
const T optical_center_ndc,
182 template <
typename T>
185 template <
typename T>
188 : left_(left), right_(right), bottom_(bottom), top_(top) {}
190 template <
typename T>
193 const T l = -std::tan(left_.Radians()) * near_p;
194 const T r = std::tan(right_.Radians()) * near_p;
195 const T b = -std::tan(bottom_.Radians()) * near_p;
196 const T t = std::tan(top_.Radians()) * near_p;
200 template <
typename T>
211 template <
typename T>
214 const T kOne =
static_cast<T>(1.0);
217 const T kTanVertFov = kOne / m(1, 1);
218 const T kTanHorzFov = kOne / m(0, 0);
219 const T t = (m(1, 2) + kOne) * kTanVertFov;
220 const T b = (m(1, 2) - kOne) * kTanVertFov;
221 const T l = (m(0, 2) - kOne) * kTanHorzFov;
222 const T r = (m(0, 2) + kOne) * kTanHorzFov;
224 return FromTangents(-l, r, -b, t);
227 template <
typename T>
228 template <
typename U>
230 : left_(fov.GetLeft()),
231 right_(fov.GetRight()),
232 bottom_(fov.GetBottom()),
233 top_(fov.GetTop()) {}
235 template <
typename T>
237 const T kOne =
static_cast<T>(1.0);
238 const T kTwo =
static_cast<T>(2.0);
239 const T tan_left = std::tan(left_.Radians());
240 const T tan_right = std::tan(right_.Radians());
241 const T tan_bottom = std::tan(bottom_.Radians());
242 const T tan_top = std::tan(top_.Radians());
243 const T x_ndc = kTwo * tan_left / (tan_left + tan_right) - kOne;
244 const T y_ndc = kTwo * tan_bottom / (tan_bottom + tan_top) - kOne;
248 template <
typename T>
253 if (!ComputeHalfAnglesForTotalFovAndOpticalCenter1d(
254 fov_x, optical_center_ndc[0], &left, &right))
256 if (!ComputeHalfAnglesForTotalFovAndOpticalCenter1d(
257 fov_y, optical_center_ndc[1], &bottom, &top))
269 template <
typename T>
273 const T kOne =
static_cast<T>(1.0);
274 T p = optical_center_ndc;
327 const T inv_tan_total_fov = kOne / tan(total_fov.
Radians());
328 const T discriminant = kOne +
Square(inv_tan_total_fov) -
Square(p);
329 if (discriminant < 0)
return false;
340 const double sign = p < -kOne ? -kOne : kOne;
342 atan((sign * std::sqrt(discriminant) - inv_tan_total_fov) / (kOne - p)));
346 *angle2_out = total_fov - *angle1_out;
347 if (invert) std::swap(*angle1_out, *angle2_out);
351 template <
typename T>
356 ComputeHalfAnglesForCenteredFovAndOpticalCenter1d(
357 fov_x, optical_center_ndc[0], &left, &right);
358 ComputeHalfAnglesForCenteredFovAndOpticalCenter1d(
359 fov_y, optical_center_ndc[1], &bottom, &top);
364 template <
typename T>
366 const Angle<T> centered_fov,
const T optical_center_ndc,
368 const T kOne =
static_cast<T>(1.0);
369 const T kTwo =
static_cast<T>(2.0);
370 const T p = optical_center_ndc;
397 const T x = kOne / std::tan(centered_fov.
Radians() / kTwo);
403 template <
typename T>
416 const T tan_left = std::tan(left_.Radians());
417 const T tan_right = std::tan(right_.Radians());
421 template <
typename T>
425 const T tan_bottom = std::tan(bottom_.Radians());
426 const T tan_top = std::tan(top_.Radians());
430 template <
typename T>
432 out <<
"FOV[" << left_ <<
", " << right_ <<
", " << bottom_ <<
", " << top_
436 template <
typename T>
441 if (!base::GetExpectedChar<','>(in)) {
446 if (!base::GetExpectedChar<','>(in)) {
451 if (!base::GetExpectedChar<','>(in)) {
463 template <
typename T>
470 template <
typename T>
477 template <
typename T>
479 const T kZero =
static_cast<T>(0.0);
480 if (left_.Radians() != kZero || right_.Radians() != kZero ||
481 bottom_.Radians() != kZero || top_.Radians() != kZero)
486 template <
typename T>
498 #endif // ION_MATH_FIELDOFVIEW_H_
void Read(std::istream &in)
This is used for reading FOV objects from a stream.
Angle< T > GetCenteredFovY() const
static FieldOfView< T > FromProjectionMatrix(const Matrix< 4, T > &matrix)
Constructs a FieldOfView by extracting the four frustum planes from the projection matrix...
FieldOfView< float > FieldOfViewf
bool SetFromTotalFovAndOpticalCenter(const Angle< T > fov_x, const Angle< T > fov_y, const Point< 2, T > &optical_center_ndc)
Resets the FieldOfView based on a total field of view in both dimensions, and an optical center for t...
FieldOfView()
The default constructor sets an angle of 0 (in any unit) for all four half-angles.
FieldOfView< double > FieldOfViewd
p_ndc **static FieldOfView< T > FromCenteredFovAndOpticalCenter(const Angle< T > centered_fov_x, const Angle< T > centered_fov_y, const Point< 2, T > &optical_center_ndc)
Constructs a FieldOfView based on a centered field of view and an optical center for the projection...
Matrix< 4, T > GetProjectionMatrix(T near_p, T far_p) const
Computes the projection matrix corresponding to the frustum defined by the four half angles and the t...
A simple class to represent angles.
T Radians() const
Get the angle in degrees or radians.
The Matrix class defines a square N-dimensional matrix.
ION_API const Matrix< 4, T > PerspectiveMatrixFromFrustum(T x_left, T x_right, T y_bottom, T y_top, T z_near, T z_far)
Returns a 4x4 perspective projection matrix based on the given parameters, which follow the conventio...
friend bool operator!=(const FieldOfView &fov0, const FieldOfView &fov1)
Angle< T > GetLeft() const
Accessors for all four half-angles.
std::istream & GetExpectedChar(std::istream &in)
Reads a single character from the stream and returns the stream.
friend bool operator==(const FieldOfView &fov0, const FieldOfView &fov1)
Exact equality and inequality comparisons.
Encapsulates a generalized, asymmetric field of view with four half angles.
void SetBottom(const Angle< T > &bottom)
std::istream & GetExpectedString(std::istream &in, const std::string &expected)
Attempts to read a string from the stream and returns the stream.
static Angle FromRadians(const T &angle)
Create a angle from radians (no conversion).
void Print(std::ostream &out) const
This is used for printing FOV objects to a stream.
const T Square(const T &val)
Squares a value.
static FieldOfView< T > FromTangents(const T &left, const T &right, const T &bottom, const T &top)
Constructs a FieldOfView from four values tan(alpha) for each half-angle alpha.
Angle< T > GetBottom() const
std::istream & operator>>(std::istream &in, Angle< T > &a)
bool IsZero() const
Returns true iff all four angles are zero (which is the case after using the default constructor)...
Angle< T > GetCenteredFovX() const
Gets the centered FOV in each dimension.
std::ostream & operator<<(std::ostream &out, const Angle< T > &a)
An Angle is streamed as degrees.
void SetTop(const Angle< T > &top)
void SetRight(const Angle< T > &right)
void SetLeft(const Angle< T > &left)
Setters for all four half-angles.
Angle< T > GetTop() const
Point< 2, T > GetOpticalCenter() const
Returns the optical center of a projection that is created using this FieldOfView.
Angle< T > GetRight() const