Math/Frustum: Fix Contains(Box) and Intersect(points, n)
This commit is contained in:
parent
4494249dc1
commit
161c4f6aca
|
|
@ -152,7 +152,7 @@ namespace Nz
|
||||||
float radius = projectedExtents.x + projectedExtents.y + projectedExtents.z;
|
float radius = projectedExtents.x + projectedExtents.y + projectedExtents.z;
|
||||||
|
|
||||||
float distance = plane.SignedDistance(center);
|
float distance = plane.SignedDistance(center);
|
||||||
if (distance < T(-radius))
|
if (distance < T(radius))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -219,16 +219,12 @@ namespace Nz
|
||||||
{
|
{
|
||||||
for (const auto& plane : m_planes)
|
for (const auto& plane : m_planes)
|
||||||
{
|
{
|
||||||
std::size_t j;
|
for (std::size_t i = 0; i < pointCount; ++i)
|
||||||
for (j = 0; j < pointCount; j++ )
|
|
||||||
{
|
{
|
||||||
if (plane.SignedDistance(points[j]) > T(0.0))
|
if (plane.SignedDistance(points[i]) < T(0.0))
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j == pointCount)
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -378,24 +374,27 @@ namespace Nz
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr IntersectionSide Frustum<T>::Intersect(const Vector3<T>* points, std::size_t pointCount) const
|
constexpr IntersectionSide Frustum<T>::Intersect(const Vector3<T>* points, std::size_t pointCount) const
|
||||||
{
|
{
|
||||||
std::size_t c = 0;
|
IntersectionSide side = IntersectionSide::Inside;
|
||||||
|
|
||||||
for (const auto& plane : m_planes)
|
for (const auto& plane : m_planes)
|
||||||
{
|
{
|
||||||
std::size_t j;
|
bool outside = true;
|
||||||
for (j = 0; j < pointCount; j++ )
|
std::size_t insidePoint = 0;
|
||||||
|
for (std::size_t i = 0; i < pointCount; ++i)
|
||||||
{
|
{
|
||||||
if (plane.SignedDistance(points[j]) > T(0.0))
|
// If at least one point is outside of the frustum, we're intersecting
|
||||||
break;
|
if (plane.SignedDistance(points[i]) < T(0.0))
|
||||||
}
|
side = IntersectionSide::Intersecting;
|
||||||
|
|
||||||
if (j == pointCount)
|
|
||||||
return IntersectionSide::Outside;
|
|
||||||
else
|
else
|
||||||
c++;
|
outside = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (c == 6) ? IntersectionSide::Inside : IntersectionSide::Intersecting;
|
// But if no point is intersecting on this plane, then it's outside
|
||||||
|
if (outside)
|
||||||
|
return IntersectionSide::Outside;
|
||||||
|
}
|
||||||
|
|
||||||
|
return side;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,42 @@ SCENARIO("Frustum", "[MATH][FRUSTUM]")
|
||||||
|
|
||||||
WHEN("We ask for intersection with objects outside the frustum")
|
WHEN("We ask for intersection with objects outside the frustum")
|
||||||
{
|
{
|
||||||
|
GIVEN("Bounding volumes")
|
||||||
|
{
|
||||||
|
Nz::BoundingVolumef bv(Nz::Boxf(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 10.f));
|
||||||
|
bv.Update(Nz::Matrix4f::Identity());
|
||||||
|
|
||||||
|
CHECK_FALSE(frustum.Contains(bv));
|
||||||
|
CHECK(frustum.Intersect(bv) == Nz::IntersectionSide::Intersecting);
|
||||||
|
|
||||||
|
bv.Update(Nz::Matrix4f::Translate(Nz::Vector3f::UnitX() * -50.f));
|
||||||
|
|
||||||
|
CHECK_FALSE(frustum.Contains(bv));
|
||||||
|
CHECK(frustum.Intersect(bv) == Nz::IntersectionSide::Outside);
|
||||||
|
|
||||||
|
bv.Update(Nz::Matrix4f::Translate(Nz::Vector3f::UnitX() * 50.f));
|
||||||
|
|
||||||
|
CHECK(frustum.Contains(bv));
|
||||||
|
CHECK(frustum.Intersect(bv) == Nz::IntersectionSide::Inside);
|
||||||
|
}
|
||||||
|
|
||||||
|
GIVEN("Boxes")
|
||||||
|
{
|
||||||
|
Nz::Boxf insideBox(Nz::Vector3f::UnitX() * 50.f, Nz::Vector3f::Unit() * 10.f);
|
||||||
|
Nz::Boxf intersectingBox(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 10.f);
|
||||||
|
Nz::Boxf outsideBox(Nz::Vector3f::UnitX() * -50.f, Nz::Vector3f::Unit() * 10.f);
|
||||||
|
|
||||||
|
CHECK(frustum.Contains(insideBox));
|
||||||
|
CHECK_FALSE(frustum.Contains(intersectingBox));
|
||||||
|
CHECK_FALSE(frustum.Contains(outsideBox));
|
||||||
|
|
||||||
|
CHECK(frustum.Intersect(insideBox) == Nz::IntersectionSide::Inside);
|
||||||
|
CHECK(frustum.Intersect(intersectingBox) == Nz::IntersectionSide::Intersecting);
|
||||||
|
CHECK(frustum.Intersect(outsideBox) == Nz::IntersectionSide::Outside);
|
||||||
|
}
|
||||||
|
|
||||||
THEN("These results are expected")
|
THEN("These results are expected")
|
||||||
{
|
{
|
||||||
Nz::BoundingVolumef bv(Nz::Boxf(Nz::Vector3f::Zero(), Nz::Vector3f::Unit()));
|
|
||||||
bv.Update(Nz::Matrix4f::Identity());
|
|
||||||
REQUIRE(Nz::IntersectionSide::Outside == frustum.Intersect(bv));
|
|
||||||
REQUIRE(Nz::IntersectionSide::Outside == frustum.Intersect(Nz::Boxf(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 0.9f)));
|
|
||||||
Nz::OrientedBoxf obb(Nz::Boxf(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 0.9f));
|
Nz::OrientedBoxf obb(Nz::Boxf(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 0.9f));
|
||||||
obb.Update(Nz::Matrix4f::Identity());
|
obb.Update(Nz::Matrix4f::Identity());
|
||||||
REQUIRE(Nz::IntersectionSide::Outside == frustum.Intersect(obb));
|
REQUIRE(Nz::IntersectionSide::Outside == frustum.Intersect(obb));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue