| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- 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))
|