Skip to content

Commit

Permalink
Improve test coverage for Frustum, Quat, Euler, Shear (AcademySoftwar…
Browse files Browse the repository at this point in the history
…eFoundation#328)

* Increase test coverage for Euler, Frustum, Quat, Shear

- Added python symbols "EULER_XYZLayout" and "EULER_IJKLayout" to complete API for
  Euler constructors

- Added some comments indicating what looks to be dead, unreachable
  code. I left the code in place because I'm not 100% sure.

Signed-off-by: Cary Phillips <cary@ilm.com>

* Fix Quat.identity()

Signed-off-by: Cary Phillips <cary@ilm.com>

* Revert inadvertent whitespace-only changes

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
  • Loading branch information
cary-ilm authored Jun 29, 2023
1 parent 7971e3a commit bd0e707
Show file tree
Hide file tree
Showing 11 changed files with 794 additions and 22 deletions.
2 changes: 2 additions & 0 deletions src/Imath/ImathFrustum.h
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,7 @@ Frustum<T>::projectionMatrixExc () const
abs (farTimesNear) >
std::numeric_limits<T>::max () * abs (farMinusNear))
{
// impossible condition: already tested above
throw std::domain_error ("Bad viewing frustum: "
"projection matrix cannot be computed.");
}
Expand All @@ -575,6 +576,7 @@ Frustum<T>::projectionMatrixExc () const
abs (twoTimesNear) >
std::numeric_limits<T>::max () * abs (topMinusBottom)))
{
// impossible condition: already tested above
throw std::domain_error ("Bad viewing frustum: "
"projection matrix cannot be computed.");
}
Expand Down
2 changes: 1 addition & 1 deletion src/Imath/ImathMatrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ template <class T> class IMATH_EXPORT_TEMPLATE_TYPE Matrix33
/// Trace
IMATH_HOSTDEVICE constexpr T trace() const IMATH_NOEXCEPT;

/// Set matrix to rotation by r (in radians)
/// Set matrix to rotation by r (in radians, assumed to be a scalar) around (0, 0, 1)
/// @return const referenced to this
template <class S>
IMATH_HOSTDEVICE const Matrix33& setRotation (S r) IMATH_NOEXCEPT;
Expand Down
183 changes: 180 additions & 3 deletions src/ImathTest/testFrustum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ testFrustum ()
{
cout << "Testing functions in ImathFrustum.h";

bool caught;

cout << "\nperspective ";

float n = 1.7f;
Expand Down Expand Up @@ -248,13 +250,85 @@ testFrustum ()
IMATH_INTERNAL_NAMESPACE::abs<float> (m[3][3]) < 1e-6f);
cout << "3";

IMATH_INTERNAL_NAMESPACE::Frustum<float> badFrustum;

badFrustum.set(n, f, l, r, t, t, false);

caught = false;
try
{
badFrustum.projectionMatrixExc();
assert(!"projectionMatrixExc() didn't throw with bad frustum");
}
catch (std::domain_error&)
{
caught = true;
}
assert (caught);
cout << "4";

badFrustum.set(n, n, l, r, b, t, false);

caught = false;
try
{
badFrustum.projectionMatrixExc();
assert(!"projectionMatrixExc() didn't throw with bad frustum");
}
catch (std::domain_error&)
{
caught = true;
}
assert (caught);
cout << "5";

badFrustum.set(n, n, l, r, b, t, false);

caught = false;
try
{
badFrustum.projectionMatrixExc();
assert(!"projectionMatrixExc() didn't throw with bad frustum");
}
catch (std::domain_error&)
{
caught = true;
}
assert (caught);
cout << "6";

badFrustum.set(n, f, l, r, t, t, true);

caught = false;
try
{
badFrustum.projectionMatrixExc();
assert(!"projectionMatrixExc() didn't throw with bad frustum");
}
catch (std::domain_error&)
{
caught = true;
}
assert (caught);
cout << "7";

caught = false;
try
{
badFrustum.aspectExc();
assert (!"aspectExc didn't throw when top-bottom==0");
}
catch (std::domain_error&)
{
caught = true;
}
assert (caught);
cout << "8";

cout << "\nplanes ";
testFrustumPlanes (frustum);

cout << "\nexceptions ";
IMATH_INTERNAL_NAMESPACE::Frustum<float> badFrustum;

bool caught;

badFrustum.set (n, n, l, r, t, b, false);
caught = false;
Expand Down Expand Up @@ -373,7 +447,110 @@ testFrustum ()
assert (f1.screenRadius (v3, one) == f1.screenRadiusExc (v3, one));
assert (f1.projectPointToScreen (v3) == f1.projectPointToScreenExc (v3));

f1.set (n, f, zero, one, one);
f2.setExc (n, f, zero, one, one);

assert (f1 == f2);

assert (
f1.ZToDepth (zMin, zMin, zMax) == f1.ZToDepthExc (zMin, zMin, zMax));
assert (f1.normalizedZToDepth (float(zMin)) == f1.normalizedZToDepthExc (float(zMin)));
assert (f1.DepthToZ (n, zMin, zMax) == f1.DepthToZExc (n, zMin, zMax));
assert (f1.worldRadius (v3, one) == f1.worldRadiusExc (v3, one));
assert (f1.screenRadius (v3, one) == f1.screenRadiusExc (v3, one));
assert (f1.projectPointToScreen (v3) == f1.projectPointToScreenExc (v3));

f1.setOrthographic (true);
assert (
f1.ZToDepth (zMin, zMin, zMax) == f1.ZToDepthExc (zMin, zMin, zMax));
assert (f1.normalizedZToDepth (float(zMin)) == f1.normalizedZToDepthExc (float(zMin)));
assert (f1.DepthToZ (n, zMin, zMax) == f1.DepthToZExc (n, zMin, zMax));
assert (f1.worldRadius (v3, one) == f1.worldRadiusExc (v3, one));
assert (f1.screenRadius (v3, one) == f1.screenRadiusExc (v3, one));
assert (f1.projectPointToScreen (v3) == f1.projectPointToScreenExc (v3));

f1.set(n, n, l, l, b, b, true);
caught = false;
try
{
f1.projectPointToScreenExc (v3);
assert (!"projectPointToScreenExc failed to throw with bad frustum");
}
catch (std::domain_error&)
{
caught = true;
}
assert (caught);

caught = false;
try
{
f1.ZToDepthExc(100, 100, 100);
assert (!"ZToDepthExc failed to throw with zmax=zmin");
}
catch (std::domain_error&)
{
caught = true;
}
assert (caught);

caught = false;
try
{
f1.DepthToZExc (100, 100, 100);
assert (!"normalizedZToDepth failed to throw with bad frustum");
}
catch (std::domain_error&)
{
caught = true;
}
assert (caught);

f1.setOrthographic(false);

caught = false;
try
{
f1.DepthToZExc (100, 100, 100);
assert (!"DepthToZExc failed to throw with bad frustum");
}
catch (std::domain_error&)
{
caught = true;
}
assert (caught);

f1.set(n, f, l, r, b, t, true);
caught = false;
try
{
v3.z = 1.0 / std::numeric_limits<float>::max();
f1.screenRadiusExc (v3, 1.0);
assert (!"screenRadiusExc failed to throw with bad p");
}
catch (std::domain_error&)
{
caught = true;
}
assert (caught);

cout << "\npassed noexcept equality verification";

float fovx = 1.0;
float fovy = 1.0;
float aspect = 1.0;

caught = false;
try
{
badFrustum.setExc (n, f, fovx, fovy, aspect);
assert (!"nfovx and fovy can't both be 0.0");
}
catch (std::domain_error&)
{
caught = true;
}
assert (caught);

cout << "\nok\n\n";
}
31 changes: 31 additions & 0 deletions src/ImathTest/testQuat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,32 @@ testQuatT ()
assert (q1.r == 6 && q1.v == Vec3<T> (7, 8, 9));
}

// m * q
{
Matrix33<T> m;
m.setRotation(T(M_PI_2));
Quat<T> q;
q.setAxisAngle (Vec3<T> (0, 0, 1), T(M_PI_2));
Matrix33<T> mp = m * q;
Matrix33<T> r (-9.999999e-01f, 1.589326e-08f, 0.000000e+00f,
-1.589326e-08f, -9.999999e-01f, 0.000000e+00f,
0.000000e+00f, 0.000000e+00f, 1.000000e+00);
assert(mp.equalWithAbsError(r, 1e-5));
}

// q * m
{
Matrix33<T> m;
m.setRotation(T(M_PI_2));
Quat<T> q;
q.setAxisAngle (Vec3<T> (0, 0, 1), T(M_PI_2));
Matrix33<T> mp = m * q;
Matrix33<T> r (-9.999999e-01f, 1.589326e-08f, 0.000000e+00f,
-1.589326e-08f, -9.999999e-01f, 0.000000e+00f,
0.000000e+00f, 0.000000e+00f, 1.000000e+00);
assert(mp.equalWithAbsError(r, 1e-5));
}

//
// invert(), inverse()
//
Expand Down Expand Up @@ -78,6 +104,11 @@ testQuatT ()

q.normalize ();
assert (q == Quat<T> (0, 0, 1, 0));

q = Quat<T> (0, Vec3<T> (0, 0, 0));
q.normalize();
assert (q.r == 1 && q.v == Vec3<T>(0,0,0));

}

//
Expand Down
45 changes: 45 additions & 0 deletions src/ImathTest/testShear.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ testShear ()
{
cout << "Testing functions in ImathShear.h" << endl;

assert (IMATH_INTERNAL_NAMESPACE::Shear6f::baseTypeLowest() ==
std::numeric_limits<float>::lowest());
assert (IMATH_INTERNAL_NAMESPACE::Shear6f::baseTypeMax() ==
std::numeric_limits<float>::max());
assert (IMATH_INTERNAL_NAMESPACE::Shear6f::baseTypeSmallest() ==
std::numeric_limits<float>::min());
assert (IMATH_INTERNAL_NAMESPACE::Shear6f::baseTypeEpsilon() ==
std::numeric_limits<float>::epsilon());

cout << "Imath::Shear6 constructors" << endl;

const float epsilon = std::numeric_limits<float>::epsilon ();
Expand Down Expand Up @@ -195,5 +204,41 @@ testShear ()
std::fabs ((X.zx / Y.zx) - tmp.zx) <= 1e-5f &&
std::fabs ((X.zy / Y.zy) - tmp.zy) <= 1e-5f);


IMATH_INTERNAL_NAMESPACE::Shear6f s (1.0, 2.0, 3.0, 4.0, 5.0, 6.0);
tmp.setValue(s.xy, s.xz, s.yz, s.yx, s.zx, s.zy);
assert (tmp.xy == s.xy &&
tmp.xz == s.xz &&
tmp.yz == s.yz &&
tmp.yx == s.yx &&
tmp.zx == s.zx &&
tmp.zy == s.zy);
s = IMATH_INTERNAL_NAMESPACE::Shear6f();
tmp.getValue(s.xy, s.xz, s.yz, s.yx, s.zx, s.zy);
assert (tmp.xy == s.xy &&
tmp.xz == s.xz &&
tmp.yz == s.yz &&
tmp.yx == s.yx &&
tmp.zx == s.zx &&
tmp.zy == s.zy);

s = IMATH_INTERNAL_NAMESPACE::Shear6f();
s.setValue(tmp);
assert (tmp.xy == s.xy &&
tmp.xz == s.xz &&
tmp.yz == s.yz &&
tmp.yx == s.yx &&
tmp.zx == s.zx &&
tmp.zy == s.zy);

s = IMATH_INTERNAL_NAMESPACE::Shear6f();
tmp.getValue(s);
assert (tmp.xy == s.xy &&
tmp.xz == s.xz &&
tmp.yz == s.yz &&
tmp.yx == s.yx &&
tmp.zx == s.zx &&
tmp.zy == s.zy);

cout << "ok\n" << endl;
}
Loading

0 comments on commit bd0e707

Please sign in to comment.