core: coarser smooth-route tolerance + shell support bound (L119, evaluator v224)

Chord error 2.5 -> 10 cm, shell work skipped outside the 0-0.75 m band. Sweep pairs -39%, prepare -60%,
near-ready 3-8% faster than L115 but still +13..+22% vs L109. Floor offset 7.88 mm; captures match L115
by eye; fast tier, walk audits, Clang/GCC W1/W8/W12 determinism green. Not for merge yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-10-30 05:35:59 +01:00
1 parent 6e52fb48b2
commit 707bc61553
40 files changed
+2352 -54

No files matched your search

@@ -147,7 +147,9 @@ namespace VoxelForgeCore
// by the opt-in passage composer profile, except the mesh composition itself.
std::uint64_t passageSweepRouteSegmentCandidates = 0;
std::uint64_t passageSweepSegmentSamplePairs = 0;
std::uint64_t passageSweepPrepareNanoseconds = 0;
std::uint64_t passageSweepOutsideInfluencePairs = 0;
std::uint64_t passageSweepShellSupportSkips = 0;
std::uint64_t passageSweepMinimumUpdates = 0;
std::uint64_t passageSweepBaseInfluenceSamples = 0;
std::uint64_t passageSweepDetailShellSamples = 0;
@@ -474,8 +476,9 @@ namespace VoxelForgeCore
// Version 220 adaptively samples passage curves and rounds open-air wall crests.
// Version 221 ranks passage segments before floor shaping and preserves their signed exterior distance.
// Version 223 projects the floor onto one continuous arc-length profile and groups
// dense passage samples into coarse tile candidates.
inline constexpr std::uint32_t WorldAssemblyEvaluatorVersion = 223;
// dense passage samples into coarse tile candidates. Version 224 keeps the same
// continuous floor while relaxing the spline chord tolerance and bounding shell work.
inline constexpr std::uint32_t WorldAssemblyEvaluatorVersion = 224;
enum class FieldChannel : std::uint32_t
{
+68 -41
View File
@@ -4605,7 +4605,7 @@ private:
const double qPerMetre=Q*1000000.0/
std::max<std::uint32_t>(1,ResolvedLayout->coreVoxelSizeMicrometres);
constexpr double PassageSegmentSpacingMetres=8.0;
constexpr double PassageSegmentChordErrorMetres=0.025;
constexpr double PassageSegmentChordErrorMetres=0.100;
std::size_t preparedSegments=0,controlSpans=0;
for(std::size_t passageIndex=0;passageIndex<ResolvedLayout->passages.size();
++passageIndex)
@@ -11441,6 +11441,9 @@ inline void FStandaloneShapeWorld::FScopedPassageTileQueries::prepareSweptTubeBa
constexpr double OpenAirSideWallHeightMetres=1.0;
if(!shape_||step<=0||cells<=0||!std::isfinite(passageCarveReachMetres_)
||std::abs(passageCarveReachMetres_-InfluenceMetres)>1.0e-9)return;
const bool profile=profileStats_!=nullptr;
const auto prepareStart=profile?std::chrono::steady_clock::now()
:std::chrono::steady_clock::time_point{};
auto sweep=std::make_shared<FPassageTileSweepData>();
sweep->gridMinimumSubvoxels={
@@ -11463,7 +11466,6 @@ inline void FStandaloneShapeWorld::FScopedPassageTileQueries::prepareSweptTubeBa
constexpr double MouthShellBlendMetres=5.0;
const double wallReliefShell=0.41*qPerMetre;
const double floorDetailShell=1.0*qPerMetre;
const bool profile=profileStats_!=nullptr;
if(profile)
{
profileStats_->passageSweepRouteSegmentCandidates=routeSegmentCandidateCount_;
@@ -11550,8 +11552,6 @@ inline void FStandaloneShapeWorld::FScopedPassageTileQueries::prepareSweptTubeBa
FStandaloneShapeWorld::PassageFlatFloorCenterZSubvoxels(
constants,segments,segmentIndex,floorT,segment,
qx,qy,floorDepth,qPerMetre);
const double flatDistance=FStandaloneShapeWorld::PassageFlatBottomDistance(
static_cast<float>(signedDistance),floorCenterZ,qz,floorDepth,qPerMetre);
if(profile)++profileStats_->passageSweepSegmentSamplePairs;
if(signedDistance>sweep->influenceSubvoxels)
{
@@ -11572,51 +11572,75 @@ inline void FStandaloneShapeWorld::FScopedPassageTileQueries::prepareSweptTubeBa
sample.floorSegmentIndex=static_cast<std::uint32_t>(
segmentIndex);
}
const double alongMetres=segment.authoredAlongMetres
+t*segment.authoredLengthMetres;
const double mouthDistanceMetres=std::max(0.0,std::min(alongMetres,
constants.totalPathLengthMetres-alongMetres));
const double shellFade=std::clamp(mouthDistanceMetres/
MouthShellBlendMetres,0.0,1.0);
const double smoothShellFade=shellFade*shellFade
*(3.0-2.0*shellFade);
const double floorDistanceMetres=(floorCenterZ-floorDepth-qz)/qPerMetre;
const double floorBlend=std::clamp(floorDistanceMetres/0.25,0.0,1.0);
const double smoothFloorBlend=floorBlend*floorBlend
*(3.0-2.0*floorBlend);
const double wallElevationMetres=(qz-(floorCenterZ-floorDepth))
/qPerMetre;
const double mouthWallThickness=segment.routeSegment
?smoothShellFade*shellThickness:0.0;
double floorExtensionFade=1.0;
if(!segment.routeSegment)
// A negative shell distance is possible only when the flattened tube
// distance lies in [0, shellThickness]. SmoothMaxDistance is at least
// max(roundDistance, floorDistance) and can raise that maximum by no
// more than cornerWidth/6. Skip its work for pairs outside this exact
// support, with a small subvoxel guard for float rounding. The final
// shell union only consumes negative distances.
constexpr double CornerBlendMetres=0.50;
const float roundDistanceFloat=static_cast<float>(signedDistance);
const float floorDistanceFloat=static_cast<float>(floorCenterZ-floorDepth-qz);
const double flatDistanceLowerBound=std::max(
static_cast<double>(roundDistanceFloat),
static_cast<double>(floorDistanceFloat));
const double cornerWidth=static_cast<double>(static_cast<float>(
CornerBlendMetres*qPerMetre));
const bool shellSupportPossible=flatDistanceLowerBound
>=-cornerWidth/6.0-1.0
&&flatDistanceLowerBound<=shellThickness+1.0;
if(shellSupportPossible)
{
const double pastMouthMetres=std::max(0.0,alongMetres
-constants.totalPathLengthMetres);
const double extensionFade=std::clamp(1.0
-pastMouthMetres/MouthShellBlendMetres,0.0,1.0);
floorExtensionFade=extensionFade*extensionFade
*(3.0-2.0*extensionFade);
const double flatDistance=FStandaloneShapeWorld::PassageFlatBottomDistance(
roundDistanceFloat,floorCenterZ,qz,floorDepth,qPerMetre);
const double alongMetres=segment.authoredAlongMetres
+t*segment.authoredLengthMetres;
const double mouthDistanceMetres=std::max(0.0,std::min(alongMetres,
constants.totalPathLengthMetres-alongMetres));
const double shellFade=std::clamp(mouthDistanceMetres/
MouthShellBlendMetres,0.0,1.0);
const double smoothShellFade=shellFade*shellFade
*(3.0-2.0*shellFade);
const double floorDistanceMetres=(floorCenterZ-floorDepth-qz)/qPerMetre;
const double floorBlend=std::clamp(floorDistanceMetres/0.25,0.0,1.0);
const double smoothFloorBlend=floorBlend*floorBlend
*(3.0-2.0*floorBlend);
const double wallElevationMetres=(qz-(floorCenterZ-floorDepth))
/qPerMetre;
const double mouthWallThickness=segment.routeSegment
?smoothShellFade*shellThickness:0.0;
double floorExtensionFade=1.0;
if(!segment.routeSegment)
{
const double pastMouthMetres=std::max(0.0,alongMetres
-constants.totalPathLengthMetres);
const double extensionFade=std::clamp(1.0
-pastMouthMetres/MouthShellBlendMetres,0.0,1.0);
floorExtensionFade=extensionFade*extensionFade
*(3.0-2.0*extensionFade);
}
const double floorShellThickness=smoothFloorBlend*shellThickness
*floorExtensionFade*smoothShellFade;
const double wallShellDistance=
FStandaloneShapeWorld::PassageRoundedWallShellDistance(
flatDistance,wallElevationMetres*qPerMetre,
OpenAirSideWallHeightMetres*qPerMetre,mouthWallThickness);
const double floorShellDistance=std::max(
-static_cast<double>(flatDistance),
static_cast<double>(flatDistance)-floorShellThickness);
const double localShellDistance=std::min(wallShellDistance,
floorShellDistance);
sample.shellSignedDistance=std::min(sample.shellSignedDistance,
localShellDistance);
}
const double floorShellThickness=smoothFloorBlend*shellThickness
*floorExtensionFade*smoothShellFade;
const double wallShellDistance=
FStandaloneShapeWorld::PassageRoundedWallShellDistance(
flatDistance,wallElevationMetres*qPerMetre,
OpenAirSideWallHeightMetres*qPerMetre,mouthWallThickness);
const double floorShellDistance=std::max(-static_cast<double>(flatDistance),
static_cast<double>(flatDistance)-floorShellThickness);
const double localShellDistance=std::min(wallShellDistance,
floorShellDistance);
sample.shellSignedDistance=std::min(sample.shellSignedDistance,
localShellDistance);
else if(profile)
++profileStats_->passageSweepShellSupportSkips;
// Rank the tube body by round SDF. Its floor plane is selected
// independently above from the nearest centerline position.
if(!sample.valid||signedDistance<sample.roundSignedDistance
||(signedDistance==sample.roundSignedDistance
&&segmentIndex<sample.segmentIndex))
{
sample.signedDistance=flatDistance;
sample.roundSignedDistance=signedDistance;
sample.centerZSubvoxels=cz;
sample.radiusSubvoxels=radius;
@@ -11686,6 +11710,9 @@ inline void FStandaloneShapeWorld::FScopedPassageTileQueries::prepareSweptTubeBa
profileStats_->passageSweepNoInfluenceGridSamples=
static_cast<std::uint64_t>(std::count(anyPassageInfluence.begin(),
anyPassageInfluence.end(),static_cast<std::uint8_t>(0)));
profileStats_->passageSweepPrepareNanoseconds+=static_cast<std::uint64_t>(
std::max<std::int64_t>(0,std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::steady_clock::now()-prepareStart).count()));
}
passageSweepData_=std::move(sweep);
}