Bug: Chaos::SweepQuery on "Invisible" terrain returns a hit with initial overlaps (when bComputeMTD=false)

FHeightfieldRaycastVisitor::VisitSweep skips the painted-hole (visibility

mask) check when the swept sphere starts in initial overlap with a

heightfield cell, producing a spurious zero-distance hit on invisible

terrain.

See repro description.

Root cause

----------

GeometryQueries.h SweepQuery routes (Sphere, bComputeMTD=false) through

FHeightField::Raycast, which with Thickness>0 uses

FHeightfieldRaycastVisitor::VisitSweep (HeightField.cpp ~line 110).

That visitor has two hit branches. The “border” branch at ~line 217-237

filters cells via:

bHole = GeomData->MaterialIndices[CellIndex] == TNumericLimits<uint8>::Max();

if (!bHole) { …store hit… }

The earlier “initial overlap” branch at ~line 145-157 returns the hit

without consulting MaterialIndices:

if (Time == 0)

{

 const FVec3 ClosestPtOnTri \= FindClosestPointOnTriangle(...);

 if (DistToTriangle2 \<\= Radius2\)

 {

   OutTime \= 0;

   ...

   return true;  // \<\- hole check missing

 }

}

So a sphere already overlapping a hole cell at t=0 bypasses the filter.

Suggested fix

-------------

Mirror the existing hole test in the initial-overlap branch:

if (DistToTriangle2 <= Radius2)

{

 const int32 CellIndex \= FaceIndex / 2;

 if (GeomData\-\>MaterialIndices.IsValidIndex(CellIndex)

   \&\& GeomData\-\>MaterialIndices\[CellIndex] \=\= TNumericLimits\<uint8\>::Max())

 {

   return false;

 }

 OutTime \= 0;

 ...

 return true;

}

[Attachment Removed]

Steps to Reproduce
1. Landscape with one or more cells painted out by the Visibility tool

(heightfield MaterialIndex == 0xFF).

2. Sweep a TSphere against the landscape from a Start position that lies

inside the hole cell, with any Dir/Length, using

Chaos::SweepQuery(…, bComputeMTD=false).

Observed

--------

SweepQuery returns bHit=true with OutTime==0 on the hole cell. The same

sweep started just outside the hole correctly returns no hit.

Expected

--------

No hit on hole cells regardless of whether the overlap is initial

(Time==0) or along the sweep, matching the behaviour of the GJK sweep

path (SweepGeomImp / THeightfieldSweepVisitor) and FHeightField::Overlap*.

[Attachment Removed]

Hi Soren, and thank you for the ticket.

Apologies this has taken a while to respond to. Would you be able to provide a repro project for this please and we can investigate further?

Best

Geoff Stacey

Developer Relations

EPIC Games

[Attachment Removed]