t32-instanced-gltf.mjs 1.7 KB

1234567891011121314151617181920212223242526
  1. import assert from 'node:assert/strict'
  2. import { readFile } from 'node:fs/promises'
  3. import { enuToGltf, instanceGltf } from '../../../src/modules/cockpit/services/pipeInstanceGltf.js'
  4. import { Matrix4, Matrix3, Cartesian3 } from 'cesium'
  5. // Independent literal: installed Cesium default correction maps glTF [x,y,z] -> ENU [z,x,y].
  6. const correction = Matrix4.fromRotationTranslation(Matrix3.fromArray([0,1,0,0,0,1,1,0,0]))
  7. const converted = new Cartesian3(...enuToGltf([11,23,37]))
  8. assert.deepEqual(Matrix4.multiplyByPoint(correction, converted, new Cartesian3()), new Cartesian3(11,23,37))
  9. const template = JSON.parse(await readFile(new URL('../../../public/cockpit/models/pipes/spline.gltf', import.meta.url)))
  10. const doc = instanceGltf(template, [
  11. { translation: [0,0,0], rotation: [0,0,0,1], scale: [.4,.4,10] },
  12. { translation: [1,2,3], rotation: [0,0,0,1], scale: [.4,.4,20] },
  13. ])
  14. assert.equal(doc.meshes.length, 1)
  15. assert.equal(doc.meshes[0].primitives.length, 1)
  16. assert.equal(doc.buffers[0].uri, template.buffers[0].uri, 'shared template geometry not copied per instance')
  17. const attrs = doc.nodes[0].extensions.EXT_mesh_gpu_instancing.attributes
  18. assert.equal(doc.accessors[attrs.TRANSLATION].count, 2)
  19. assert.equal(doc.accessors[attrs.SCALE].count, 2)
  20. assert.ok(doc.extensionsRequired.includes('EXT_mesh_gpu_instancing'))
  21. assert.equal(template.nodes[0].extensions, undefined, 'shared template remains immutable')
  22. const data = Buffer.from(doc.buffers[1].uri.split(',')[1], 'base64')
  23. assert.equal(data.readFloatLE(12), 1)
  24. assert.equal(data.readFloatLE(20), 3)
  25. assert.equal(data.readFloatLE(80-4), 20)
  26. console.log('PASS two GPU instances reuse one immutable mesh and preserve literal TRS')