import assert from 'node:assert/strict' import { readFileSync, existsSync, writeFileSync } from 'node:fs' import { resolve, dirname, join } from 'node:path' import { Cesium3DTileset } from 'cesium' const dir = resolve(process.argv[2]), tree = JSON.parse(readFileSync(join(dir, 'tileset.json'))) const report = JSON.parse(readFileSync(join(dir, 'manifest.json'))) const sourceRecords = new Map(), ids = new Set() for (const source of report.sources) { const sourceDir = resolve(dir, '..', source.source) const m = JSON.parse(readFileSync(join(sourceDir, 'manifest.json'))) for (const id of m.cells.flatMap((c) => c.buildingIds)) { assert.ok(!ids.has(id)); ids.add(id) } for (const r of m.files) sourceRecords.set(resolve(sourceDir, r.uri), r) } const cesium = new Cesium3DTileset({ skipLevelOfDetail: true }) let content = 0, coarse = 0, fine = 0, maxTriangles = 0, maxVertices = 0 const used = new Set() function check(tile) { if (tile.children?.length) { assert.equal(tile.refine, 'REPLACE') assert.equal(tile.geometricError, 1000000) // Coarse parent content keeps its source request sphere so distant coarse // partitions can retire; structural parents without content remain unbounded. if (tile.content?.uri && /-lod1\.glb$/.test(tile.content.uri)) { assert.ok(tile.viewerRequestVolume?.sphere) } else assert.equal(tile.viewerRequestVolume, undefined) if (tile !== tree.root) assert.ok(tile.boundingVolume.sphere) } if (tile.content?.uri) { const path = resolve(dir, tile.content.uri) assert.ok(existsSync(path), path) assert.ok(!used.has(path), 'same geometry referenced twice') used.add(path) if (tile.content.uri !== 'root-anchor.glb') { const record = sourceRecords.get(path) assert.ok(record, `unrecorded ${path}`) content++ maxTriangles = Math.max(maxTriangles, record.triangles) maxVertices = Math.max(maxVertices, record.vertices) assert.ok(record.triangles <= 20000 && record.vertices <= 60000) if (record.level === 'lod1') { coarse++; assert.ok(tile.viewerRequestVolume?.sphere) } else { fine++ assert.equal(tile.geometricError, 0) const sphere = tile.viewerRequestVolume.sphere, box = tile.boundingVolume.box assert.ok(Math.abs(sphere[3] - Math.hypot(box[3], box[7], box[11]) - 250) < 0.01) } } } for (const child of tile.children || []) check(child) } check(tree.root) assert.equal(content, sourceRecords.size) assert.equal(ids.size, report.buildings) // Version-pinned private Cesium parser checks structure only; no traversal/render frame. const actual = cesium.loadTileset(new URL(`file:///${join(dir, 'tileset.json').replaceAll('\\', '/')}`).href, tree) assert.ok(actual.children.length > 0) cesium.destroy() const result = { passed: true, buildings: ids.size, content, coarse, fine, maxTriangles, maxVertices, oneHierarchy: true, cesiumPrivateTreeParsed: true, traversalValidated: false, geometryReused: true, caveat: 'Offline structural/resource acceptance only; rendering, FPS and GPU memory unmeasured.' } if (process.argv[3]) writeFileSync(process.argv[3], JSON.stringify(result, null, 2)) console.log(JSON.stringify(result))