murow 0.0.71 → 0.0.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -5
- package/dist/cjs/renderer/{base-2d-renderer.js → base/renderer-2d.js} +1 -1
- package/dist/cjs/renderer/{base-3d-renderer.js → base/renderer-3d.js} +1 -1
- package/dist/cjs/renderer/gltf/helpers.js +1 -0
- package/dist/cjs/renderer/gltf/parser.js +1 -0
- package/dist/cjs/renderer/gltf/skeletal-animation.js +1 -0
- package/dist/cjs/renderer/gltf/skin-parser.js +1 -0
- package/dist/cjs/renderer/index.js +1 -1
- package/dist/cjs/renderer/math.js +1 -0
- package/dist/cjs/renderer/prefab-bucket/concrete.js +1 -0
- package/dist/cjs/renderer/prefab-bucket/index.js +1 -0
- package/dist/cjs/renderer/prefab-bucket/parsers.js +1 -0
- package/dist/cjs/renderer/prefab-bucket/specs.js +1 -0
- package/dist/cjs/renderer/spritesheet/helpers.js +1 -0
- package/dist/cjs/renderer/spritesheet/parser.js +1 -0
- package/dist/cjs/renderer/types.js +1 -1
- package/dist/esm/renderer/base/renderer-2d.js +1 -0
- package/dist/esm/renderer/base/renderer-3d.js +1 -0
- package/dist/esm/renderer/gltf/helpers.js +1 -0
- package/dist/esm/renderer/gltf/parser.js +1 -0
- package/dist/esm/renderer/gltf/skeletal-animation.js +1 -0
- package/dist/esm/renderer/gltf/skin-parser.js +1 -0
- package/dist/esm/renderer/index.js +1 -1
- package/dist/esm/renderer/math.js +1 -0
- package/dist/esm/renderer/prefab-bucket/concrete.js +1 -0
- package/dist/esm/renderer/prefab-bucket/index.js +1 -0
- package/dist/esm/renderer/prefab-bucket/parsers.js +1 -0
- package/dist/esm/renderer/prefab-bucket/specs.js +0 -0
- package/dist/esm/renderer/spritesheet/helpers.js +1 -0
- package/dist/esm/renderer/spritesheet/parser.js +1 -0
- package/dist/types/renderer/{base-2d-renderer.d.ts → base/renderer-2d.d.ts} +2 -2
- package/dist/types/renderer/{base-3d-renderer.d.ts → base/renderer-3d.d.ts} +2 -2
- package/dist/types/renderer/{base-renderer.d.ts → base/renderer.d.ts} +1 -1
- package/dist/types/renderer/gltf/helpers.d.ts +43 -0
- package/dist/types/renderer/gltf/parser.d.ts +49 -0
- package/dist/{webgpu/types/3d → types/renderer/gltf}/skeletal-animation.d.ts +8 -2
- package/dist/{webgpu/types/3d/gltf-skin-parser.d.ts → types/renderer/gltf/skin-parser.d.ts} +11 -5
- package/dist/types/renderer/index.d.ts +14 -3
- package/dist/types/renderer/prefab-bucket/concrete.d.ts +55 -0
- package/dist/types/renderer/prefab-bucket/index.d.ts +113 -0
- package/dist/types/renderer/prefab-bucket/parsers.d.ts +8 -0
- package/dist/types/renderer/prefab-bucket/specs.d.ts +166 -0
- package/dist/types/renderer/spritesheet/helpers.d.ts +38 -0
- package/dist/types/renderer/spritesheet/parser.d.ts +21 -0
- package/dist/types/renderer/types.d.ts +17 -7
- package/dist/webgpu/cjs/index.js +479 -1082
- package/dist/webgpu/esm/index.js +485 -1079
- package/dist/webgpu/types/2d/renderer.d.ts +34 -3
- package/dist/webgpu/types/2d/sprite-accessor.d.ts +1 -1
- package/dist/webgpu/types/3d/clip-resync-coordinator.d.ts +20 -0
- package/dist/webgpu/types/3d/renderer.d.ts +64 -14
- package/dist/webgpu/types/3d/skeletal-animation-compute/index.d.ts +1 -1
- package/dist/webgpu/types/3d/skeletal-animation-compute/kernel.d.ts +19 -2
- package/dist/webgpu/types/3d/skeletal-animation-compute/packer.d.ts +1 -1
- package/dist/webgpu/types/camera/camera-2d.d.ts +1 -1
- package/dist/webgpu/types/camera/camera-3d.d.ts +1 -1
- package/dist/webgpu/types/index.d.ts +15 -12
- package/dist/webgpu/types/particle/emitter.d.ts +1 -1
- package/dist/webgpu/types/spritesheet/spritesheet.d.ts +5 -34
- package/package.json +1 -1
- package/dist/esm/renderer/base-2d-renderer.js +0 -1
- package/dist/esm/renderer/base-3d-renderer.js +0 -1
- /package/dist/cjs/renderer/{base-renderer.js → base/renderer.js} +0 -0
- /package/dist/esm/renderer/{base-renderer.js → base/renderer.js} +0 -0
- /package/dist/{webgpu/types/core → types/renderer}/math.d.ts +0 -0
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ npm install murow
|
|
|
11
11
|
## Usage
|
|
12
12
|
|
|
13
13
|
```typescript
|
|
14
|
-
import { FixedTicker, EventSystem, BinaryCodec, generateId, lerp } from 'murow';
|
|
14
|
+
import { FixedTicker, EventSystem, BinaryCodec, generateId, lerp, PrefabBucket } from 'murow';
|
|
15
15
|
// or
|
|
16
16
|
import { FixedTicker } from 'murow/core';
|
|
17
17
|
import { WebGPU2DRenderer } from 'murow/webgpu';
|
|
@@ -64,10 +64,12 @@ Key features:
|
|
|
64
64
|
- **Transport agnostic** — works with WebSocket, WebRTC, UDP, etc.
|
|
65
65
|
- **Type-safe** protocol integration with `IntentRegistry` and `SnapshotRegistry`
|
|
66
66
|
|
|
67
|
-
### [Renderer](./src/renderer) — Abstract renderer interfaces
|
|
68
|
-
-
|
|
69
|
-
- `Base2DRenderer` —
|
|
70
|
-
- `
|
|
67
|
+
### [Renderer](./src/renderer) — Abstract renderer interfaces + asset pipeline
|
|
68
|
+
Renderer-agnostic primitives consumed by any backend (`@murow/webgpu`, future PixiJS, Three.js, …).
|
|
69
|
+
- `BaseRenderer` / `Base2DRenderer` / `Base3DRenderer` — abstract contracts
|
|
70
|
+
- [`PrefabBucket`](./src/renderer/prefab-bucket) — typed registry for spawnable assets. Declare → load → typed lookup; the renderer self-sizes from the bucket
|
|
71
|
+
- `parseGltf` / `parseSpritesheet` — pure CPU parsers (no GPU, no canvas)
|
|
72
|
+
- `SkeletalAnimation` — CPU-side bone evaluation for skinned meshes
|
|
71
73
|
|
|
72
74
|
### [WebGPU](./src/../webgpu) — WebGPU rendering backend
|
|
73
75
|
The WebGPU renderer is bundled with murow and accessible via `murow/webgpu`:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var s=Object.defineProperty;var n=Object.getOwnPropertyDescriptor;var o=Object.getOwnPropertyNames;var S=Object.prototype.hasOwnProperty;var d=(r,e)=>{for(var t in e)s(r,t,{get:e[t],enumerable:!0})},m=(r,e,t,p)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of o(e))!S.call(r,a)&&a!==t&&s(r,a,{get:()=>e[a],enumerable:!(p=n(e,a))||p.enumerable});return r};var c=r=>m(s({},"__esModule",{value:!0}),r);var b={};d(b,{Base2DRenderer:()=>l});module.exports=c(b);var i=require("./
|
|
1
|
+
var s=Object.defineProperty;var n=Object.getOwnPropertyDescriptor;var o=Object.getOwnPropertyNames;var S=Object.prototype.hasOwnProperty;var d=(r,e)=>{for(var t in e)s(r,t,{get:e[t],enumerable:!0})},m=(r,e,t,p)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of o(e))!S.call(r,a)&&a!==t&&s(r,a,{get:()=>e[a],enumerable:!(p=n(e,a))||p.enumerable});return r};var c=r=>m(s({},"__esModule",{value:!0}),r);var b={};d(b,{Base2DRenderer:()=>l});module.exports=c(b);var i=require("./renderer");class l extends i.BaseRenderer{constructor(e,t){super(e,t),this.maxSprites=t.maxSprites??1024}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var s=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var l=(r,e)=>{for(var a in e)s(r,a,{get:e[a],enumerable:!0})},c=(r,e,a,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of d(e))!p.call(r,t)&&t!==a&&s(r,t,{get:()=>e[t],enumerable:!(n=m(e,t))||n.enumerable});return r};var D=r=>c(s({},"__esModule",{value:!0}),r);var x={};l(x,{Base3DRenderer:()=>i});module.exports=D(x);var o=require("./
|
|
1
|
+
var s=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var l=(r,e)=>{for(var a in e)s(r,a,{get:e[a],enumerable:!0})},c=(r,e,a,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of d(e))!p.call(r,t)&&t!==a&&s(r,t,{get:()=>e[t],enumerable:!(n=m(e,t))||n.enumerable});return r};var D=r=>c(s({},"__esModule",{value:!0}),r);var x={};l(x,{Base3DRenderer:()=>i});module.exports=D(x);var o=require("./renderer");class i extends o.BaseRenderer{constructor(e,a){super(e,a),this.maxModels=a.maxModels??32}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var g=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var C=Object.prototype.hasOwnProperty;var U=(n,t)=>{for(var e in t)g(n,e,{get:t[e],enumerable:!0})},j=(n,t,e,c)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of p(t))!C.call(n,i)&&i!==e&&g(n,i,{get:()=>t[i],enumerable:!(c=k(t,i))||c.enumerable});return n};var N=n=>j(g({},"__esModule",{value:!0}),n);var R={};U(R,{bakeTransformIntoVertices:()=>B,decodeGltfContainer:()=>I,extractPrimitiveAttributes:()=>J,remapSkinAttributes:()=>$,validateAndBuildSkinRemaps:()=>S});module.exports=N(R);const M=F("glTF"),O=F("JSON"),T=F("BIN\0"),x=65535;function I(n,t){if(new Uint32Array(n,0,1)[0]!==M)return{gltf:JSON.parse(new TextDecoder().decode(n)),glbBinaryChunk:null};let c,i=null,r=12;for(;r<n.byteLength;){const s=new Uint32Array(n,r,1)[0],u=new Uint32Array(n,r+4,1)[0];if(r+=8,u===O){const o=new Uint8Array(n,r,s);c=JSON.parse(new TextDecoder().decode(o))}else u===T&&(i=n.slice(r,r+s));r+=s}if(!c)throw new Error(`Invalid GLB: no JSON chunk in ${t}`);return{gltf:c,glbBinaryChunk:i}}function S(n,t,e,c,i){const r=new Map;for(let o=0;o<e.jointCount;o++)r.set(e.jointNodeIndices[o],o);const s=e.inverseBindMatrices,u=new Set;for(const o of n.nodes)o.mesh!==void 0&&o.skin!==void 0&&u.add(o.skin);for(const o of u){if(o===t)continue;const l=n.skins[o];if(!l)continue;const d=l.joints;if(d.length!==e.jointCount)throw new Error(`glTF has incompatible skins (skin ${o} has ${d.length} joints, canonical skin ${t} has ${e.jointCount}). Multi-skeleton models are not supported yet.`);const f=new Uint16Array(d.length);for(let a=0;a<d.length;a++){const b=r.get(d[a]);if(b===void 0)throw new Error(`glTF skin ${o} references node ${d[a]} which is not a joint in canonical skin ${t}. Multi-skeleton models are not supported yet.`);f[a]=b}const A=i(l.inverseBindMatrices).data,h=1e-4;for(let a=0;a<d.length;a++){const b=f[a];for(let w=0;w<16;w++)if(Math.abs(A[a*16+w]-s[b*16+w])>h)throw new Error(`glTF skin ${o} has different inverse bind matrices than canonical skin ${t}. Multi-skeleton models are not supported yet.`)}c.set(o,f)}}function $(n,t,e,c){const i=t!==e?c.get(t):void 0;if(!i)return n;const r=new Uint16Array(n.joints.length);for(let s=0;s<n.joints.length;s++)r[s]=i[n.joints[s]];return{joints:r,weights:n.weights}}function J(n,t){const e=new Float32Array(t(n.attributes.POSITION).data),c=n.attributes.NORMAL!==void 0?new Float32Array(t(n.attributes.NORMAL).data):void 0,i=n.attributes.TEXCOORD_0!==void 0?new Float32Array(t(n.attributes.TEXCOORD_0).data):void 0;let r;if(n.indices!==void 0){const s=t(n.indices);r=s.data.length>x?new Uint32Array(s.data):new Uint16Array(s.data)}return{positions:e,normals:c,uvs:i,indices:r}}function B(n,t,e){const c=n.length/3;for(let i=0;i<c;i++){const r=i*3,s=n[r],u=n[r+1],o=n[r+2];if(n[r]=e[0]*s+e[4]*u+e[8]*o+e[12],n[r+1]=e[1]*s+e[5]*u+e[9]*o+e[13],n[r+2]=e[2]*s+e[6]*u+e[10]*o+e[14],t){const l=t[r],d=t[r+1],f=t[r+2],y=e[0]*l+e[4]*d+e[8]*f,A=e[1]*l+e[5]*d+e[9]*f,h=e[2]*l+e[6]*d+e[10]*f,a=Math.sqrt(y*y+A*A+h*h);a>0&&(t[r]=y/a,t[r+1]=A/a,t[r+2]=h/a)}}}function F(n){return n.charCodeAt(0)|n.charCodeAt(1)<<8|n.charCodeAt(2)<<16|n.charCodeAt(3)<<24}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var D=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var W=Object.getOwnPropertyNames;var j=Object.prototype.hasOwnProperty;var q=(s,a)=>{for(var b in a)D(s,b,{get:a[b],enumerable:!0})},H=(s,a,b,h)=>{if(a&&typeof a=="object"||typeof a=="function")for(let p of W(a))!j.call(s,p)&&p!==b&&D(s,p,{get:()=>a[p],enumerable:!(h=_(a,p))||h.enumerable});return s};var K=s=>H(D({},"__esModule",{value:!0}),s);var X={};q(X,{parseGltf:()=>Q});module.exports=K(X);var $=require("../math"),c=require("./skin-parser"),u=require("./helpers");async function Q(s,a){const b=await fetch(s),h=s.substring(0,s.lastIndexOf("/")+1),p=await b.arrayBuffer(),{gltf:t,glbBinaryChunk:V}=(0,u.decodeGltfContainer)(p,s);if(!t.meshes?.length)throw new Error(`No meshes found in ${s}`);const T=[];for(let e=0;e<(t.buffers?.length??0);e++){const n=t.buffers[e];if(V&&(!n.uri||n.uri===""))T.push(V);else if(n.uri){const i=await fetch(h+n.uri);T.push(await i.arrayBuffer())}}const y=e=>{const n=t.accessors[e],i=t.bufferViews[n.bufferView],r=T[i.buffer],o={5120:Int8Array,5121:Uint8Array,5122:Int16Array,5123:Uint16Array,5125:Uint32Array,5126:Float32Array},d={5120:1,5121:1,5122:2,5123:2,5125:4,5126:4},f={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},g=o[n.componentType],w=d[n.componentType],l=f[n.type]??1,B=(i.byteOffset??0)+(n.byteOffset??0),x=i.byteStride??w*l,A=w*l;if(x===A)return{data:new g(r,B,n.count*l),count:n.count,elementSize:l};const S=new g(n.count*l),P=new Uint8Array(r),v=new Uint8Array(S.buffer);for(let C=0;C<n.count;C++){const J=B+C*x,L=C*A;for(let G=0;G<A;G++)v[L+G]=P[J+G]}return{data:S,count:n.count,elementSize:l}},M=new Map,z=async e=>{if(M.has(e))return M.get(e);const n=t.images?.[e];if(!n)return;let i;if(n.bufferView!==void 0){const r=t.bufferViews[n.bufferView],o=T[r.buffer],d=new Uint8Array(o,r.byteOffset??0,r.byteLength);i=new Blob([d],{type:n.mimeType??"image/png"})}else if(n.uri){const r=n.uri.startsWith("data:")?n.uri:h+n.uri;i=await(await fetch(r)).blob()}if(i){const r=await createImageBitmap(i);return M.set(e,r),r}},O=t.nodes?.findIndex(e=>e.mesh!==void 0&&e.skin!==void 0)??-1,k=O!==-1?t.nodes[O].skin:void 0;let m=null,I=[];const R=new Map;k!==void 0&&t.skins?.[k]&&(m=(0,c.parseSkin)(t,k,y),I=(0,c.parseAnimations)(t,m,y),a?.animations&&(I=I.filter(e=>a.animations.includes(e.name))),(0,u.validateAndBuildSkinRemaps)(t,k,m,R,y));const U=[];for(let e=0;e<t.nodes.length;e++)t.nodes[e].mesh!==void 0&&U.push(e);const E=U.length>0?U.map(e=>t.nodes[e].mesh):[0],F=[];for(const e of E){const n=t.meshes[e];if(!n)continue;const i=t.nodes.find(f=>f.mesh===e),r=i?.skin,o=m!==null&&r!==void 0;let d=null;i&&!o&&(i.scale||i.rotation||i.translation||i.matrix)&&(d=(0,$.nodeToMat4)(i));for(const f of n.primitives){const{positions:g,normals:w,uvs:l,indices:B}=(0,u.extractPrimitiveAttributes)(f,y);d&&!o&&(0,u.bakeTransformIntoVertices)(g,w,d);let x;if(f.material!==void 0){const v=t.materials?.[f.material]?.pbrMetallicRoughness?.baseColorTexture?.index;v!==void 0&&t.textures?.[v]&&(x=await z(t.textures[v].source))}let A,S=!1;if(o){const P=(0,c.parsePrimitiveSkinAttributes)(f,y);P&&(A=(0,u.remapSkinAttributes)(P,r,k,R),S=!0)}F.push({positions:g,normals:w,uvs:l,indices:B,texture:x,skinAttrs:A,skinned:S})}}let N=null;if(!a?.freezeAnimations&&m){const e=t.animations??[],n=e.map((r,o)=>r.name??`animation_${o}`),i=(0,c.buildNodeToJointMap)(m);N={availableAnimations:n,decodeAnimation(r){const o=e.findIndex((d,f)=>(d.name??`animation_${f}`)===r);if(o<0)throw new Error(`glTF ${s} has no animation named '${r}'`);return(0,c.decodeAnimationClip)(e[o],`animation_${o}`,i,y)}}}return{src:s,primitives:F,skin:m?{data:m,animClips:I}:null,source:N}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var C=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var I=(b,e)=>{for(var r in e)C(b,r,{get:e[r],enumerable:!0})},M=(b,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of S(e))!k.call(b,i)&&i!==r&&C(b,i,{get:()=>e[i],enumerable:!(n=A(e,i))||n.enumerable});return b};var w=b=>M(C({},"__esModule",{value:!0}),b);var F={};I(F,{SkeletalAnimation:()=>R});module.exports=w(F);var f=require("../math"),g=require("../../core/lerp");class R{constructor(e,r){this.clips=[];this.clipsByName=new Map;this._scratchVec3=new Float32Array(3);this._scratchQuat=new Float32Array(4);this.skinData=e;const n=e.jointCount;this.localMatrices=new Float32Array(n*16),this.worldMatrices=new Float32Array(n*16),this.blendScratch=new Float32Array(n*16),this.originalRestPoseTRS=new Float32Array(e.restPoseTRS),this.currentTRS=new Float32Array(n*10),this.skelRootMat=new Float32Array(16),e.skeletonRootMatrix?this.skelRootMat.set(e.skeletonRootMatrix):(this.skelRootMat[0]=1,this.skelRootMat[5]=1,this.skelRootMat[10]=1,this.skelRootMat[15]=1),this.topoOrder=new Uint16Array(n);const i=new Uint8Array(n);let s=0;const t=o=>{if(i[o])return;i[o]=1;const d=e.parentJointIndices[o];d!==-1&&t(d),this.topoOrder[s++]=o};for(let o=0;o<n;o++)t(o);for(const o of r)this.loadClip(o)}loadClip(e,r=!0){const n=this.clips.length;return this.clips.push({id:n,name:e.name,duration:e.duration,channels:e.channels,loop:r}),this.clipsByName.set(e.name,n),n}replaceClips(e,r=!0){const n=new Map(this.clipsByName),i=this.clips.length;this.clips=[],this.clipsByName.clear();for(const t of e)this.loadClip(t,r);const s=new Int32Array(i).fill(-1);for(const[t,o]of n){const d=this.clipsByName.get(t);d!==void 0&&(s[o]=d)}return s}getClipId(e){const r=this.clipsByName.get(e);if(r===void 0)throw new Error(`Skeletal clip "${e}" not found`);return r}getClipNames(){return this.clips.map(e=>e.name)}getClip(e){return this.clips[e]??null}get clipCount(){return this.clips.length}createState(e,r=1,n=!0){return{clipId:typeof e=="string"?this.getClipId(e):e,time:0,speed:r,playing:n,loop:!0,prevClipId:-1,prevTime:0,prevSpeed:1,blendWeight:1,blendDuration:0,onEnd:()=>null}}play(e,r,n){const i=typeof r=="string"?this.getClipId(r):r,s=n?.crossfade??0;s>0&&e.playing?(e.prevClipId=e.clipId,e.prevTime=e.time,e.prevSpeed=e.speed,e.blendWeight=0,e.blendDuration=s):(e.prevClipId=-1,e.blendWeight=1,e.blendDuration=0),e.onEnd=n?.onEnd??(()=>null),e.loop=n?.loop??!0,e.clipId=i,e.time=0,e.playing=!0,n?.speed!==void 0&&(e.speed=n.speed)}stop(e){e.playing=!1}resume(e){e.playing=!0}update(e,r,n,i=0){const s=this.skinData.jointCount;e.playing&&this.advanceTime(e,r);const t=e.prevClipId!==-1&&e.blendDuration>0&&e.blendWeight<1;if(t&&(e.blendWeight+=r/e.blendDuration,e.blendWeight>=1&&(e.blendWeight=1,e.prevClipId=-1,e.blendDuration=0)),t&&e.prevClipId!==-1){const o=this.clips[e.prevClipId];o&&(e.prevTime+=r*e.prevSpeed,o.loop&&e.prevTime>=o.duration&&(e.prevTime%=o.duration)),this.evaluateClip(e.prevClipId,e.prevTime,this.blendScratch,0),this.evaluateClip(e.clipId,e.time,n,i);const d=e.blendWeight,m=this.blendScratch,l=s*16;for(let a=0;a<l;a++)n[i+a]=(0,g.lerp)(m[a],n[i+a],d)}else this.evaluateClip(e.clipId,e.time,n,i)}advanceTime(e,r){const n=this.clips[e.clipId];!n||n.duration<=0||(e.time+=r*e.speed,e.time>=n.duration&&(n.loop?e.time%=n.duration:(e.time=n.duration-1e-4,e.playing=!1)),e.time<0&&(n.loop?e.time=n.duration+e.time%n.duration:(e.time=0,e.playing=!1)))}evaluateClip(e,r,n,i){const s=this.clips[e];if(!s)return;const t=this.skinData,o=t.jointCount,d=this.localMatrices,m=this.worldMatrices,l=this.currentTRS;l.set(this.originalRestPoseTRS);for(const p of s.channels){const u=p.jointIndex;if(u>=o)continue;const h=u*10,y=this.sampleChannel(p,r);p.path==="translation"?(l[h]=y[0],l[h+1]=y[1],l[h+2]=y[2]):p.path==="rotation"?(l[h+3]=y[0],l[h+4]=y[1],l[h+5]=y[2],l[h+6]=y[3]):p.path==="scale"&&(l[h+7]=y[0],l[h+8]=y[1],l[h+9]=y[2])}for(let p=0;p<o;p++){const u=p*10;(0,f.trsToMat4)(l[u],l[u+1],l[u+2],l[u+3],l[u+4],l[u+5],l[u+6],l[u+7],l[u+8],l[u+9],d,p*16)}const a=this.topoOrder,c=this.skelRootMat;for(let p=0;p<o;p++){const u=a[p],h=t.parentJointIndices[u];h===-1?(0,f.mat4Mul)(c,0,d,u*16,m,u*16):(0,f.mat4Mul)(m,h*16,d,u*16,m,u*16)}const v=t.inverseBindMatrices;for(let p=0;p<o;p++)(0,f.mat4Mul)(m,p*16,v,p*16,n,i+p*16)}computeRestPose(e,r=0){const n=this.skinData,i=n.jointCount,s=this.localMatrices,t=this.worldMatrices,o=this.originalRestPoseTRS;for(let a=0;a<i;a++){const c=a*10;(0,f.trsToMat4)(o[c],o[c+1],o[c+2],o[c+3],o[c+4],o[c+5],o[c+6],o[c+7],o[c+8],o[c+9],s,a*16)}const d=this.topoOrder,m=this.skelRootMat;for(let a=0;a<i;a++){const c=d[a],v=n.parentJointIndices[c];v===-1?(0,f.mat4Mul)(m,0,s,c*16,t,c*16):(0,f.mat4Mul)(t,v*16,s,c*16,t,c*16)}const l=n.inverseBindMatrices;for(let a=0;a<i;a++)(0,f.mat4Mul)(t,a*16,l,a*16,e,r+a*16)}sampleChannel(e,r){const n=e.timestamps,i=e.values,s=e.path==="rotation"?4:3;if(r<=n[0])return i.subarray(0,s);if(r>=n[n.length-1])return i.subarray((n.length-1)*s,n.length*s);let t=0,o=n.length-1;for(;t<o-1;){const p=t+o>>1;n[p]<=r?t=p:o=p}if(e.interpolation==="STEP")return i.subarray(t*s,t*s+s);const d=n[t],m=n[o],l=m>d?(r-d)/(m-d):0,a=t*s,c=o*s;if(e.path==="rotation")return this.nlerpQuat(i,a,i,c,l);const v=this._scratchVec3;return v[0]=(0,g.lerp)(i[a],i[c],l),v[1]=(0,g.lerp)(i[a+1],i[c+1],l),v[2]=(0,g.lerp)(i[a+2],i[c+2],l),v}nlerpQuat(e,r,n,i,s){const t=this._scratchQuat,d=e[r]*n[i]+e[r+1]*n[i+1]+e[r+2]*n[i+2]+e[r+3]*n[i+3]<0?-1:1,m=1-s;t[0]=m*e[r]+s*n[i]*d,t[1]=m*e[r+1]+s*n[i+1]*d,t[2]=m*e[r+2]+s*n[i+2]*d,t[3]=m*e[r+3]+s*n[i+3]*d;const l=Math.sqrt(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]+t[3]*t[3]);if(l>0){const a=1/l;t[0]*=a,t[1]*=a,t[2]*=a,t[3]*=a}return t}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var R=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var v=Object.prototype.hasOwnProperty;var U=(n,t)=>{for(var o in t)R(n,o,{get:t[o],enumerable:!0})},D=(n,t,o,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of P(t))!v.call(n,r)&&r!==o&&R(n,r,{get:()=>t[r],enumerable:!(i=w(t,r))||i.enumerable});return n};var J=n=>D(R({},"__esModule",{value:!0}),n);var H={};U(H,{buildNodeToJointMap:()=>T,createPackedAnimationData:()=>z,decodeAnimationClip:()=>M,getNodeTRS:()=>F,packSkinAndAnimations:()=>G,parseAnimations:()=>E,parsePrimitiveSkinAttributes:()=>W,parseSkin:()=>L});module.exports=J(H);var j=require("../math");function L(n,t,o){const i=n.skins[t],r=i.joints,l=r.length,m=o(i.inverseBindMatrices),x=new Float32Array(m.data),y=new Uint16Array(r),f=new Map;for(let a=0;a<l;a++)f.set(r[a],a);const c=new Map;for(let a=0;a<n.nodes.length;a++){const e=n.nodes[a].children;if(e)for(const s of e)c.set(s,a)}const p=new Int16Array(l).fill(-1);for(let a=0;a<l;a++){let e=c.get(r[a]);for(;e!==void 0;){const s=f.get(e);if(s!==void 0){p[a]=s;break}e=c.get(e)}}let A=null;for(let a=0;a<l;a++){if(p[a]!==-1)continue;let e=c.get(r[a]);const s=[];for(;e!==void 0&&!f.has(e);)s.push(e),e=c.get(e);if(s.length>0){A=(0,j.mat4IdentityNew)();for(let d=s.length-1;d>=0;d--){const g=(0,j.nodeToMat4)(n.nodes[s[d]]);A=(0,j.mat4MulNew)(A,g)}}break}const h=new Float32Array(l*10);for(let a=0;a<l;a++){const e=F(n.nodes[r[a]]);h.set(e,a*10)}return{jointCount:l,jointNodeIndices:y,inverseBindMatrices:x,parentJointIndices:p,skeletonRootMatrix:A,restPoseTRS:h}}function M(n,t,o,i){const r=[];let l=0;for(const m of n.channels){const x=m.target.node,y=o.get(x);if(y===void 0)continue;const f=m.target.path;if(f!=="translation"&&f!=="rotation"&&f!=="scale")continue;const c=n.samplers[m.sampler],p=c.interpolation??"LINEAR";if(p!=="LINEAR"&&p!=="STEP")continue;const A=i(c.input),h=new Float32Array(A.data),a=i(c.output),e=new Float32Array(a.data);if(h.length>0){const s=h[h.length-1];s>l&&(l=s)}r.push({jointIndex:y,path:f,timestamps:h,values:e,interpolation:p})}return r.length===0?null:{name:n.name??t,duration:l,channels:r}}function T(n){const t=new Map;for(let o=0;o<n.jointCount;o++)t.set(n.jointNodeIndices[o],o);return t}function E(n,t,o){if(!n.animations?.length)return[];const i=T(t),r=[];for(let l=0;l<n.animations.length;l++){const m=M(n.animations[l],`animation_${r.length}`,i,o);m&&r.push(m)}return r}function B(n){if(n instanceof Uint8Array){const t=new Float32Array(n.length);for(let o=0;o<n.length;o++)t[o]=n[o]/255;return t}if(n instanceof Uint16Array){const t=new Float32Array(n.length);for(let o=0;o<n.length;o++)t[o]=n[o]/65535;return t}return new Float32Array(n)}function _(n){const t=n.length/4;for(let o=0;o<t;o++){const i=o*4,r=n[i]+n[i+1]+n[i+2]+n[i+3];if(r>0&&Math.abs(r-1)>1e-5){const l=1/r;n[i]*=l,n[i+1]*=l,n[i+2]*=l,n[i+3]*=l}}}function W(n,t){if(n.attributes.JOINTS_0===void 0||n.attributes.WEIGHTS_0===void 0)return null;const o=t(n.attributes.JOINTS_0),i=t(n.attributes.WEIGHTS_0),r=o.data instanceof Uint16Array?o.data:new Uint16Array(o.data),l=B(i.data);return _(l),{joints:r,weights:l}}function F(n){const t=new Float32Array(10);if(n.matrix)return t[0]=n.matrix[12],t[1]=n.matrix[13],t[2]=n.matrix[14],t[3]=0,t[4]=0,t[5]=0,t[6]=1,t[7]=1,t[8]=1,t[9]=1,t;const o=n.translation??[0,0,0],i=n.rotation??[0,0,0,1],r=n.scale??[1,1,1];return t[0]=o[0],t[1]=o[1],t[2]=o[2],t[3]=i[0],t[4]=i[1],t[5]=i[2],t[6]=i[3],t[7]=r[0],t[8]=r[1],t[9]=r[2],t}function z(){return{channels:[],keyframeData:[],clips:[],skins:[],parentIndices:[],topoOrder:[],ibmData:[],restTRS:[],skelRootMats:[],jointChannelLookup:[]}}function G(n,t,o){const i=n.skins.length,r=t.jointCount,l=n.parentIndices.length,m=n.topoOrder.length,x=n.ibmData.length/16,y=n.restTRS.length/10,f=n.skelRootMats.length/16;for(let e=0;e<r;e++)n.parentIndices.push(t.parentJointIndices[e]);const c=new Uint8Array(r),p=e=>{if(c[e])return;c[e]=1;const s=t.parentJointIndices[e];s!==-1&&p(s),n.topoOrder.push(e)};for(let e=0;e<r;e++)p(e);for(let e=0;e<t.inverseBindMatrices.length;e++)n.ibmData.push(t.inverseBindMatrices[e]);for(let e=0;e<r;e++)for(let s=0;s<10;s++)n.restTRS.push(t.restPoseTRS[e*10+s]);if(t.skeletonRootMatrix)for(let e=0;e<16;e++)n.skelRootMats.push(t.skeletonRootMatrix[e]);else{const e=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];for(let s=0;s<16;s++)n.skelRootMats.push(e[s])}const A=n.clips.length,h=n.jointChannelLookup.length;n.skins.push({jointCount:r,parentOffset:l,topoOffset:m,ibmOffset:x,restTRSOffset:y,skelRootMatIndex:f,clipOffset:A,jointLookupStart:h});const a=new Map;for(let e=0;e<r;e++)a.set(t.jointNodeIndices[e],e);for(const e of o){const s=n.channels.length,d=[...e.channels].sort((u,I)=>u.jointIndex-I.jointIndex);for(const u of d){const I=u.path==="translation"?0:u.path==="rotation"?1:2,k=u.interpolation==="STEP"?4:0,O=n.keyframeData.length,C=u.timestamps.length,N=u.path==="rotation"?4:3;for(let b=0;b<C;b++)n.keyframeData.push(u.timestamps[b]);for(let b=0;b<C*N;b++)n.keyframeData.push(u.values[b]);n.channels.push({jointIndex:u.jointIndex,pathAndInterp:I|k,keyframeCount:C,dataOffset:O})}const g=d.length;let S=0;for(let u=0;u<r;u++){const I=S;for(;S<g&&d[S].jointIndex===u;)S++;n.jointChannelLookup.push(s+I),n.jointChannelLookup.push(S-I)}n.clips.push({channelStart:s,channelCount:g,duration:e.duration,looping:1})}return i}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var x=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var n=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var b=(t,o)=>{for(var f in o)x(t,f,{get:o[f],enumerable:!0})},m=(t,o,f,a)=>{if(o&&typeof o=="object"||typeof o=="function")for(let p of n(o))!c.call(t,p)&&p!==f&&x(t,p,{get:()=>o[p],enumerable:!(a=i(o,p))||a.enumerable});return t},r=(t,o,f)=>(m(t,o,"default"),f&&m(f,o,"default"));var u=t=>m(x({},"__esModule",{value:!0}),t);var e={};b(e,{PrefabBucket:()=>k.PrefabBucket,SkeletalAnimation:()=>l.SkeletalAnimation});module.exports=u(e);r(e,require("./types"),module.exports);r(e,require("./base/renderer"),module.exports);r(e,require("./base/renderer-2d"),module.exports);r(e,require("./base/renderer-3d"),module.exports);r(e,require("./math"),module.exports);r(e,require("./gltf/skin-parser"),module.exports);r(e,require("./gltf/parser"),module.exports);var l=require("./gltf/skeletal-animation");r(e,require("./spritesheet/helpers"),module.exports);r(e,require("./spritesheet/parser"),module.exports);r(e,require("./prefab-bucket"),module.exports);r(e,require("./prefab-bucket/specs"),module.exports);var k=require("./prefab-bucket/concrete");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var k=(r,n)=>{for(var m in n)e(r,m,{get:n[m],enumerable:!0})},B=(r,n,m,a)=>{if(n&&typeof n=="object"||typeof n=="function")for(let u of g(n))!h.call(r,u)&&u!==m&&e(r,u,{get:()=>n[u],enumerable:!(a=_(n,u))||a.enumerable});return r};var C=r=>B(e({},"__esModule",{value:!0}),r);var K={};k(K,{mat4Identity:()=>D,mat4IdentityNew:()=>E,mat4Mul:()=>H,mat4MulNew:()=>J,nodeToMat4:()=>G,trsToMat4:()=>N});module.exports=C(K);function D(r,n){r[n]=1,r[n+1]=0,r[n+2]=0,r[n+3]=0,r[n+4]=0,r[n+5]=1,r[n+6]=0,r[n+7]=0,r[n+8]=0,r[n+9]=0,r[n+10]=1,r[n+11]=0,r[n+12]=0,r[n+13]=0,r[n+14]=0,r[n+15]=1}function E(){const r=new Float32Array(16);return r[0]=1,r[5]=1,r[10]=1,r[15]=1,r}function N(r,n,m,a,u,y,o,c,A,F,l,i){const b=a*a,t=u*u,x=y*y,p=a*u,w=a*y,M=u*y,v=o*a,T=o*u,j=o*y;l[i]=(1-2*(t+x))*c,l[i+1]=2*(p+j)*c,l[i+2]=2*(w-T)*c,l[i+3]=0,l[i+4]=2*(p-j)*A,l[i+5]=(1-2*(b+x))*A,l[i+6]=2*(M+v)*A,l[i+7]=0,l[i+8]=2*(w+T)*F,l[i+9]=2*(M-v)*F,l[i+10]=(1-2*(b+t))*F,l[i+11]=0,l[i+12]=r,l[i+13]=n,l[i+14]=m,l[i+15]=1}function G(r){const n=new Float32Array(16);if(r.matrix)return n.set(r.matrix),n;const m=r.translation??[0,0,0],a=r.rotation??[0,0,0,1],u=r.scale??[1,1,1];return N(m[0],m[1],m[2],a[0],a[1],a[2],a[3],u[0],u[1],u[2],n,0),n}const I=new Float32Array(16);function H(r,n,m,a,u,y){for(let o=0;o<4;o++)for(let c=0;c<4;c++)I[c*4+o]=r[n+o]*m[a+c*4]+r[n+4+o]*m[a+c*4+1]+r[n+8+o]*m[a+c*4+2]+r[n+12+o]*m[a+c*4+3];u.set(I,y)}function J(r,n){const m=new Float32Array(16);for(let a=0;a<4;a++)for(let u=0;u<4;u++)m[u*4+a]=r[a]*n[u*4]+r[4+a]*n[u*4+1]+r[8+a]*n[u*4+2]+r[12+a]*n[u*4+3];return m}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var a=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var n=Object.getOwnPropertyNames;var o=Object.prototype.hasOwnProperty;var f=(r,e)=>{for(var s in e)a(r,s,{get:e[s],enumerable:!0})},b=(r,e,s,c)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of n(e))!o.call(r,t)&&t!==s&&a(r,t,{get:()=>e[t],enumerable:!(c=S(e,t))||c.enumerable});return r};var P=r=>b(a({},"__esModule",{value:!0}),r);var u={};f(u,{PrefabBucket:()=>i});module.exports=P(u);var d=require("./index"),p=require("./parsers");class i extends d.BasePrefabBucket{constructor(e){const s=e==="3d"?p.parsers3d:p.parsers2d;super(e,s)}add(e){return super.add(e)}addAll(e){return super.addAll(e)}get(e){return super.get(e)}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var n=Object.defineProperty;var o=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var b=(s,e)=>{for(var r in e)n(s,r,{get:e[r],enumerable:!0})},c=(s,e,r,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of d(e))!p.call(s,a)&&a!==r&&n(s,a,{get:()=>e[a],enumerable:!(t=o(e,a))||t.enumerable});return s};var P=s=>c(n({},"__esModule",{value:!0}),s);var h={};b(h,{BasePrefabBucket:()=>u});module.exports=P(h);var f=require("../../core/events");class u{constructor(e,r={}){this.pending=[];this.pendingIds=new Set;this.prefabs=null;this.mode=e,this.parsers=r,this.events=new f.EventSystem({events:["clips-changed"]})}add(e){if(this.prefabs)throw new Error("PrefabBucket: cannot add after load() \u2014 bucket is frozen");if(this.pendingIds.has(e.id))throw new Error(`PrefabBucket: duplicate id '${e.id}'`);return this.pending.push(e),this.pendingIds.add(e.id),this}addAll(e){if(this.prefabs)throw new Error("PrefabBucket: cannot add after load() \u2014 bucket is frozen");const r=new Set;for(const t of e){if(this.pendingIds.has(t.id)||r.has(t.id))throw new Error(`PrefabBucket: duplicate id '${t.id}'`);r.add(t.id)}for(const t of e)this.pending.push(t),this.pendingIds.add(t.id);return this}async load(){if(this.prefabs)return;const e={events:this.events},r=await Promise.all(this.pending.map(a=>{const i=this.parsers[a.type];if(!i)throw new Error(`PrefabBucket: no parser registered for type '${a.type}'`);return i(a,e)})),t=new Map;for(const a of r)t.set(a.id,a);this.prefabs=t,this.pending=[],this.pendingIds.clear()}get(e){if(!this.prefabs)throw new Error(`PrefabBucket: get('${e}') called before load()`);const r=this.prefabs.get(e);if(!r)throw new Error(`PrefabBucket: unknown prefab id '${e}'`);return r}get loaded(){return this.prefabs!==null}get size(){return this.prefabs?this.prefabs.size:this.pending.length}entries(){if(!this.prefabs)throw new Error("PrefabBucket: entries() called before load()");return Array.from(this.prefabs.values())}getAllByType(e){if(!this.prefabs)throw new Error(`PrefabBucket: getAllByType('${e}') called before load()`);const r=[];for(const t of this.prefabs.values())t.type===e&&r.push(t);return r}resetAnimations(){if(this.prefabs)for(const e of this.prefabs.values())e.resetAnimations?.()}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var u=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var C=(n,e)=>{for(var i in e)u(n,i,{get:e[i],enumerable:!0})},A=(n,e,i,h)=>{if(e&&typeof e=="object"||typeof e=="function")for(let p of v(e))!k.call(n,p)&&p!==i&&u(n,p,{get:()=>e[p],enumerable:!(h=b(e,p))||h.enumerable});return n};var D=n=>A(u({},"__esModule",{value:!0}),n);var x={};C(x,{parsers2d:()=>z,parsers3d:()=>S});module.exports=D(x);var y=require("../gltf/parser"),P=require("../spritesheet/parser");const S={gltf:async(n,e)=>{if(n.type!=="gltf")throw new Error("gltf parser given non-gltf spec");const i=await(0,y.parseGltf)(n.src,{animations:n.animations!==void 0?[...n.animations]:void 0,freezeAnimations:n.freezeAnimations===!0}),h=i.primitives.filter(d=>d.skinned).length,p=i.skin?.data.jointCount??0;let w=0;for(const d of i.primitives)w+=d.positions.length/3;const t={type:"gltf",id:n.id,parsed:i,skinnedPartCount:h,jointCount:p,totalVertexCount:w,metadata:n.metadata??{}},g=n.animations!==void 0?[...n.animations]:i.skin?.animClips.map(d=>d.name)??[];if(g.length>0){const d={};for(const f of g)d[f]=f;t.animations=d,t.animationList=g}if(n.freezeAnimations!==!0){t.loadAnimations=async f=>{const r=i.skin,m=i.source;if(!r||!m)throw new Error(`loadAnimations: prefab '${n.id}' has no source \u2014 was the model skinned and not frozen?`);const l=new Set(r.animClips.map(s=>s.name)),a=[];for(const s of f){if(l.has(s))continue;const o=m.decodeAnimation(s);o&&(r.animClips.push(o),l.add(s),a.push(s))}if(a.length>0){t.animationList||(t.animationList=[]),t.animations||(t.animations={});const s=t.animationList,o=t.animations;for(const c of a)s.push(c),o[c]=c;e.events.emit("clips-changed",{prefabId:n.id,added:a,removed:[]})}},t.unloadAnimations=f=>{const r=i.skin;if(!r)return;const m=new Set(f),l=[];if(r.animClips=r.animClips.filter(a=>m.has(a.name)?(l.push(a.name),!1):!0),l.length>0){const a=t.animationList;if(a)for(let o=a.length-1;o>=0;o--)m.has(a[o])&&a.splice(o,1);const s=t.animations;if(s)for(const o of l)delete s[o];e.events.emit("clips-changed",{prefabId:n.id,added:[],removed:l})}};const d=new Set(g);t.resetAnimations=()=>{const f=i.skin;if(!f)return;const r=[];for(const m of f.animClips)d.has(m.name)||r.push(m.name);r.length>0&&t.unloadAnimations(r)}}return t},grid:n=>{if(n.type!=="grid")throw new Error("grid parser given non-grid spec");return{type:"grid",id:n.id,size:n.size,step:n.step,lineWidth:n.lineWidth,metadata:n.metadata??{}}}},z={spritesheet:async(n,e)=>{if(n.type!=="spritesheet")throw new Error("spritesheet parser given non-spritesheet spec");const i=await(0,P.parseSpritesheet)({image:n.src,frameWidth:n.frameWidth,frameHeight:n.frameHeight,data:n.data});return{type:"spritesheet",id:n.id,parsed:i,frameCount:i.uvs.length,width:i.width,height:i.height,metadata:n.metadata??{}}}};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var a=Object.defineProperty;var o=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var s=Object.prototype.hasOwnProperty;var l=(n,e,i,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of d(e))!s.call(n,t)&&t!==i&&a(n,t,{get:()=>e[t],enumerable:!(r=o(e,t))||r.enumerable});return n};var p=n=>l(a({},"__esModule",{value:!0}),n);var y={};module.exports=p(y);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var u=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var f=Object.prototype.hasOwnProperty;var b=(e,r)=>{for(var t in r)u(e,t,{get:r[t],enumerable:!0})},x=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of p(r))!f.call(e,o)&&o!==t&&u(e,o,{get:()=>r[o],enumerable:!(n=i(r,o))||n.enumerable});return e};var l=e=>x(u({},"__esModule",{value:!0}),e);var k={};b(k,{computeGridUVs:()=>w,computeTexturePackerUVs:()=>y,loadImage:()=>h});module.exports=l(k);function w(e,r,t,n){const o=Math.floor(e/t),m=Math.floor(r/n),c=[];for(let a=0;a<m;a++)for(let s=0;s<o;s++)c.push({minX:s*t/e,minY:a*n/r,maxX:(s+1)*t/e,maxY:(a+1)*n/r});return c}function y(e){const{w:r,h:t}=e.meta.size,n=[];for(const o of Object.keys(e.frames)){const m=e.frames[o].frame;n.push({minX:m.x/r,minY:m.y/t,maxX:(m.x+m.w)/r,maxY:(m.y+m.h)/t})}return n}async function h(e){const t=await(await fetch(e)).blob();return createImageBitmap(t)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var p=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var s=Object.getOwnPropertyNames;var n=Object.prototype.hasOwnProperty;var d=(e,t)=>{for(var i in t)p(e,i,{get:t[i],enumerable:!0})},o=(e,t,i,m)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of s(t))!n.call(e,a)&&a!==i&&p(e,a,{get:()=>t[a],enumerable:!(m=h(t,a))||m.enumerable});return e};var f=e=>o(p({},"__esModule",{value:!0}),e);var g={};d(g,{parseSpritesheet:()=>S});module.exports=f(g);var r=require("./helpers");async function S(e){const t=await(0,r.loadImage)(e.image);let i;if(e.data){const a=await(await fetch(e.data)).json();i=(0,r.computeTexturePackerUVs)(a)}else e.frameWidth&&e.frameHeight?i=(0,r.computeGridUVs)(t.width,t.height,e.frameWidth,e.frameHeight):i=[{minX:0,minY:0,maxX:1,maxY:1}];return{bitmap:t,uvs:i,width:t.width,height:t.height}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var o=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var a=Object.prototype.hasOwnProperty;var i=(r,e,t,m)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of u(e))!a.call(r,n)&&n!==t&&o(r,n,{get:()=>e[n],enumerable:!(m=b(e,n))||m.enumerable});return r};var p=r=>i(o({},"__esModule",{value:!0}),r);var l={};module.exports=p(l);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{BaseRenderer as t}from"./renderer";class p extends t{constructor(r,e){super(r,e),this.maxSprites=e.maxSprites??1024}}export{p as Base2DRenderer};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{BaseRenderer as a}from"./renderer";class n extends a{constructor(r,e){super(r,e),this.maxModels=e.maxModels??32}}export{n as Base3DRenderer};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const F=g("glTF"),k=g("JSON"),p=g("BIN\0"),C=65535;function U(n,r){if(new Uint32Array(n,0,1)[0]!==F)return{gltf:JSON.parse(new TextDecoder().decode(n)),glbBinaryChunk:null};let c,a=null,t=12;for(;t<n.byteLength;){const i=new Uint32Array(n,t,1)[0],u=new Uint32Array(n,t+4,1)[0];if(t+=8,u===k){const o=new Uint8Array(n,t,i);c=JSON.parse(new TextDecoder().decode(o))}else u===p&&(a=n.slice(t,t+i));t+=i}if(!c)throw new Error(`Invalid GLB: no JSON chunk in ${r}`);return{gltf:c,glbBinaryChunk:a}}function j(n,r,e,c,a){const t=new Map;for(let o=0;o<e.jointCount;o++)t.set(e.jointNodeIndices[o],o);const i=e.inverseBindMatrices,u=new Set;for(const o of n.nodes)o.mesh!==void 0&&o.skin!==void 0&&u.add(o.skin);for(const o of u){if(o===r)continue;const l=n.skins[o];if(!l)continue;const d=l.joints;if(d.length!==e.jointCount)throw new Error(`glTF has incompatible skins (skin ${o} has ${d.length} joints, canonical skin ${r} has ${e.jointCount}). Multi-skeleton models are not supported yet.`);const f=new Uint16Array(d.length);for(let s=0;s<d.length;s++){const b=t.get(d[s]);if(b===void 0)throw new Error(`glTF skin ${o} references node ${d[s]} which is not a joint in canonical skin ${r}. Multi-skeleton models are not supported yet.`);f[s]=b}const A=a(l.inverseBindMatrices).data,h=1e-4;for(let s=0;s<d.length;s++){const b=f[s];for(let w=0;w<16;w++)if(Math.abs(A[s*16+w]-i[b*16+w])>h)throw new Error(`glTF skin ${o} has different inverse bind matrices than canonical skin ${r}. Multi-skeleton models are not supported yet.`)}c.set(o,f)}}function N(n,r,e,c){const a=r!==e?c.get(r):void 0;if(!a)return n;const t=new Uint16Array(n.joints.length);for(let i=0;i<n.joints.length;i++)t[i]=a[n.joints[i]];return{joints:t,weights:n.weights}}function M(n,r){const e=new Float32Array(r(n.attributes.POSITION).data),c=n.attributes.NORMAL!==void 0?new Float32Array(r(n.attributes.NORMAL).data):void 0,a=n.attributes.TEXCOORD_0!==void 0?new Float32Array(r(n.attributes.TEXCOORD_0).data):void 0;let t;if(n.indices!==void 0){const i=r(n.indices);t=i.data.length>C?new Uint32Array(i.data):new Uint16Array(i.data)}return{positions:e,normals:c,uvs:a,indices:t}}function O(n,r,e){const c=n.length/3;for(let a=0;a<c;a++){const t=a*3,i=n[t],u=n[t+1],o=n[t+2];if(n[t]=e[0]*i+e[4]*u+e[8]*o+e[12],n[t+1]=e[1]*i+e[5]*u+e[9]*o+e[13],n[t+2]=e[2]*i+e[6]*u+e[10]*o+e[14],r){const l=r[t],d=r[t+1],f=r[t+2],y=e[0]*l+e[4]*d+e[8]*f,A=e[1]*l+e[5]*d+e[9]*f,h=e[2]*l+e[6]*d+e[10]*f,s=Math.sqrt(y*y+A*A+h*h);s>0&&(r[t]=y/s,r[t+1]=A/s,r[t+2]=h/s)}}}function g(n){return n.charCodeAt(0)|n.charCodeAt(1)<<8|n.charCodeAt(2)<<16|n.charCodeAt(3)<<24}export{O as bakeTransformIntoVertices,U as decodeGltfContainer,M as extractPrimitiveAttributes,N as remapSkinAttributes,j as validateAndBuildSkinRemaps};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{nodeToMat4 as z}from"../math";import{parseSkin as E,parseAnimations as J,parsePrimitiveSkinAttributes as L,decodeAnimationClip as _,buildNodeToJointMap as W}from"./skin-parser";import{bakeTransformIntoVertices as j,decodeGltfContainer as q,extractPrimitiveAttributes as H,remapSkinAttributes as K,validateAndBuildSkinRemaps as Q}from"./helpers";async function ee(u,v){const V=await fetch(u),I=u.substring(0,u.lastIndexOf("/")+1),O=await V.arrayBuffer(),{gltf:t,glbBinaryChunk:B}=q(O,u);if(!t.meshes?.length)throw new Error(`No meshes found in ${u}`);const w=[];for(let e=0;e<(t.buffers?.length??0);e++){const n=t.buffers[e];if(B&&(!n.uri||n.uri===""))w.push(B);else if(n.uri){const i=await fetch(I+n.uri);w.push(await i.arrayBuffer())}}const d=e=>{const n=t.accessors[e],i=t.bufferViews[n.bufferView],r=w[i.buffer],s={5120:Int8Array,5121:Uint8Array,5122:Int16Array,5123:Uint16Array,5125:Uint32Array,5126:Float32Array},o={5120:1,5121:1,5122:2,5123:2,5125:4,5126:4},a={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},p=s[n.componentType],b=o[n.componentType],c=a[n.type]??1,S=(i.byteOffset??0)+(n.byteOffset??0),y=i.byteStride??b*c,m=b*c;if(y===m)return{data:new p(r,S,n.count*c),count:n.count,elementSize:c};const A=new p(n.count*c),h=new Uint8Array(r),k=new Uint8Array(A.buffer);for(let g=0;g<n.count;g++){const N=S+g*y,$=g*m;for(let P=0;P<m;P++)k[$+P]=h[N+P]}return{data:A,count:n.count,elementSize:c}},C=new Map,R=async e=>{if(C.has(e))return C.get(e);const n=t.images?.[e];if(!n)return;let i;if(n.bufferView!==void 0){const r=t.bufferViews[n.bufferView],s=w[r.buffer],o=new Uint8Array(s,r.byteOffset??0,r.byteLength);i=new Blob([o],{type:n.mimeType??"image/png"})}else if(n.uri){const r=n.uri.startsWith("data:")?n.uri:I+n.uri;i=await(await fetch(r)).blob()}if(i){const r=await createImageBitmap(i);return C.set(e,r),r}},G=t.nodes?.findIndex(e=>e.mesh!==void 0&&e.skin!==void 0)??-1,l=G!==-1?t.nodes[G].skin:void 0;let f=null,x=[];const M=new Map;l!==void 0&&t.skins?.[l]&&(f=E(t,l,d),x=J(t,f,d),v?.animations&&(x=x.filter(e=>v.animations.includes(e.name))),Q(t,l,f,M,d));const T=[];for(let e=0;e<t.nodes.length;e++)t.nodes[e].mesh!==void 0&&T.push(e);const F=T.length>0?T.map(e=>t.nodes[e].mesh):[0],U=[];for(const e of F){const n=t.meshes[e];if(!n)continue;const i=t.nodes.find(a=>a.mesh===e),r=i?.skin,s=f!==null&&r!==void 0;let o=null;i&&!s&&(i.scale||i.rotation||i.translation||i.matrix)&&(o=z(i));for(const a of n.primitives){const{positions:p,normals:b,uvs:c,indices:S}=H(a,d);o&&!s&&j(p,b,o);let y;if(a.material!==void 0){const k=t.materials?.[a.material]?.pbrMetallicRoughness?.baseColorTexture?.index;k!==void 0&&t.textures?.[k]&&(y=await R(t.textures[k].source))}let m,A=!1;if(s){const h=L(a,d);h&&(m=K(h,r,l,M),A=!0)}U.push({positions:p,normals:b,uvs:c,indices:S,texture:y,skinAttrs:m,skinned:A})}}let D=null;if(!v?.freezeAnimations&&f){const e=t.animations??[],n=e.map((r,s)=>r.name??`animation_${s}`),i=W(f);D={availableAnimations:n,decodeAnimation(r){const s=e.findIndex((o,a)=>(o.name??`animation_${a}`)===r);if(s<0)throw new Error(`glTF ${u} has no animation named '${r}'`);return _(e[s],`animation_${s}`,i,d)}}}return{src:u,primitives:U,skin:f?{data:f,animClips:x}:null,source:D}}export{ee as parseGltf};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{trsToMat4 as g,mat4Mul as v}from"../math";import{lerp as b}from"../../core/lerp";class k{constructor(e,o){this.clips=[];this.clipsByName=new Map;this._scratchVec3=new Float32Array(3);this._scratchQuat=new Float32Array(4);this.skinData=e;const n=e.jointCount;this.localMatrices=new Float32Array(n*16),this.worldMatrices=new Float32Array(n*16),this.blendScratch=new Float32Array(n*16),this.originalRestPoseTRS=new Float32Array(e.restPoseTRS),this.currentTRS=new Float32Array(n*10),this.skelRootMat=new Float32Array(16),e.skeletonRootMatrix?this.skelRootMat.set(e.skeletonRootMatrix):(this.skelRootMat[0]=1,this.skelRootMat[5]=1,this.skelRootMat[10]=1,this.skelRootMat[15]=1),this.topoOrder=new Uint16Array(n);const r=new Uint8Array(n);let s=0;const i=t=>{if(r[t])return;r[t]=1;const d=e.parentJointIndices[t];d!==-1&&i(d),this.topoOrder[s++]=t};for(let t=0;t<n;t++)i(t);for(const t of o)this.loadClip(t)}loadClip(e,o=!0){const n=this.clips.length;return this.clips.push({id:n,name:e.name,duration:e.duration,channels:e.channels,loop:o}),this.clipsByName.set(e.name,n),n}replaceClips(e,o=!0){const n=new Map(this.clipsByName),r=this.clips.length;this.clips=[],this.clipsByName.clear();for(const i of e)this.loadClip(i,o);const s=new Int32Array(r).fill(-1);for(const[i,t]of n){const d=this.clipsByName.get(i);d!==void 0&&(s[t]=d)}return s}getClipId(e){const o=this.clipsByName.get(e);if(o===void 0)throw new Error(`Skeletal clip "${e}" not found`);return o}getClipNames(){return this.clips.map(e=>e.name)}getClip(e){return this.clips[e]??null}get clipCount(){return this.clips.length}createState(e,o=1,n=!0){return{clipId:typeof e=="string"?this.getClipId(e):e,time:0,speed:o,playing:n,loop:!0,prevClipId:-1,prevTime:0,prevSpeed:1,blendWeight:1,blendDuration:0,onEnd:()=>null}}play(e,o,n){const r=typeof o=="string"?this.getClipId(o):o,s=n?.crossfade??0;s>0&&e.playing?(e.prevClipId=e.clipId,e.prevTime=e.time,e.prevSpeed=e.speed,e.blendWeight=0,e.blendDuration=s):(e.prevClipId=-1,e.blendWeight=1,e.blendDuration=0),e.onEnd=n?.onEnd??(()=>null),e.loop=n?.loop??!0,e.clipId=r,e.time=0,e.playing=!0,n?.speed!==void 0&&(e.speed=n.speed)}stop(e){e.playing=!1}resume(e){e.playing=!0}update(e,o,n,r=0){const s=this.skinData.jointCount;e.playing&&this.advanceTime(e,o);const i=e.prevClipId!==-1&&e.blendDuration>0&&e.blendWeight<1;if(i&&(e.blendWeight+=o/e.blendDuration,e.blendWeight>=1&&(e.blendWeight=1,e.prevClipId=-1,e.blendDuration=0)),i&&e.prevClipId!==-1){const t=this.clips[e.prevClipId];t&&(e.prevTime+=o*e.prevSpeed,t.loop&&e.prevTime>=t.duration&&(e.prevTime%=t.duration)),this.evaluateClip(e.prevClipId,e.prevTime,this.blendScratch,0),this.evaluateClip(e.clipId,e.time,n,r);const d=e.blendWeight,m=this.blendScratch,l=s*16;for(let a=0;a<l;a++)n[r+a]=b(m[a],n[r+a],d)}else this.evaluateClip(e.clipId,e.time,n,r)}advanceTime(e,o){const n=this.clips[e.clipId];!n||n.duration<=0||(e.time+=o*e.speed,e.time>=n.duration&&(n.loop?e.time%=n.duration:(e.time=n.duration-1e-4,e.playing=!1)),e.time<0&&(n.loop?e.time=n.duration+e.time%n.duration:(e.time=0,e.playing=!1)))}evaluateClip(e,o,n,r){const s=this.clips[e];if(!s)return;const i=this.skinData,t=i.jointCount,d=this.localMatrices,m=this.worldMatrices,l=this.currentTRS;l.set(this.originalRestPoseTRS);for(const p of s.channels){const u=p.jointIndex;if(u>=t)continue;const h=u*10,y=this.sampleChannel(p,o);p.path==="translation"?(l[h]=y[0],l[h+1]=y[1],l[h+2]=y[2]):p.path==="rotation"?(l[h+3]=y[0],l[h+4]=y[1],l[h+5]=y[2],l[h+6]=y[3]):p.path==="scale"&&(l[h+7]=y[0],l[h+8]=y[1],l[h+9]=y[2])}for(let p=0;p<t;p++){const u=p*10;g(l[u],l[u+1],l[u+2],l[u+3],l[u+4],l[u+5],l[u+6],l[u+7],l[u+8],l[u+9],d,p*16)}const a=this.topoOrder,c=this.skelRootMat;for(let p=0;p<t;p++){const u=a[p],h=i.parentJointIndices[u];h===-1?v(c,0,d,u*16,m,u*16):v(m,h*16,d,u*16,m,u*16)}const f=i.inverseBindMatrices;for(let p=0;p<t;p++)v(m,p*16,f,p*16,n,r+p*16)}computeRestPose(e,o=0){const n=this.skinData,r=n.jointCount,s=this.localMatrices,i=this.worldMatrices,t=this.originalRestPoseTRS;for(let a=0;a<r;a++){const c=a*10;g(t[c],t[c+1],t[c+2],t[c+3],t[c+4],t[c+5],t[c+6],t[c+7],t[c+8],t[c+9],s,a*16)}const d=this.topoOrder,m=this.skelRootMat;for(let a=0;a<r;a++){const c=d[a],f=n.parentJointIndices[c];f===-1?v(m,0,s,c*16,i,c*16):v(i,f*16,s,c*16,i,c*16)}const l=n.inverseBindMatrices;for(let a=0;a<r;a++)v(i,a*16,l,a*16,e,o+a*16)}sampleChannel(e,o){const n=e.timestamps,r=e.values,s=e.path==="rotation"?4:3;if(o<=n[0])return r.subarray(0,s);if(o>=n[n.length-1])return r.subarray((n.length-1)*s,n.length*s);let i=0,t=n.length-1;for(;i<t-1;){const p=i+t>>1;n[p]<=o?i=p:t=p}if(e.interpolation==="STEP")return r.subarray(i*s,i*s+s);const d=n[i],m=n[t],l=m>d?(o-d)/(m-d):0,a=i*s,c=t*s;if(e.path==="rotation")return this.nlerpQuat(r,a,r,c,l);const f=this._scratchVec3;return f[0]=b(r[a],r[c],l),f[1]=b(r[a+1],r[c+1],l),f[2]=b(r[a+2],r[c+2],l),f}nlerpQuat(e,o,n,r,s){const i=this._scratchQuat,d=e[o]*n[r]+e[o+1]*n[r+1]+e[o+2]*n[r+2]+e[o+3]*n[r+3]<0?-1:1,m=1-s;i[0]=m*e[o]+s*n[r]*d,i[1]=m*e[o+1]+s*n[r+1]*d,i[2]=m*e[o+2]+s*n[r+2]*d,i[3]=m*e[o+3]+s*n[r+3]*d;const l=Math.sqrt(i[0]*i[0]+i[1]*i[1]+i[2]*i[2]+i[3]*i[3]);if(l>0){const a=1/l;i[0]*=a,i[1]*=a,i[2]*=a,i[3]*=a}return i}}export{k as SkeletalAnimation};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{nodeToMat4 as T,mat4MulNew as F,mat4IdentityNew as k}from"../math";function D(n,t,o){const s=n.skins[t],r=s.joints,l=r.length,m=o(s.inverseBindMatrices),j=new Float32Array(m.data),y=new Uint16Array(r),f=new Map;for(let i=0;i<l;i++)f.set(r[i],i);const c=new Map;for(let i=0;i<n.nodes.length;i++){const e=n.nodes[i].children;if(e)for(const a of e)c.set(a,i)}const p=new Int16Array(l).fill(-1);for(let i=0;i<l;i++){let e=c.get(r[i]);for(;e!==void 0;){const a=f.get(e);if(a!==void 0){p[i]=a;break}e=c.get(e)}}let A=null;for(let i=0;i<l;i++){if(p[i]!==-1)continue;let e=c.get(r[i]);const a=[];for(;e!==void 0&&!f.has(e);)a.push(e),e=c.get(e);if(a.length>0){A=k();for(let d=a.length-1;d>=0;d--){const S=T(n.nodes[a[d]]);A=F(A,S)}}break}const h=new Float32Array(l*10);for(let i=0;i<l;i++){const e=v(n.nodes[r[i]]);h.set(e,i*10)}return{jointCount:l,jointNodeIndices:y,inverseBindMatrices:j,parentJointIndices:p,skeletonRootMatrix:A,restPoseTRS:h}}function O(n,t,o,s){const r=[];let l=0;for(const m of n.channels){const j=m.target.node,y=o.get(j);if(y===void 0)continue;const f=m.target.path;if(f!=="translation"&&f!=="rotation"&&f!=="scale")continue;const c=n.samplers[m.sampler],p=c.interpolation??"LINEAR";if(p!=="LINEAR"&&p!=="STEP")continue;const A=s(c.input),h=new Float32Array(A.data),i=s(c.output),e=new Float32Array(i.data);if(h.length>0){const a=h[h.length-1];a>l&&(l=a)}r.push({jointIndex:y,path:f,timestamps:h,values:e,interpolation:p})}return r.length===0?null:{name:n.name??t,duration:l,channels:r}}function N(n){const t=new Map;for(let o=0;o<n.jointCount;o++)t.set(n.jointNodeIndices[o],o);return t}function J(n,t,o){if(!n.animations?.length)return[];const s=N(t),r=[];for(let l=0;l<n.animations.length;l++){const m=O(n.animations[l],`animation_${r.length}`,s,o);m&&r.push(m)}return r}function w(n){if(n instanceof Uint8Array){const t=new Float32Array(n.length);for(let o=0;o<n.length;o++)t[o]=n[o]/255;return t}if(n instanceof Uint16Array){const t=new Float32Array(n.length);for(let o=0;o<n.length;o++)t[o]=n[o]/65535;return t}return new Float32Array(n)}function P(n){const t=n.length/4;for(let o=0;o<t;o++){const s=o*4,r=n[s]+n[s+1]+n[s+2]+n[s+3];if(r>0&&Math.abs(r-1)>1e-5){const l=1/r;n[s]*=l,n[s+1]*=l,n[s+2]*=l,n[s+3]*=l}}}function L(n,t){if(n.attributes.JOINTS_0===void 0||n.attributes.WEIGHTS_0===void 0)return null;const o=t(n.attributes.JOINTS_0),s=t(n.attributes.WEIGHTS_0),r=o.data instanceof Uint16Array?o.data:new Uint16Array(o.data),l=w(s.data);return P(l),{joints:r,weights:l}}function v(n){const t=new Float32Array(10);if(n.matrix)return t[0]=n.matrix[12],t[1]=n.matrix[13],t[2]=n.matrix[14],t[3]=0,t[4]=0,t[5]=0,t[6]=1,t[7]=1,t[8]=1,t[9]=1,t;const o=n.translation??[0,0,0],s=n.rotation??[0,0,0,1],r=n.scale??[1,1,1];return t[0]=o[0],t[1]=o[1],t[2]=o[2],t[3]=s[0],t[4]=s[1],t[5]=s[2],t[6]=s[3],t[7]=r[0],t[8]=r[1],t[9]=r[2],t}function E(){return{channels:[],keyframeData:[],clips:[],skins:[],parentIndices:[],topoOrder:[],ibmData:[],restTRS:[],skelRootMats:[],jointChannelLookup:[]}}function B(n,t,o){const s=n.skins.length,r=t.jointCount,l=n.parentIndices.length,m=n.topoOrder.length,j=n.ibmData.length/16,y=n.restTRS.length/10,f=n.skelRootMats.length/16;for(let e=0;e<r;e++)n.parentIndices.push(t.parentJointIndices[e]);const c=new Uint8Array(r),p=e=>{if(c[e])return;c[e]=1;const a=t.parentJointIndices[e];a!==-1&&p(a),n.topoOrder.push(e)};for(let e=0;e<r;e++)p(e);for(let e=0;e<t.inverseBindMatrices.length;e++)n.ibmData.push(t.inverseBindMatrices[e]);for(let e=0;e<r;e++)for(let a=0;a<10;a++)n.restTRS.push(t.restPoseTRS[e*10+a]);if(t.skeletonRootMatrix)for(let e=0;e<16;e++)n.skelRootMats.push(t.skeletonRootMatrix[e]);else{const e=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];for(let a=0;a<16;a++)n.skelRootMats.push(e[a])}const A=n.clips.length,h=n.jointChannelLookup.length;n.skins.push({jointCount:r,parentOffset:l,topoOffset:m,ibmOffset:j,restTRSOffset:y,skelRootMatIndex:f,clipOffset:A,jointLookupStart:h});const i=new Map;for(let e=0;e<r;e++)i.set(t.jointNodeIndices[e],e);for(const e of o){const a=n.channels.length,d=[...e.channels].sort((u,I)=>u.jointIndex-I.jointIndex);for(const u of d){const I=u.path==="translation"?0:u.path==="rotation"?1:2,C=u.interpolation==="STEP"?4:0,R=n.keyframeData.length,g=u.timestamps.length,M=u.path==="rotation"?4:3;for(let b=0;b<g;b++)n.keyframeData.push(u.timestamps[b]);for(let b=0;b<g*M;b++)n.keyframeData.push(u.values[b]);n.channels.push({jointIndex:u.jointIndex,pathAndInterp:I|C,keyframeCount:g,dataOffset:R})}const S=d.length;let x=0;for(let u=0;u<r;u++){const I=x;for(;x<S&&d[x].jointIndex===u;)x++;n.jointChannelLookup.push(a+I),n.jointChannelLookup.push(x-I)}n.clips.push({channelStart:a,channelCount:S,duration:e.duration,looping:1})}return s}export{N as buildNodeToJointMap,E as createPackedAnimationData,O as decodeAnimationClip,v as getNodeTRS,B as packSkinAndAnimations,J as parseAnimations,L as parsePrimitiveSkinAttributes,D as parseSkin};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./types";export*from"./base
|
|
1
|
+
export*from"./types";export*from"./base/renderer";export*from"./base/renderer-2d";export*from"./base/renderer-3d";export*from"./math";export*from"./gltf/skin-parser";export*from"./gltf/parser";import{SkeletalAnimation as l}from"./gltf/skeletal-animation";export*from"./spritesheet/helpers";export*from"./spritesheet/parser";export*from"./prefab-bucket";export*from"./prefab-bucket/specs";import{PrefabBucket as u}from"./prefab-bucket/concrete";export{u as PrefabBucket,l as SkeletalAnimation};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function N(r,n){r[n]=1,r[n+1]=0,r[n+2]=0,r[n+3]=0,r[n+4]=0,r[n+5]=1,r[n+6]=0,r[n+7]=0,r[n+8]=0,r[n+9]=0,r[n+10]=1,r[n+11]=0,r[n+12]=0,r[n+13]=0,r[n+14]=0,r[n+15]=1}function _(){const r=new Float32Array(16);return r[0]=1,r[5]=1,r[10]=1,r[15]=1,r}function I(r,n,i,a,u,y,o,c,A,F,m,l){const e=a*a,b=u*u,t=y*y,x=a*u,p=a*y,w=u*y,M=o*a,v=o*u,T=o*y;m[l]=(1-2*(b+t))*c,m[l+1]=2*(x+T)*c,m[l+2]=2*(p-v)*c,m[l+3]=0,m[l+4]=2*(x-T)*A,m[l+5]=(1-2*(e+t))*A,m[l+6]=2*(w+M)*A,m[l+7]=0,m[l+8]=2*(p+v)*F,m[l+9]=2*(w-M)*F,m[l+10]=(1-2*(e+b))*F,m[l+11]=0,m[l+12]=r,m[l+13]=n,m[l+14]=i,m[l+15]=1}function g(r){const n=new Float32Array(16);if(r.matrix)return n.set(r.matrix),n;const i=r.translation??[0,0,0],a=r.rotation??[0,0,0,1],u=r.scale??[1,1,1];return I(i[0],i[1],i[2],a[0],a[1],a[2],a[3],u[0],u[1],u[2],n,0),n}const j=new Float32Array(16);function h(r,n,i,a,u,y){for(let o=0;o<4;o++)for(let c=0;c<4;c++)j[c*4+o]=r[n+o]*i[a+c*4]+r[n+4+o]*i[a+c*4+1]+r[n+8+o]*i[a+c*4+2]+r[n+12+o]*i[a+c*4+3];u.set(j,y)}function k(r,n){const i=new Float32Array(16);for(let a=0;a<4;a++)for(let u=0;u<4;u++)i[u*4+a]=r[a]*n[u*4]+r[4+a]*n[u*4+1]+r[8+a]*n[u*4+2]+r[12+a]*n[u*4+3];return i}export{N as mat4Identity,_ as mat4IdentityNew,h as mat4Mul,k as mat4MulNew,g as nodeToMat4,I as trsToMat4};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{BasePrefabBucket as s}from"./index";import{parsers2d as t,parsers3d as p}from"./parsers";class S extends s{constructor(e){const r=e==="3d"?p:t;super(e,r)}add(e){return super.add(e)}addAll(e){return super.addAll(e)}get(e){return super.get(e)}}export{S as PrefabBucket};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{EventSystem as n}from"../../core/events";class o{constructor(e,t={}){this.pending=[];this.pendingIds=new Set;this.prefabs=null;this.mode=e,this.parsers=t,this.events=new n({events:["clips-changed"]})}add(e){if(this.prefabs)throw new Error("PrefabBucket: cannot add after load() \u2014 bucket is frozen");if(this.pendingIds.has(e.id))throw new Error(`PrefabBucket: duplicate id '${e.id}'`);return this.pending.push(e),this.pendingIds.add(e.id),this}addAll(e){if(this.prefabs)throw new Error("PrefabBucket: cannot add after load() \u2014 bucket is frozen");const t=new Set;for(const r of e){if(this.pendingIds.has(r.id)||t.has(r.id))throw new Error(`PrefabBucket: duplicate id '${r.id}'`);t.add(r.id)}for(const r of e)this.pending.push(r),this.pendingIds.add(r.id);return this}async load(){if(this.prefabs)return;const e={events:this.events},t=await Promise.all(this.pending.map(a=>{const s=this.parsers[a.type];if(!s)throw new Error(`PrefabBucket: no parser registered for type '${a.type}'`);return s(a,e)})),r=new Map;for(const a of t)r.set(a.id,a);this.prefabs=r,this.pending=[],this.pendingIds.clear()}get(e){if(!this.prefabs)throw new Error(`PrefabBucket: get('${e}') called before load()`);const t=this.prefabs.get(e);if(!t)throw new Error(`PrefabBucket: unknown prefab id '${e}'`);return t}get loaded(){return this.prefabs!==null}get size(){return this.prefabs?this.prefabs.size:this.pending.length}entries(){if(!this.prefabs)throw new Error("PrefabBucket: entries() called before load()");return Array.from(this.prefabs.values())}getAllByType(e){if(!this.prefabs)throw new Error(`PrefabBucket: getAllByType('${e}') called before load()`);const t=[];for(const r of this.prefabs.values())r.type===e&&t.push(r);return t}resetAnimations(){if(this.prefabs)for(const e of this.prefabs.values())e.resetAnimations?.()}}export{o as BasePrefabBucket};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{parseGltf as w}from"../gltf/parser";import{parseSpritesheet as y}from"../spritesheet/parser";const v={gltf:async(n,l)=>{if(n.type!=="gltf")throw new Error("gltf parser given non-gltf spec");const t=await w(n.src,{animations:n.animations!==void 0?[...n.animations]:void 0,freezeAnimations:n.freezeAnimations===!0}),c=t.primitives.filter(o=>o.skinned).length,u=t.skin?.data.jointCount??0;let g=0;for(const o of t.primitives)g+=o.positions.length/3;const i={type:"gltf",id:n.id,parsed:t,skinnedPartCount:c,jointCount:u,totalVertexCount:g,metadata:n.metadata??{}},p=n.animations!==void 0?[...n.animations]:t.skin?.animClips.map(o=>o.name)??[];if(p.length>0){const o={};for(const d of p)o[d]=d;i.animations=o,i.animationList=p}if(n.freezeAnimations!==!0){i.loadAnimations=async d=>{const a=t.skin,f=t.source;if(!a||!f)throw new Error(`loadAnimations: prefab '${n.id}' has no source \u2014 was the model skinned and not frozen?`);const m=new Set(a.animClips.map(r=>r.name)),e=[];for(const r of d){if(m.has(r))continue;const s=f.decodeAnimation(r);s&&(a.animClips.push(s),m.add(r),e.push(r))}if(e.length>0){i.animationList||(i.animationList=[]),i.animations||(i.animations={});const r=i.animationList,s=i.animations;for(const h of e)r.push(h),s[h]=h;l.events.emit("clips-changed",{prefabId:n.id,added:e,removed:[]})}},i.unloadAnimations=d=>{const a=t.skin;if(!a)return;const f=new Set(d),m=[];if(a.animClips=a.animClips.filter(e=>f.has(e.name)?(m.push(e.name),!1):!0),m.length>0){const e=i.animationList;if(e)for(let s=e.length-1;s>=0;s--)f.has(e[s])&&e.splice(s,1);const r=i.animations;if(r)for(const s of m)delete r[s];l.events.emit("clips-changed",{prefabId:n.id,added:[],removed:m})}};const o=new Set(p);i.resetAnimations=()=>{const d=t.skin;if(!d)return;const a=[];for(const f of d.animClips)o.has(f.name)||a.push(f.name);a.length>0&&i.unloadAnimations(a)}}return i},grid:n=>{if(n.type!=="grid")throw new Error("grid parser given non-grid spec");return{type:"grid",id:n.id,size:n.size,step:n.step,lineWidth:n.lineWidth,metadata:n.metadata??{}}}},k={spritesheet:async(n,l)=>{if(n.type!=="spritesheet")throw new Error("spritesheet parser given non-spritesheet spec");const t=await y({image:n.src,frameWidth:n.frameWidth,frameHeight:n.frameHeight,data:n.data});return{type:"spritesheet",id:n.id,parsed:t,frameCount:t.uvs.length,width:t.width,height:t.height,metadata:n.metadata??{}}}};export{k as parsers2d,v as parsers3d};
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function c(e,n,r,o){const s=Math.floor(e/r),t=Math.floor(n/o),u=[];for(let m=0;m<t;m++)for(let a=0;a<s;a++)u.push({minX:a*r/e,minY:m*o/n,maxX:(a+1)*r/e,maxY:(m+1)*o/n});return u}function i(e){const{w:n,h:r}=e.meta.size,o=[];for(const s of Object.keys(e.frames)){const t=e.frames[s].frame;o.push({minX:t.x/n,minY:t.y/r,maxX:(t.x+t.w)/n,maxY:(t.y+t.h)/r})}return o}async function p(e){const r=await(await fetch(e)).blob();return createImageBitmap(r)}export{c as computeGridUVs,i as computeTexturePackerUVs,p as loadImage};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{computeGridUVs as r,computeTexturePackerUVs as m,loadImage as p}from"./helpers";async function n(e){const t=await p(e.image);let i;if(e.data){const a=await(await fetch(e.data)).json();i=m(a)}else e.frameWidth&&e.frameHeight?i=r(t.width,t.height,e.frameWidth,e.frameHeight):i=[{minX:0,minY:0,maxX:1,maxY:1}];return{bitmap:t,uvs:i,width:t.width,height:t.height}}export{n as parseSpritesheet};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Abstract base for 2D renderers. Defines the sprite-based rendering API.
|
|
3
3
|
*/
|
|
4
|
-
import { BaseRenderer } from "./
|
|
5
|
-
import type { Camera2DState, Renderer2DOptions, SpriteHandle, SpriteOptions, SpritesheetHandle, SpritesheetSource } from "
|
|
4
|
+
import { BaseRenderer } from "./renderer";
|
|
5
|
+
import type { Camera2DState, Renderer2DOptions, SpriteHandle, SpriteOptions, SpritesheetHandle, SpritesheetSource } from "../types";
|
|
6
6
|
export declare abstract class Base2DRenderer extends BaseRenderer<Renderer2DOptions> {
|
|
7
7
|
readonly maxSprites: number;
|
|
8
8
|
abstract readonly camera: Camera2DState;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Abstract base for 3D renderers. Defines the model/instance-based rendering API.
|
|
3
3
|
*/
|
|
4
|
-
import { BaseRenderer } from "./
|
|
5
|
-
import type { Camera3DState, Renderer3DOptions } from "
|
|
4
|
+
import { BaseRenderer } from "./renderer";
|
|
5
|
+
import type { Camera3DState, Renderer3DOptions } from "../types";
|
|
6
6
|
export declare abstract class Base3DRenderer extends BaseRenderer<Renderer3DOptions> {
|
|
7
7
|
readonly maxModels: number;
|
|
8
8
|
abstract readonly camera: Camera3DState;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Abstract base for all renderers. Provides lifecycle and canvas management.
|
|
3
3
|
*/
|
|
4
|
-
import type { ClearColor, RendererOptions } from "
|
|
4
|
+
import type { ClearColor, RendererOptions } from "../types";
|
|
5
5
|
export declare abstract class BaseRenderer<TOptions extends RendererOptions = RendererOptions> {
|
|
6
6
|
readonly canvas: HTMLCanvasElement;
|
|
7
7
|
protected readonly options: TOptions;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure glTF parsing helpers — container decoding, primitive extraction, and
|
|
3
|
+
* transform baking. No fetch, no GPU, no closure state.
|
|
4
|
+
*/
|
|
5
|
+
import type { SkinData, AccessorReader } from './skin-parser';
|
|
6
|
+
/**
|
|
7
|
+
* Decode a fetched glTF payload — either a JSON .gltf or a binary .glb container —
|
|
8
|
+
* into the parsed JSON object and (for .glb) the embedded binary chunk.
|
|
9
|
+
*/
|
|
10
|
+
export declare function decodeGltfContainer(arrayBuffer: ArrayBuffer, url: string): {
|
|
11
|
+
gltf: any;
|
|
12
|
+
glbBinaryChunk: ArrayBuffer | null;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Validate that every skin referenced by a mesh node is equivalent to the
|
|
16
|
+
* canonical skin (same joint nodes in any order, same IBMs) and build a joint
|
|
17
|
+
* remap from each non-canonical skin's index space into canonical's.
|
|
18
|
+
*
|
|
19
|
+
* Throws if any skin is structurally incompatible — truly independent skeletons
|
|
20
|
+
* in one file are not supported yet.
|
|
21
|
+
*/
|
|
22
|
+
export declare function validateAndBuildSkinRemaps(gltf: any, canonicalSkinIndex: number, skinData: SkinData, skinJointRemaps: Map<number, Uint16Array>, getAccessorData: AccessorReader): void;
|
|
23
|
+
/** Remap a primitive's joint indices into canonical joint space, if needed. */
|
|
24
|
+
export declare function remapSkinAttributes(attrs: {
|
|
25
|
+
joints: Uint16Array;
|
|
26
|
+
weights: Float32Array;
|
|
27
|
+
}, meshSkinIndex: number | undefined, canonicalSkinIndex: number | undefined, skinJointRemaps: Map<number, Uint16Array>): {
|
|
28
|
+
joints: Uint16Array;
|
|
29
|
+
weights: Float32Array;
|
|
30
|
+
};
|
|
31
|
+
/** Extract per-primitive vertex attributes (positions, normals, UVs, indices) from glTF accessors. */
|
|
32
|
+
export declare function extractPrimitiveAttributes(primitive: any, getAccessorData: AccessorReader): {
|
|
33
|
+
positions: Float32Array;
|
|
34
|
+
normals: Float32Array | undefined;
|
|
35
|
+
uvs: Float32Array | undefined;
|
|
36
|
+
indices: Uint16Array | Uint32Array | undefined;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Bake a column-major mat4 into positions (in place) and re-orient + renormalize
|
|
40
|
+
* normals. Used to fold a non-skinned mesh node's transform into its vertices
|
|
41
|
+
* so the renderer doesn't need to know about per-mesh node transforms.
|
|
42
|
+
*/
|
|
43
|
+
export declare function bakeTransformIntoVertices(positions: Float32Array, normals: Float32Array | undefined, mm: Float32Array): void;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type SkinData, type AnimationClipData, type PrimitiveSkinAttributes } from './skin-parser';
|
|
2
|
+
/** Per-primitive CPU data ready for upload. */
|
|
3
|
+
export interface ParsedGltfPrimitive {
|
|
4
|
+
positions: Float32Array;
|
|
5
|
+
normals?: Float32Array;
|
|
6
|
+
uvs?: Float32Array;
|
|
7
|
+
indices?: Uint16Array | Uint32Array;
|
|
8
|
+
texture?: ImageBitmap;
|
|
9
|
+
/** Present iff the primitive belongs to a skinned mesh. */
|
|
10
|
+
skinAttrs?: PrimitiveSkinAttributes;
|
|
11
|
+
/** True iff this primitive should be loaded as a skinned model. */
|
|
12
|
+
skinned: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Retained parser state for decoding more clips after the initial `parseGltf`.
|
|
16
|
+
* Null when the spec opted out via `freezeAnimations: true`.
|
|
17
|
+
*/
|
|
18
|
+
export interface ParsedGltfSource {
|
|
19
|
+
readonly availableAnimations: readonly string[];
|
|
20
|
+
/** Returns null if the clip has no channels targeting joints in this skin. Throws on unknown name. */
|
|
21
|
+
decodeAnimation(name: string): AnimationClipData | null;
|
|
22
|
+
}
|
|
23
|
+
/** Skin + filtered animation clips. Mutated by lazy `loadAnimations` / `unloadAnimations`. */
|
|
24
|
+
export interface ParsedGltfSkin {
|
|
25
|
+
data: SkinData;
|
|
26
|
+
animClips: AnimationClipData[];
|
|
27
|
+
}
|
|
28
|
+
/** CPU-side result of parsing a glTF / glb URL. */
|
|
29
|
+
export interface ParsedGltf {
|
|
30
|
+
/** Source URL the model was loaded from. */
|
|
31
|
+
src: string;
|
|
32
|
+
/** One entry per primitive that should become a model part. */
|
|
33
|
+
primitives: ParsedGltfPrimitive[];
|
|
34
|
+
/** Skin + filtered animation clips, or null if the model has no skin. */
|
|
35
|
+
skin: ParsedGltfSkin | null;
|
|
36
|
+
/** Retained parser state for lazy clip decoding. Null when the spec passed `freezeAnimations: true`. */
|
|
37
|
+
source: ParsedGltfSource | null;
|
|
38
|
+
}
|
|
39
|
+
export interface ParseGltfOptions {
|
|
40
|
+
/** Whitelist of clip names to keep. */
|
|
41
|
+
animations?: string[];
|
|
42
|
+
/** Release the source JSON + accessor reader after parse. Disables lazy load. */
|
|
43
|
+
freezeAnimations?: boolean;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Parse a glTF / .glb file from a URL into CPU-side data.
|
|
47
|
+
* Does no GPU work. Safe to call in parallel; safe to call before a renderer exists.
|
|
48
|
+
*/
|
|
49
|
+
export declare function parseGltf(url: string, opts?: ParseGltfOptions): Promise<ParsedGltf>;
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* // outputMatrices is a Float32Array view into the bone matrix buffer
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
|
-
import type { SkinData, AnimationClipData, AnimationChannel } from './
|
|
19
|
+
import type { SkinData, AnimationClipData, AnimationChannel } from './skin-parser';
|
|
20
20
|
export interface SkeletalClip {
|
|
21
21
|
readonly id: number;
|
|
22
22
|
readonly name: string;
|
|
@@ -57,8 +57,14 @@ export declare class SkeletalAnimation {
|
|
|
57
57
|
private readonly currentTRS;
|
|
58
58
|
private readonly topoOrder;
|
|
59
59
|
private readonly skelRootMat;
|
|
60
|
-
constructor(skinData: SkinData, clips: AnimationClipData[]
|
|
60
|
+
constructor(skinData: SkinData, clips: AnimationClipData[]);
|
|
61
61
|
loadClip(clip: AnimationClipData, loop?: boolean): number;
|
|
62
|
+
/**
|
|
63
|
+
* Replace the clip list wholesale. Returns an old-id → new-id remap so
|
|
64
|
+
* callers can fix in-flight `SkeletalAnimState.clipId` / `prevClipId`
|
|
65
|
+
* references. Removed clips map to -1.
|
|
66
|
+
*/
|
|
67
|
+
replaceClips(clips: AnimationClipData[], loop?: boolean): Int32Array;
|
|
62
68
|
getClipId(name: string): number;
|
|
63
69
|
getClipNames(): string[];
|
|
64
70
|
getClip(id: number): SkeletalClip | null;
|
|
@@ -8,6 +8,8 @@ export interface SkinData {
|
|
|
8
8
|
parentJointIndices: Int16Array;
|
|
9
9
|
/** World matrix of the skeleton root (non-joint ancestors of root joints). Column-major mat4, 16 floats. Null if identity. */
|
|
10
10
|
skeletonRootMatrix: Float32Array | null;
|
|
11
|
+
/** Rest-pose TRS for each joint, packed as [tx, ty, tz, qx, qy, qz, qw, sx, sy, sz]. jointCount * 10 floats. */
|
|
12
|
+
restPoseTRS: Float32Array;
|
|
11
13
|
}
|
|
12
14
|
export interface AnimationChannel {
|
|
13
15
|
/** Index into the skin's joint list (not node index). */
|
|
@@ -39,13 +41,17 @@ export type AccessorReader = (accessorIndex: number) => {
|
|
|
39
41
|
*/
|
|
40
42
|
export declare function parseSkin(gltf: any, skinIndex: number, getAccessorData: AccessorReader): SkinData;
|
|
41
43
|
/**
|
|
42
|
-
*
|
|
44
|
+
* Decode one glTF animation entry into an `AnimationClipData`.
|
|
45
|
+
* Returns null if no channels target joints in this skin, or all channels use
|
|
46
|
+
* an unsupported interpolation mode.
|
|
43
47
|
*/
|
|
44
|
-
export declare function
|
|
48
|
+
export declare function decodeAnimationClip(anim: any, nameFallback: string, nodeToJoint: ReadonlyMap<number, number>, getAccessorData: AccessorReader): AnimationClipData | null;
|
|
49
|
+
/** Node→joint index map for a parsed skin. Build once and reuse when decoding clips lazily. */
|
|
50
|
+
export declare function buildNodeToJointMap(skinData: SkinData): Map<number, number>;
|
|
45
51
|
/**
|
|
46
|
-
*
|
|
47
|
-
* Returns null if the primitive has no skinning attributes.
|
|
52
|
+
* Parse animation clips that target joints in a skin.
|
|
48
53
|
*/
|
|
54
|
+
export declare function parseAnimations(gltf: any, skinData: SkinData, getAccessorData: AccessorReader): AnimationClipData[];
|
|
49
55
|
export declare function parsePrimitiveSkinAttributes(primitive: any, getAccessorData: AccessorReader): PrimitiveSkinAttributes | null;
|
|
50
56
|
/**
|
|
51
57
|
* Get a node's local TRS as [tx, ty, tz, qx, qy, qz, qw, sx, sy, sz].
|
|
@@ -98,4 +104,4 @@ export declare function createPackedAnimationData(): PackedAnimationData;
|
|
|
98
104
|
* Pack a skin + its animations into the flat GPU buffers.
|
|
99
105
|
* Returns the skin index within the packed data.
|
|
100
106
|
*/
|
|
101
|
-
export declare function packSkinAndAnimations(packed: PackedAnimationData, skinData: SkinData, clips: AnimationClipData[]
|
|
107
|
+
export declare function packSkinAndAnimations(packed: PackedAnimationData, skinData: SkinData, clips: AnimationClipData[]): number;
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
export * from "./types";
|
|
2
|
-
export * from "./base
|
|
3
|
-
export * from "./base-2d
|
|
4
|
-
export * from "./base-3d
|
|
2
|
+
export * from "./base/renderer";
|
|
3
|
+
export * from "./base/renderer-2d";
|
|
4
|
+
export * from "./base/renderer-3d";
|
|
5
|
+
export * from "./math";
|
|
6
|
+
export * from "./gltf/skin-parser";
|
|
7
|
+
export * from "./gltf/parser";
|
|
8
|
+
export { SkeletalAnimation } from "./gltf/skeletal-animation";
|
|
9
|
+
export type { SkeletalClip, SkeletalAnimState, PlayOptions } from "./gltf/skeletal-animation";
|
|
10
|
+
export * from "./spritesheet/helpers";
|
|
11
|
+
export * from "./spritesheet/parser";
|
|
12
|
+
export * from "./prefab-bucket";
|
|
13
|
+
export * from "./prefab-bucket/specs";
|
|
14
|
+
export { PrefabBucket } from "./prefab-bucket/concrete";
|
|
15
|
+
export type { PrefabBucket2D, PrefabBucket3D } from "./prefab-bucket/concrete";
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PrefabBucket — typed registry of reusable spawn templates.
|
|
3
|
+
*
|
|
4
|
+
* Pass `'2d'` or `'3d'` to the constructor to pick the spec/prefab universe.
|
|
5
|
+
* Parsers are wired implicitly; user code only sees `add`, `addAll`, `load`, `get`.
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* const bucket = new PrefabBucket('3d')
|
|
9
|
+
* .add({ type: 'gltf', id: 'minion', url: '/minion.glb' })
|
|
10
|
+
* .add({ type: 'grid', id: 'floor', size: 20, step: 0.33, lineWidth: 0.001 });
|
|
11
|
+
*
|
|
12
|
+
* await bucket.load();
|
|
13
|
+
*
|
|
14
|
+
* bucket.get('minion'); // typed as GltfPrefab — `.animations`, `.jointCount`, …
|
|
15
|
+
* bucket.get('floor'); // typed as GridPrefab — `.size`, `.step`, `.lineWidth`
|
|
16
|
+
* bucket.get('typo'); // ❌ TS error: '"typo"' not in '"minion" | "floor"'
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
import { BasePrefabBucket, type StringOr } from './index';
|
|
20
|
+
import type { Prefab2D, Prefab2DSpec, Prefab3D, Prefab3DSpec, PrefabFor } from './specs';
|
|
21
|
+
type SpecForMode<M> = M extends '3d' ? Prefab3DSpec : Prefab2DSpec;
|
|
22
|
+
type PrefabUnionForMode<M> = M extends '3d' ? Prefab3D : Prefab2D;
|
|
23
|
+
/**
|
|
24
|
+
* Registry of prefab specs and their parsed variants. The bucket tracks the mapping of
|
|
25
|
+
* spec `id` strings to their parsed prefab types, so `get` narrows to the correct
|
|
26
|
+
* prefab type based on the provided id. The bucket is mutable; call `add`/`addAll`
|
|
27
|
+
* to register new specs and their prefab types. Call `load` to parse all registered
|
|
28
|
+
* specs and populate the bucket's internal prefab registry.
|
|
29
|
+
*/
|
|
30
|
+
export declare class PrefabBucket<M extends '2d' | '3d' = '3d', Specs extends Record<string, SpecForMode<M>> = {}> extends BasePrefabBucket<M, SpecForMode<M>, PrefabUnionForMode<M>, Specs> {
|
|
31
|
+
constructor(mode: M);
|
|
32
|
+
/**
|
|
33
|
+
* Add a spec. Chains return the subclass type so the bucket variable's
|
|
34
|
+
* static type accumulates id→spec mappings, enabling `get` to narrow.
|
|
35
|
+
*/
|
|
36
|
+
add<const S extends SpecForMode<M>>(spec: S): PrefabBucket<M, Specs & {
|
|
37
|
+
[K in S['id']]: S;
|
|
38
|
+
}>;
|
|
39
|
+
addAll<const Ss extends readonly SpecForMode<M>[]>(specs: Ss): PrefabBucket<M, Specs & {
|
|
40
|
+
[K in Ss[number]['id']]: Extract<Ss[number], {
|
|
41
|
+
id: K;
|
|
42
|
+
}>;
|
|
43
|
+
}>;
|
|
44
|
+
/**
|
|
45
|
+
* Return the parsed prefab variant for this id. Narrow type — `get('minion')`
|
|
46
|
+
* returns `GltfPrefab` (with `.animations`, `.jointCount`), not the union.
|
|
47
|
+
*
|
|
48
|
+
* Accepts any string at runtime but autocompletes known ids.
|
|
49
|
+
*/
|
|
50
|
+
get<K extends keyof Specs & string, R = PrefabFor<Specs[K]>>(id: StringOr<K>): R;
|
|
51
|
+
}
|
|
52
|
+
/** Convenience aliases for explicit mode typing (e.g. function params). */
|
|
53
|
+
export type PrefabBucket2D<Specs extends Record<string, Prefab2DSpec> = {}> = PrefabBucket<'2d', Specs>;
|
|
54
|
+
export type PrefabBucket3D<Specs extends Record<string, Prefab3DSpec> = {}> = PrefabBucket<'3d', Specs>;
|
|
55
|
+
export type { GltfPrefab, GltfSpec, GridPrefab, GridSpec, Prefab2D, Prefab2DSpec, Prefab3D, Prefab3DSpec, PrefabFor, SpritesheetPrefab, SpritesheetSpec, } from './specs';
|