feat(passages): §6.5 landings -- you arrive somewhere you can stand

The last unbuilt Tier 1 item. A passage was a bore through rock with no
floor inside the walkable angle, so its mouth was not a standing position
and neither was anything near it -- the departure mouth measured a FOUR-CELL
player-fit component. You arrived and there was nowhere to stand.

Both ends of all 7 passages now open into a landing, sized from the body:
  capsule diameter 2.72 vox      floor >= 12 vox (3 m) to stand and turn
  capsule height 7.04 vox        room >= 12 vox tall, stock mouth gives 18 (4.5 m)
  3-voxel floor slab, tube tangent to it -- no lip to climb out of
  connector 5-vox radius: 2.5 m clear width, 3 m clear height
  ramps over 44 deg get a deterministic level dog-leg

⭐ THE MOUTHS ARE NO LONGER SPECKS:
  archetype        components      largest      arrival-departure
  Maze             309 -> 340      176 -> 3210    43-81  -> 3210-3210
  TunnelNetwork    467 -> 227     1292 -> 3841     2-1   -> 3841-269
  Underwater        86 -> 117       35 -> 3838     3-11  -> 3838-267
  FlatPlain         45 ->  11      259 -> 2130     1-1   ->  268-273
  CrystalChamber   197 ->  90       24 ->  286     1-1   ->  286-274
  FloatingIslands    2 ->   1        3 ->   72     1-1   ->   72-72

Law 1/8 -> 2/7 connected (1 refused on MaxCells), and critically ZERO
connections now run through a four-cell pocket.

Every landing floor was verified against the FINAL density, after all posts:
14/14 pass the 44 deg slope bracket, worst room gradient .059, worst
connector .522. 14/14 deterministic root joins. 0 seal failures.
0 box-verdict violations across 82 proved + 174 mixed, 109,142 voxels.
Op-stack bit-identical, order-independence green over 10 slots / 31
passages / 3 pool orders. Cache 0.665 us rebuild, 0.646 us hot.

Post order: origin spine -> vertical seal -> passage tube + landing floor
-> XY edge seal. Landings clamp 4 voxels inside the vertical seal; the XY
seal stays last and wins at world edges.

⚠️ ARCHITECTURAL NOTE, not a detail: landings join a deterministic annular
ROOT HUB at (0,0), built identically for every endpoint -- no nearest-
component search, no passage ordering. That is what makes the join
guaranteed rather than likely, and it extends the (0,0) spine concept from
a landmark into a structural network. It also means routes tend to pass
through the centre, which is a gameplay consequence worth Jahni's eye.

⚠️ AND IT DOES NOT CLOSE THE LAW. Codex is explicit: the landings guarantee
membership in the new root network, NOT in the archetype's pre-existing fit
component. The whole-strate Maze check still shows a 71.9-voxel gap between
1,235 and 2,938-cell components. So the native corridor networks remain
disconnected from the root network in places. Real, separate, next.

52 build-and-measure cycles, ~9 hours, finding real geometry bugs on the
way (a landing floor overlapping the ramp cells and hiding a floor
discontinuity; the disturbance pass refilling connector headroom).

Build clean, 32/32 success, 0 failed. Showcase regenerated.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K8V9my1PL68pmQb2gutZZV
This commit is contained in:
Fr0zkaandClaude Opus 5 committed 2026-09-06 23:55:47 +02:00
1 parent e4e159f0cd
commit 413c15de24
14 files changed
+1943 -187

No files matched your search

@@ -2056,6 +2056,520 @@ namespace
}
}
namespace
{
constexpr float VF_LandingCarveSafetyMargin = 4.0f;
struct FVoxelPassageLandingConnectorProjection
{
FVector2D Closest = FVector2D::ZeroVector;
float DistanceAlong = 0.0f;
float TotalLength = 0.0f;
float SegmentLength = 0.0f;
float SegmentParameter = 0.0f;
int32 SegmentIndex = 0;
};
FVoxelPassageLandingConnectorProjection VF_ProjectPassageLandingConnector(
const FVector& Position,
const FVoxelPassageLanding& Landing)
{
const FVector2D A(Landing.ConnectorStart.X, Landing.ConnectorStart.Y);
const FVector2D Control(Landing.ConnectorControl.X, Landing.ConnectorControl.Y);
const FVector2D B(Landing.ConnectorEnd.X, Landing.ConnectorEnd.Y);
const FVector2D P(Position.X, Position.Y);
const bool bBend = Landing.bHasConnectorBend;
const FVector2D FirstEnd = bBend ? Control : B;
const FVector2D FirstVector = FirstEnd - A;
const FVector2D SecondVector = B - Control;
const float FirstLength = FirstVector.Size();
const float SecondLength = bBend ? SecondVector.Size() : 0.0f;
FVoxelPassageLandingConnectorProjection Result;
Result.TotalLength = FirstLength + SecondLength;
Result.Closest = A;
Result.SegmentLength = FirstLength;
if (Result.TotalLength <= KINDA_SMALL_NUMBER)
{
return Result;
}
float BestDistanceSquared = FLT_MAX;
const auto ProjectSegment = [&](const FVector2D& SegmentStart,
const FVector2D& SegmentEnd,
float SegmentOffset,
int32 SegmentIndex)
{
const FVector2D Segment = SegmentEnd - SegmentStart;
const float LengthSquared = Segment.SizeSquared();
const float Parameter = LengthSquared > KINDA_SMALL_NUMBER
? FMath::Clamp(FVector2D::DotProduct(P - SegmentStart, Segment)
/ LengthSquared, 0.0f, 1.0f)
: 0.0f;
const FVector2D Candidate = SegmentStart + Segment * Parameter;
const float DistanceSquared = (P - Candidate).SizeSquared();
if (DistanceSquared < BestDistanceSquared
|| (DistanceSquared == BestDistanceSquared
&& SegmentIndex < Result.SegmentIndex))
{
BestDistanceSquared = DistanceSquared;
Result.Closest = Candidate;
Result.DistanceAlong = SegmentOffset
+ FMath::Sqrt(FMath::Max(LengthSquared, 0.0f)) * Parameter;
Result.SegmentLength = FMath::Sqrt(FMath::Max(LengthSquared, 0.0f));
Result.SegmentParameter = Parameter;
Result.SegmentIndex = SegmentIndex;
}
};
ProjectSegment(A, FirstEnd, 0.0f, 0);
if (bBend)
{
ProjectSegment(Control, B, FirstLength, 1);
}
return Result;
}
float VF_PassageLandingConnectorFloorParameter(
const FVoxelPassageLandingConnectorProjection& Projection,
const FVoxelPassageLanding& Landing)
{
if (Projection.TotalLength <= KINDA_SMALL_NUMBER)
{
return 0.0f;
}
if (Landing.bHasConnectorBend)
{
// The first leg is deliberately level with the room. The second leg carries the
// complete rise and ends with a short level overlap inside the root annulus.
if (Projection.SegmentIndex == 0)
{
return 0.0f;
}
const float RootFlatLength = Landing.RootSpineRadius > 0.0f ? 2.25f : 0.0f;
const float RampLength = FMath::Max(
Projection.SegmentLength - RootFlatLength, KINDA_SMALL_NUMBER);
return FMath::Clamp(
Projection.SegmentParameter * Projection.SegmentLength / RampLength,
0.0f, 1.0f);
}
// The direct zero-rise case remains a single segment. Keep the old end aprons for
// descriptors produced by older cooked data, even though new passages use the bend when
// a non-zero rise needs a guaranteed slope.
const float SourceFlatLength = FMath::Max(Landing.HalfWidth - 1.0f, 0.0f);
const float RootFlatLength = Landing.RootSpineRadius > 0.0f ? 2.25f : 0.0f;
const float SourceDistance = FMath::Clamp(
SourceFlatLength, 0.0f, Projection.TotalLength * 0.49f);
const float RootDistance = FMath::Clamp(
Projection.TotalLength - RootFlatLength,
Projection.TotalLength * 0.51f, Projection.TotalLength);
if (RootDistance <= SourceDistance + KINDA_SMALL_NUMBER)
{
return FMath::Clamp(
Projection.DistanceAlong / Projection.TotalLength, 0.0f, 1.0f);
}
return FMath::Clamp(
(Projection.DistanceAlong - SourceDistance)
/ (RootDistance - SourceDistance), 0.0f, 1.0f);
}
}
FVoxelPassageLanding VF_BuildPassageLanding(
const FVector& InStandingPoint,
float MouthRadius,
const FVector& InDoorDirection,
float StrateTopZ,
float StrateBottomZ,
float BoundarySealThickness,
bool bSourcePlayerFit,
bool bHasNetworkConnector,
const FVector& NetworkPoint,
float RootSpineRadius)
{
FVoxelPassageLanding Landing;
// Body-derived dimensions at the authored 25 cm voxel scale:
// player diameter = 2 * 34 cm = 0.68 m = 2.72 voxels;
// a 3 m turn floor is 3 / 0.25 = 12 voxels across;
// capsule height = 2 * 88 cm = 1.76 m = 7.04 voxels;
// 1 m of headroom adds 4 voxels, so the minimum room height rounds to 12 voxels (3 m).
// The tube radius adds two voxels of clearance around the doorway. The support writer keeps
// one voxel inside the room wall, so HalfWidth=max(7, MouthRadius+2) gives a guaranteed
// 12-voxel = 3 m flat support floor, while the authored chamber is 14 voxels = 3.5 m wide.
const float SafeMouthRadius = FMath::Max(FMath::Abs(MouthRadius), 1.0f);
const float DesiredHalfWidth = FMath::Max(7.0f, SafeMouthRadius + 2.0f);
const float BodyHeightWithHeadroom = FVoxelPlayerCapsuleConstants::HeightVoxels + 4.0f;
const float DesiredHeight = FMath::Max(
FMath::Max(12.0f, BodyHeightWithHeadroom),
2.0f * SafeMouthRadius + 2.0f);
const float SafeSeal = FMath::Max(BoundarySealThickness, 0.0f);
FVector Direction(InDoorDirection.X, InDoorDirection.Y, 0.0f);
if (!Direction.Normalize())
{
Direction = FVector(1.0f, 0.0f, 0.0f);
}
Landing.StandingPoint = InStandingPoint;
Landing.FloorZ = InStandingPoint.Z - 0.5f;
Landing.HalfWidth = DesiredHalfWidth;
Landing.CeilingZ = Landing.FloorZ + DesiredHeight;
Landing.FloorThickness = 3.0f;
Landing.DoorDirection = Direction;
Landing.RootSpineRadius = FMath::Max(RootSpineRadius, 0.0f);
Landing.bSourcePlayerFit = bSourcePlayerFit;
Landing.bHasNetworkConnector = false;
Landing.RootFloorZ = Landing.FloorZ;
Landing.RootCeilingZ = Landing.CeilingZ;
// Keep the complete room and its floor strictly inside the vertical seal. Normal authored
// strates have far more room than this bound; the clamp is a fail-safe for a source pose near
// a seal and never moves a normal interior pose.
const float InnerBottom = StrateBottomZ + SafeSeal;
const float InnerTop = StrateTopZ - SafeSeal;
if (FMath::IsFinite(InnerBottom) && FMath::IsFinite(InnerTop)
&& InnerTop > InnerBottom)
{
// Passage carving is intentionally ordered after the vertical seal and fades over its
// four-voxel blend radius. Keep both the underside of the support slab and the top of the
// room beyond that radius from the seal, so the landing cannot use the passage exception
// to open a strate boundary.
const float MinFloor = InnerBottom + Landing.FloorThickness
+ VF_LandingCarveSafetyMargin;
const float MaxFloor = InnerTop - DesiredHeight - VF_LandingCarveSafetyMargin;
if (MaxFloor >= MinFloor)
{
Landing.FloorZ = FMath::Clamp(Landing.FloorZ, MinFloor, MaxFloor);
Landing.StandingPoint.Z = Landing.FloorZ + 0.5f;
Landing.CeilingZ = Landing.FloorZ + DesiredHeight;
}
else
{
// A degenerate strate cannot satisfy the full body/headroom contract. Fail closed
// instead of emitting a partial chamber whose blend would approach a seal.
Landing.HalfWidth = 0.0f;
Landing.CeilingZ = Landing.FloorZ;
Landing.bSourcePlayerFit = false;
return Landing;
}
}
// The tube centreline is tangent to the floor: the tube bottom is exactly FloorZ. The door
// sits one voxel inside the room so the room/tube smooth union cannot leave a lip.
Landing.DoorPoint = Landing.StandingPoint
+ Direction * FMath::Max(0.0f, Landing.HalfWidth - 1.0f);
Landing.DoorPoint.Z = Landing.FloorZ + SafeMouthRadius;
if (bHasNetworkConnector
&& FMath::IsFinite(NetworkPoint.X)
&& FMath::IsFinite(NetworkPoint.Y)
&& FMath::IsFinite(NetworkPoint.Z))
{
// The connector is a swept rectangular ramp. Its source end keeps the authored landing
// floor; its root end is the common, deterministic interior floor supplied by the
// manager. This is what joins two mouths in one strate when their source floors sit at
// opposite sides of the strate. The manager chooses the common level inside the same
// seal-safe interval as this builder, so no source query or passage order can affect it.
// Five voxels = 1.25 m half-width / 2.5 m clear width. This is the smallest whole-voxel
// annular root corridor that leaves a 1.36-voxel player capsule a two-voxel fit margin on
// the support lattice, while the landing itself remains the 3 m turn floor. Its separate
// 12-voxel (3 m) clear height gives the 1.76 m capsule more than 1 m of headroom while the
// player walks out to the network root. The floor rise is linear along the horizontal
// run; if the direct run is too short, a level dog-leg makes the final ramp satisfy the
// same 44 degree walkable limit by construction.
Landing.ConnectorRadius = 5.0f;
const float ConnectorHeight = FMath::Max(
12.0f, FVoxelPlayerCapsuleConstants::HeightVoxels + 4.0f);
Landing.ConnectorCeilingZ = Landing.FloorZ + ConnectorHeight;
Landing.RootFloorZ = NetworkPoint.Z;
Landing.RootCeilingZ = Landing.RootFloorZ + ConnectorHeight;
// Clamp the supplied common level again at the geometry boundary. This is deliberately
// a clamp, not a per-passage repair: all callers derive NetworkPoint.Z from the strate's
// bounds, and malformed tiny strates remain sealed rather than producing a root breach.
if (FMath::IsFinite(InnerBottom) && FMath::IsFinite(InnerTop)
&& InnerTop > InnerBottom)
{
const float RootMinFloor = InnerBottom + Landing.FloorThickness
+ VF_LandingCarveSafetyMargin;
const float RootMaxFloor = InnerTop - ConnectorHeight
- VF_LandingCarveSafetyMargin;
if (RootMaxFloor >= RootMinFloor)
{
Landing.RootFloorZ = FMath::Clamp(
Landing.RootFloorZ, RootMinFloor, RootMaxFloor);
Landing.RootCeilingZ = Landing.RootFloorZ + ConnectorHeight;
}
else
{
// There is no seal-safe interval for a full landing connector in a malformed
// tiny strate. Fail closed: a partial ramp that reaches a boundary is worse than
// an explicit unanswered landing, and normal authored strates never enter this
// branch.
return Landing;
}
}
else
{
return Landing;
}
const float ConnectorZ = (Landing.FloorZ + Landing.ConnectorCeilingZ) * 0.5f;
const float RootConnectorZ = (Landing.RootFloorZ + Landing.RootCeilingZ) * 0.5f;
FVector2D RootEntryDirection(
Landing.StandingPoint.X - NetworkPoint.X,
Landing.StandingPoint.Y - NetworkPoint.Y);
if (!RootEntryDirection.Normalize())
{
RootEntryDirection = FVector2D(Direction.X, Direction.Y);
if (!RootEntryDirection.Normalize())
{
RootEntryDirection = FVector2D(1.0f, 0.0f);
}
}
// The structural spine is a vertical air column, so its centre is not a standing
// endpoint. End the ramp in the middle of the support annulus instead: with the 1.36-voxel
// capsule radius, a centre at RootSpineRadius+2.25 sits at least one capsule radius outside
// the spine and at least one capsule radius inside the 4.5-voxel support edge. Every
// passage therefore enters the same continuous, floor-backed annular hub, while the spine
// itself remains open and unsealed.
const float RootEntryRadius = Landing.RootSpineRadius + 2.25f;
const FVector2D RootEntryXY(
NetworkPoint.X + RootEntryDirection.X * RootEntryRadius,
NetworkPoint.Y + RootEntryDirection.Y * RootEntryRadius);
Landing.ConnectorStart = FVector(
Landing.StandingPoint.X, Landing.StandingPoint.Y, ConnectorZ);
Landing.ConnectorEnd = FVector(RootEntryXY.X, RootEntryXY.Y, RootConnectorZ);
// A direct source-to-root ramp is usually gentle, but its length is not a contract: a
// legal source pose can be close to the spine while its floor is near a strate face. Add a
// deterministic level dog-leg whenever the direct run cannot meet the 44-degree law.
// The final leg is the only rising part, and its extra horizontal run includes the root
// annulus overlap. This makes the slope a construction guarantee for every seed, rather
// than a property observed in today's showcase seeds. WorldRadiusVoxels is deliberately
// zero, so the bounded world rim cannot be approached by this lateral safety run.
constexpr float WalkableSlope = 0.9656888f; // tan(44 degrees)
constexpr float RootFlatLength = 2.25f;
const FVector2D SourceXY(Landing.ConnectorStart.X, Landing.ConnectorStart.Y);
const FVector2D RootXY(Landing.ConnectorEnd.X, Landing.ConnectorEnd.Y);
const FVector2D Direct = RootXY - SourceXY;
const float DirectLength = Direct.Size();
const float FloorRise = FMath::Abs(Landing.RootFloorZ - Landing.FloorZ);
const float RequiredRampLength = FloorRise / WalkableSlope;
const float SourceFlatLength = FMath::Max(Landing.HalfWidth - 1.0f, 0.0f);
if (FloorRise > KINDA_SMALL_NUMBER
&& (DirectLength <= KINDA_SMALL_NUMBER
|| DirectLength < RequiredRampLength + RootFlatLength + SourceFlatLength))
{
FVector2D Along = Direct;
if (!Along.Normalize())
{
Along = FVector2D(Direction.X, Direction.Y);
if (!Along.Normalize())
{
Along = FVector2D(1.0f, 0.0f);
}
}
const FVector2D Perpendicular(-Along.Y, Along.X);
const float DogLegLength = RequiredRampLength + RootFlatLength + 1.0f;
const FVector2D ControlXY = RootXY + Perpendicular * DogLegLength;
Landing.ConnectorControl = FVector(ControlXY.X, ControlXY.Y, ConnectorZ);
Landing.bHasConnectorBend = true;
}
else if (FloorRise > KINDA_SMALL_NUMBER)
{
// Keep the same straight geometry when it already satisfies the bound. The explicit
// false flag is part of the descriptor so the evaluator and order-independence test
// cannot infer a different topology from an uninitialised control point.
Landing.ConnectorControl = FVector::ZeroVector;
Landing.bHasConnectorBend = false;
}
else
{
Landing.ConnectorControl = FVector(
(Landing.ConnectorStart.X + Landing.ConnectorEnd.X) * 0.5f,
(Landing.ConnectorStart.Y + Landing.ConnectorEnd.Y) * 0.5f,
ConnectorZ);
Landing.bHasConnectorBend = false;
}
Landing.bHasNetworkConnector = true;
}
return Landing;
}
float VF_EvaluatePassageLandingSDF(
const FVector& Position,
const FVoxelPassageLanding& Landing)
{
if (!FMath::IsFinite(Position.X) || !FMath::IsFinite(Position.Y)
|| !FMath::IsFinite(Position.Z)
|| !FMath::IsFinite(Landing.StandingPoint.X)
|| !FMath::IsFinite(Landing.StandingPoint.Y)
|| !FMath::IsFinite(Landing.FloorZ)
|| !FMath::IsFinite(Landing.CeilingZ)
|| !FMath::IsFinite(Landing.HalfWidth)
|| Landing.HalfWidth <= 0.0f
|| Landing.CeilingZ <= Landing.FloorZ)
{
return FLT_MAX;
}
const FVector RoomCenter(
Landing.StandingPoint.X,
Landing.StandingPoint.Y,
(Landing.FloorZ + Landing.CeilingZ) * 0.5f);
constexpr float RoomRounding = 1.5f;
const FVector RoomHalfExtent(
FMath::Max(Landing.HalfWidth - RoomRounding, 0.25f),
FMath::Max(Landing.HalfWidth - RoomRounding, 0.25f),
FMath::Max((Landing.CeilingZ - Landing.FloorZ) * 0.5f - RoomRounding, 0.25f));
// max(Room, FloorZ-Z) is the important distinction from a bore: below FloorZ is solid,
// while every horizontal section above it has the same flat floor plane.
float LandingSDF = FMath::Max(
VoxelSDF::RoundedBox(Position, RoomCenter, RoomHalfExtent, RoomRounding),
Landing.FloorZ - Position.Z);
if (Landing.bHasNetworkConnector && Landing.ConnectorRadius > 0.0f
&& FMath::IsFinite(Landing.ConnectorCeilingZ)
&& Landing.ConnectorCeilingZ > Landing.FloorZ
&& FMath::IsFinite(Landing.RootFloorZ)
&& FMath::IsFinite(Landing.RootCeilingZ)
&& Landing.RootCeilingZ > Landing.RootFloorZ)
{
const FVoxelPassageLandingConnectorProjection Projection =
VF_ProjectPassageLandingConnector(Position, Landing);
const float FloorT = VF_PassageLandingConnectorFloorParameter(Projection, Landing);
const float HorizontalSDF = (FVector2D(Position.X, Position.Y)
- Projection.Closest).Size()
- Landing.ConnectorRadius;
const float ConnectorFloorZ = FMath::Lerp(
Landing.FloorZ, Landing.RootFloorZ, FloorT);
const float ConnectorCeilingZ = FMath::Lerp(
Landing.ConnectorCeilingZ, Landing.RootCeilingZ, FloorT);
const float VerticalSDF = FMath::Max(
ConnectorFloorZ - Position.Z,
Position.Z - ConnectorCeilingZ);
// A swept box with a flat source leg and a measured-slope final ramp, not a round bore:
// the floor normal is deterministic and bounded, while the fixed twelve-voxel clear height
// follows the route. The source and root ends are exactly the two flat landing floors.
const float ConnectorSDF = FMath::Max(HorizontalSDF, VerticalSDF);
LandingSDF = VoxelSDF::SmoothMin(LandingSDF, ConnectorSDF, 3.0f);
if (Landing.RootSpineRadius >= 0.0f)
{
// A shared hub turns the guaranteed root join into a walkable network. With the normal
// origin spine it is an annulus outside that shaft; with a disabled spine it safely
// degenerates to a disk, so the landing contract still has a guaranteed root volume.
const float HubRadius = Landing.RootSpineRadius + Landing.ConnectorRadius;
const float RadialDistance = FMath::Sqrt(
FMath::Square(Position.X) + FMath::Square(Position.Y));
const float HubHorizontalSDF = FMath::Max(
Landing.RootSpineRadius - RadialDistance,
RadialDistance - HubRadius);
const float HubVerticalSDF = FMath::Max(
Landing.RootFloorZ - Position.Z,
Position.Z - Landing.RootCeilingZ);
const float HubSDF = FMath::Max(HubHorizontalSDF, HubVerticalSDF);
LandingSDF = VoxelSDF::SmoothMin(LandingSDF, HubSDF, 3.0f);
}
}
return LandingSDF;
}
bool VF_IsPassageLandingFloor(
const FVector& Position,
const FVoxelPassageLanding& Landing)
{
if (!FMath::IsFinite(Position.X) || !FMath::IsFinite(Position.Y)
|| !FMath::IsFinite(Position.Z) || !FMath::IsFinite(Landing.FloorZ)
|| !FMath::IsFinite(Landing.FloorThickness)
|| Landing.FloorThickness <= 0.0f || Landing.HalfWidth <= 0.0f)
{
return false;
}
const auto IsInFloorBand = [](float Z, float FloorZ, float Thickness)
{
// The analytic ramp and the sampled density use the same float interpolation, but a
// caller can arrive at the mathematically identical plane through a different fused
// multiply/add sequence. Include one machine epsilon on the upper side so the support
// backstop cannot disappear at an exact floor sample.
return Z <= FloorZ + KINDA_SMALL_NUMBER && Z > FloorZ - Thickness;
};
const bool bInsideRootSpine = Landing.RootSpineRadius > 0.0f
&& FMath::Square(Position.X) + FMath::Square(Position.Y)
<= FMath::Square(Landing.RootSpineRadius);
// The room floor is a true horizontal landing: it is the only floor that owns the full
// three-metre turning patch. The central root spine is left open.
if (IsInFloorBand(Position.Z, Landing.FloorZ, Landing.FloorThickness)
&& !bInsideRootSpine)
{
const float FloorHalfWidth = FMath::Max(Landing.HalfWidth - 1.0f, 0.0f);
if (FMath::Abs(Position.X - Landing.StandingPoint.X) <= FloorHalfWidth
&& FMath::Abs(Position.Y - Landing.StandingPoint.Y) <= FloorHalfWidth)
{
return true;
}
}
if (Landing.bHasNetworkConnector && Landing.ConnectorRadius > 0.0f
&& FMath::IsFinite(Landing.RootFloorZ)
&& FMath::IsFinite(Landing.RootCeilingZ)
&& Landing.RootCeilingZ > Landing.RootFloorZ)
{
const FVoxelPassageLandingConnectorProjection Projection =
VF_ProjectPassageLandingConnector(Position, Landing);
const FVector2D& Closest = Projection.Closest;
const float FloorT = VF_PassageLandingConnectorFloorParameter(Projection, Landing);
const float ConnectorFloorZ = FMath::Lerp(
Landing.FloorZ, Landing.RootFloorZ, FloorT);
if (!bInsideRootSpine
&& IsInFloorBand(Position.Z, ConnectorFloorZ, Landing.FloorThickness))
{
// Keep connector support inset by half a voxel from its clear width. The landing
// chamber—not this narrow transit leg—owns the 3 m turn floor; this inset preserves
// a solid walking strip without capping a neighbouring shaft at its edge.
const float FloorRadius = FMath::Max(
Landing.ConnectorRadius - 0.5f,
FVoxelPlayerCapsuleConstants::RadiusVoxels);
if ((FVector2D(Position.X, Position.Y) - Closest).SizeSquared()
<= FMath::Square(FloorRadius))
{
return true;
}
}
if (IsInFloorBand(Position.Z, Landing.RootFloorZ, Landing.FloorThickness))
{
// The common root hub is a walkable annulus, not a cap over the vertical spine. Its
// 4.5-voxel support inset leaves the same 0.5-voxel air clearance at the outer wall as
// the connector and never writes inside the spine radius.
const float RadialDistanceSquared = FMath::Square(Position.X)
+ FMath::Square(Position.Y);
const float HubInnerRadius = Landing.RootSpineRadius;
const float HubOuterSupportRadius = Landing.RootSpineRadius
+ FMath::Max(Landing.ConnectorRadius - 0.5f,
FVoxelPlayerCapsuleConstants::RadiusVoxels);
const bool bOutsideSpine = Landing.RootSpineRadius <= 0.0f
|| RadialDistanceSquared > FMath::Square(HubInnerRadius);
if (bOutsideSpine
&& RadialDistanceSquared <= FMath::Square(HubOuterSupportRadius))
{
return true;
}
}
}
return false;
}
bool VF_SuggestLandingPoint(
ECaveGeneratorType Archetype,
const FStrateGenerationParams& CaveParams,