code wiki / (root) / nx_prepared_motion_candidate_t316.nx

nx_prepared_motion_candidate_t316.nx

buildroot/runtime/nx_prepared_motion_candidate_t316.nx

8228 B2 linesdepth 0pulls 0 transitivereach 17 importersview sourcekind librarytopic prepared
docsdependenciesstructsconstsfunctions

about

Native-emitted prepared-source transport; host scene clock, source-bound manifest, reserved owned WASM tail memory.

dependencies 0 imports · 5 importers

nx_prepared_motion_candidate_t nx_game_page_motion_candidate_t328 nx_prepared_character_bundle.nx nx_prepared_character_bundle_emit_ nx_prepared_motion_emit_gate_t316. nx_prepared_motion_emit_gate_t316_

imports: none

imported by: nx_game_page_motion_candidate_t328.nxnx_prepared_character_bundle.nxnx_prepared_character_bundle_emit_t316_gate.nxnx_prepared_motion_emit_gate_t316.nxnx_prepared_motion_emit_gate_t316_gate.nx

structs

none

consts

none

functions

2func nx_prepared_motion_js()->*u8{return "class NishiPreparedMotion {\n static async create(manifest, readBytes, publish, expectedSourceSha256) {\n if(manifest?.schema!=='nishi-native-fullclip/1'||!/^([0-9a-f]{64})$/.test(manifest.sourceSha256)||typeof readBytes!=='function'||typeof publish!=='function'||manifest.sourceSha256!==expectedSourceSha256) throw Error('prepared-motion-manifest');\n const records=['wasm','clip','geometry','influenceBounds'];\n for(const name of records){const r=manifest[name];if(!r||!Number.isSafeInteger(r.bytes)||r.bytes<=0||!/^[0-9a-f]{64}$/.test(r.sha256)||typeof r.url!=='string')throw Error('prepared-motion-record:'+name);}\n const data=await Promise.all(records.map(name=>readBytes(manifest[name])));\n const loaded=await WebAssembly.instantiate(data[0],{}), ex=loaded.instance.exports;\n if(!(ex.memory instanceof WebAssembly.Memory)||typeof ex.gltf_pose_frame!=='function'||typeof ex.gltf_pose_bounds!=='function'||typeof ex.gltf_pose_work_words!=='function'||typeof ex.gltf_pose_broad_bounds!=='function')throw Error('prepared-motion-exports');\n const clip=new DataView(data[1] instanceof ArrayBuffer?data[1]:data[1].buffer,data[1].byteOffset||0,data[1].byteLength);\n if(clip.byteLength<160||clip.byteLength%8)throw Error('prepared-motion-clip-size');\n const h=Array.from({length:20},(_,i)=>Number(clip.getBigInt64(i*8,true)));\n if(!h.every(Number.isSafeInteger)||h[0]!==1196441905||h[1]!==1||h[2]*8!==clip.byteLength||h[3]!==manifest.nodes||h[4]!==manifest.joints||h[5]!==manifest.channels||h[6]!==manifest.duration||h[7]!==manifest.q||h[8]!==manifest.timeQ||h[13]<20||h[13]+h[4]>h[2])throw Error('prepared-motion-clip-contract');\n if(!Number.isSafeInteger(manifest.vertices)||manifest.vertices<=0||data[2].byteLength!==manifest.vertices*88||h[6]<=0)throw Error('prepared-motion-geometry-contract');\n const self=new NishiPreparedMotion();self.manifest=Object.freeze({...manifest});self.ex=ex;self.publish=publish;self.header=h;self.revision=0;self.mode='paused';self.time=0;self.cycle=0;self.error=null;self.clockOrigin=null;self.clockTime=null;\n const words=Number(ex.gltf_pose_work_words(BigInt(h[3])));if(!Number.isSafeInteger(words)||words<=0)throw Error('prepared-motion-workspace');\n if(!Number.isSafeInteger(manifest.arenaStartBytes)||manifest.arenaStartBytes<=0||manifest.arenaStartBytes%8||manifest.arenaStartBytes!==ex.memory.buffer.byteLength)throw Error('prepared-motion-arena-contract');let cursor=manifest.arenaStartBytes;const allocate=bytes=>{const off=cursor;cursor=Math.ceil((cursor+bytes)/8)*8;return off;};\n self.packet=allocate(clip.byteLength);self.work=allocate(words*8);self.palette=allocate(h[4]*128);self.geometry=allocate(data[2].byteLength);self.broadPack=allocate(data[3].byteLength);self.broadWords=data[3].byteLength/8;if(self.broadWords!==10+h[4]*7)throw Error('prepared-motion-influence-size');self.bounds=allocate(48);self.scratch=allocate(512);self.words=words;\n if(cursor>ex.memory.buffer.byteLength)ex.memory.grow(Math.ceil((cursor-ex.memory.buffer.byteLength)/65536));\n new Uint8Array(ex.memory.buffer,self.packet,clip.byteLength).set(new Uint8Array(clip.buffer,clip.byteOffset,clip.byteLength));\n const geom=data[2];new Uint8Array(ex.memory.buffer,self.geometry,geom.byteLength).set(geom instanceof ArrayBuffer?new Uint8Array(geom):new Uint8Array(geom.buffer,geom.byteOffset,geom.byteLength));\n const broad=data[3];new Uint8Array(ex.memory.buffer,self.broadPack,broad.byteLength).set(broad instanceof ArrayBuffer?new Uint8Array(broad):new Uint8Array(broad.buffer,broad.byteOffset,broad.byteLength));\n self.jointNodes=Array.from({length:h[4]},(_,i)=>Number(clip.getBigInt64((h[13]+i)*8,true)));\n if(!self.jointNodes.every(n=>Number.isSafeInteger(n)&&n>=0&&n<h[3]))throw Error('prepared-motion-joint-node');\n self.evaluate(0);return self;\n }\n status(){return {state:this.error?'failed':this.mode,time:this.time,timeQ:this.header[8],duration:this.header[6],cycle:this.cycle,revision:this.revision,continuousPlayback:this.mode==='once'||this.mode==='loop',rootMotion:{policy:'authored-source',cycleBoundary:this.mode==='loop'?'explicit-source-reset':'stop-at-authored-end',worldNavigation:'unbound'},bounds:this.sample?.boundsKind||'not-evaluated-for-current-pose',groundContact:'host-owned-unqualified',sourceSha256:this.manifest.sourceSha256,clipSha256:this.manifest.clip.sha256,wasmSha256:this.manifest.wasm.sha256,error:this.error};}\n evaluate(time, includeBounds=true){\n if(!Number.isSafeInteger(time)||time<0||time>this.header[6])throw Error('prepared-motion-time');\n const ex=this.ex,h=this.header,B=BigInt,available=ex.memory.buffer.byteLength;\n const rc=ex.gltf_pose_frame(...[this.packet,h[2],time,0,this.work,this.words,this.palette,h[4]*16,available].map(B));\n if(rc!==B(h[4]))throw Error('prepared-motion-native-frame:'+rc);\n const br=includeBounds?ex.gltf_pose_bounds(...[this.palette,h[4],this.geometry,this.manifest.vertices,this.bounds,this.scratch,available].map(B)):ex.gltf_pose_broad_bounds(...[this.palette,h[4],this.broadPack,this.broadWords,this.bounds,this.scratch,available].map(B));\n if(br!==B(includeBounds?this.manifest.vertices:h[4]))throw Error('prepared-motion-native-bounds:'+br);\n const view=new DataView(ex.memory.buffer),read=(off,n)=>Array.from({length:n},(_,i)=>{const v=Number(view.getBigInt64(off+i*8,true));if(!Number.isSafeInteger(v))throw Error('prepared-motion-output-range');return v;});\n const palette=read(this.palette,h[4]*16),bounds=read(this.bounds,6),world=this.work+h[3]*26*8;\n const jointWorld=this.jointNodes.map(n=>read(world+n*128+96,3));const rootNode=this.manifest.rootMotion?.sourceNode;if(!Number.isSafeInteger(rootNode)||rootNode<0||rootNode>=h[3])throw Error('prepared-motion-root-node');const rootWorld=read(world+rootNode*128+96,3);\n const rows=new Float32Array(palette.length);for(let j=0;j<h[4];j++)for(let c=0;c<4;c++)for(let k=0;k<4;k++)rows[c*h[4]*4+j*4+k]=palette[j*16+c*4+k]/h[7];\n const sample={time,channels:h[5],palette,bounds,jointWorld,rootWorld,boundsState:'ready',boundsKind:includeBounds?'native-exact-all-vertices':'native-conservative-influence-aabb'};\n this.publish(sample,rows,{revision:this.revision+1,cycle:this.cycle});this.sample=sample;this.time=time;this.revision++;this.error=null;return sample;\n }\n pause(){this.mode='paused';this.clockOrigin=null;return this.status();}\n seek(time){this.pause();try{this.evaluate(time);}catch(error){this.error={code:'prepared-motion-evaluation',message:String(error.message||error)};throw error;}return this.status();}\n reset(){this.cycle=0;return this.seek(0);}\n play(mode='once'){\n if(mode!=='once'&&mode!=='loop')throw Error('prepared-motion-mode');this.pause();if(this.time===this.header[6])this.evaluate(0);this.mode=mode;this.error=null;this.initialTime=this.time;return this.status();\n }\n step(sceneTimeMs){\n if(this.mode!=='once'&&this.mode!=='loop')return this.status();\n try{\n if(!Number.isFinite(sceneTimeMs)||sceneTimeMs<0||(this.clockTime!==null&&sceneTimeMs<this.clockTime))throw Error('prepared-motion-scene-clock');\n if(sceneTimeMs===this.clockTime&&this.clockOrigin!==null)return this.status();if(this.clockOrigin===null)this.clockOrigin=sceneTimeMs;this.clockTime=sceneTimeMs;\n const elapsed=this.initialTime+Math.floor((sceneTimeMs-this.clockOrigin)*this.header[8]/1000);\n if(!Number.isSafeInteger(elapsed)||elapsed<0)throw Error('prepared-motion-clock');this.cycle=Math.floor(elapsed/this.header[6]);\n const done=this.mode==='once'&&elapsed>=this.header[6];this.evaluate(done?this.header[6]:elapsed%this.header[6],false);if(done)this.pause();\n }catch(error){this.pause();this.error={code:'prepared-motion-playback',message:String(error.message||error)};}\n return this.status();\n }\n auditBounds(){return this.evaluate(this.time,true);}\n dispose(){this.pause();this.publish=()=>{};this.mode='disposed';return this.status();}\n}\nwindow.NishiPreparedMotion=NishiPreparedMotion;\n"}