import test from 'node:test'; import assert from 'node:assert/strict'; import fs from 'node:fs'; import {Matrix4,Vector3,Quaternion} from '../vendor/three.module.js'; const root=new URL('../assets/soma/',import.meta.url),read=name=>JSON.parse(fs.readFileSync(new URL(name,root),'utf8')); const rig=read('rig.json'),reports=read('fit-report.json'); test('SOMA export has valid native mesh, skin weights, topology and bind transforms',()=>{ assert.equal(rig.model,'SOMA-X');assert.equal(rig.vertices.length,4505);assert.equal(rig.faces.length,9006);assert.equal(rig.jointNames.length,78); for(const f of rig.faces)for(const j of f)assert.ok(Number.isInteger(j)&&j>=0&&j{assert.ok(v.every(Number.isFinite));assert.ok(Math.abs(rig.skinWeights[i].reduce((a,b)=>a+b,0)-1)<1e-5);rig.skinIndices[i].forEach(j=>assert.ok(j>=0&&j<78));}); for(const b of rig.bindMatrices)assert.ok(Math.abs(new Matrix4().fromArray(b.flat()).determinant())>0.9); }); test('All 33 SOMA animations match saved frame counts and have usable normalized transforms',()=>{ assert.equal(Object.keys(reports).length,33); const inv=rig.bindMatrices.map(m=>new Matrix4().fromArray(m.flat()).transpose().invert()); for(const [name,r] of Object.entries(reports)){ const bytes=fs.readFileSync(new URL(name+'.bin',root)),a=new Float32Array(bytes.buffer,bytes.byteOffset,bytes.length/4); assert.equal(a.length,r.frames*2*78*7,name);assert.ok(r.scale>0&&Number.isFinite(r.meanJointError)); for(let i=0;i{ const r=reports['fall-real-synthetic-2-5'],b=fs.readFileSync(new URL('fall-real-synthetic-2-5.bin',root)),a=new Float32Array(b.buffer,b.byteOffset,b.length/4),stride=78*7; const energy=offset=>{let sum=0,n=0;for(let f=76;f