wip(assembler): round L37 -- FI mouth carve-fade fix, no raised bridge (style 0); research R1
The passage mouth fade multiplied the signed carve distance by zero, which turned native rock into an open surface (the reason earlier rounds stamped walk pads at mouths); it now blends between the uncarved field and the full signed carve. The FI style-0 route followed a lifted grade envelope over the crater (the "bridge"); it now runs on the rim and follows the native surface. New built-shape and crease audits with thresholds frozen before the fix (L36 and box controls fail). 24/24 passage rows, 30/30 determinism, 16/16 invariants, 18/18 interface/ring. Unreal: one recipe setter (uncompiled). Research R1 (read-only, web): ranked proposals for natural walkable mouths, floor-limited carve first. 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
8be1c4d9ef
commit
3e443bf81c
33 files changed
+2767
-86
No files matched your search
@@ -221,6 +221,7 @@ namespace
|
||||
out<<"{\"stable_id\":"<<LayoutEscape(p.stableId)
|
||||
<<",\"upper_strate_index\":"<<p.upperStrateIndex
|
||||
<<",\"lower_strate_index\":"<<p.lowerStrateIndex
|
||||
<<",\"style\":"<<p.style
|
||||
<<",\"placement_radius_q\":"<<p.placementRadiusSubvoxels
|
||||
<<",\"upper_mouth_q\":["<<p.upperMouthSubvoxels[0]<<','
|
||||
<<p.upperMouthSubvoxels[1]<<','<<p.upperMouthSubvoxels[2]
|
||||
@@ -683,6 +684,8 @@ std::optional<ResolvedLayoutSnapshotV3> ResolvedLayoutSnapshotV3::FromJson(
|
||||
ResolvedLayoutPassageV1 p;p.stableId=LayoutString(v,"stable_id");
|
||||
p.upperStrateIndex=static_cast<std::int32_t>(LayoutInt(v,"upper_strate_index"));
|
||||
p.lowerStrateIndex=static_cast<std::int32_t>(LayoutInt(v,"lower_strate_index"));
|
||||
if(v.Get("style").IsNumber())
|
||||
p.style=static_cast<std::uint32_t>(LayoutInt(v,"style"));
|
||||
p.placementRadiusSubvoxels=LayoutInt(v,"placement_radius_q");
|
||||
p.mouthRadiusSubvoxels=LayoutInt(v,"mouth_radius_q");p.midRadiusSubvoxels=LayoutInt(v,"mid_radius_q");
|
||||
const auto& upper=v.Get("upper_mouth_q").AsArray();
|
||||
@@ -808,6 +811,7 @@ bool PlanResolvedLayoutPassagesV1(ResolvedLayoutSnapshotV3& layout,std::int32_t
|
||||
for(std::uint32_t connection=0;connection<connectionCount;++connection)
|
||||
{
|
||||
ResolvedLayoutPassageV1 passage;
|
||||
passage.style=style;
|
||||
passage.stableId="passage/"+std::to_string(upper.strateIndex)+"-"
|
||||
+std::to_string(lower.strateIndex)+"/"+std::to_string(connection);
|
||||
passage.upperStrateIndex=upper.strateIndex;passage.lowerStrateIndex=lower.strateIndex;
|
||||
@@ -886,22 +890,45 @@ bool PlanResolvedLayoutPassagesV1(ResolvedLayoutSnapshotV3& layout,std::int32_t
|
||||
std::max(ringRadius,clearRingRadius));
|
||||
}
|
||||
if(anchoredIslandPassage)
|
||||
ringRadius=std::min(ringRadius,mouthRadius+qPerMetre/2);
|
||||
{
|
||||
const std::int64_t craterRimRouteRadius=VoxelForgeCore::WorldAssemblyEvaluatorVersion>=185
|
||||
&&style==0&&!anchoredSpiral&&passageAnchor&&passageAnchor->values.size()>3
|
||||
?std::max<std::int64_t>(midRadius,
|
||||
passageAnchor->values[3]+2*qPerMetre)
|
||||
:mouthRadius+qPerMetre/2;
|
||||
ringRadius=std::min(ringRadius,anchoredSpiral
|
||||
?mouthRadius+qPerMetre/2:craterRimRouteRadius);
|
||||
}
|
||||
std::uint32_t phase=static_cast<std::uint32_t>(PassageSeed(seed,
|
||||
upper.strateIndex,lower.strateIndex,connection,0x50484153u)%16);
|
||||
if(hasUpperRoute)
|
||||
{
|
||||
std::int64_t bestAlignment=std::numeric_limits<std::int64_t>::min();
|
||||
const std::uint32_t hashedPhase=phase;
|
||||
const std::int64_t phaseX=style==0&&anchoredIslandPassage
|
||||
&&!anchoredSpiral&&passageAnchor
|
||||
?upperMouth[0]-passageAnchor->values[0]
|
||||
:(hasUpperTangent?upperTangent[0]:upperMouth[0]);
|
||||
const std::int64_t phaseY=style==0&&anchoredIslandPassage
|
||||
&&!anchoredSpiral&&passageAnchor
|
||||
?upperMouth[1]-passageAnchor->values[1]
|
||||
:(hasUpperTangent?upperTangent[1]:upperMouth[1]);
|
||||
for(std::uint32_t offset=0;offset<16;++offset)
|
||||
{
|
||||
const std::uint32_t candidate=static_cast<std::uint32_t>(
|
||||
(hashedPhase+offset)%16);
|
||||
const std::int64_t alignment=(hasUpperTangent?upperTangent[0]:upperMouth[0])
|
||||
*directions[candidate][0]
|
||||
+(hasUpperTangent?upperTangent[1]:upperMouth[1])
|
||||
*directions[candidate][1];
|
||||
if(alignment>bestAlignment)
|
||||
const std::int64_t alignment=phaseX*directions[candidate][0]
|
||||
+phaseY*directions[candidate][1];
|
||||
if(style==0&&anchoredIslandPassage&&!anchoredSpiral&&passageAnchor)
|
||||
{
|
||||
const std::int64_t targetProjection=ringRadius*65536;
|
||||
if(alignment<=0)continue;
|
||||
const std::int64_t tangentError=std::abs(alignment-targetProjection);
|
||||
if(tangentError<bestAlignment
|
||||
||bestAlignment==std::numeric_limits<std::int64_t>::min())
|
||||
{bestAlignment=tangentError;phase=candidate;}
|
||||
}
|
||||
else if(alignment>bestAlignment)
|
||||
{bestAlignment=alignment;phase=candidate;}
|
||||
}
|
||||
}
|
||||
@@ -924,7 +951,18 @@ bool PlanResolvedLayoutPassagesV1(ResolvedLayoutSnapshotV3& layout,std::int32_t
|
||||
}
|
||||
bool clockwise=(PassageSeed(seed,upper.strateIndex,lower.strateIndex,
|
||||
connection,0x44495245u)&1u)!=0;
|
||||
if(anchoredSpiral&&passageAnchor&&hasUpperTangent)
|
||||
if(style==0&&anchoredIslandPassage&&!anchoredSpiral&&passageAnchor)
|
||||
{
|
||||
const auto& ringDirection=directions[phase];
|
||||
const double radiusX=static_cast<double>(ringRadius)*ringDirection[0]/65536.0;
|
||||
const double radiusY=static_cast<double>(ringRadius)*ringDirection[1]/65536.0;
|
||||
const double anchorX=static_cast<double>(passageAnchor->values[0]);
|
||||
const double anchorY=static_cast<double>(passageAnchor->values[1]);
|
||||
const double connectorX=anchorX+radiusX-upperMouth[0];
|
||||
const double connectorY=anchorY+radiusY-upperMouth[1];
|
||||
clockwise=connectorX*(-radiusY)+connectorY*radiusX>=0.0;
|
||||
}
|
||||
else if(anchoredSpiral&&passageAnchor&&hasUpperTangent)
|
||||
{
|
||||
const double radialX=static_cast<double>(upperMouth[0]-passageAnchor->values[0]);
|
||||
const double radialY=static_cast<double>(upperMouth[1]-passageAnchor->values[1]);
|
||||
@@ -1068,7 +1106,8 @@ bool PlanResolvedLayoutPassagesV1(ResolvedLayoutSnapshotV3& layout,std::int32_t
|
||||
hasAnchorHelix=helixEndIndex>0;
|
||||
}
|
||||
const std::int64_t routeGradeQ16=hasAnchorHelix
|
||||
&&lower.generatorKind=="SurfaceWorld"?8000:TargetGradeQ16;
|
||||
&&lower.generatorKind=="SurfaceWorld"?8000
|
||||
:style==0&&anchoredIslandPassage&&!anchoredSpiral?15500:TargetGradeQ16;
|
||||
const std::array<std::int64_t,2> firstRing=ringPoint(phase);
|
||||
if(hasAnchorHelix&&pathStyle==1u)
|
||||
{
|
||||
@@ -1168,7 +1207,7 @@ bool PlanResolvedLayoutPassagesV1(ResolvedLayoutSnapshotV3& layout,std::int32_t
|
||||
pushXY(ringPoint(lowerPhase));
|
||||
}
|
||||
pushXY({lowerMouth[0],lowerMouth[1]});totalHorizontal=measurePath();
|
||||
const std::size_t lowerMouthIndex=xy.size()-1;
|
||||
std::size_t lowerMouthIndex=xy.size()-1;
|
||||
std::vector<std::array<std::int64_t,3>> lowerLandingPoints;
|
||||
if(hasLowerTangent)
|
||||
{
|
||||
@@ -1202,6 +1241,27 @@ bool PlanResolvedLayoutPassagesV1(ResolvedLayoutSnapshotV3& layout,std::int32_t
|
||||
if(lowerLandingPoints.empty())
|
||||
{error=passage.stableId+" lower route has no landing length inside PassageConfig.DistanceMax";return false;}
|
||||
}
|
||||
if(VoxelForgeCore::WorldAssemblyEvaluatorVersion>=188
|
||||
&&style==0&&anchoredIslandPassage&&!anchoredSpiral&&xy.size()>4)
|
||||
{
|
||||
std::vector<std::array<std::int64_t,2>> refined;
|
||||
refined.reserve(xy.size()*2);
|
||||
for(std::size_t index=0;index+1<xy.size();++index)
|
||||
{
|
||||
refined.push_back(xy[index]);
|
||||
if(index<3)continue;
|
||||
refined.push_back({
|
||||
static_cast<std::int64_t>(std::llround(0.5*(
|
||||
static_cast<double>(xy[index][0])
|
||||
+static_cast<double>(xy[index+1][0])))),
|
||||
static_cast<std::int64_t>(std::llround(0.5*(
|
||||
static_cast<double>(xy[index][1])
|
||||
+static_cast<double>(xy[index+1][1]))))});
|
||||
}
|
||||
refined.push_back(xy.back());
|
||||
if(lowerMouthIndex>3)lowerMouthIndex+=lowerMouthIndex-3;
|
||||
xy.swap(refined);
|
||||
}
|
||||
totalHorizontal=measurePath();
|
||||
if(loops>=256||totalHorizontal==0)
|
||||
{error=passage.stableId+" could not fit a supported grade inside the resolved placement radius";return false;}
|
||||
|
||||
Reference in new issue
Block a user