proto: first liminal fixtures - flat field + monolith, periodic hills, raised road in fog (L141)
Standalone only: fixtures, liminal_road_override (fillDais), --audit-liminal-road-walk, capture-only distance fog. Road 65 m x 6 m, 22 m up, capsule walk 127/127. Owner hashes unchanged (v227), fast tier, Clang/GCC green. Hills repeat every 80 m but the capture reaches 56 m, so only one rise shows. Also R48 (who owns the tunnel mouth): recommends a bounded joint plan of passage ports and layer landing candidates. 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
eb47d72258
commit
9c6d261d01
15 files changed
+823
-12
No files matched your search
@@ -592,6 +592,11 @@ uniform float uHeightCenter;
|
||||
uniform float uHeightRange;
|
||||
uniform float uTileEdgeWidth;
|
||||
uniform vec3 uLightDirection;
|
||||
uniform vec3 uCameraWorld;
|
||||
uniform vec3 uFogColor;
|
||||
uniform float uFogStart;
|
||||
uniform float uFogEnd;
|
||||
uniform int uFogEnabled;
|
||||
uniform int uHeadlamp;
|
||||
uniform int uGrazingLight;
|
||||
uniform int uClipEnabled;
|
||||
@@ -643,6 +648,11 @@ void main()
|
||||
color=mix(color,resourceColor/max(resourceWeight,0.001),
|
||||
clamp(resourceWeight,0.0,0.95))*illumination;
|
||||
}
|
||||
if(uFogEnabled!=0)
|
||||
{
|
||||
float fogT=smoothstep(uFogStart,uFogEnd,length(vWorldPosition-uCameraWorld));
|
||||
color=mix(color,uFogColor,fogT);
|
||||
}
|
||||
if(uTileEdges!=0&&vTileData.z>0.0)
|
||||
{
|
||||
vec2 local=mod(vWorldPosition.xy-vTileData.xy,vTileData.z);
|
||||
@@ -707,7 +717,8 @@ void main()
|
||||
bool HeightTint,bool Headlamp,bool TileEdges,
|
||||
double TileEdgeWidthMeters,bool HasLightDirection,
|
||||
const std::array<double,3>& LightDirection,bool ClipPlaneEnabled,
|
||||
const std::array<double,4>& ClipPlane)
|
||||
const std::array<double,4>& ClipPlane,bool FogEnabled,
|
||||
double FogStartMeters,double FogEndMeters,const std::array<double,3>& FogColor)
|
||||
{
|
||||
EGLDisplay Display=MakeDisplay();
|
||||
EGLint Major=0,Minor=0;
|
||||
@@ -796,7 +807,10 @@ void main()
|
||||
glViewport(0,0,Width,Height);glDisable(GL_CULL_FACE);glEnable(GL_DEPTH_TEST);
|
||||
// A covered empty ray represents open air. Keep it visibly blue so it cannot
|
||||
// be mistaken for the old near-black result from a scene that lacked tiles.
|
||||
glDepthFunc(GL_LEQUAL);glClearColor(0.30f,0.48f,0.62f,1.0f);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glClearColor(FogEnabled?static_cast<float>(FogColor[0]):0.30f,
|
||||
FogEnabled?static_cast<float>(FogColor[1]):0.48f,
|
||||
FogEnabled?static_cast<float>(FogColor[2]):0.62f,1.0f);
|
||||
glClearDepthf(1.0f);glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
glUseProgram(Program);
|
||||
glUniform1f(glGetUniformLocation(Program,"uTanHalfHorizontal"),static_cast<float>(TanHalfHorizontal));
|
||||
@@ -825,6 +839,18 @@ void main()
|
||||
static_cast<float>(ActiveLightDirection[0]),
|
||||
static_cast<float>(ActiveLightDirection[1]),
|
||||
static_cast<float>(ActiveLightDirection[2]));
|
||||
glUniform3f(glGetUniformLocation(Program,"uCameraWorld"),
|
||||
static_cast<float>(Scene.CameraMeters[0]),
|
||||
static_cast<float>(Scene.CameraMeters[1]),
|
||||
static_cast<float>(Scene.CameraMeters[2]));
|
||||
glUniform3f(glGetUniformLocation(Program,"uFogColor"),
|
||||
static_cast<float>(FogColor[0]),static_cast<float>(FogColor[1]),
|
||||
static_cast<float>(FogColor[2]));
|
||||
glUniform1f(glGetUniformLocation(Program,"uFogStart"),
|
||||
static_cast<float>(FogStartMeters));
|
||||
glUniform1f(glGetUniformLocation(Program,"uFogEnd"),
|
||||
static_cast<float>(FogEndMeters));
|
||||
glUniform1i(glGetUniformLocation(Program,"uFogEnabled"),FogEnabled?1:0);
|
||||
glDrawElements(GL_TRIANGLES,static_cast<GLsizei>(Scene.Indices.size()),GL_UNSIGNED_INT,nullptr);
|
||||
glFinish();
|
||||
std::vector<std::uint8_t> Pixels(static_cast<std::size_t>(Width)*Height*4);
|
||||
@@ -863,7 +889,7 @@ int main(int argc,char** argv)
|
||||
if(argc==2&&std::string_view(argv[1])=="--print-source-stamp")return 0;
|
||||
if(argc<3)
|
||||
{
|
||||
std::fprintf(stderr,"Usage: %s scene.vfmesh output.png [--size=WIDTHxHEIGHT] [--fov-deg=90] [--height-range-m=N] [--height-center-m=N] [--camera-m=X,Y,Z] [--yaw-deg=N] [--pitch-deg=N] [--shade=readable|normal] [--height-tint=on|off] [--headlamp=on|off] [--light-direction=X,Y,Z] [--tile-edges=on|off] [--tile-skirts=on|off] [--tile-edge-width-m=N] [--clip-plane=NX,NY,NZ,D] [--focus-region=X,Y,Z,R]\n",argv[0]);
|
||||
std::fprintf(stderr,"Usage: %s scene.vfmesh output.png [--size=WIDTHxHEIGHT] [--fov-deg=90] [--height-range-m=N] [--height-center-m=N] [--camera-m=X,Y,Z] [--yaw-deg=N] [--pitch-deg=N] [--shade=readable|normal] [--height-tint=on|off] [--headlamp=on|off] [--light-direction=X,Y,Z] [--fog=on|off] [--fog-start-m=N] [--fog-end-m=N] [--fog-color=R,G,B] [--tile-edges=on|off] [--tile-skirts=on|off] [--tile-edge-width-m=N] [--clip-plane=NX,NY,NZ,D] [--focus-region=X,Y,Z,R]\n",argv[0]);
|
||||
return 2;
|
||||
}
|
||||
int Width=2560,Height=1440;double Fov=90.0,HeightRangeMeters=64.0;
|
||||
@@ -871,6 +897,8 @@ int main(int argc,char** argv)
|
||||
bool HasYaw=false,HasPitch=false;double Yaw=0.0,Pitch=0.0;
|
||||
bool HasCamera=false;std::array<double,3> Camera{};
|
||||
bool HasLightDirection=false;std::array<double,3> LightDirection{};
|
||||
bool FogEnabled=false;double FogStartMeters=50.0,FogEndMeters=200.0;
|
||||
std::array<double,3> FogColor={0.62,0.70,0.75};
|
||||
bool ReadableMode=true,HeightTint=true,TileEdges=false,TileSkirts=true,Headlamp=false;
|
||||
double TileEdgeWidthMeters=0.15;
|
||||
bool ClipPlaneEnabled=false;std::array<double,4> ClipPlane{};
|
||||
@@ -967,6 +995,38 @@ int main(int argc,char** argv)
|
||||
{std::fprintf(stderr,"Invalid light direction; use X,Y,Z with non-zero length\n");return 2;}
|
||||
HasLightDirection=true;
|
||||
}
|
||||
else if(Arg.starts_with("--fog="))
|
||||
{
|
||||
const std::string_view Mode=Arg.substr(6);
|
||||
if(Mode=="on")FogEnabled=true;
|
||||
else if(Mode=="off")FogEnabled=false;
|
||||
else {std::fprintf(stderr,"Invalid fog mode\n");return 2;}
|
||||
}
|
||||
else if(Arg.starts_with("--fog-start-m="))
|
||||
{
|
||||
char* End=nullptr;const std::string Value(Arg.substr(14));
|
||||
FogStartMeters=std::strtod(Value.c_str(),&End);
|
||||
if(End==Value.c_str()||*End!='\0'||!std::isfinite(FogStartMeters)
|
||||
||FogStartMeters<0.0||FogStartMeters>20000.0)
|
||||
{std::fprintf(stderr,"Invalid fog start distance\n");return 2;}
|
||||
}
|
||||
else if(Arg.starts_with("--fog-end-m="))
|
||||
{
|
||||
char* End=nullptr;const std::string Value(Arg.substr(12));
|
||||
FogEndMeters=std::strtod(Value.c_str(),&End);
|
||||
if(End==Value.c_str()||*End!='\0'||!std::isfinite(FogEndMeters)
|
||||
||FogEndMeters<=0.0||FogEndMeters>20000.0)
|
||||
{std::fprintf(stderr,"Invalid fog end distance\n");return 2;}
|
||||
}
|
||||
else if(Arg.starts_with("--fog-color="))
|
||||
{
|
||||
const std::string Value(Arg.substr(12));
|
||||
if(std::sscanf(Value.c_str(),"%lf,%lf,%lf",&FogColor[0],&FogColor[1],
|
||||
&FogColor[2])!=3
|
||||
||std::any_of(FogColor.begin(),FogColor.end(),[](double Channel)
|
||||
{return !std::isfinite(Channel)||Channel<0.0||Channel>1.0;}))
|
||||
{std::fprintf(stderr,"Invalid fog color; use R,G,B in 0..1\n");return 2;}
|
||||
}
|
||||
else if(Arg.starts_with("--tile-edges="))
|
||||
{
|
||||
const std::string_view Mode=Arg.substr(13);
|
||||
@@ -1002,6 +1062,8 @@ int main(int argc,char** argv)
|
||||
}
|
||||
else {std::fprintf(stderr,"Unknown option: %.*s\n",static_cast<int>(Arg.size()),Arg.data());return 2;}
|
||||
}
|
||||
if(FogEnabled&&FogEndMeters<=FogStartMeters)
|
||||
{std::fprintf(stderr,"Fog end distance must be greater than fog start distance\n");return 2;}
|
||||
FScene Scene;std::string Error;
|
||||
if(!LoadScene(argv[1],Scene,Error))
|
||||
{std::fprintf(stderr,"[OffscreenCapture] FAIL: %s\n",Error.c_str());return 2;}
|
||||
@@ -1077,14 +1139,16 @@ int main(int argc,char** argv)
|
||||
FocusRadius,static_cast<unsigned long long>(Scene.DrawnTriangles));
|
||||
}
|
||||
}
|
||||
std::printf("[OffscreenScene] voxels_per_meter=%.6f camera_m=(%.3f,%.3f,%.3f) yaw=%.2f pitch=%.2f height_m=%.3f..%.3f height_center_m=%.3f shade=%s height_tint=%s tile_edges=%s vertices=%zu triangles=%llu\n",
|
||||
std::printf("[OffscreenScene] voxels_per_meter=%.6f camera_m=(%.3f,%.3f,%.3f) yaw=%.2f pitch=%.2f height_m=%.3f..%.3f height_center_m=%.3f shade=%s height_tint=%s tile_edges=%s fog=%s fog_distance_m=%.1f..%.1f fog_color=(%.2f,%.2f,%.2f) vertices=%zu triangles=%llu\n",
|
||||
1000000.0/Scene.VoxelSizeMicrons,Scene.CameraMeters[0],Scene.CameraMeters[1],Scene.CameraMeters[2],
|
||||
Scene.YawDegrees,Scene.PitchDegrees,Scene.MinimumHeight,Scene.MaximumHeight,
|
||||
HeightCenterMeters,
|
||||
ReadableMode?"readable":"normal",HeightTint?"on":"off",
|
||||
TileEdges?"on":"off",Scene.Vertices.size(),
|
||||
TileEdges?"on":"off",FogEnabled?"on":"off",FogStartMeters,FogEndMeters,
|
||||
FogColor[0],FogColor[1],FogColor[2],Scene.Vertices.size(),
|
||||
static_cast<unsigned long long>(Scene.Triangles));
|
||||
return Render(Scene,argv[2],Width,Height,Fov,HeightRangeMeters,HeightCenterMeters,ReadableMode,
|
||||
HeightTint,Headlamp,TileEdges,
|
||||
TileEdgeWidthMeters,HasLightDirection,LightDirection,ClipPlaneEnabled,ClipPlane)?0:3;
|
||||
TileEdgeWidthMeters,HasLightDirection,LightDirection,ClipPlaneEnabled,ClipPlane,
|
||||
FogEnabled,FogStartMeters,FogEndMeters,FogColor)?0:3;
|
||||
}
|
||||
@@ -108,6 +108,7 @@ namespace
|
||||
bool ResolvedLayoutOnly=false;
|
||||
bool AuditResolvedLayoutBoundaries=false;
|
||||
bool AuditResolvedLayoutPassages=false;
|
||||
bool AuditLiminalRoadWalk=false;
|
||||
bool AuditSurfaceClearance=false;
|
||||
bool AuditStrateTransitions=false;
|
||||
int TransitionModeOverride=-1;
|
||||
@@ -1447,6 +1448,7 @@ namespace
|
||||
" --audit-strate-transitions (measure interface crossing, band thickness and holes)\n"
|
||||
" --transition-mode=hard|gradient|interleaved --transition-width-chunks=N (fixture override)\n"
|
||||
" --audit-resolved-layout-passages (capsule, support, route-binding and blocked-control audit)\n"
|
||||
" --audit-liminal-road-walk (capsule, support, width and grade audit for the liminal road)\n"
|
||||
" --audit-heightfield-profile (brute-force the profiled field intervals and route)\n"
|
||||
" --audit-motif-intervals (brute-force motif bounds, BVH and shape-free guards)\n"
|
||||
" --audit-landmark-reachability (capsule, support, grade and buried-L43 control)\n"
|
||||
@@ -1494,6 +1496,7 @@ namespace
|
||||
else if(arg=="--resolved-layout-only")options.ResolvedLayoutOnly=true;
|
||||
else if(arg=="--audit-resolved-layout-boundaries")options.AuditResolvedLayoutBoundaries=true;
|
||||
else if(arg=="--audit-resolved-layout-passages")options.AuditResolvedLayoutPassages=true;
|
||||
else if(arg=="--audit-liminal-road-walk")options.AuditLiminalRoadWalk=true;
|
||||
else if(arg=="--native-owner-fi")options.NativeOwnerFloatingIslandsRecipe=true;
|
||||
else if(arg=="--density-dispatch-report")
|
||||
{options.DensityDispatchReport=true;options.StreamHash=true;options.StreamHashTiles=true;}
|
||||
@@ -1875,7 +1878,13 @@ int main(int argc,char** argv)
|
||||
&&!StandaloneWorldAssemblyPrototype::ValidateExportedCorePlanMatchesOwner(
|
||||
*ownerWorld,worldAssembly,resolvedLayout,error))
|
||||
{std::fprintf(stderr,"Unreal-resolved Core plan/owner slot validation failed: %s\n",error.c_str());return 2;}
|
||||
if(!std::holds_alternative<std::nullptr_t>(ownerJsonRoot.Get("motif_family_override").Data))
|
||||
const bool hasMotifFamily=!std::holds_alternative<std::nullptr_t>(
|
||||
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;}
|
||||
if(hasMotifFamily)
|
||||
{
|
||||
std::vector<VoxelForgeCore::ResolvedLayoutStampRequestV1> requests;
|
||||
if(!StandaloneWorldAssemblyPrototype::BuildMotifFamilyRequests(ownerJsonRoot,
|
||||
@@ -1903,6 +1912,25 @@ int main(int argc,char** argv)
|
||||
static_cast<unsigned long long>(motif.irregularitySeed));
|
||||
}
|
||||
}
|
||||
if(hasLiminalRoad)
|
||||
{
|
||||
std::vector<VoxelForgeCore::ResolvedLayoutStampRequestV1> requests(1);
|
||||
if(!StandaloneWorldAssemblyPrototype::BuildLiminalRoadRequest(ownerJsonRoot,
|
||||
*ownerWorld,worldAssembly,resolvedLayout,requests.front(),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);
|
||||
}
|
||||
if(options.LandmarkChamberDemo)
|
||||
{
|
||||
std::vector<VoxelForgeCore::ResolvedLayoutStampRequestV1> requests;
|
||||
@@ -2404,5 +2432,5 @@ int main(int argc,char** argv)
|
||||
options.MovingCameraSpeedMetersPerSecond,options.MovingCameraDurationSeconds,
|
||||
options.MovingCameraDwellSeconds,options.ColdWorkerTimeline,
|
||||
options.AuditPassageSourceClamp,options.AuditPassageCarveReach,
|
||||
options.AuditPassageTileSeams);
|
||||
options.AuditPassageTileSeams,options.AuditLiminalRoadWalk);
|
||||
}
|
||||
@@ -2384,7 +2384,8 @@ namespace StandaloneStreamBenchmark
|
||||
bool bMovingCameraTrace=false,double MovingCameraSpeedMetersPerSecond=0.0,
|
||||
double MovingCameraDurationSeconds=12.0,double MovingCameraDwellSeconds=5.0,
|
||||
bool bColdWorkerTimeline=false,bool bAuditPassageSourceClamp=false,
|
||||
bool bAuditPassageCarveReach=false,bool bAuditPassageTileSeams=false)
|
||||
bool bAuditPassageCarveReach=false,bool bAuditPassageTileSeams=false,
|
||||
bool bAuditLiminalRoadWalk=false)
|
||||
{
|
||||
using Clock=std::chrono::steady_clock;
|
||||
const std::clock_t ColdCpuOrigin=std::clock();
|
||||
@@ -2554,7 +2555,7 @@ namespace StandaloneStreamBenchmark
|
||||
||bAuditOreVeinYield||bAuditLandmarkReachability||bAuditStrateTransitions
|
||||
||bAuditResolvedLayoutPassages||bAuditResolvedLayoutBoundaries
|
||||
||bAuditTileShapeReadiness||bAuditBasePageEquivalence||bAuditRouteParity
|
||||
||bAuditPassageSourceClamp||bAuditPassageCarveReach;
|
||||
||bAuditPassageSourceClamp||bAuditPassageCarveReach||bAuditLiminalRoadWalk;
|
||||
const bool bDeferFarWorld=bIncludeFarWorld&&!bMovingCameraTrace&&!bFarWorldAudit;
|
||||
VoxelForgeCore::ShapeBuildRequest ShapeRequest;
|
||||
ShapeRequest.minVoxel={FineMin.X,FineMin.Y,FineMin.Z};
|
||||
@@ -2820,10 +2821,10 @@ namespace StandaloneStreamBenchmark
|
||||
Streamer.Stop();
|
||||
return passed?0:11;
|
||||
}
|
||||
if(bAuditResolvedLayoutPassages)
|
||||
if(bAuditResolvedLayoutPassages||bAuditLiminalRoadWalk)
|
||||
{
|
||||
if(ResolvedLayout==nullptr||!CoreSnapshot.resolvedLayout())
|
||||
{Streamer.Stop();std::fprintf(stderr,"[ResolvedPassageAudit] missing resolved-layout snapshot\n");return 2;}
|
||||
{Streamer.Stop();std::fprintf(stderr,"[ResolvedWalkAudit] missing resolved-layout snapshot\n");return 2;}
|
||||
struct FWalkAudit
|
||||
{
|
||||
std::uint64_t segments=0,centers=0,capsuleSamples=0,blocked=0;
|
||||
@@ -2961,6 +2962,67 @@ namespace StandaloneStreamBenchmark
|
||||
&&audit.gradeFailures==0;
|
||||
return audit;
|
||||
};
|
||||
const auto auditLiminalRoadWalk=[&](bool required)
|
||||
{
|
||||
bool found=false;
|
||||
bool passed=true;
|
||||
for(const auto& road:ResolvedLayout->stamps)
|
||||
{
|
||||
if(road.stableId!="liminal/raised-road-v1")continue;
|
||||
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;
|
||||
constexpr double CapsuleHeightMetres=1.76;
|
||||
constexpr double HalfCapsuleHeightMetres=CapsuleHeightMetres*0.5;
|
||||
constexpr double EndInsetMetres=1.0;
|
||||
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});
|
||||
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 "
|
||||
"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(),
|
||||
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");
|
||||
}
|
||||
if(!found&&required)
|
||||
{
|
||||
std::printf("[LiminalRoadWalkAudit] status=FAIL reason=road_stamp_missing\n");
|
||||
return false;
|
||||
}
|
||||
return passed;
|
||||
};
|
||||
if(bAuditLiminalRoadWalk&&!bAuditResolvedLayoutPassages)
|
||||
{
|
||||
const bool passed=auditLiminalRoadWalk(true);
|
||||
Streamer.Stop();
|
||||
return passed?0:14;
|
||||
}
|
||||
const auto qToMetres=[&](std::int64_t q)
|
||||
{return static_cast<double>(q)*World.CoreVoxelSizeMicrons
|
||||
/(VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel*1000000.0);};
|
||||
@@ -4919,6 +4981,7 @@ namespace StandaloneStreamBenchmark
|
||||
routeAudit.firstUnsupported[i][1],routeAudit.firstUnsupported[i][2],
|
||||
routeAudit.firstUnsupported[i][3]);
|
||||
}
|
||||
const bool liminalRoadAuditPassed=auditLiminalRoadWalk(false);
|
||||
for(std::size_t passageIndex=0;
|
||||
passageIndex<ResolvedLayout->passages.size();++passageIndex)
|
||||
{
|
||||
@@ -4984,6 +5047,7 @@ namespace StandaloneStreamBenchmark
|
||||
&&shellAuditPassed
|
||||
&&routePasses>0&&routePasses==routeWalkPasses&&routePasses==routeBindings
|
||||
&&routeBindingFailures==0
|
||||
&&liminalRoadAuditPassed
|
||||
&&blockedCompiled&&blockedControls==passageCount;
|
||||
std::printf("[ResolvedPassageAuditSummary] interfaces=%llu passed=%llu natural=%llu/%llu strate_routes=%llu route_walkable=%llu route_points=%llu route_bindings=%llu route_binding_failures=%llu blocked_controls=%llu/%llu status=%s\n",
|
||||
static_cast<unsigned long long>(passageCount),static_cast<unsigned long long>(passagePasses),
|
||||
|
||||
@@ -587,6 +587,69 @@ namespace StandaloneWorldAssemblyPrototype
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool BuildLiminalRoadRequest(const VFJson::Value& root,
|
||||
const FStandaloneOwnerWorld& owner,
|
||||
const VoxelForgeCore::WorldAssemblyManifest& assembly,
|
||||
const VoxelForgeCore::ResolvedLayoutSnapshotV3& layout,
|
||||
VoxelForgeCore::ResolvedLayoutStampRequestV1& request,std::string& error)
|
||||
{
|
||||
using namespace VoxelForgeCore;
|
||||
const VFJson::Value& overrideValue=root.Get("liminal_road_override");
|
||||
if(!overrideValue.IsObject())
|
||||
{error="liminal_road_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 road requires a valid flatField SurfaceWorld recipe";return false;}
|
||||
|
||||
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;}
|
||||
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;}
|
||||
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());
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool AttachRound1WorldAssemblyPrototype(FStandaloneOwnerWorld& owner,VFJson::Value& root,
|
||||
std::string& error,const std::string& manifestOutputPath,
|
||||
VoxelForgeCore::WorldAssemblyManifest* outManifest=nullptr)
|
||||
|
||||
Reference in new issue
Block a user