BuildPassageSpatialIndices adds the 4.335 m reach in core-voxel units, so the broadphase reaches ~1.08 m while the sweep cutoff says 4 m. Physically-correct 2 m bounds are larger than v225's and 4.9-9.9% slower; captures at all L125 poses pixel-identical. Patch kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
175 lines
13 KiB
Diff
175 lines
13 KiB
Diff
diff --git a/Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h b/Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h
|
||
index dc4ca32..aac34ff 100644
|
||
--- a/Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h
|
||
+++ b/Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h
|
||
@@ -494,7 +494,8 @@ namespace VoxelForgeCore
|
||
// Version 223 projects the floor onto one continuous arc-length profile and groups
|
||
// 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 = 225;
|
||
+ // Version 226 bounds smooth-passage influence in physical metres and narrows its reach.
|
||
+ inline constexpr std::uint32_t WorldAssemblyEvaluatorVersion = 226;
|
||
|
||
enum class FieldChannel : std::uint32_t
|
||
{
|
||
diff --git a/Standalone/Core/src/ShapeWorldInternal.h b/Standalone/Core/src/ShapeWorldInternal.h
|
||
index 517f375..dc258a1 100644
|
||
--- a/Standalone/Core/src/ShapeWorldInternal.h
|
||
+++ b/Standalone/Core/src/ShapeWorldInternal.h
|
||
@@ -72,11 +72,11 @@ static bool VF_IsL98PassagePrepareTraceEnabled()
|
||
return bEnabled;
|
||
}
|
||
|
||
-static double VF_L93PassageCarveReachMetres()
|
||
+static double VF_L129PassageCarveReachMetres()
|
||
{
|
||
- // The generated world uses a fixed bounded tube influence. An explicit diagnostic
|
||
- // option can still select the legacy point-evaluation path for comparisons.
|
||
- return 4.0;
|
||
+ // Keep the sweep cutoff and its spatial bounds on one physical reach. Diagnostic
|
||
+ // comparisons can still select another bounded reach or the point-evaluation path.
|
||
+ return 2.0;
|
||
}
|
||
|
||
enum class EPassageDensityQueryCaller : std::size_t
|
||
@@ -306,7 +306,7 @@ public:
|
||
profileStats_(profileStats),profileLod_(profileLod),
|
||
passageCarveReachMetres_(std::isfinite(passageCarveReachMetres)
|
||
&&passageCarveReachMetres>=0.0?passageCarveReachMetres
|
||
- :VF_L93PassageCarveReachMetres())
|
||
+ :VF_L129PassageCarveReachMetres())
|
||
{
|
||
mayContainResolvedBoundaryBand_=shape.ResolvedBoundaryBandsIntersectSubvoxelRange(
|
||
minimumSubvoxels_[2],maximumSubvoxels_[2]);
|
||
@@ -4813,11 +4813,14 @@ private:
|
||
constexpr double Q=static_cast<double>(VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
|
||
constexpr double PassageShellMetres=0.75;
|
||
constexpr double ReliefMetres=0.21;
|
||
- constexpr double SweepReachMetres=4.0;
|
||
+ const double SweepReachMetres=VF_L129PassageCarveReachMetres();
|
||
constexpr double CornerBlendMetres=0.50;
|
||
constexpr std::size_t CandidateFineSamplesPerSpan=5;
|
||
+ const double qPerMetre=Q*1000000.0/
|
||
+ std::max<std::uint32_t>(1,ResolvedLayout->coreVoxelSizeMicrometres);
|
||
const double requiredReach=std::max(SweepReachMetres+ReliefMetres
|
||
+CornerBlendMetres*0.25,PassageShellMetres+ReliefMetres);
|
||
+ const double requiredReachCoreVoxels=requiredReach*qPerMetre/Q;
|
||
for(std::size_t passageIndex=0;passageIndex<ResolvedLayout->passages.size();
|
||
++passageIndex)
|
||
{
|
||
@@ -4854,7 +4857,7 @@ private:
|
||
routeMinimum[axis]=std::min(routeMinimum[axis],localMinimum[axis]);
|
||
routeMaximum[axis]=std::max(routeMaximum[axis],localMaximum[axis]);
|
||
}
|
||
- const double localExtent=requiredReach
|
||
+ const double localExtent=requiredReachCoreVoxels
|
||
+std::max(prepared.radiusA,prepared.radiusB)/Q+0.01;
|
||
FPassageProofBound proof;
|
||
for(std::size_t axis=0;axis<3;++axis)
|
||
@@ -4872,7 +4875,8 @@ private:
|
||
std::ceil((localMaximum[axis]+localExtent)*Q));
|
||
}
|
||
}
|
||
- const double routeExtent=maximumRadiusSubvoxels/Q+requiredReach+0.01;
|
||
+ const double routeExtent=maximumRadiusSubvoxels/Q
|
||
+ +requiredReachCoreVoxels+0.01;
|
||
const double tileExtent=routeExtent;
|
||
std::array<std::int64_t,3> featureMinimum{},featureMaximum{};
|
||
for(std::size_t axis=0;axis<3;++axis)
|
||
@@ -11442,7 +11446,7 @@ inline void FStandaloneShapeWorld::FScopedPassageTileQueries::prepareSweptTubeBa
|
||
const FIntVector& origin,std::int32_t step,std::int32_t cells,std::uint32_t seed)
|
||
{
|
||
constexpr std::int64_t Q=VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel;
|
||
- constexpr double InfluenceMetres=4.0;
|
||
+ const double InfluenceMetres=VF_L129PassageCarveReachMetres();
|
||
constexpr double OpenAirSideWallHeightMetres=1.0;
|
||
if(!shape_||step<=0||cells<=0||!std::isfinite(passageCarveReachMetres_)
|
||
||std::abs(passageCarveReachMetres_-InfluenceMetres)>1.0e-9)return;
|
||
diff --git a/Standalone/Tools/verify/baselines/README.md b/Standalone/Tools/verify/baselines/README.md
|
||
index 45fbb9f..fc7a59a 100644
|
||
--- a/Standalone/Tools/verify/baselines/README.md
|
||
+++ b/Standalone/Tools/verify/baselines/README.md
|
||
@@ -4,7 +4,7 @@ These inputs are byte-for-byte copies of the historical files consumed by the
|
||
verification gates. The gates now read this tracked directory instead of
|
||
`Saved/Linux`, which is generated and is not present in a fresh checkout.
|
||
|
||
-- `owner-hash/`: L46, L52 and L53 diagnostics plus the pinned v212/v214 owner hash baselines.
|
||
+- `owner-hash/`: L46, L52 and L53 diagnostics plus the pinned v212/v214 and L129 v226 owner hash baselines.
|
||
- `historical-controls/`: L35, L36 and L38 regression-control logs.
|
||
- `fixtures/`: Linux25 owner JSON inputs and L33 style-override fixtures.
|
||
- `landmarks/`: L45–L48 landmark mesh and layout controls.
|
||
diff --git a/Standalone/Tools/verify/baselines/owner-hash/canonical/owner-hash-floating-islands-style2-v226.baseline b/Standalone/Tools/verify/baselines/owner-hash/canonical/owner-hash-floating-islands-style2-v226.baseline
|
||
new file mode 100644
|
||
index 0000000..9d3b87b
|
||
--- /dev/null
|
||
+++ b/Standalone/Tools/verify/baselines/owner-hash/canonical/owner-hash-floating-islands-style2-v226.baseline
|
||
@@ -0,0 +1,12 @@
|
||
+[PipelineFullDetailHash] tiles=960 density=0x91931a57a067fd92 mesh=0xa818654be89790ac payload=0x370ff80451105a39 topology=0x06e507557aa70173
|
||
+[PipelineWholeViewHash] tiles=2370 density=0x1573b570e1cbbf7e mesh=0xd88bf8bcf69ce1ce payload=0x347541780c9d8d71 topology=0x6b8ff8640be6e9d4
|
||
+[PipelineLODHash] lod=0 tiles=512 density=0x2fd4c78685a43cfe mesh=0x50478cff1c1f8ca0 payload=0x54e48e57e0af26de topology=0x860c011cfdb9833a
|
||
+[PipelineLODHash] lod=1 tiles=448 density=0x4b8d9a6dcd2942ad mesh=0x17e89b7087bfe711 payload=0x2389c109eb780db6 topology=0x7eccd4cf560d0630
|
||
+[PipelineLODHash] lod=2 tiles=320 density=0x600ce5633a8f9e83 mesh=0xcd40f163b4cf3e0e payload=0xbe81dc276737a33a topology=0x942806963fedb92d
|
||
+[PipelineLODHash] lod=3 tiles=208 density=0xf778be0581c49ed8 mesh=0x9aacf9e2a23034f8 payload=0xc1d4a985f2db3df5 topology=0xcdfdb412d3784023
|
||
+[PipelineLODHash] lod=4 tiles=240 density=0xfb11591772a3d18e mesh=0xebf2baee8764591b payload=0xe491d7ac9c0061ad topology=0xd618ac33b95ce494
|
||
+[PipelineLODHash] lod=5 tiles=144 density=0x2f8b7b7fb1e67258 mesh=0x4cd508cbe97344fd payload=0x2b6e96a6050458c9 topology=0x4ff6d0eda8988573
|
||
+[PipelineLODHash] lod=6 tiles=96 density=0x0114a34c8b8d6113 mesh=0xb1fec4d01ae1fa44 payload=0x3e50cfd429b8e950 topology=0x08090c96d15c1618
|
||
+[PipelineLODHash] lod=7 tiles=96 density=0x3836ed8cfce73418 mesh=0x40bc6589c5fc1aac payload=0x677349bcae16790f topology=0x36e3aa53192e6a6b
|
||
+[PipelineLODHash] lod=8 tiles=306 density=0x144f3c1fd722708b mesh=0xef77b28bf7fd9453 payload=0xe3f47b37fcd61489 topology=0x5a3c73e295494e04
|
||
+[PipelineExactQueryHash] probes=9 density=0x7b7c50ac24ccadcc unclamped=0x7b7c50ac24ccadcc detail=0xefcba20c0c70c415 collision=0xe604823a249029bf path=direct-Core-queries
|
||
diff --git a/Standalone/Tools/verify/baselines/owner-hash/canonical/owner-hash-owner4-surface-world-style1-v226.baseline b/Standalone/Tools/verify/baselines/owner-hash/canonical/owner-hash-owner4-surface-world-style1-v226.baseline
|
||
new file mode 100644
|
||
index 0000000..128c807
|
||
--- /dev/null
|
||
+++ b/Standalone/Tools/verify/baselines/owner-hash/canonical/owner-hash-owner4-surface-world-style1-v226.baseline
|
||
@@ -0,0 +1,12 @@
|
||
+[PipelineFullDetailHash] tiles=960 density=0xe1aa01ac806a84fb mesh=0x453624e695910639 payload=0x2f5793602ea13144 topology=0x31a43376cb129e55
|
||
+[PipelineWholeViewHash] tiles=2578 density=0xb82dc1dcdadda8ff mesh=0xe74e85bf3cb0909b payload=0x40bc3871dd9dccbe topology=0x855e712b549606c3
|
||
+[PipelineLODHash] lod=0 tiles=512 density=0x8119a4f12c4661f4 mesh=0xc074e3705293bef2 payload=0x36c965f6b43875ea topology=0x38bed0df168486d0
|
||
+[PipelineLODHash] lod=1 tiles=448 density=0x6270dd0856c53432 mesh=0xa803bb427deeba9a payload=0xf4718f1ce85d4f4f topology=0x7b770585aafd8174
|
||
+[PipelineLODHash] lod=2 tiles=320 density=0xf774df80811a61c1 mesh=0xb223f0f68d0310f8 payload=0x6c3fd8c4aa100ee9 topology=0x923485084c866600
|
||
+[PipelineLODHash] lod=3 tiles=272 density=0x62088ea9f38d2ed0 mesh=0x19bb327ba4ba3287 payload=0xd04c1223d50da0ea topology=0xf3817d1351cc89c5
|
||
+[PipelineLODHash] lod=4 tiles=272 density=0xb743eb64967bddcd mesh=0xf6b5bd36b0ebfead payload=0xd1284c1540f50636 topology=0x4a6e197e2a1a9500
|
||
+[PipelineLODHash] lod=5 tiles=208 density=0x38706b628a74dd17 mesh=0x445b1c7b51489cbb payload=0x713efc66290768f7 topology=0x56486b919146bb1e
|
||
+[PipelineLODHash] lod=6 tiles=144 density=0xd53849b2002a1faa mesh=0xaa210abc8498c415 payload=0xd109aef8639706d1 topology=0x61a4d75fbbc35268
|
||
+[PipelineLODHash] lod=7 tiles=96 density=0xb0ea9a140275c9cc mesh=0x3ffd8365c8b0ec29 payload=0x3577afb0a2e4a420 topology=0x97530aafde15b7e0
|
||
+[PipelineLODHash] lod=8 tiles=306 density=0x8b3d1816799d67a0 mesh=0x80bf554f17700e1e payload=0xccbe22c3333a9c34 topology=0xcb11b28f6b6bcc50
|
||
+[PipelineExactQueryHash] probes=9 density=0xf2df67b38b7802df unclamped=0x48b347986345b557 detail=0xefcba20c0c70c415 collision=0x137e8f6c0b03a624 path=direct-Core-queries
|
||
diff --git a/Standalone/Tools/verify/baselines/owner-hash/canonical/owner-hash-surface-world-style1-v226.baseline b/Standalone/Tools/verify/baselines/owner-hash/canonical/owner-hash-surface-world-style1-v226.baseline
|
||
new file mode 100644
|
||
index 0000000..49f85bb
|
||
--- /dev/null
|
||
+++ b/Standalone/Tools/verify/baselines/owner-hash/canonical/owner-hash-surface-world-style1-v226.baseline
|
||
@@ -0,0 +1,12 @@
|
||
+[PipelineFullDetailHash] tiles=960 density=0xace56c8f205238ad mesh=0xa9c603a1248de6b8 payload=0xea55f1f4fcc6a894 topology=0x5ea7bc78a1b678ae
|
||
+[PipelineWholeViewHash] tiles=2370 density=0x637fdf29ccba949b mesh=0xb02cf034b0c9e375 payload=0x74240706eac0c770 topology=0xe607e19fd4684210
|
||
+[PipelineLODHash] lod=0 tiles=512 density=0xcd6ab28cfa504aca mesh=0xf03dc80a669fca31 payload=0x397aded1c3d2d297 topology=0xb4a1dc84fabc1fe3
|
||
+[PipelineLODHash] lod=1 tiles=448 density=0xce6e713828b2a20a mesh=0x1cf408c25d67d18c payload=0x8a2b5d20571c997e topology=0x51cd985fe8e7d100
|
||
+[PipelineLODHash] lod=2 tiles=320 density=0x353ee7ab408a9da1 mesh=0x8d355a8d598d56d5 payload=0x458f26e32d815635 topology=0x2e89b3cba09efcfe
|
||
+[PipelineLODHash] lod=3 tiles=208 density=0xfe4f53b3ec010392 mesh=0xbd04d2da98d5b2e0 payload=0x10627f36d82200e8 topology=0xd625f3434ac0a893
|
||
+[PipelineLODHash] lod=4 tiles=240 density=0x0be8798407724eaf mesh=0x131c303cbbe51434 payload=0x2a90ecf0a2411ca0 topology=0xe3e054a371152e08
|
||
+[PipelineLODHash] lod=5 tiles=144 density=0xf20897ad272103a9 mesh=0x13d00b6253ae1f72 payload=0x0db3880693a962fa topology=0x462bd87a80f15e89
|
||
+[PipelineLODHash] lod=6 tiles=96 density=0xc040fcac457d6313 mesh=0x1ed132eeb718fb62 payload=0xcd0214e35577c6e3 topology=0x2c56c69e6fdcfd64
|
||
+[PipelineLODHash] lod=7 tiles=96 density=0xc2d419446355fdb8 mesh=0x4ea44452574fc84b payload=0xfd9779bedfc9ae0f topology=0x8948546e770c9b72
|
||
+[PipelineLODHash] lod=8 tiles=306 density=0x62db31696f2da831 mesh=0xd373f9e9481532fe payload=0x540a60526e0e3e46 topology=0xc725cb901e6dc335
|
||
+[PipelineExactQueryHash] probes=9 density=0xc949c4df2ce6f9d9 unclamped=0xc949c4df2ce6f9d9 detail=0x114c501e2d830d94 collision=0xe6011d3a248d4849 path=direct-Core-queries
|
||
diff --git a/Standalone/Tools/verify/verify.py b/Standalone/Tools/verify/verify.py
|
||
index 5fc1584..70f6a69 100644
|
||
--- a/Standalone/Tools/verify/verify.py
|
||
+++ b/Standalone/Tools/verify/verify.py
|
||
@@ -122,11 +122,11 @@ RECIPE_RE = re.compile(
|
||
|
||
def owner_hash_baseline(recipe: str, style: int) -> tuple[Path, str]:
|
||
if recipe == "surface-world" and style == 1:
|
||
- return (BASELINES / "owner-hash/canonical/owner-hash-surface-world-style1-v225.baseline",
|
||
- "L125-v225-stamped-passage-sweep")
|
||
+ return (BASELINES / "owner-hash/canonical/owner-hash-surface-world-style1-v226.baseline",
|
||
+ "L129-v226-physical-passage-reach")
|
||
if recipe == "floating-islands" and style == 2:
|
||
- return (BASELINES / "owner-hash/canonical/owner-hash-floating-islands-style2-v225.baseline",
|
||
- "L125-v225-stamped-passage-sweep")
|
||
+ return (BASELINES / "owner-hash/canonical/owner-hash-floating-islands-style2-v226.baseline",
|
||
+ "L129-v226-physical-passage-reach")
|
||
raise VerificationFailure(f"no pinned owner hash baseline for {recipe} style {style}")
|
||
|
||
|