wip(assembler): round L23 -- inter-strate passages planned from the resolved layout and carved
After L22 the FI -> SW passage no longer connected the strates (legacy owner-voxel coordinates, lower end 23 m above SW), and Core never carved passages through the bands. Now the director plans passages from the resolved layout (PlanResolvedLayoutPassagesV1; deterministic hash of seed/strates/connection; placement disk from PassageConfig, 8-24 m around (0,0)); shared composition applies generator field -> bands -> bounded passage carve and support shelf, opening the bands only along the tunnel. Mouths bind to the strate routes. Capsule audit: 0 blocked / 0 unsupported (325,962 samples FI, 284,319 TunnelNetwork), negative controls detected; all 8 generator kinds exercised. SW away from the passage is bit-identical. Layout V3, evaluator 9. Open: look not yet natural (stepped tube in FI void, terraced SW arrival); SW-as-upper route planning fails; Unreal adapter uncompiled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
This commit is contained in:
1 parent
55c26a05a7
commit
71d09a8c52
14 files changed
+1465
-112
No files matched your search
@@ -991,7 +991,7 @@ bool AttachValidatedWorldAssembly(const UVoxelSettings* Settings,
|
||||
|
||||
// Keep the inspectable physical-layout export separate from the manifest identity: it is
|
||||
// assembled from the same resolved slots/plans, but adding it must not salt evaluation hashes.
|
||||
VoxelForgeCore::ResolvedLayoutSnapshotV2 Layout;
|
||||
VoxelForgeCore::ResolvedLayoutSnapshotV3 Layout;
|
||||
Layout.worldIdentity = std::string("owner-world/seed/")
|
||||
+ std::to_string(StrateManager->GetWorldSeed());
|
||||
Layout.ownerVoxelSizeMicrometres = static_cast<std::uint32_t>(std::llround(OwnerVoxelSizeCm * 10000.0));
|
||||
@@ -1029,9 +1029,27 @@ bool AttachValidatedWorldAssembly(const UVoxelSettings* Settings,
|
||||
return static_cast<std::int64_t>(std::llround(static_cast<double>(Fixed)
|
||||
* ExpectedCoreVoxelMicrons / VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel));
|
||||
};
|
||||
std::vector<VoxelForgeCore::ResolvedLayoutPassageConfigV1> PassageConfigs;
|
||||
for (const FStrateSlot& Slot : StrateManager->GetLayout())
|
||||
{
|
||||
if (Slot.Definition == nullptr) continue;
|
||||
const FStratePassageConfig& AuthoredPassage = Slot.Definition->PassageConfig;
|
||||
const auto OwnerVoxelsToCoreQ = [OwnerVoxelMicrons, ExpectedCoreVoxelMicrons](double Value)
|
||||
{
|
||||
return static_cast<std::int64_t>(std::llround(Value * OwnerVoxelMicrons
|
||||
* VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel / ExpectedCoreVoxelMicrons));
|
||||
};
|
||||
VoxelForgeCore::ResolvedLayoutPassageConfigV1 PassageConfig;
|
||||
PassageConfig.upperStrateIndex = Slot.StrateIndex;
|
||||
PassageConfig.connections = AuthoredPassage.Connections;
|
||||
PassageConfig.mouthRadiusSubvoxels = OwnerVoxelsToCoreQ(AuthoredPassage.MouthRadius);
|
||||
PassageConfig.midRadiusSubvoxels = OwnerVoxelsToCoreQ(AuthoredPassage.MidRadius);
|
||||
PassageConfig.reachMinimumSubvoxels = OwnerVoxelsToCoreQ(AuthoredPassage.ReachMin);
|
||||
PassageConfig.reachMaximumSubvoxels = OwnerVoxelsToCoreQ(AuthoredPassage.ReachMax);
|
||||
PassageConfig.distanceMinimumSubvoxels = OwnerVoxelsToCoreQ(AuthoredPassage.DistanceMin);
|
||||
PassageConfig.distanceMaximumSubvoxels = OwnerVoxelsToCoreQ(AuthoredPassage.DistanceMax);
|
||||
PassageConfig.wanderSubvoxels = OwnerVoxelsToCoreQ(AuthoredPassage.Wander);
|
||||
PassageConfigs.push_back(PassageConfig);
|
||||
const ECaveGeneratorType Type = StrateManager->GetGeneratorTypeForChunk(
|
||||
FIntVector(0, 0, Slot.TopChunkZ));
|
||||
VoxelForgeCore::ResolvedLayoutStratumV2 Item;
|
||||
@@ -1065,8 +1083,8 @@ bool AttachValidatedWorldAssembly(const UVoxelSettings* Settings,
|
||||
Item.managerLookup = "UVoxelStrateManager::GetGeneratorTypeForChunk; transition is controlled by upper strate";
|
||||
if (Type == ECaveGeneratorType::SurfaceWorld)
|
||||
{
|
||||
Item.boundDispatchPath = "BuildSurfaceStratumPlan uses resolved layout chunk width from ResolvedLayoutSnapshotV2";
|
||||
Item.queryDispatchPath = "NativeSurfaceDensityAt selects floor(CoreZ / resolved layout chunk width) from ResolvedLayoutSnapshotV2";
|
||||
Item.boundDispatchPath = "BuildSurfaceStratumPlan uses resolved layout chunk width from ResolvedLayoutSnapshotV3";
|
||||
Item.queryDispatchPath = "NativeSurfaceDensityAt selects floor(CoreZ / resolved layout chunk width) from ResolvedLayoutSnapshotV3";
|
||||
const auto Plan = std::find_if(Manifest->plan.strates.begin(), Manifest->plan.strates.end(),
|
||||
[&Slot](const auto& Entry) { return Entry.strateIndex == Slot.StrateIndex; });
|
||||
if (Plan != Manifest->plan.strates.end())
|
||||
@@ -1097,8 +1115,8 @@ bool AttachValidatedWorldAssembly(const UVoxelSettings* Settings,
|
||||
}
|
||||
else if (Type == ECaveGeneratorType::FloatingIslands)
|
||||
{
|
||||
Item.boundDispatchPath = "BuildFloatingIslandStratumPlan uses resolved layout chunk width from ResolvedLayoutSnapshotV2";
|
||||
Item.queryDispatchPath = "NativeFloatingIslandDensityAt selects floor(CoreZ / resolved layout chunk width) from ResolvedLayoutSnapshotV2";
|
||||
Item.boundDispatchPath = "BuildFloatingIslandStratumPlan uses resolved layout chunk width from ResolvedLayoutSnapshotV3";
|
||||
Item.queryDispatchPath = "NativeFloatingIslandDensityAt selects floor(CoreZ / resolved layout chunk width) from ResolvedLayoutSnapshotV3";
|
||||
const auto Plan = std::find_if(Manifest->floatingIslands.begin(), Manifest->floatingIslands.end(),
|
||||
[&Slot](const auto& Entry) { return Entry.strateIndex == Slot.StrateIndex; });
|
||||
std::int64_t SealMicrometres = 0;
|
||||
@@ -1117,11 +1135,21 @@ bool AttachValidatedWorldAssembly(const UVoxelSettings* Settings,
|
||||
Island.centerSubvoxels[2], Island.radiusSubvoxels, Island.topHalfSubvoxels };
|
||||
Item.anchors.push_back(std::move(Anchor));
|
||||
}
|
||||
for (std::size_t RouteIndex = 0; RouteIndex < Plan->manifest.plan.route.size(); ++RouteIndex)
|
||||
{
|
||||
const auto& Point = Plan->manifest.plan.route[RouteIndex];
|
||||
VoxelForgeCore::ResolvedLayoutAnchorV2 Anchor;
|
||||
Anchor.kind = "route_point"; Anchor.stableId = "route/" + std::to_string(RouteIndex);
|
||||
Anchor.units = "1/256 Core voxel";
|
||||
Anchor.values = { Point.positionSubvoxels[0], Point.positionSubvoxels[1],
|
||||
Point.positionSubvoxels[2], Point.radiusSubvoxels };
|
||||
Item.anchors.push_back(std::move(Anchor));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Item.boundDispatchPath = "resolved manager slot scaled by ResolvedLayoutSnapshotV2 chunk width";
|
||||
Item.boundDispatchPath = "resolved manager slot scaled by ResolvedLayoutSnapshotV3 chunk width";
|
||||
Item.queryDispatchPath = "legacy Core route selects manager chunk by floor(CoreZ / resolved layout chunk width)";
|
||||
}
|
||||
const std::int64_t SealMicrometres=static_cast<std::int64_t>(std::llround(
|
||||
@@ -1142,23 +1170,16 @@ bool AttachValidatedWorldAssembly(const UVoxelSettings* Settings,
|
||||
"none", "none" };
|
||||
Item.content.bottomMicrometres+=SealMicrometres;
|
||||
Item.content.topMicrometres-=SealMicrometres;
|
||||
for (std::size_t PassageIndex = 0; PassageIndex < StrateManager->GetPassages().Num(); ++PassageIndex)
|
||||
{
|
||||
const FVoxelPassage& Passage = StrateManager->GetPassages()[static_cast<int32>(PassageIndex)];
|
||||
if (Passage.UpperStrateIndex != Slot.StrateIndex && Passage.LowerStrateIndex != Slot.StrateIndex) continue;
|
||||
VoxelForgeCore::ResolvedLayoutAnchorV2 Anchor;
|
||||
Anchor.kind = "passage"; Anchor.stableId = "passage/" + std::to_string(PassageIndex);
|
||||
Anchor.units = "milli owner voxels";
|
||||
Anchor.values = { static_cast<std::int64_t>(std::llround(Passage.UpperPoint.X * 1000.0)),
|
||||
static_cast<std::int64_t>(std::llround(Passage.UpperPoint.Y * 1000.0)),
|
||||
static_cast<std::int64_t>(std::llround(Passage.UpperPoint.Z * 1000.0)),
|
||||
static_cast<std::int64_t>(std::llround(Passage.LowerPoint.X * 1000.0)),
|
||||
static_cast<std::int64_t>(std::llround(Passage.LowerPoint.Y * 1000.0)),
|
||||
static_cast<std::int64_t>(std::llround(Passage.LowerPoint.Z * 1000.0)) };
|
||||
Item.anchors.push_back(std::move(Anchor));
|
||||
}
|
||||
Layout.strates.push_back(std::move(Item));
|
||||
}
|
||||
std::string PassagePlanError;
|
||||
if (!VoxelForgeCore::PlanResolvedLayoutPassagesV1(Layout,
|
||||
StrateManager->GetWorldSeed(), PassageConfigs, PassagePlanError))
|
||||
{
|
||||
OutError = FString::Printf(TEXT("Resolved inter-strate passage planning failed: %s"),
|
||||
UTF8_TO_TCHAR(PassagePlanError.c_str()));
|
||||
return false;
|
||||
}
|
||||
std::string LayoutError;
|
||||
if (!Layout.finalize(LayoutError))
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user