wip: L174 Design50 steps 0-2 in progress (interrupted for a power cut)
Audits collect gates and run seams (landing discs + end runs, LOD0/1), tagged uncapped failures, separate exempt counts, self-overlap census; level end runs; overlap/turn constraints. Partial sweep: end runs pass 3/3 per seed; 1-2 end-turn violations per seed; 50-110k tagged seam mismatches per seed (real vs audit artefact not yet decided). Not verified; resume L174. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
1 parent
b09728354d
commit
dee53c8d2a
9 files changed
+2155
-257
No files matched your search
@@ -327,6 +327,9 @@ namespace VoxelForgeCore
|
||||
// boundary-face bit mask (bit order: -X,+X,-Y,+Y,-Z,+Z).
|
||||
std::vector<std::uint8_t> skirtFaceMasks;
|
||||
std::vector<float> debugDensitySamples;
|
||||
std::array<std::int32_t,3> debugDensityOriginVoxels{};
|
||||
std::array<std::int32_t,3> debugDensityDimensions{};
|
||||
std::int32_t debugDensityStepVoxels = 0;
|
||||
MeshGroups groups;
|
||||
TileGenerationStats diagnostics;
|
||||
std::uint64_t densitySampleCount = 0;
|
||||
@@ -512,7 +515,8 @@ namespace VoxelForgeCore
|
||||
// boundary-blended host rock from widening the authored passage wall.
|
||||
// v238 plans one resolved passage spline with explicit landing chambers.
|
||||
// v239 plans their floor planes as the passage's continuous floor profile.
|
||||
inline constexpr std::uint32_t WorldAssemblyEvaluatorVersion = 239;
|
||||
// v240 adds level end runs and rejects passage tube overlaps and hairpins.
|
||||
inline constexpr std::uint32_t WorldAssemblyEvaluatorVersion = 240;
|
||||
|
||||
enum class FieldChannel : std::uint32_t
|
||||
{
|
||||
@@ -1336,6 +1340,69 @@ namespace VoxelForgeCore
|
||||
std::int64_t clearHeightSubvoxels = 0;
|
||||
};
|
||||
|
||||
inline std::int64_t ResolvedLayoutPassageLandingDiscRadiusSubvoxels(
|
||||
std::int64_t mouthRadiusSubvoxels,
|
||||
std::uint32_t coreVoxelSizeMicrometres) noexcept
|
||||
{
|
||||
if(coreVoxelSizeMicrometres==0)return 0;
|
||||
const std::int64_t qPerMetre=static_cast<std::int64_t>(std::llround(
|
||||
static_cast<double>(WorldAssemblySubvoxelsPerVoxel)*1000000.0
|
||||
/coreVoxelSizeMicrometres));
|
||||
return std::max<std::int64_t>(3*qPerMetre,
|
||||
mouthRadiusSubvoxels+qPerMetre);
|
||||
}
|
||||
|
||||
inline bool IsInsideResolvedLayoutPassageLandingDiscV1(
|
||||
const std::array<std::int64_t,2>& centerSubvoxels,
|
||||
std::int64_t radiusSubvoxels,double xSubvoxels,double ySubvoxels) noexcept
|
||||
{
|
||||
if(radiusSubvoxels<=0)return false;
|
||||
const double dx=xSubvoxels-static_cast<double>(centerSubvoxels[0]);
|
||||
const double dy=ySubvoxels-static_cast<double>(centerSubvoxels[1]);
|
||||
const double radius=static_cast<double>(radiusSubvoxels);
|
||||
return dx*dx+dy*dy<=radius*radius;
|
||||
}
|
||||
|
||||
inline bool IsInsideResolvedLayoutPassageLandingRimV1(
|
||||
const std::array<std::int64_t,2>& centerSubvoxels,
|
||||
std::int64_t radiusSubvoxels,std::int64_t halfWidthSubvoxels,
|
||||
double xSubvoxels,double ySubvoxels) noexcept
|
||||
{
|
||||
if(radiusSubvoxels<=0||halfWidthSubvoxels<0)return false;
|
||||
const double dx=xSubvoxels-static_cast<double>(centerSubvoxels[0]);
|
||||
const double dy=ySubvoxels-static_cast<double>(centerSubvoxels[1]);
|
||||
return std::abs(std::hypot(dx,dy)-static_cast<double>(radiusSubvoxels))
|
||||
<=static_cast<double>(halfWidthSubvoxels);
|
||||
}
|
||||
|
||||
// Shared landing-volume predicate for planners, the passage composer, and audits.
|
||||
// Query coordinates use the same world subvoxel units as the resolved passage.
|
||||
inline double ResolvedLayoutPassageLandingFloorAtXYSubvoxels(
|
||||
const ResolvedLayoutPassageLandingChamberV1& chamber,
|
||||
double xSubvoxels,double ySubvoxels) noexcept
|
||||
{
|
||||
return static_cast<double>(chamber.floorCenterSubvoxels[2])
|
||||
+static_cast<double>(chamber.floorGradientQ16[0])/65536.0
|
||||
*(xSubvoxels-static_cast<double>(chamber.floorCenterSubvoxels[0]))
|
||||
+static_cast<double>(chamber.floorGradientQ16[1])/65536.0
|
||||
*(ySubvoxels-static_cast<double>(chamber.floorCenterSubvoxels[1]));
|
||||
}
|
||||
|
||||
inline bool IsInsideResolvedLayoutPassageLandingChamberV1(
|
||||
const ResolvedLayoutPassageLandingChamberV1& chamber,
|
||||
double xSubvoxels,double ySubvoxels,double zSubvoxels) noexcept
|
||||
{
|
||||
if(chamber.radiusSubvoxels<=0||chamber.clearHeightSubvoxels<=0)return false;
|
||||
const double dx=xSubvoxels-static_cast<double>(chamber.floorCenterSubvoxels[0]);
|
||||
const double dy=ySubvoxels-static_cast<double>(chamber.floorCenterSubvoxels[1]);
|
||||
const double radius=static_cast<double>(chamber.radiusSubvoxels);
|
||||
const double floor=ResolvedLayoutPassageLandingFloorAtXYSubvoxels(
|
||||
chamber,xSubvoxels,ySubvoxels);
|
||||
return dx*dx+dy*dy<=radius*radius
|
||||
&&zSubvoxels>=floor
|
||||
&&zSubvoxels<=floor+static_cast<double>(chamber.clearHeightSubvoxels);
|
||||
}
|
||||
|
||||
struct ResolvedLayoutPassageV1
|
||||
{
|
||||
std::string stableId;
|
||||
@@ -1348,6 +1415,8 @@ namespace VoxelForgeCore
|
||||
std::array<std::int64_t, 3> lowerMouthSubvoxels{};
|
||||
std::int64_t mouthRadiusSubvoxels = 0;
|
||||
std::int64_t midRadiusSubvoxels = 0;
|
||||
// Planned flat distance from each landing, at least R+1 m.
|
||||
std::int64_t endRunSubvoxels = 0;
|
||||
// Derived from the mouth binding; the main descent is monotone through this point.
|
||||
std::size_t lowerMouthControlIndex = 0;
|
||||
ResolvedLayoutPassageLandingChamberV1 upperLandingChamber;
|
||||
@@ -1380,6 +1449,47 @@ namespace VoxelForgeCore
|
||||
std::int64_t cascadeLedgeSubvoxels = 0;
|
||||
};
|
||||
|
||||
struct ResolvedLayoutPassageSelfOverlapAuditV1
|
||||
{
|
||||
std::uint64_t segmentPairs = 0;
|
||||
std::uint64_t measuredSegmentPairs = 0;
|
||||
std::uint64_t localExemptSegmentPairs = 0;
|
||||
std::uint64_t overlappingSegmentPairs = 0;
|
||||
std::uint64_t firstOverlapSegmentA = 0;
|
||||
std::uint64_t firstOverlapSegmentB = 0;
|
||||
std::uint64_t firstLandingColumnSegment = 0;
|
||||
bool firstLandingColumnIsLower = false;
|
||||
std::uint64_t landingColumnViolations = 0;
|
||||
double maximumEndTurnDegrees = 0.0;
|
||||
std::uint32_t endTurnViolations = 0;
|
||||
double minimumClearanceMetres = 0.0;
|
||||
bool hasOverlapLocation = false;
|
||||
bool hasMeasuredCoverage = false;
|
||||
bool passed = false;
|
||||
};
|
||||
VFCORE_API ResolvedLayoutPassageSelfOverlapAuditV1
|
||||
AuditResolvedLayoutPassageSelfOverlapV1(
|
||||
const ResolvedLayoutPassageV1& passage,
|
||||
std::uint32_t coreVoxelSizeMicrometres);
|
||||
|
||||
struct ResolvedLayoutPassageEndRunAuditV1
|
||||
{
|
||||
double requiredEndRunMetres = 0.0;
|
||||
double measuredStartMetres = 0.0;
|
||||
double measuredEndMetres = 0.0;
|
||||
double startMaximumFloorDeviationMetres = 0.0;
|
||||
double endMaximumFloorDeviationMetres = 0.0;
|
||||
double startMaximumGradeDegrees = 0.0;
|
||||
double endMaximumGradeDegrees = 0.0;
|
||||
bool hasMeasuredCoverage = false;
|
||||
bool passed = false;
|
||||
};
|
||||
VFCORE_API ResolvedLayoutPassageEndRunAuditV1
|
||||
AuditResolvedLayoutPassageEndRunsV1(
|
||||
const ResolvedLayoutPassageV1& passage,
|
||||
std::uint32_t coreVoxelSizeMicrometres,
|
||||
std::int64_t endRunSubvoxels = 0);
|
||||
|
||||
struct VFCORE_API ResolvedLayoutSnapshotV3
|
||||
{
|
||||
std::uint32_t schemaVersion = ResolvedLayoutSchemaVersionV3;
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -2890,6 +2890,7 @@ namespace VoxelForgeCore
|
||||
const auto MarchingCubesStart=std::chrono::steady_clock::now();
|
||||
FVoxelUniformBlockProofAuditStats BlockProofAudit;
|
||||
FVoxelMeshData mesh;
|
||||
FIntVector DebugDensityOrigin,DebugDensityDimensions;
|
||||
{
|
||||
FStandaloneShapeWorld::FScopedStampSamplingStep stampSamplingStep(MeshStep);
|
||||
mesh=mesher.GenerateMesh(origin,MeshStep,MeshCells,nullptr,
|
||||
@@ -2897,7 +2898,9 @@ namespace VoxelForgeCore
|
||||
(options.hashDensity||options.captureDensitySamples)?&densityValues:nullptr,
|
||||
options.profileMesherStages?&McStageTimings:nullptr,
|
||||
options.auditUniformBlockProofs?&BlockProofAudit:nullptr,
|
||||
options.forceFullDensityCapture);
|
||||
options.forceFullDensityCapture,
|
||||
options.captureDensitySamples?&DebugDensityOrigin:nullptr,
|
||||
options.captureDensitySamples?&DebugDensityDimensions:nullptr);
|
||||
}
|
||||
passageFeatureScope.copySweptTubeRuntimeCounts();
|
||||
if(options.auditUniformBlockProofs)
|
||||
@@ -3222,7 +3225,15 @@ namespace VoxelForgeCore
|
||||
std::chrono::steady_clock::now()-materialQueryStart).count():0.0;
|
||||
out.indices.reserve(static_cast<std::size_t>(mesh.Triangles.Num()));
|
||||
for(const int32 index:mesh.Triangles)out.indices.push_back(static_cast<std::uint32_t>(index));
|
||||
if(options.captureDensitySamples)out.debugDensitySamples=std::move(densityValues);
|
||||
if(options.captureDensitySamples)
|
||||
{
|
||||
out.debugDensitySamples=std::move(densityValues);
|
||||
out.debugDensityOriginVoxels={DebugDensityOrigin.X,DebugDensityOrigin.Y,
|
||||
DebugDensityOrigin.Z};
|
||||
out.debugDensityDimensions={DebugDensityDimensions.X,
|
||||
DebugDensityDimensions.Y,DebugDensityDimensions.Z};
|
||||
out.debugDensityStepVoxels=MeshStep;
|
||||
}
|
||||
if(options.hashDensity)
|
||||
{
|
||||
std::uint64_t densityHash=14695981039346656037ull;
|
||||
|
||||
Reference in new issue
Block a user