import assert from 'node:assert/strict' import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs' import { resolve, join, relative } from 'node:path' import { parseGlb } from './instance-repeated-meshes.mjs' import { instanceSafePrimitives } from './instance-safe-primitives.mjs' import { compressInstanceBuffers } from './instance-buffer-codec.mjs' const source = resolve(process.argv[2]), output = resolve(process.argv[3]) assert.ok(source && output && source !== output) assert.ok(!existsSync(output), 'use a new immutable output directory') const manifest = JSON.parse(readFileSync(join(source,'manifest.json'),'utf8')) const tree = JSON.parse(readFileSync(join(source,'tileset.json'),'utf8')) mkdirSync(output,{recursive:true}) const results = new Map(), report = { source, count: manifest.count, cells: [], fallbackCells: manifest.fallbackCells, budget: manifest.budget, totals: {sourceBytes:0,outputBytes:0,sourceNodes:0,outputNodes:0,instancedPlacements:0,instancedBuildings:0}, candidateOnly:true } for(const cell of manifest.cells){ const path = join(source,cell.lod0.uri), bytes = readFileSync(path) const result = instanceSafePrimitives(bytes) if(result.report.instanceGroups) result.bytes=compressInstanceBuffers(result.bytes) writeFileSync(join(output,cell.lod0.uri),result.bytes) const {json} = parseGlb(result.bytes) const drawPrimitives=json.nodes.reduce((sum,n)=>sum+json.meshes[n.mesh].primitives.length,0) const coarseUri=relative(output,join(source,cell.lod1.uri)).replaceAll('\\','/') const record={ ...cell, lod1:{...cell.lod1,uri:coarseUri}, lod0:{...cell.lod0, bytes:result.bytes.length, drawPrimitives}, ...result.report, sourceBytes:bytes.length, instancedBuildings:new Set(result.report.records.flatMap(r=>r.names).filter(n=>!n.endsWith('_buried_foundation'))).size } report.cells.push(record);results.set(cell.lod0.uri,record) report.totals.sourceBytes+=bytes.length;report.totals.outputBytes+=result.bytes.length report.totals.sourceNodes+=result.report.originalNodes;report.totals.outputNodes+=result.report.outputNodes report.totals.instancedPlacements+=result.report.instancedPlacements;report.totals.instancedBuildings+=record.instancedBuildings } for(const tile of tree.root.children){ const uri=tile.content.uri tile.content.uri=relative(output,join(source,uri)).replaceAll('\\','/') assert.ok(results.has(tile.children[0].content.uri)) } writeFileSync(join(output,'tileset.json'),JSON.stringify(tree,null,2)) writeFileSync(join(output,'manifest.json'),JSON.stringify(report,null,2)) console.log(JSON.stringify({output,cells:report.cells.length,fallbackCells:report.fallbackCells.length,...report.totals}))