Browse Source

Merge 47e7f6bdb4 into ce5157e4fe

pull/482/merge
Jonathan Hale 2 weeks ago committed by GitHub
parent
commit
622d23dfcc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 6
      src/Magnum/Math/Intersection.h
  2. 22
      src/Magnum/Math/Test/DistanceTest.cpp
  3. 56
      src/Magnum/Math/Test/IntersectionTest.cpp

6
src/Magnum/Math/Intersection.h

@ -270,6 +270,7 @@ template<class T> bool aabbFrustum(const Vector3<T>& aabbCenter, const Vector3<T
Checks for each plane of the frustum whether the sphere is behind the plane Checks for each plane of the frustum whether the sphere is behind the plane
(the points distance larger than the sphere's radius) using (the points distance larger than the sphere's radius) using
@ref Distance::pointPlaneScaled(). @ref Distance::pointPlaneScaled().
@see @ref MeshTools::boundingSphereBouncingBubble() @see @ref MeshTools::boundingSphereBouncingBubble()
*/ */
@ -532,19 +533,16 @@ template<class T> bool aabbFrustum(const Vector3<T>& aabbCenter, const Vector3<T
} }
template<class T> bool sphereFrustum(const Vector3<T>& sphereCenter, const T sphereRadius, const Frustum<T>& frustum) { template<class T> bool sphereFrustum(const Vector3<T>& sphereCenter, const T sphereRadius, const Frustum<T>& frustum) {
const T radiusSq = sphereRadius*sphereRadius;
for(const Vector4<T>& plane: frustum) { for(const Vector4<T>& plane: frustum) {
/* The sphere is in front of one of the frustum planes (normals point /* The sphere is in front of one of the frustum planes (normals point
outwards) */ outwards) */
if(Distance::pointPlaneScaled<T>(sphereCenter, plane) < -radiusSq) if(Distance::pointPlane<T>(sphereCenter, plane) >= sphereRadius)
return false; return false;
} }
return true; return true;
} }
template<class T> bool pointCone(const Vector3<T>& point, const Vector3<T>& coneOrigin, const Vector3<T>& coneNormal, const Rad<T> coneAngle) { template<class T> bool pointCone(const Vector3<T>& point, const Vector3<T>& coneOrigin, const Vector3<T>& coneNormal, const Rad<T> coneAngle) {
const T tanAngleSqPlusOne = Math::pow<2>(Math::tan(coneAngle*T(0.5))) + T(1); const T tanAngleSqPlusOne = Math::pow<2>(Math::tan(coneAngle*T(0.5))) + T(1);
return pointCone(point, coneOrigin, coneNormal, tanAngleSqPlusOne); return pointCone(point, coneOrigin, coneNormal, tanAngleSqPlusOne);

22
src/Magnum/Math/Test/DistanceTest.cpp

@ -213,10 +213,26 @@ void DistanceTest::lineSegmentPoint3D() {
} }
void DistanceTest::pointPlane() { void DistanceTest::pointPlane() {
Vector3 point{0.0f, 0.0f, 0.0f}; {
Vector4 plane{3.0f, 0.0f, 4.0f, 5.0f}; Vector4 plane{3.0f, 0.0f, 4.0f, 5.0f};
CORRADE_COMPARE(Distance::pointPlane({}, plane), 1.0f);
CORRADE_COMPARE(Distance::pointPlane(point, plane), 1.0f); }
{
/* Origin plane with normal {0, 1, 0} */
Vector4 plane{0.0f, 1.0f, 0.0f, 0.0f};
/* Point lies in front of plane, 2 units away */
CORRADE_COMPARE(Distance::pointPlane({0.0f, 2.0f, 0.0f}, plane), 2.0f);
/* Point lies in begind the plane, 2 units away */
CORRADE_COMPARE(Distance::pointPlane({0.0f, -2.0f, 0.0f}, plane), -2.0f);
}
{
/* Origin plane offset by 1 normal with normal {0, 1, 0} */
Vector4 plane{0.0f, 1.0f, 0.0f, -1.0f};
/* Point lies in front of plane, 2 units away */
CORRADE_COMPARE(Distance::pointPlane({0.0f, 2.0f, 0.0f}, plane), 1.0f);
/* Point lies in begind the plane, 2 units away */
CORRADE_COMPARE(Distance::pointPlane({0.0f, -2.0f, 0.0f}, plane), -3.0f);
}
} }
void DistanceTest::pointPlaneScaled() { void DistanceTest::pointPlaneScaled() {

56
src/Magnum/Math/Test/IntersectionTest.cpp

@ -255,12 +255,12 @@ void IntersectionTest::rayRange() {
void IntersectionTest::aabbFrustum() { void IntersectionTest::aabbFrustum() {
const Frustum frustum{ const Frustum frustum{
{1.0f, 0.0f, 0.0f, 0.0f},
{-1.0f, 0.0f, 0.0f, 5.0f}, {-1.0f, 0.0f, 0.0f, 5.0f},
{0.0f, 1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, -1.0f, 0.0f, 1.0f}, {0.0f, -1.0f, 0.0f, 1.0f},
{0.0f, 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 0.0f},
{0.0f, 0.0f, -1.0f, 10.0f}}; {0.0f, 0.0f, -1.0f, 10.0f},
{0.0f, 0.0f, 1.0f, 0.0f}};
/* Fully inside */ /* Fully inside */
CORRADE_VERIFY(Intersection::aabbFrustum(Vector3{0.0f}, Vector3{1.0f}, frustum)); CORRADE_VERIFY(Intersection::aabbFrustum(Vector3{0.0f}, Vector3{1.0f}, frustum));
@ -278,20 +278,50 @@ void IntersectionTest::aabbFrustum() {
} }
void IntersectionTest::sphereFrustum() { void IntersectionTest::sphereFrustum() {
/* Frustum spanning [(-10, -10, -10), (0, 0, 0)] */
const Frustum frustum{ const Frustum frustum{
{-1.0f, 0.0f, 0.0f, -10.0f},
{1.0f, 0.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 0.0f},
{-1.0f, 0.0f, 0.0f, 10.0f}, {0.0f, -0.5f, 0.0f, -5.0f}, /* Intentionally not normalized */
{0.0f, 1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 0.0f},
{0.0f, -1.0f, 0.0f, 10.0f},
{0.0f, 0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, -1.0f, 10.0f}}; {0.0f, 0.0f, -2.0f, -20.0f}}; /* Intentionally not normalized */
/* Sphere on edge */ /* Sphere overlapping each face by 0.5 */
CORRADE_VERIFY(Intersection::sphereFrustum({0.0f, 0.0f, -1.0f}, 1.5f, frustum)); CORRADE_VERIFY(Intersection::sphereFrustum({ 1.0f, 0.0f, 0.0f}, 1.5f, frustum));
CORRADE_VERIFY(Intersection::sphereFrustum({-11.0f, 0.0f, 0.0f}, 1.5f, frustum));
CORRADE_VERIFY(Intersection::sphereFrustum({ 0.0f, 1.0f, 0.0f}, 1.5f, frustum));
CORRADE_VERIFY(Intersection::sphereFrustum({ 0.0f,-11.0f, 0.0f}, 1.5f, frustum));
CORRADE_VERIFY(Intersection::sphereFrustum({ 0.0f, 0.0f, 1.0f}, 1.5f, frustum));
CORRADE_VERIFY(Intersection::sphereFrustum({ 0.0f, 0.0f,-11.0f}, 1.5f, frustum));
/* Sphere touching each face */
CORRADE_VERIFY(!Intersection::sphereFrustum({ 1.0f, 0.0f, 0.0f}, 1.0f, frustum));
CORRADE_VERIFY(!Intersection::sphereFrustum({-11.0f, 0.0f, 0.0f}, 1.0f, frustum));
CORRADE_VERIFY(!Intersection::sphereFrustum({ 0.0f, 1.0f, 0.0f}, 1.0f, frustum));
CORRADE_VERIFY(!Intersection::sphereFrustum({ 0.0f,-11.0f, 0.0f}, 1.0f, frustum));
CORRADE_VERIFY(!Intersection::sphereFrustum({ 0.0f, 0.0f, 1.0f}, 1.0f, frustum));
CORRADE_VERIFY(!Intersection::sphereFrustum({ 0.0f, 0.0f,-11.0f}, 1.0f, frustum));
/* Sphere inside */ /* Sphere inside */
CORRADE_VERIFY(Intersection::sphereFrustum({5.5f, 5.5f, 5.5f}, 1.5f, frustum)); CORRADE_VERIFY(Intersection::sphereFrustum({-1.0f, -2.0f, -3.0f}, 1.5f, frustum));
/* Sphere outside */ /* Sphere outside each face */
CORRADE_VERIFY(!Intersection::sphereFrustum({0.0f, 0.0f, 100.0f}, 0.5f, frustum)); CORRADE_VERIFY(!Intersection::sphereFrustum({ 1.0f, 0.0f, 0.0f}, 0.5f, frustum));
CORRADE_VERIFY(!Intersection::sphereFrustum({-11.0f, 0.0f, 0.0f}, 0.5f, frustum));
CORRADE_VERIFY(!Intersection::sphereFrustum({ 0.0f, 1.0f, 0.0f}, 0.5f, frustum));
CORRADE_VERIFY(!Intersection::sphereFrustum({ 0.0f,-11.0f, 0.0f}, 0.5f, frustum));
CORRADE_VERIFY(!Intersection::sphereFrustum({ 0.0f, 0.0f, 1.0f}, 0.5f, frustum));
CORRADE_VERIFY(!Intersection::sphereFrustum({ 0.0f, 0.0f,-11.0f}, 0.5f, frustum));
/* Some "Corner" cases, sphere touching corner, but shouldn't intersect */
CORRADE_VERIFY(!Intersection::sphereFrustum({1.1f, 1.1f, 1.1f}, 1.1f, frustum));
CORRADE_VERIFY(!Intersection::sphereFrustum({-11.1f, -11.1f, -11.1f}, 1.1f, frustum));
CORRADE_VERIFY(!Intersection::sphereFrustum({1.1f, -11.1f, 1.1f}, 1.1f, frustum));
CORRADE_VERIFY(!Intersection::sphereFrustum({-11.1f, 1.1f, -11.1f}, 1.1f, frustum));
CORRADE_VERIFY(!Intersection::sphereFrustum({-11.1f, 1.1f, 1.1f}, 1.1f, frustum));
CORRADE_VERIFY(!Intersection::sphereFrustum({1.1f, -11.1f, -11.1f}, 1.1f, frustum));
CORRADE_VERIFY(!Intersection::sphereFrustum({1.1f, 1.1f, -11.1f}, 1.1f, frustum));
CORRADE_VERIFY(!Intersection::sphereFrustum({-11.1f, -11.1f, 1.1f}, 1.1f, frustum));
} }
void IntersectionTest::pointCone() { void IntersectionTest::pointCone() {

Loading…
Cancel
Save