#include "Json.h" #include "OwnerWorldLoader.h" #include "StandaloneCoreScheduler.h" #include "WorldAssemblyPrototype.h" #include "StandaloneSnapshotAdapter.h" #include #include #include #include #include #include namespace { constexpr double CoreVoxelsPerMeter=4.0; constexpr std::int64_t SubvoxelsPerCoreVoxel= VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel; void PrintDensity(VoxelForgeCore::World& World,const char* Label,double X,double Y,double Z) { const VoxelForgeCore::Vec3d Point{X*CoreVoxelsPerMeter,Y*CoreVoxelsPerMeter, Z*CoreVoxelsPerMeter}; const double Density=World.densityAt(Point); const double Raw=World.unclampedDensityAt(Point); std::printf("[DensitySample] label=%s xyz_m=%.6f,%.6f,%.6f density_core_vox=%.9f " "density_cm=%.4f unclamped_core_vox=%.9f sign=%s\n",Label,X,Y,Z,Density, Density*25.0,Raw,Density<0.0?"solid":"air"); } void PrintCrossing(VoxelForgeCore::World& World,const char* Label,double X,double Y, double BottomM,double TopM) { const auto DensityAt=[&](double Z) { return World.densityAt({X*CoreVoxelsPerMeter,Y*CoreVoxelsPerMeter, Z*CoreVoxelsPerMeter}); }; double Lo=BottomM,Hi=TopM; double LoDensity=DensityAt(Lo),HiDensity=DensityAt(Hi); if((LoDensity<0.0)==(HiDensity<0.0)) { std::printf("[DensityCrossing] label=%s bracket_m=%.6f..%.6f signs=%s/%s result=none\n", Label,Lo,Hi,LoDensity<0.0?"solid":"air",HiDensity<0.0?"solid":"air"); return; } for(int Iteration=0;Iteration<64;++Iteration) { const double Mid=(Lo+Hi)*0.5; const double MidDensity=DensityAt(Mid); if((MidDensity<0.0)==(LoDensity<0.0)) {Lo=Mid;LoDensity=MidDensity;} else {Hi=Mid;HiDensity=MidDensity;} } std::printf("[DensityCrossing] label=%s z_m=%.9f bracket_m=%.6f..%.6f " "density_core_vox=%.9f/%.9f\n",Label,(Lo+Hi)*0.5,BottomM,TopM, LoDensity,HiDensity); } } int main(int argc,char** argv) { if(argc!=2) { std::fprintf(stderr,"usage: %s owner-world.json\n",argv[0]); return 2; } VFJson::Value Root; std::string Error; { std::ifstream Input(argv[1],std::ios::binary); if(!Input){std::fprintf(stderr,"owner JSON open failed\n");return 2;} std::string Text{std::istreambuf_iterator(Input),std::istreambuf_iterator{}}; if(!VFJson::Parser(std::move(Text)).Parse(Root,Error)) {std::fprintf(stderr,"owner JSON parse failed: %s\n",Error.c_str());return 2;} } if(!StandaloneWorldAssemblyPrototype::SelectTopStrateAsFloatingIslands(Root,Error)) {std::fprintf(stderr,"FI selection failed: %s\n",Error.c_str());return 2;} auto Owner=std::make_shared(); if(!StandaloneOwnerLoader::Resolve(Root,*Owner,Error)) {std::fprintf(stderr,"owner resolve failed: %s\n",Error.c_str());return 2;} VoxelForgeCore::WorldAssemblyManifest Assembly; if(!StandaloneWorldAssemblyPrototype::AttachRound1WorldAssemblyPrototype( *Owner,Root,Error,{},&Assembly) ||!StandaloneWorldAssemblyPrototype::AttachFloatingIslandWorldAssembly( *Owner,Root,Assembly,Error)) {std::fprintf(stderr,"plan construction failed: %s\n",Error.c_str());return 2;} auto Snapshot=VoxelForgeCore::MakeStandaloneSnapshotFromParsedJson(Root,Owner->Seed,3,8, false,false,Error); if(!Snapshot) {std::fprintf(stderr,"snapshot resolve failed: %s\n",Error.c_str());return 2;} const auto* ResolvedAssembly=Snapshot.worldAssembly(); if(!ResolvedAssembly||ResolvedAssembly->floatingIslands.empty()) {std::fprintf(stderr,"resolved FloatingIslands plan missing\n");return 2;} VoxelForgeCore::World World(std::move(Snapshot)); VoxelForgeCore::ShapeBuildRequest Request; Request.minVoxel={-96,-512,-288}; Request.maxVoxel={96,96,64}; Request.clipMinVoxel=Request.minVoxel; Request.clipMaxVoxel=Request.maxVoxel; Request.workerLimit=12; Request.includeFarWorld=false; FStandaloneCoreScheduler Scheduler; if(!World.compile(Request,Scheduler,Error)) {std::fprintf(stderr,"shape compile failed: %s\n",Error.c_str());return 2;} const auto& Plan=ResolvedAssembly->floatingIslands.front(); const auto& Recipe=Plan.manifest.recipe; std::printf("[FloatingIslandBounds] geometry_version=%u owner_voxel_um=%u core_voxel_um=%u " "owner_to_core=%u/%u chunks=%d..%d layout_z_m=%.6f..%.6f ceiling_start_m=%.6f " "seal_m=%.6f bottom_cap=%s\n",Recipe.geometryVersion,Recipe.ownerVoxelSizeMicrons, Recipe.coreVoxelSizeMicrons,Recipe.ownerToCoreScaleNumerator, Recipe.ownerToCoreScaleDenominator,Plan.topChunkZ,Plan.bottomChunkZ, static_cast(Recipe.layoutMinimumZSubvoxels)/SubvoxelsPerCoreVoxel/4.0, static_cast(Recipe.layoutMaximumZSubvoxels)/SubvoxelsPerCoreVoxel/4.0, static_cast(Recipe.layoutMaximumZSubvoxels-Recipe.boundarySealSubvoxels) /SubvoxelsPerCoreVoxel/4.0, static_cast(Recipe.boundarySealSubvoxels)/SubvoxelsPerCoreVoxel/4.0, Recipe.geometryVersion<3?"legacy":"removed"); std::printf("[DensityProbe] flat_square_xy_m=-11.612444,-118.221237 " "compiled=%d core_voxel_size_cm=25\n",World.isCompiled()?1:0); constexpr double X=-11.612443923950195; constexpr double Y=-118.22123718261719; for(double Z:{2.75,2.99,3.00,3.01,3.25,3.49,3.50,3.51,3.75,3.99,4.00,4.01, 4.05,4.125,4.25,4.50,5.00, 7.75,8.00,8.25,-60.25,-60.00,-59.75,-59.50,-59.25}) PrintDensity(World,"flat-square",X,Y,Z); PrintCrossing(World,"shared-upper-ceiling",X,Y,3.50,3.75); PrintCrossing(World,"upper-boundary-cap",X,Y,4.00,4.25); PrintCrossing(World,"old-eight-metre-wrapper",X,Y,7.75,8.25); PrintCrossing(World,"removed-lower-boundary-seal",X,Y,-60.25,-59.75); for(const auto& Probe:std::array,3>{{ {{-66.3,-38.7}},{{-62.3,-54.6}},{{-53.34,-22.84}}}}) { std::printf("[DensityProbeXY] xy_m=%.3f,%.3f\n",Probe[0],Probe[1]); for(double Z:{3.49,3.50,3.51,3.75,3.875,3.99,4.00,4.01,4.05,4.125}) PrintDensity(World,"boundary-ray",Probe[0],Probe[1],Z); PrintCrossing(World,"boundary-ray",Probe[0],Probe[1],3.49,4.125); } for(const auto& Probe:std::array,4>{{ {{-67.0,-39.0}},{{-66.0,-39.0}},{{-67.0,-38.0}},{{-66.0,-38.0}}}}) { PrintDensity(World,"boundary-grid-node",Probe[0],Probe[1],3.875); PrintDensity(World,"boundary-grid-node",Probe[0],Probe[1],4.125); } return 0; }