proto: liminal pass 2 - hills to the horizon, swept road over a cloud floor, pillar grid (L142)

Captures stream LOD0-8 (hills repeat at 80 m to the horizon). Road: cubic swept solid deck, 376.8 m, 8 m wide, max
12.06 deg, 17 supports, cloud floor ~45 m below; walk audit 0 blocked/unsupported, 300 m negative control fails as
expected. 15x15 identical pillar grid at 76 m. Owner canonical hashes unchanged; fast tier, Clang/GCC green.

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-11-01 09:31:56 +01:00
1 parent 9c6d261d01
commit 6cd9e4da76
17 files changed
+1129 -98

No files matched your search

+58 -15
View File
@@ -1882,8 +1882,11 @@ int main(int argc,char** argv)
ownerJsonRoot.Get("motif_family_override").Data);
const bool hasLiminalRoad=!std::holds_alternative<std::nullptr_t>(
ownerJsonRoot.Get("liminal_road_override").Data);
if(hasMotifFamily&&hasLiminalRoad)
{std::fprintf(stderr,"motif_family_override and liminal_road_override cannot be combined\n");return 2;}
const bool hasLiminalPillarGrid=!std::holds_alternative<std::nullptr_t>(
ownerJsonRoot.Get("liminal_pillar_grid_override").Data);
if((hasMotifFamily&&hasLiminalRoad)||(hasMotifFamily&&hasLiminalPillarGrid)
||(hasLiminalRoad&&hasLiminalPillarGrid))
{std::fprintf(stderr,"liminal content overrides must be used in separate fixtures\n");return 2;}
if(hasMotifFamily)
{
std::vector<VoxelForgeCore::ResolvedLayoutStampRequestV1> requests;
@@ -1914,22 +1917,62 @@ int main(int argc,char** argv)
}
if(hasLiminalRoad)
{
std::vector<VoxelForgeCore::ResolvedLayoutStampRequestV1> requests(1);
if(!StandaloneWorldAssemblyPrototype::BuildLiminalRoadRequest(ownerJsonRoot,
*ownerWorld,worldAssembly,resolvedLayout,requests.front(),error)
std::vector<VoxelForgeCore::ResolvedLayoutStampRequestV1> requests;
if(!StandaloneWorldAssemblyPrototype::BuildLiminalRoadRequests(ownerJsonRoot,
*ownerWorld,worldAssembly,resolvedLayout,requests,error)
||!VoxelForgeCore::ResolveResolvedLayoutStampsV1(
resolvedLayout,seed,requests,error))
{std::fprintf(stderr,"Liminal road resolution failed: %s\n",error.c_str());return 2;}
const auto& road=resolvedLayout.stamps.front();
std::printf("[LiminalRoadResolved] vocabulary=%u id=%s strate=%d shape=rounded_dais "
"center_m=(%.3f,%.3f,%.3f) top_m=%.3f span_m=%.3f width_m=%.3f "
"grade_deg=0.000 placement=free route_keepout=PASS band_clearance=PASS status=PASS\n",
resolvedLayout.stampVocabularyVersion,road.stableId.c_str(),road.strateIndex,
road.positionMicrometres[0]/1.0e6,road.positionMicrometres[1]/1.0e6,
road.positionMicrometres[2]/1.0e6,
(road.positionMicrometres[2]+road.halfExtentsMicrometres[2])/1.0e6,
2.0*road.halfExtentsMicrometres[0]/1.0e6,
2.0*road.halfExtentsMicrometres[1]/1.0e6);
std::vector<const VoxelForgeCore::ResolvedLayoutStampV1*> deck;
std::size_t supportCount=0;
const std::string deckPrefix="liminal/road-clouds-v2/deck/";
const std::string supportPrefix="liminal/road-clouds-v2/support/";
for(const auto& stamp:resolvedLayout.stamps)
{
if(stamp.stableId.starts_with(deckPrefix))deck.push_back(&stamp);
else if(stamp.stableId.starts_with(supportPrefix))++supportCount;
}
std::sort(deck.begin(),deck.end(),[](const auto* a,const auto* b)
{return a->stableId<b->stableId;});
double pathLength=0.0,maxGradeDegrees=0.0;
for(std::size_t i=0;i<deck.size();++i)
{
const auto* segment=deck[i];
const double dx=(segment->sweepEndpointsMicrometres[1][0]
-segment->sweepEndpointsMicrometres[0][0])/1.0e6;
const double dy=(segment->sweepEndpointsMicrometres[1][1]
-segment->sweepEndpointsMicrometres[0][1])/1.0e6;
const double dz=std::abs(segment->sweepEndpointsMicrometres[1][2]
-segment->sweepEndpointsMicrometres[0][2])/1.0e6;
const double horizontal=std::hypot(dx,dy);
pathLength+=horizontal;
maxGradeDegrees=std::max(maxGradeDegrees,
std::atan2(dz,horizontal)*57.29577951308232);
}
const double width=deck.empty()?0.0:
2.0*deck.front()->halfExtentsMicrometres[1]/1.0e6;
std::printf("[LiminalRoadResolved] vocabulary=%u id=liminal/road-clouds-v2 "
"strate=%d shape=swept_deck_segments deck_segments=%zu supports=%zu "
"path_length_m=%.3f width_m=%.3f grade_max_deg=%.3f "
"placement=free route_keepout=PASS band_clearance=PASS status=%s\n",
resolvedLayout.stampVocabularyVersion,
deck.empty()?-1:deck.front()->strateIndex,deck.size(),supportCount,pathLength,
width,maxGradeDegrees,deck.size()>1&&pathLength>=300.0&&width>=3.0
&&maxGradeDegrees<=15.0?"PASS":"FAIL");
if(deck.size()<2||pathLength<80.0||width<3.0||maxGradeDegrees>15.0)
{std::fprintf(stderr,"Liminal road resolved outside the walkable road bounds\n");return 2;}
}
if(hasLiminalPillarGrid)
{
std::vector<VoxelForgeCore::ResolvedLayoutStampRequestV1> requests;
if(!StandaloneWorldAssemblyPrototype::BuildLiminalPillarGridRequests(ownerJsonRoot,
*ownerWorld,worldAssembly,resolvedLayout,requests,error)
||!VoxelForgeCore::ResolveResolvedLayoutStampsV1(
resolvedLayout,seed,requests,error))
{std::fprintf(stderr,"Liminal pillar-grid resolution failed: %s\n",error.c_str());return 2;}
std::printf("[LiminalPillarGridResolved] vocabulary=%u pillars=%zu shape=identical_vertical_cylinders "
"placement=regular_grid route_keepout=PASS band_clearance=PASS status=PASS\n",
resolvedLayout.stampVocabularyVersion,resolvedLayout.stamps.size());
}
if(options.LandmarkChamberDemo)
{
+99 -30
View File
@@ -2966,53 +2966,122 @@ namespace StandaloneStreamBenchmark
{
bool found=false;
bool passed=true;
std::vector<const VoxelForgeCore::ResolvedLayoutStampV1*> deck;
constexpr std::string_view DeckPrefix="liminal/road-clouds-v2/deck/";
for(const auto& road:ResolvedLayout->stamps)
{
if(road.stableId!="liminal/raised-road-v1")continue;
if(road.stableId.starts_with(DeckPrefix))deck.push_back(&road);
}
if(!deck.empty())
{
found=true;
const bool longAxisX=(road.yawQuarterTurns&1u)==0;
const double centerX=road.positionMicrometres[0]/1.0e6;
const double centerY=road.positionMicrometres[1]/1.0e6;
const double centerZ=road.positionMicrometres[2]/1.0e6;
const double halfLength=road.halfExtentsMicrometres[longAxisX?0:1]/1.0e6;
const double halfWidth=road.halfExtentsMicrometres[longAxisX?1:0]/1.0e6;
const double deckZ=centerZ+road.halfExtentsMicrometres[2]/1.0e6;
constexpr double CapsuleRadiusMetres=0.34;
std::sort(deck.begin(),deck.end(),[](const auto* a,const auto* b)
{return a->stableId<b->stableId;});
constexpr double CapsuleHeightMetres=1.76;
constexpr double HalfCapsuleHeightMetres=CapsuleHeightMetres*0.5;
constexpr double EndInsetMetres=1.0;
constexpr double SlopeCapsuleClearanceMetres=0.12;
std::vector<std::array<double,3>> roadPath;
const double inset=std::min(EndInsetMetres,halfLength*0.25);
for(const double along:{-halfLength+inset,halfLength-inset})
roadPath.push_back({(centerX+(longAxisX?along:0.0))/coreMetres,
(centerY+(longAxisX?0.0:along))/coreMetres,
(deckZ+HalfCapsuleHeightMetres)/coreMetres});
roadPath.reserve(deck.size()*4);
std::vector<std::array<double,3>> centerline;
centerline.reserve(deck.size()+1);
bool surfacePathValid=true;
for(std::size_t i=0;i<deck.size();++i)
{
const auto* segment=deck[i];
if(segment->kind!=VoxelForgeCore::ResolvedSdfStampKindV1::fillSweptDeckSegment)
surfacePathValid=false;
const auto point=[&](std::size_t endpoint)
{return std::array<double,3>{
segment->sweepEndpointsMicrometres[endpoint][0]/1.0e6,
segment->sweepEndpointsMicrometres[endpoint][1]/1.0e6,
segment->sweepEndpointsMicrometres[endpoint][2]/1.0e6};};
const auto a=point(0),b=point(1);
if(i==0)centerline.push_back(a);
else if(std::abs(centerline.back()[0]-a[0])>1.0e-6
||std::abs(centerline.back()[1]-a[1])>1.0e-6
||std::abs(centerline.back()[2]-a[2])>1.0e-6)
surfacePathValid=false;
centerline.push_back(b);
}
double pathLengthMetres=0.0,maxGradeDegrees=0.0;
std::uint64_t surfaceProbes=0,surfaceMisses=0;
const auto surfaceTopAt=[&](double xMetres,double yMetres,
double nominalTop,double& surfaceTop)
{
++surfaceProbes;
double low=nominalTop-0.25,high=nominalTop+1.0;
if(Shape.densityAt({xMetres/coreMetres,yMetres/coreMetres,
low/coreMetres})>=0.0f
||Shape.densityAt({xMetres/coreMetres,yMetres/coreMetres,
high/coreMetres})<0.0f)
{++surfaceMisses;return false;}
for(int iteration=0;iteration<20;++iteration)
{
const double middle=(low+high)*0.5;
if(Shape.densityAt({xMetres/coreMetres,yMetres/coreMetres,
middle/coreMetres})<0.0f)low=middle;
else high=middle;
}
surfaceTop=high;
return true;
};
const double halfThickness=deck.front()->halfExtentsMicrometres[2]/1.0e6;
for(std::size_t segment=1;segment<centerline.size();++segment)
{
const auto& a=centerline[segment-1];const auto& b=centerline[segment];
const double dx=b[0]-a[0],dy=b[1]-a[1];
const double horizontal=std::hypot(dx,dy);
pathLengthMetres+=horizontal;
const std::uint64_t intervals=std::max<std::uint64_t>(1,
static_cast<std::uint64_t>(std::ceil(horizontal/0.5)));
for(std::uint64_t step=0;step<=intervals;++step)
{
if(segment>1&&step==0)continue;
const double t=static_cast<double>(step)/intervals;
const double x=a[0]+dx*t,y=a[1]+dy*t;
const double nominalTop=a[2]+(b[2]-a[2])*t+halfThickness;
double actualTop=nominalTop;
if(!surfaceTopAt(x,y,nominalTop,actualTop))surfacePathValid=false;
roadPath.push_back({x/coreMetres,y/coreMetres,
(actualTop+HalfCapsuleHeightMetres
+SlopeCapsuleClearanceMetres)/coreMetres});
}
}
for(std::size_t i=1;i<roadPath.size();++i)
{
const double dx=(roadPath[i][0]-roadPath[i-1][0])*coreMetres;
const double dy=(roadPath[i][1]-roadPath[i-1][1])*coreMetres;
const double dz=std::abs(roadPath[i][2]-roadPath[i-1][2])*coreMetres;
const double horizontal=std::hypot(dx,dy);
maxGradeDegrees=std::max(maxGradeDegrees,
std::atan2(dz,horizontal)*57.29577951308232);
}
const FWalkAudit roadAudit=auditPlayerPath(Shape,roadPath,
0.125,0.125,1.125,3,0.45);
const double widthMetres=2.0*halfWidth;
const double horizontal=std::hypot(roadPath[1][0]-roadPath[0][0],
roadPath[1][1]-roadPath[0][1])*coreMetres;
const double vertical=std::abs(roadPath[1][2]-roadPath[0][2])*coreMetres;
const double gradeDegrees=std::atan2(vertical,horizontal)*
57.29577951308232;
passed=road.kind==VoxelForgeCore::ResolvedSdfStampKindV1::fillDais
&&widthMetres>=2.0*CapsuleRadiusMetres
&&gradeDegrees<=15.0&&roadAudit.passed;
std::printf("[LiminalRoadWalkAudit] id=%s stations=%llu capsule_samples=%llu "
const double widthMetres=2.0*deck.front()->halfExtentsMicrometres[1]/1.0e6;
passed=std::all_of(deck.begin(),deck.end(),[](const auto* road)
{return road->kind==VoxelForgeCore::ResolvedSdfStampKindV1::fillSweptDeckSegment;})
&&pathLengthMetres>=300.0&&widthMetres>=3.0
&&maxGradeDegrees<=15.0&&surfacePathValid&&roadAudit.passed;
std::printf("[LiminalRoadWalkAudit] id=liminal/road-clouds-v2 "
"deck_stamps=%zu path_length_m=%.3f stations=%llu capsule_samples=%llu "
"blocked=%llu support_samples=%llu unsupported=%llu grade_failures=%llu "
"width_m=%.3f capsule_diameter_m=%.3f grade_deg=%.3f grade_limit_deg=15.000 "
"status=%s\n",road.stableId.c_str(),
"surface_probes=%llu surface_misses=%llu width_m=%.3f minimum_width_m=3.000 "
"max_grade_deg=%.3f grade_limit_deg=15.000 status=%s\n",
deck.size(),pathLengthMetres,
static_cast<unsigned long long>(roadAudit.centers),
static_cast<unsigned long long>(roadAudit.capsuleSamples),
static_cast<unsigned long long>(roadAudit.blocked),
static_cast<unsigned long long>(roadAudit.supportSamples),
static_cast<unsigned long long>(roadAudit.unsupported),
static_cast<unsigned long long>(roadAudit.gradeFailures),widthMetres,
2.0*CapsuleRadiusMetres,gradeDegrees,passed?"PASS":"FAIL");
static_cast<unsigned long long>(roadAudit.gradeFailures),
static_cast<unsigned long long>(surfaceProbes),
static_cast<unsigned long long>(surfaceMisses),widthMetres,
maxGradeDegrees,passed?"PASS":"FAIL");
}
if(!found&&required)
{
std::printf("[LiminalRoadWalkAudit] status=FAIL reason=road_stamp_missing\n");
std::printf("[LiminalRoadWalkAudit] status=FAIL reason=road_path_missing\n");
return false;
}
return passed;
+213 -31
View File
@@ -587,13 +587,15 @@ namespace StandaloneWorldAssemblyPrototype
return true;
}
inline bool BuildLiminalRoadRequest(const VFJson::Value& root,
inline bool BuildLiminalRoadRequests(const VFJson::Value& root,
const FStandaloneOwnerWorld& owner,
const VoxelForgeCore::WorldAssemblyManifest& assembly,
const VoxelForgeCore::ResolvedLayoutSnapshotV3& layout,
VoxelForgeCore::ResolvedLayoutStampRequestV1& request,std::string& error)
std::vector<VoxelForgeCore::ResolvedLayoutStampRequestV1>& requests,
std::string& error)
{
using namespace VoxelForgeCore;
requests.clear();
const VFJson::Value& overrideValue=root.Get("liminal_road_override");
if(!overrideValue.IsObject())
{error="liminal_road_override must be an object";return false;}
@@ -604,49 +606,229 @@ namespace StandaloneWorldAssemblyPrototype
const VFJson::Value& strateValue=overrideValue.Get("strate_index");
const auto* id=std::get_if<std::string>(&overrideValue.Get("stable_id").Data);
const auto& position=overrideValue.Get("position_xy_m").AsArray();
const auto& extents=overrideValue.Get("half_extents_m").AsArray();
const VFJson::Value& heightValue=overrideValue.Get("deck_height_above_field_m");
const VFJson::Value& yawValue=overrideValue.Get("yaw_quarter_turns");
if(!strateValue.IsNumber()||!id||id->empty()||position.size()!=2||extents.size()!=3
||!heightValue.IsNumber()||!std::isfinite(heightValue.Number())
||!yawValue.IsNumber()||yawValue.Integer()<0||yawValue.Integer()>3)
{error="liminal road requires stable_id, strate_index, position, extents, deck height and yaw";return false;}
const auto& position=overrideValue.Get("start_xy_m").AsArray();
const auto readNumber=[&](const char* key,double fallback,double& result)
{
const VFJson::Value& value=overrideValue.Get(key);
if(std::holds_alternative<std::nullptr_t>(value.Data))
{result=fallback;return true;}
if(!value.IsNumber()||!std::isfinite(value.Number()))return false;
result=value.Number();return true;
};
double pathLength=0.0,curveControl=0.0,deckHeight=0.0,riseControl=0.0;
double halfWidth=0.0,halfThickness=0.0,sampleSpacing=0.0;
double supportSpacing=0.0,supportRadius=0.0;
if(!strateValue.IsNumber()||!id||id->empty()||position.size()!=2
||!readNumber("path_length_m",360.0,pathLength)
||!readNumber("curve_control_offset_m",84.0,curveControl)
||!readNumber("deck_height_above_field_m",44.0,deckHeight)
||!readNumber("rise_control_m",22.0,riseControl)
||!readNumber("half_width_m",3.2,halfWidth)
||!readNumber("half_thickness_m",0.65,halfThickness)
||!readNumber("sample_spacing_m",1.0,sampleSpacing)
||!readNumber("support_spacing_m",24.0,supportSpacing)
||!readNumber("support_radius_m",0.55,supportRadius))
{error="liminal road requires a valid identity, start, and finite path parameters";return false;}
for(const auto& value:position)
if(!value.IsNumber()||!std::isfinite(value.Number()))
{error="liminal road position_xy_m must contain finite metre values";return false;}
for(const auto& value:extents)
if(!value.IsNumber()||!std::isfinite(value.Number())
||value.Number()<0.5||value.Number()>100.0)
{error="liminal road half_extents_m must contain values from 0.5 to 100 metres";return false;}
if(heightValue.Number()<1.0||heightValue.Number()>100.0)
{error="liminal road deck height must be from 1 to 100 metres above the field";return false;}
{error="liminal road start_xy_m must contain finite metre values";return false;}
if(std::abs(position[0].Number())>5000.0||std::abs(position[1].Number())>5000.0
||pathLength<80.0||pathLength>1000.0||curveControl<0.0||curveControl>200.0
||deckHeight<30.0||deckHeight>60.0||riseControl<0.0||riseControl>30.0
||halfWidth<1.5||halfWidth>10.0||halfThickness<0.5||halfThickness>3.0
||sampleSpacing<1.0||sampleSpacing>6.0
||supportSpacing<8.0||supportSpacing>60.0
||supportRadius<0.5||supportRadius>1.5)
{error="liminal road dimensions are outside the bounded walkable-road ranges";return false;}
const auto strateIndex=static_cast<std::int32_t>(strateValue.Integer());
const auto strate=std::find_if(layout.strates.begin(),layout.strates.end(),
[strateIndex](const auto& value){return value.strateIndex==strateIndex
&&value.generatorKind=="SurfaceWorld";});
if(strate==layout.strates.end())
{error="liminal_road_override must select a resolved SurfaceWorld strate";return false;}
if(extents[0].Number()<10.0||extents[1].Number()<0.75
||extents[0].Number()<=extents[1].Number()*4.0)
{error="liminal road must be long and narrow, with at least 1.5 metres half-width";return false;}
const auto metresToMicrometres=[](double value)
{return static_cast<std::int64_t>(std::llround(value*1000000.0));};
const std::int64_t fieldFloorMicrometres=static_cast<std::int64_t>(std::llround(
static_cast<double>(assembly.recipe.surfaceProfile.h0Subvoxels)
*owner.CoreVoxelSizeMicrons/WorldAssemblySubvoxelsPerVoxel));
request={};
request.stableId=*id;
request.strateIndex=strateIndex;
request.kind=ResolvedSdfStampKindV1::fillDais;
request.anchorPositionMicrometres={metresToMicrometres(position[0].Number()),
metresToMicrometres(position[1].Number()),
fieldFloorMicrometres+metresToMicrometres(heightValue.Number())
-metresToMicrometres(extents[2].Number())};
request.halfExtentsMicrometres={metresToMicrometres(extents[0].Number()),
metresToMicrometres(extents[1].Number()),metresToMicrometres(extents[2].Number())};
request.yawQuarterTurns=static_cast<std::uint8_t>(yawValue.Integer());
const std::int64_t startX=metresToMicrometres(position[0].Number());
const std::int64_t startY=metresToMicrometres(position[1].Number());
const std::int64_t lengthUm=metresToMicrometres(pathLength);
const std::int64_t lateralUm=metresToMicrometres(curveControl);
const std::int64_t deckBaseUm=fieldFloorMicrometres+metresToMicrometres(deckHeight);
const std::int64_t riseUm=metresToMicrometres(riseControl);
const std::int64_t halfWidthUm=metresToMicrometres(halfWidth);
const std::int64_t halfThicknessUm=metresToMicrometres(halfThickness);
const std::uint32_t steps=static_cast<std::uint32_t>(std::ceil(pathLength/sampleSpacing));
const auto lerpInteger=[steps](std::int64_t a,std::int64_t b,std::uint32_t i)
{
const std::int64_t numerator=(b-a)*static_cast<std::int64_t>(i);
const std::int64_t rounded=numerator>=0
?numerator+static_cast<std::int64_t>(steps/2)
:numerator-static_cast<std::int64_t>(steps/2);
return a+rounded/static_cast<std::int64_t>(steps);
};
const auto bezier=[&](const std::array<std::int64_t,4>& controls,std::uint32_t i)
{
const std::int64_t a=lerpInteger(controls[0],controls[1],i);
const std::int64_t b=lerpInteger(controls[1],controls[2],i);
const std::int64_t c=lerpInteger(controls[2],controls[3],i);
const std::int64_t d=lerpInteger(a,b,i);
const std::int64_t e=lerpInteger(b,c,i);
return lerpInteger(d,e,i);
};
const std::array<std::int64_t,4> xControls={startX,
startX+lengthUm/3,startX+(2*lengthUm)/3,startX+lengthUm};
const std::array<std::int64_t,4> yControls={startY,startY+lateralUm,
startY-lateralUm,startY};
const std::array<std::int64_t,4> zControls={deckBaseUm,deckBaseUm+riseUm,
deckBaseUm-riseUm,deckBaseUm};
std::vector<std::array<std::int64_t,3>> path;
path.reserve(static_cast<std::size_t>(steps)+1);
const auto halfUp=[](std::int64_t numerator,std::int64_t denominator)
{return (numerator>=0?numerator+denominator/2:numerator-denominator/2)/denominator;};
for(std::uint32_t i=0;i<=steps;++i)
{
const auto t=static_cast<std::int64_t>(i);
const auto n=static_cast<std::int64_t>(steps);
path.push_back({xControls[0]+halfUp(lengthUm*t,n),
bezier(yControls,i),bezier(zControls,i)});
}
const auto makeStamp=[&](std::string stableId,ResolvedSdfStampKindV1 kind,
const std::array<std::int64_t,3>& positionUm,
const std::array<std::int64_t,3>& halfExtentsUm,std::int64_t smoothWidthUm)
{
ResolvedLayoutStampRequestV1 request;
request.stableId=std::move(stableId);request.strateIndex=strateIndex;
request.kind=kind;request.anchorPositionMicrometres=positionUm;
request.halfExtentsMicrometres=halfExtentsUm;
request.smoothWidthMicrometres=smoothWidthUm;
requests.push_back(std::move(request));
};
const std::int64_t deckSmoothUm=250000;
const std::int64_t segmentOverlapUm=350000;
for(std::uint32_t i=1;i<path.size();++i)
{
const auto& a=path[i-1];const auto& b=path[i];
const double dx=static_cast<double>(b[0]-a[0]);
const double dy=static_cast<double>(b[1]-a[1]);
const double dz=static_cast<double>(b[2]-a[2]);
const std::int64_t halfLengthUm=static_cast<std::int64_t>(std::ceil(
std::sqrt(dx*dx+dy*dy+dz*dz)*0.5))+segmentOverlapUm;
ResolvedLayoutStampRequestV1 request;
request.stableId=*id+"/deck/"+std::to_string(10000+i-1).substr(1);
request.strateIndex=strateIndex;
request.kind=ResolvedSdfStampKindV1::fillSweptDeckSegment;
request.anchorPositionMicrometres={
(a[0]+b[0])/2,(a[1]+b[1])/2,(a[2]+b[2])/2};
request.sweepEndpointsMicrometres={a,b};
request.halfExtentsMicrometres={halfLengthUm,halfWidthUm,halfThicknessUm};
request.smoothWidthMicrometres=deckSmoothUm;
requests.push_back(std::move(request));
}
const std::int64_t supportBaseUm=fieldFloorMicrometres-2000000;
const std::int64_t supportRadiusUm=metresToMicrometres(supportRadius);
double distanceSinceSupport=supportSpacing;
std::uint32_t supportIndex=0;
for(std::uint32_t i=0;i<path.size();++i)
{
if(i>0)
{
const auto& a=path[i-1];const auto& b=path[i];
const double dx=static_cast<double>(b[0]-a[0]);
const double dy=static_cast<double>(b[1]-a[1]);
distanceSinceSupport+=std::hypot(dx,dy)/1000000.0;
}
if(i!=0&&i+1!=path.size()&&distanceSinceSupport<supportSpacing)continue;
const std::int64_t supportTopUm=path[i][2]-halfThicknessUm+50000;
const std::int64_t supportHalfHeightUm=(supportTopUm-supportBaseUm)/2;
const std::int64_t supportCenterUm=(supportTopUm+supportBaseUm)/2;
if(supportHalfHeightUm<500000)
{error="liminal road support is too short to resolve safely";requests.clear();return false;}
makeStamp(*id+"/support/"+std::to_string(10000+supportIndex).substr(1),
ResolvedSdfStampKindV1::fillPillar,
{path[i][0],path[i][1],supportCenterUm},
{supportRadiusUm,supportRadiusUm,supportHalfHeightUm},100000);
++supportIndex;distanceSinceSupport=0.0;
}
return true;
}
inline bool BuildLiminalPillarGridRequests(const VFJson::Value& root,
const FStandaloneOwnerWorld& owner,
const VoxelForgeCore::WorldAssemblyManifest& assembly,
const VoxelForgeCore::ResolvedLayoutSnapshotV3& layout,
std::vector<VoxelForgeCore::ResolvedLayoutStampRequestV1>& requests,
std::string& error)
{
using namespace VoxelForgeCore;
requests.clear();
const VFJson::Value& overrideValue=root.Get("liminal_pillar_grid_override");
if(!overrideValue.IsObject())
{error="liminal_pillar_grid_override must be an object";return false;}
if(assembly.recipe.surfaceProfile.version!=1
||assembly.recipe.surfaceProfile.kind!=WorldAssemblySurfaceProfileKindV1::flatField
||owner.CoreVoxelSizeMicrons==0)
{error="the liminal pillar grid requires a valid flatField SurfaceWorld recipe";return false;}
const auto* id=std::get_if<std::string>(&overrideValue.Get("stable_id").Data);
const VFJson::Value& strateValue=overrideValue.Get("strate_index");
const auto& center=overrideValue.Get("center_xy_m").AsArray();
const auto readNumber=[&](const char* key,double fallback,double& result)
{
const VFJson::Value& value=overrideValue.Get(key);
if(std::holds_alternative<std::nullptr_t>(value.Data))
{result=fallback;return true;}
if(!value.IsNumber()||!std::isfinite(value.Number()))return false;
result=value.Number();return true;
};
double spacing=0.0,radius=0.0,height=0.0;
const VFJson::Value& rowsValue=overrideValue.Get("rows");
const VFJson::Value& columnsValue=overrideValue.Get("columns");
if(!id||id->empty()||!strateValue.IsNumber()||center.size()!=2
||!readNumber("spacing_m",76.0,spacing)
||!readNumber("radius_m",4.0,radius)
||!readNumber("height_m",28.0,height)
||!rowsValue.IsNumber()||!columnsValue.IsNumber())
{error="liminal pillar grid requires an identity, center, dimensions and counts";return false;}
for(const auto& value:center)
if(!value.IsNumber()||!std::isfinite(value.Number()))
{error="liminal pillar grid center_xy_m must contain finite metre values";return false;}
const int rows=static_cast<int>(rowsValue.Integer());
const int columns=static_cast<int>(columnsValue.Integer());
if(rows<3||rows>15||columns<3||columns>15||spacing<32.0||spacing>120.0
||radius<2.0||radius>12.0||height<12.0||height>60.0
||std::abs(center[0].Number())>5000.0||std::abs(center[1].Number())>5000)
{error="liminal pillar grid dimensions are outside their bounded ranges";return false;}
const auto strateIndex=static_cast<std::int32_t>(strateValue.Integer());
const auto strate=std::find_if(layout.strates.begin(),layout.strates.end(),
[strateIndex](const auto& value){return value.strateIndex==strateIndex
&&value.generatorKind=="SurfaceWorld";});
if(strate==layout.strates.end())
{error="liminal_pillar_grid_override must select a resolved SurfaceWorld strate";return false;}
const auto toMicrometres=[](double value)
{return static_cast<std::int64_t>(std::llround(value*1000000.0));};
const std::int64_t floorUm=static_cast<std::int64_t>(std::llround(
static_cast<double>(assembly.recipe.surfaceProfile.h0Subvoxels)
*owner.CoreVoxelSizeMicrons/WorldAssemblySubvoxelsPerVoxel));
const std::int64_t spacingUm=toMicrometres(spacing);
const std::int64_t radiusUm=toMicrometres(radius);
const std::int64_t halfHeightUm=toMicrometres(height*0.5);
const int rowStart=-(rows/2),columnStart=-(columns/2);
for(int row=0;row<rows;++row)
for(int column=0;column<columns;++column)
{
ResolvedLayoutStampRequestV1 request;
request.stableId=*id+"/pillar/"+std::to_string(1000+row*columns+column).substr(1);
request.strateIndex=strateIndex;
request.kind=ResolvedSdfStampKindV1::fillPillar;
request.anchorPositionMicrometres={
toMicrometres(center[0].Number())+(columnStart+column)*spacingUm,
toMicrometres(center[1].Number())+(rowStart+row)*spacingUm,
floorUm+halfHeightUm};
request.halfExtentsMicrometres={radiusUm,radiusUm,halfHeightUm};
requests.push_back(std::move(request));
}
return true;
}