#include "Json.h" #include "OwnerWorldLoader.h" #include "StandaloneCoreScheduler.h" #include "WorldAssemblyPrototype.h" #include "StandaloneSnapshotAdapter.h" #include #include #include #include #include #include #include #include int main(int argc,char** argv) { if(argc!=8) { std::fprintf(stderr,"usage: %s owner.json surface-world|floating-islands x_m y_m zmin_m zmax_m step_m\n",argv[0]); return 2; } const std::string recipe=argv[2]; if(recipe!="surface-world"&&recipe!="floating-islands")return 2; const double x=std::strtod(argv[3],nullptr),y=std::strtod(argv[4],nullptr); const double zmin=std::strtod(argv[5],nullptr),zmax=std::strtod(argv[6],nullptr); const double step=std::strtod(argv[7],nullptr); if(!std::isfinite(x)||!std::isfinite(y)||!std::isfinite(zmin)||!std::isfinite(zmax) ||!std::isfinite(step)||zmax<=zmin||step<=0.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(recipe=="floating-islands" &&!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)) {std::fprintf(stderr,"assembly setup failed: %s\n",error.c_str());return 2;} if(recipe=="floating-islands" &&!StandaloneWorldAssemblyPrototype::AttachFloatingIslandWorldAssembly( *owner,root,assembly,error)) {std::fprintf(stderr,"FI setup failed: %s\n",error.c_str());return 2;} VoxelForgeCore::ResolvedLayoutSnapshotV3 resolvedLayout; if(!StandaloneWorldAssemblyPrototype::BuildResolvedLayoutSnapshot( *owner,assembly,recipe,resolvedLayout,error)) {std::fprintf(stderr,"resolved layout build failed: %s\n",error.c_str());return 2;} auto* rootObject=std::get_if(&root.Data); if(!rootObject)return 2; VFJson::Value layoutJson; layoutJson.Data=resolvedLayout.ToJson(); (*rootObject)["resolved_layout_json"]=std::move(layoutJson); 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* layout=snapshot.resolvedLayout(); if(!layout){std::fprintf(stderr,"resolved layout missing\n");return 2;} for(const auto& stratum:layout->strates) std::printf("[DensityStratum] order=%d strate=%d generator=%s mode=%s width_um=%lld bedrock_um=%lld..%lld ceiling_um=%lld..%lld\n", stratum.order,stratum.strateIndex,stratum.generatorKind.c_str(), stratum.transitionMode.c_str(),static_cast(stratum.transitionWidthMicrometres), static_cast(stratum.bedrock.bottomMicrometres), static_cast(stratum.bedrock.topMicrometres), static_cast(stratum.ceiling.bottomMicrometres), static_cast(stratum.ceiling.topMicrometres)); const auto interface=std::find_if(layout->strates.begin(),layout->strates.end(), [](const auto& stratum){return stratum.order==0;}); if(interface==layout->strates.end())return 2; VoxelForgeCore::World world(std::move(snapshot)); VoxelForgeCore::ShapeBuildRequest request; request.minVoxel={static_cast(std::floor((x-32.0)*4.0)), static_cast(std::floor((y-32.0)*4.0)), static_cast(std::floor((zmin-4.0)*4.0))}; request.maxVoxel={static_cast(std::ceil((x+32.0)*4.0)), static_cast(std::ceil((y+32.0)*4.0)), static_cast(std::ceil((zmax+4.0)*4.0))}; 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;} std::printf("[DensityLine] recipe=%s mode=%s width_um=%lld seam_um=%lld band_top_um=%lld band_bottom_um=%lld xy_m=%.6f,%.6f core_voxel_m=0.25 status=PASS\n", recipe.c_str(),interface->transitionMode.c_str(), static_cast(interface->transitionWidthMicrometres), static_cast(interface->bedrock.bottomMicrometres), static_cast(interface->bedrock.topMicrometres), static_cast(interface->bedrock.bottomMicrometres),x,y); std::printf("z_m,density_vox,lattice_vox,unclamped_vox,dispatch\n"); const auto count=static_cast(std::floor((zmax-zmin)/step+1.0e-9)); for(std::size_t i=0;i<=count;++i) { const double z=zmin+static_cast(i)*step; const VoxelForgeCore::Vec3d p{x*4.0,y*4.0,z*4.0}; const VoxelForgeCore::Vec3i lattice{ static_cast(std::llround(x*4.0)), static_cast(std::llround(y*4.0)), static_cast(std::llround(z*4.0))}; std::printf("%.6f,%.9f,%.9f,%.9f,%s\n",z,world.densityAt(p), world.densityAtLattice(lattice),world.unclampedDensityAt(p), world.densityDispatchPathAt(p).c_str()); } return 0; }