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 distance = plane.SignedDistance(center);
|
||||
if (distance < T(-radius))
|
||||
if (distance < T(radius))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -219,15 +219,11 @@ namespace Nz
|
|||
{
|
||||
for (const auto& plane : m_planes)
|
||||
{
|
||||
std::size_t j;
|
||||
for (j = 0; j < pointCount; j++ )
|
||||
for (std::size_t i = 0; i < pointCount; ++i)
|
||||
{
|
||||
if (plane.SignedDistance(points[j]) > T(0.0))
|
||||
break;
|
||||
if (plane.SignedDistance(points[i]) < T(0.0))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (j == pointCount)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -378,24 +374,27 @@ namespace Nz
|
|||
template<typename T>
|
||||
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)
|
||||
{
|
||||
std::size_t j;
|
||||
for (j = 0; j < pointCount; j++ )
|
||||
bool outside = true;
|
||||
std::size_t insidePoint = 0;
|
||||
for (std::size_t i = 0; i < pointCount; ++i)
|
||||
{
|
||||
if (plane.SignedDistance(points[j]) > T(0.0))
|
||||
break;
|
||||
// If at least one point is outside of the frustum, we're intersecting
|
||||
if (plane.SignedDistance(points[i]) < T(0.0))
|
||||
side = IntersectionSide::Intersecting;
|
||||
else
|
||||
outside = false;
|
||||
}
|
||||
|
||||
if (j == pointCount)
|
||||
// But if no point is intersecting on this plane, then it's outside
|
||||
if (outside)
|
||||
return IntersectionSide::Outside;
|
||||
else
|
||||
c++;
|
||||
}
|
||||
|
||||
return (c == 6) ? IntersectionSide::Inside : IntersectionSide::Intersecting;
|
||||
return side;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -10,12 +10,42 @@ SCENARIO("Frustum", "[MATH][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")
|
||||
{
|
||||
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));
|
||||
obb.Update(Nz::Matrix4f::Identity());
|
||||
REQUIRE(Nz::IntersectionSide::Outside == frustum.Intersect(obb));
|
||||
|
|
|
|||
Loading…
Reference in New Issue