murow 0.0.72 → 0.0.73
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/dist/cjs/core/driver/drivers/raf.js +1 -1
- package/dist/cjs/core/sparse-batcher/sparse-batcher.js +1 -1
- package/dist/cjs/renderer/base/renderer-3d.js +1 -1
- package/dist/cjs/renderer/prefab-bucket/concrete.js +1 -1
- package/dist/cjs/renderer/prefab-bucket/index.js +1 -1
- package/dist/cjs/renderer/prefab-bucket/parsers.js +1 -1
- package/dist/cjs/renderer/prefab-bucket/specs.js +1 -1
- package/dist/esm/core/driver/drivers/raf.js +1 -1
- package/dist/esm/core/sparse-batcher/sparse-batcher.js +1 -1
- package/dist/esm/renderer/base/renderer-3d.js +1 -1
- package/dist/esm/renderer/prefab-bucket/concrete.js +1 -1
- package/dist/esm/renderer/prefab-bucket/index.js +1 -1
- package/dist/esm/renderer/prefab-bucket/parsers.js +1 -1
- package/dist/types/core/driver/drivers/raf.d.ts +13 -2
- package/dist/types/renderer/base/renderer-3d.d.ts +1 -1
- package/dist/types/renderer/prefab-bucket/concrete.d.ts +42 -2
- package/dist/types/renderer/prefab-bucket/index.d.ts +12 -2
- package/dist/types/renderer/prefab-bucket/specs.d.ts +46 -3
- package/dist/types/renderer/types.d.ts +5 -3
- package/dist/webgpu/cjs/index.js +471 -35
- package/dist/webgpu/esm/index.js +471 -35
- package/dist/webgpu/types/3d/renderer.d.ts +73 -5
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var s=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var o=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var u=(t,i)=>{for(var n in i)s(t,n,{get:i[n],enumerable:!0})},h=(t,i,n,r)=>{if(i&&typeof i=="object"||typeof i=="function")for(let e of o(i))!d.call(t,e)&&e!==n&&s(t,e,{get:()=>i[e],enumerable:!(r=l(i,e))||r.enumerable});return t};var m=t=>h(s({},"__esModule",{value:!0}),t);var p={};u(p,{RafDriver:()=>a});module.exports=m(p);class a{constructor(i){this.update=i;this.last=performance.now();this.running=!1;this.rafId=null;this.visibilityHandler=null;this.loop=()=>{if(!this.running)return;const i=performance.now(),n=i-this.last;this.last=i;const r=Math.min(n,a.MAX_DT_MS)/1e3;this.update(r),requestAnimationFrame(this.loop)}}static{this.MAX_DT_MS=250}start(){this.running=!0,this.last=performance.now(),typeof document<"u"&&!this.visibilityHandler&&(this.visibilityHandler=()=>{document.visibilityState==="visible"&&(this.last=performance.now())},document.addEventListener("visibilitychange",this.visibilityHandler)),this.rafId=requestAnimationFrame(this.loop)}stop(){this.running=!1,this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null),this.visibilityHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null)}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var a=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var v=(c,i)=>{for(var e in i)a(c,e,{get:i[e],enumerable:!0})},f=(c,i,e,s)=>{if(i&&typeof i=="object"||typeof i=="function")for(let t of b(i))!k.call(c,t)&&t!==e&&a(c,t,{get:()=>i[t],enumerable:!(s=h(i,t))||s.enumerable});return c};var y=c=>f(a({},"__esModule",{value:!0}),c);var l={};v(l,{SparseBatcher:()=>n});module.exports=y(l);class n{constructor(i){this.BUCKET_INITIAL_SIZE=256;this.buckets=new Map;this.bucketSizes=new Uint32Array(n.MAX_BUCKETS);this.activeBuckets=new Uint16Array(n.MAX_BUCKETS);this.sortBuffer=new Uint16Array(n.MAX_BUCKETS);this.activeCount=0;this.capacity=i}static{this.MAX_LAYERS=256}static{this.MAX_SHEETS=64}static{this.MAX_BUCKETS=n.MAX_LAYERS*n.MAX_SHEETS}key(i,e){return i*n.MAX_SHEETS+e}add(i,e,s){const t=this.key(i,e);this.buckets.has(t)||
|
|
1
|
+
var a=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var v=(c,i)=>{for(var e in i)a(c,e,{get:i[e],enumerable:!0})},f=(c,i,e,s)=>{if(i&&typeof i=="object"||typeof i=="function")for(let t of b(i))!k.call(c,t)&&t!==e&&a(c,t,{get:()=>i[t],enumerable:!(s=h(i,t))||s.enumerable});return c};var y=c=>f(a({},"__esModule",{value:!0}),c);var l={};v(l,{SparseBatcher:()=>n});module.exports=y(l);class n{constructor(i){this.BUCKET_INITIAL_SIZE=256;this.buckets=new Map;this.bucketSizes=new Uint32Array(n.MAX_BUCKETS);this.activeBuckets=new Uint16Array(n.MAX_BUCKETS);this.sortBuffer=new Uint16Array(n.MAX_BUCKETS);this.activeCount=0;this.capacity=i}static{this.MAX_LAYERS=256}static{this.MAX_SHEETS=64}static{this.MAX_BUCKETS=n.MAX_LAYERS*n.MAX_SHEETS}key(i,e){return i*n.MAX_SHEETS+e}add(i,e,s){const t=this.key(i,e);this.buckets.has(t)||this.buckets.set(t,new Uint32Array(this.BUCKET_INITIAL_SIZE)),this.bucketSizes[t]===0&&(this.activeBuckets[this.activeCount++]=t);const u=this.buckets.get(t);if(this.bucketSizes[t]>=u.length){const r=new Uint32Array(u.length*2);r.set(u),this.buckets.set(t,r)}this.buckets.get(t)[this.bucketSizes[t]++]=s}remove(i,e,s){const t=this.key(i,e),u=this.bucketSizes[t];if(u===0)return;const o=this.buckets.get(t);for(let r=0;r<u;r++)if(o[r]===s){o[r]=o[u-1],this.bucketSizes[t]--;break}if(this.bucketSizes[t]===0){for(let r=0;r<this.activeCount;r++)if(this.activeBuckets[r]===t){this.activeBuckets[r]=this.activeBuckets[--this.activeCount];break}}}each(i){this.sortBuffer.set(this.activeBuckets.subarray(0,this.activeCount));for(let e=1;e<this.activeCount;e++){const s=this.sortBuffer[e];let t=e-1;for(;t>=0&&this.sortBuffer[t]>s;)this.sortBuffer[t+1]=this.sortBuffer[t--];this.sortBuffer[t+1]=s}for(let e=0;e<this.activeCount;e++){const s=this.sortBuffer[e],t=s%n.MAX_SHEETS,u=this.bucketSizes[s];i(t,this.buckets.get(s).subarray(0,u),u)}}getActiveCount(){return this.activeCount}getTotalCount(){let i=0;for(let e=0;e<this.activeCount;e++)i+=this.bucketSizes[this.activeBuckets[e]];return i}clear(){this.buckets.clear(),this.bucketSizes.fill(0),this.activeCount=0}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var n=Object.defineProperty;var o=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var p=(r,e)=>{for(var a in e)n(r,a,{get:e[a],enumerable:!0})},D=(r,e,a,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of c(e))!d.call(r,t)&&t!==a&&n(r,t,{get:()=>e[t],enumerable:!(s=o(e,t))||s.enumerable});return r};var i=r=>D(n({},"__esModule",{value:!0}),r);var R={};p(R,{Base3DRenderer:()=>x});module.exports=i(R);var m=require("./renderer");class x extends m.BaseRenderer{constructor(e,a){super(e,a),this.maxInstances=a.maxInstances??32}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var f=Object.defineProperty;var P=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var g=Object.prototype.hasOwnProperty;var M=(t,e)=>{for(var s in e)f(t,s,{get:e[s],enumerable:!0})},k=(t,e,s,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of S(e))!g.call(t,r)&&r!==s&&f(t,r,{get:()=>e[r],enumerable:!(o=P(e,r))||o.enumerable});return t};var h=t=>k(f({},"__esModule",{value:!0}),t);var D={};M(D,{PrefabBucket:()=>w});module.exports=h(D);var c=require("./index"),d=require("./parsers"),u=require("../../core/generate-id");class w extends c.BasePrefabBucket{constructor(e){const s=e==="3d"?d.parsers3d:d.parsers2d;super(e,s)}add(e){return super.add(e)}addAll(e){return super.addAll(e)}get(e){return super.get(e)}addGroup(e,s){if(e.includes("."))throw new Error(`PrefabBucket.addGroup: group name '${e}' is invalid - '.' is reserved for group paths`);if(this.groups.has(e))throw new Error(`PrefabBucket.addGroup: duplicate group '${e}'`);const o=[],r=[];for(const n of s){const p=n.id;if(p!==void 0&&p.includes("."))throw new Error(`PrefabBucket.addGroup: part id '${p}' is invalid - '.' is reserved for group paths`);const a=p!==void 0?`${e}.${p}`:(0,u.generateId)({prefix:`${e}.`,size:e.length+1+8}),{offset:i,...b}=n;this.addUnchecked({...b,id:a}),o.push(a),r.push(i?{partId:a,offset:i}:{partId:a})}return super.add({type:"composite",id:e,parts:r}),this.groups.set(e,o),this}getGroup(e){const o=this.groups.get(e);if(!o)throw new Error(`PrefabBucket.getGroup: unknown group '${e}'`);const r=o.map(p=>this.get(p)),n=this;return{prefabs:r,asComposite:()=>n.get(e)}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var n=Object.defineProperty;var o=Object.getOwnPropertyDescriptor;var
|
|
1
|
+
var n=Object.defineProperty;var o=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var c=(s,e)=>{for(var t in e)n(s,t,{get:e[t],enumerable:!0})},b=(s,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of f(e))!p.call(s,a)&&a!==t&&n(s,a,{get:()=>e[a],enumerable:!(r=o(e,a))||r.enumerable});return s};var P=s=>b(n({},"__esModule",{value:!0}),s);var h={};c(h,{BasePrefabBucket:()=>u});module.exports=P(h);var d=require("../../core/events");class u{constructor(e,t={}){this.pending=[];this.pendingIds=new Set;this.prefabs=null;this.groups=new Map;this.mode=e,this.parsers=t,this.events=new d.EventSystem({events:["clips-changed"]})}add(e){if(e.id.includes("."))throw new Error(`PrefabBucket: id '${e.id}' is invalid - '.' is reserved for group paths`);return this.addUnchecked(e)}addUnchecked(e){if(this.prefabs)throw new Error("PrefabBucket: cannot add after load() - 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(r.id.includes("."))throw new Error(`PrefabBucket: id '${r.id}' is invalid - '.' is reserved for group paths`);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 i=this.parsers[a.type];if(!i)throw new Error(`PrefabBucket: no parser registered for type '${a.type}'`);return i(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?.()}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var u=Object.defineProperty;var
|
|
1
|
+
var u=Object.defineProperty;var P=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var C=(t,e)=>{for(var n in e)u(t,n,{get:e[n],enumerable:!0})},A=(t,e,n,c)=>{if(e&&typeof e=="object"||typeof e=="function")for(let p of v(e))!k.call(t,p)&&p!==n&&u(t,p,{get:()=>e[p],enumerable:!(c=P(e,p))||c.enumerable});return t};var D=t=>A(u({},"__esModule",{value:!0}),t);var E={};C(E,{parsers2d:()=>S,parsers3d:()=>z});module.exports=D(E);var b=require("../gltf/parser"),w=require("../spritesheet/parser");const z={gltf:async(t,e)=>{if(t.type!=="gltf")throw new Error("gltf parser given non-gltf spec");const n=await(0,b.parseGltf)(t.src,{animations:t.animations!==void 0?[...t.animations]:void 0,freezeAnimations:t.freezeAnimations===!0}),c=n.primitives.filter(d=>d.skinned).length,p=n.skin?.data.jointCount??0;let y=0;for(const d of n.primitives)y+=d.positions.length/3;const i={type:"gltf",id:t.id,parsed:n,skinnedPartCount:c,jointCount:p,totalVertexCount:y,metadata:t.metadata??{}},g=t.animations!==void 0?[...t.animations]:n.skin?.animClips.map(d=>d.name)??[];if(g.length>0){const d={};for(const m of g)d[m]=m;i.animations=d,i.animationList=g}if(t.freezeAnimations!==!0){i.loadAnimations=async m=>{const r=n.skin,f=n.source;if(!r||!f)throw new Error(`loadAnimations: prefab '${t.id}' has no source \u2014 was the model skinned and not frozen?`);const h=new Set(r.animClips.map(s=>s.name)),a=[];for(const s of m){if(h.has(s))continue;const o=f.decodeAnimation(s);o&&(r.animClips.push(o),h.add(s),a.push(s))}if(a.length>0){i.animationList||(i.animationList=[]),i.animations||(i.animations={});const s=i.animationList,o=i.animations;for(const l of a)s.push(l),o[l]=l;e.events.emit("clips-changed",{prefabId:t.id,added:a,removed:[]})}},i.unloadAnimations=m=>{const r=n.skin;if(!r)return;const f=new Set(m),h=[];if(r.animClips=r.animClips.filter(a=>f.has(a.name)?(h.push(a.name),!1):!0),h.length>0){const a=i.animationList;if(a)for(let o=a.length-1;o>=0;o--)f.has(a[o])&&a.splice(o,1);const s=i.animations;if(s)for(const o of h)delete s[o];e.events.emit("clips-changed",{prefabId:t.id,added:[],removed:h})}};const d=new Set(g);i.resetAnimations=()=>{const m=n.skin;if(!m)return;const r=[];for(const f of m.animClips)d.has(f.name)||r.push(f.name);r.length>0&&i.unloadAnimations(r)}}return i},grid:t=>{if(t.type!=="grid")throw new Error("grid parser given non-grid spec");return{type:"grid",id:t.id,size:t.size,step:t.step,lineWidth:t.lineWidth,metadata:t.metadata??{}}},cube:t=>{if(t.type!=="cube")throw new Error("cube parser given non-cube spec");return{type:"cube",id:t.id,size:t.size??1,metadata:t.metadata??{}}},composite:t=>{if(t.type!=="composite")throw new Error("composite parser given non-composite spec");return{type:"composite",id:t.id,parts:t.parts,metadata:t.metadata??{}}}},S={spritesheet:async(t,e)=>{if(t.type!=="spritesheet")throw new Error("spritesheet parser given non-spritesheet spec");const n=await(0,w.parseSpritesheet)({image:t.src,frameWidth:t.frameWidth,frameHeight:t.frameHeight,data:t.data});return{type:"spritesheet",id:t.id,parsed:n,frameCount:n.uvs.length,width:n.width,height:n.height,metadata:t.metadata??{}}}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var a=Object.defineProperty;var
|
|
1
|
+
var a=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var s=Object.prototype.hasOwnProperty;var l=(n,e,o,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of d(e))!s.call(n,t)&&t!==o&&a(n,t,{get:()=>e[t],enumerable:!(r=i(e,t))||r.enumerable});return n};var p=n=>l(a({},"__esModule",{value:!0}),n);var y={};module.exports=p(y);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
class
|
|
1
|
+
class t{constructor(i){this.update=i;this.last=performance.now();this.running=!1;this.rafId=null;this.visibilityHandler=null;this.loop=()=>{if(!this.running)return;const i=performance.now(),n=i-this.last;this.last=i;const e=Math.min(n,t.MAX_DT_MS)/1e3;this.update(e),requestAnimationFrame(this.loop)}}static{this.MAX_DT_MS=250}start(){this.running=!0,this.last=performance.now(),typeof document<"u"&&!this.visibilityHandler&&(this.visibilityHandler=()=>{document.visibilityState==="visible"&&(this.last=performance.now())},document.addEventListener("visibilitychange",this.visibilityHandler)),this.rafId=requestAnimationFrame(this.loop)}stop(){this.running=!1,this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null),this.visibilityHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null)}}export{t as RafDriver};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
class n{constructor(i){this.BUCKET_INITIAL_SIZE=256;this.buckets=new Map;this.bucketSizes=new Uint32Array(n.MAX_BUCKETS);this.activeBuckets=new Uint16Array(n.MAX_BUCKETS);this.sortBuffer=new Uint16Array(n.MAX_BUCKETS);this.activeCount=0;this.capacity=i}static{this.MAX_LAYERS=256}static{this.MAX_SHEETS=64}static{this.MAX_BUCKETS=n.MAX_LAYERS*n.MAX_SHEETS}key(i,e){return i*n.MAX_SHEETS+e}add(i,e,r){const t=this.key(i,e);this.buckets.has(t)||
|
|
1
|
+
class n{constructor(i){this.BUCKET_INITIAL_SIZE=256;this.buckets=new Map;this.bucketSizes=new Uint32Array(n.MAX_BUCKETS);this.activeBuckets=new Uint16Array(n.MAX_BUCKETS);this.sortBuffer=new Uint16Array(n.MAX_BUCKETS);this.activeCount=0;this.capacity=i}static{this.MAX_LAYERS=256}static{this.MAX_SHEETS=64}static{this.MAX_BUCKETS=n.MAX_LAYERS*n.MAX_SHEETS}key(i,e){return i*n.MAX_SHEETS+e}add(i,e,r){const t=this.key(i,e);this.buckets.has(t)||this.buckets.set(t,new Uint32Array(this.BUCKET_INITIAL_SIZE)),this.bucketSizes[t]===0&&(this.activeBuckets[this.activeCount++]=t);const u=this.buckets.get(t);if(this.bucketSizes[t]>=u.length){const s=new Uint32Array(u.length*2);s.set(u),this.buckets.set(t,s)}this.buckets.get(t)[this.bucketSizes[t]++]=r}remove(i,e,r){const t=this.key(i,e),u=this.bucketSizes[t];if(u===0)return;const c=this.buckets.get(t);for(let s=0;s<u;s++)if(c[s]===r){c[s]=c[u-1],this.bucketSizes[t]--;break}if(this.bucketSizes[t]===0){for(let s=0;s<this.activeCount;s++)if(this.activeBuckets[s]===t){this.activeBuckets[s]=this.activeBuckets[--this.activeCount];break}}}each(i){this.sortBuffer.set(this.activeBuckets.subarray(0,this.activeCount));for(let e=1;e<this.activeCount;e++){const r=this.sortBuffer[e];let t=e-1;for(;t>=0&&this.sortBuffer[t]>r;)this.sortBuffer[t+1]=this.sortBuffer[t--];this.sortBuffer[t+1]=r}for(let e=0;e<this.activeCount;e++){const r=this.sortBuffer[e],t=r%n.MAX_SHEETS,u=this.bucketSizes[r];i(t,this.buckets.get(r).subarray(0,u),u)}}getActiveCount(){return this.activeCount}getTotalCount(){let i=0;for(let e=0;e<this.activeCount;e++)i+=this.bucketSizes[this.activeBuckets[e]];return i}clear(){this.buckets.clear(),this.bucketSizes.fill(0),this.activeCount=0}}export{n as SparseBatcher};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{BaseRenderer as a}from"./renderer";class
|
|
1
|
+
import{BaseRenderer as a}from"./renderer";class s extends a{constructor(r,e){super(r,e),this.maxInstances=e.maxInstances??32}}export{s as Base3DRenderer};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{BasePrefabBucket as
|
|
1
|
+
import{BasePrefabBucket as f}from"./index";import{parsers2d as i,parsers3d as c}from"./parsers";import{generateId as u}from"../../core/generate-id";class M extends f{constructor(e){const t=e==="3d"?c:i;super(e,t)}add(e){return super.add(e)}addAll(e){return super.addAll(e)}get(e){return super.get(e)}addGroup(e,t){if(e.includes("."))throw new Error(`PrefabBucket.addGroup: group name '${e}' is invalid - '.' is reserved for group paths`);if(this.groups.has(e))throw new Error(`PrefabBucket.addGroup: duplicate group '${e}'`);const s=[],o=[];for(const p of t){const r=p.id;if(r!==void 0&&r.includes("."))throw new Error(`PrefabBucket.addGroup: part id '${r}' is invalid - '.' is reserved for group paths`);const n=r!==void 0?`${e}.${r}`:u({prefix:`${e}.`,size:e.length+1+8}),{offset:a,...d}=p;this.addUnchecked({...d,id:n}),s.push(n),o.push(a?{partId:n,offset:a}:{partId:n})}return super.add({type:"composite",id:e,parts:o}),this.groups.set(e,s),this}getGroup(e){const s=this.groups.get(e);if(!s)throw new Error(`PrefabBucket.getGroup: unknown group '${e}'`);const o=s.map(r=>this.get(r)),p=this;return{prefabs:o,asComposite:()=>p.get(e)}}}export{M as PrefabBucket};
|
|
@@ -1 +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()
|
|
1
|
+
import{EventSystem as n}from"../../core/events";class o{constructor(e,t={}){this.pending=[];this.pendingIds=new Set;this.prefabs=null;this.groups=new Map;this.mode=e,this.parsers=t,this.events=new n({events:["clips-changed"]})}add(e){if(e.id.includes("."))throw new Error(`PrefabBucket: id '${e.id}' is invalid - '.' is reserved for group paths`);return this.addUnchecked(e)}addUnchecked(e){if(this.prefabs)throw new Error("PrefabBucket: cannot add after load() - 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(r.id.includes("."))throw new Error(`PrefabBucket: id '${r.id}' is invalid - '.' is reserved for group paths`);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};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{parseGltf as
|
|
1
|
+
import{parseGltf as y}from"../gltf/parser";import{parseSpritesheet as b}from"../spritesheet/parser";const v={gltf:async(t,h)=>{if(t.type!=="gltf")throw new Error("gltf parser given non-gltf spec");const i=await y(t.src,{animations:t.animations!==void 0?[...t.animations]:void 0,freezeAnimations:t.freezeAnimations===!0}),l=i.primitives.filter(o=>o.skinned).length,u=i.skin?.data.jointCount??0;let g=0;for(const o of i.primitives)g+=o.positions.length/3;const n={type:"gltf",id:t.id,parsed:i,skinnedPartCount:l,jointCount:u,totalVertexCount:g,metadata:t.metadata??{}},p=t.animations!==void 0?[...t.animations]:i.skin?.animClips.map(o=>o.name)??[];if(p.length>0){const o={};for(const d of p)o[d]=d;n.animations=o,n.animationList=p}if(t.freezeAnimations!==!0){n.loadAnimations=async d=>{const a=i.skin,m=i.source;if(!a||!m)throw new Error(`loadAnimations: prefab '${t.id}' has no source \u2014 was the model skinned and not frozen?`);const f=new Set(a.animClips.map(r=>r.name)),e=[];for(const r of d){if(f.has(r))continue;const s=m.decodeAnimation(r);s&&(a.animClips.push(s),f.add(r),e.push(r))}if(e.length>0){n.animationList||(n.animationList=[]),n.animations||(n.animations={});const r=n.animationList,s=n.animations;for(const c of e)r.push(c),s[c]=c;h.events.emit("clips-changed",{prefabId:t.id,added:e,removed:[]})}},n.unloadAnimations=d=>{const a=i.skin;if(!a)return;const m=new Set(d),f=[];if(a.animClips=a.animClips.filter(e=>m.has(e.name)?(f.push(e.name),!1):!0),f.length>0){const e=n.animationList;if(e)for(let s=e.length-1;s>=0;s--)m.has(e[s])&&e.splice(s,1);const r=n.animations;if(r)for(const s of f)delete r[s];h.events.emit("clips-changed",{prefabId:t.id,added:[],removed:f})}};const o=new Set(p);n.resetAnimations=()=>{const d=i.skin;if(!d)return;const a=[];for(const m of d.animClips)o.has(m.name)||a.push(m.name);a.length>0&&n.unloadAnimations(a)}}return n},grid:t=>{if(t.type!=="grid")throw new Error("grid parser given non-grid spec");return{type:"grid",id:t.id,size:t.size,step:t.step,lineWidth:t.lineWidth,metadata:t.metadata??{}}},cube:t=>{if(t.type!=="cube")throw new Error("cube parser given non-cube spec");return{type:"cube",id:t.id,size:t.size??1,metadata:t.metadata??{}}},composite:t=>{if(t.type!=="composite")throw new Error("composite parser given non-composite spec");return{type:"composite",id:t.id,parts:t.parts,metadata:t.metadata??{}}}},k={spritesheet:async(t,h)=>{if(t.type!=="spritesheet")throw new Error("spritesheet parser given non-spritesheet spec");const i=await b({image:t.src,frameWidth:t.frameWidth,frameHeight:t.frameHeight,data:t.data});return{type:"spritesheet",id:t.id,parsed:i,frameCount:i.uvs.length,width:i.width,height:i.height,metadata:t.metadata??{}}}};export{k as parsers2d,v as parsers3d};
|
|
@@ -18,6 +18,13 @@ import { LoopDriver } from "../driver";
|
|
|
18
18
|
*/
|
|
19
19
|
export declare class RafDriver implements LoopDriver {
|
|
20
20
|
update: (dt: number) => void;
|
|
21
|
+
/**
|
|
22
|
+
* Hard upper bound on a single frame's delta, in ms. Long pauses (tab
|
|
23
|
+
* backgrounded, breakpoint hit, browser throttling) deliver one huge
|
|
24
|
+
* frame on resume. Clamping keeps the engine from trying to "catch up"
|
|
25
|
+
* by replaying that lost time at high speed.
|
|
26
|
+
*/
|
|
27
|
+
private static readonly MAX_DT_MS;
|
|
21
28
|
/**
|
|
22
29
|
* @param update - Callback invoked each frame with delta time in seconds
|
|
23
30
|
*/
|
|
@@ -25,10 +32,13 @@ export declare class RafDriver implements LoopDriver {
|
|
|
25
32
|
private last;
|
|
26
33
|
private running;
|
|
27
34
|
private rafId;
|
|
35
|
+
private visibilityHandler;
|
|
28
36
|
/**
|
|
29
37
|
* Starts the game loop using requestAnimationFrame.
|
|
30
38
|
*
|
|
31
|
-
* Resets timing to prevent large initial delta
|
|
39
|
+
* Resets timing to prevent large initial delta and installs a
|
|
40
|
+
* visibilitychange handler so the first frame after a hidden tab
|
|
41
|
+
* doesn't deliver a multi-second delta.
|
|
32
42
|
*/
|
|
33
43
|
start(): void;
|
|
34
44
|
/**
|
|
@@ -38,7 +48,8 @@ export declare class RafDriver implements LoopDriver {
|
|
|
38
48
|
/**
|
|
39
49
|
* Internal loop method that calculates delta time and schedules the next frame.
|
|
40
50
|
*
|
|
41
|
-
* Delta time is provided in seconds
|
|
51
|
+
* Delta time is provided in seconds, clamped to `MAX_DT_MS` so a paused
|
|
52
|
+
* tab doesn't deliver a multi-second frame.
|
|
42
53
|
*/
|
|
43
54
|
loop: () => void;
|
|
44
55
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { BaseRenderer } from "./renderer";
|
|
5
5
|
import type { Camera3DState, Renderer3DOptions } from "../types";
|
|
6
6
|
export declare abstract class Base3DRenderer extends BaseRenderer<Renderer3DOptions> {
|
|
7
|
-
readonly
|
|
7
|
+
readonly maxInstances: number;
|
|
8
8
|
abstract readonly camera: Camera3DState;
|
|
9
9
|
constructor(canvas: HTMLCanvasElement, options: Renderer3DOptions);
|
|
10
10
|
}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
19
|
import { BasePrefabBucket, type StringOr } from './index';
|
|
20
|
-
import type { Prefab2D, Prefab2DSpec, Prefab3D, Prefab3DSpec, PrefabFor } from './specs';
|
|
20
|
+
import type { CompositePrefab, PartOffset, Prefab2D, Prefab2DSpec, Prefab3D, Prefab3DSpec, PrefabFor } from './specs';
|
|
21
21
|
type SpecForMode<M> = M extends '3d' ? Prefab3DSpec : Prefab2DSpec;
|
|
22
22
|
type PrefabUnionForMode<M> = M extends '3d' ? Prefab3D : Prefab2D;
|
|
23
23
|
/**
|
|
@@ -48,8 +48,48 @@ export declare class PrefabBucket<M extends '2d' | '3d' = '3d', Specs extends Re
|
|
|
48
48
|
* Accepts any string at runtime but autocompletes known ids.
|
|
49
49
|
*/
|
|
50
50
|
get<K extends keyof Specs & string, R = PrefabFor<Specs[K]>>(id: StringOr<K>): R;
|
|
51
|
+
/**
|
|
52
|
+
* Register a named group of part specs. Each part is added as a top-level
|
|
53
|
+
* prefab with id `<groupName>.<partId>` (or `<groupName>.<auto-hex>` when
|
|
54
|
+
* the part omitted `id`). A `composite` prefab is also created at id
|
|
55
|
+
* `groupName`, with the parts wired up via their `offset` for spawning.
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* bucket.addGroup('campfire', [
|
|
59
|
+
* { type: 'gltf', id: 'logs', src: '/logs.glb' },
|
|
60
|
+
* { type: 'cube', id: 'flame', size: 0.3, offset: { position: [0, 0.3, 0] } },
|
|
61
|
+
* { type: 'cube', size: 0.5, offset: { position: [0, 0.8, 0] } }, // auto id
|
|
62
|
+
* ]);
|
|
63
|
+
*
|
|
64
|
+
* await bucket.load();
|
|
65
|
+
*
|
|
66
|
+
* bucket.get('campfire'); // composite (spawnable as one)
|
|
67
|
+
* bucket.get('campfire.logs'); // the part directly
|
|
68
|
+
* bucket.getGroup('campfire').prefabs; // both parts
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
addGroup(name: string, parts: readonly GroupPartInput<M>[]): this;
|
|
72
|
+
/**
|
|
73
|
+
* Look up a group registered via `addGroup`. Returns the parts in order
|
|
74
|
+
* and an `asComposite()` helper that returns the composite prefab created
|
|
75
|
+
* for the group (equivalent to `bucket.get(groupName)`).
|
|
76
|
+
*/
|
|
77
|
+
getGroup(name: string): {
|
|
78
|
+
prefabs: Prefab3D[];
|
|
79
|
+
asComposite(): CompositePrefab;
|
|
80
|
+
};
|
|
51
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* Part spec accepted by `addGroup`: a regular 3D spec with `id` optional
|
|
84
|
+
* (auto-generated when absent) and a new `offset` field.
|
|
85
|
+
*/
|
|
86
|
+
type GroupPartInput<M extends '2d' | '3d'> = M extends '3d' ? {
|
|
87
|
+
[K in Prefab3DSpec as K['type']]: Omit<K, 'id'> & {
|
|
88
|
+
id?: string;
|
|
89
|
+
offset?: PartOffset;
|
|
90
|
+
};
|
|
91
|
+
}[Prefab3DSpec['type']] : never;
|
|
52
92
|
/** Convenience aliases for explicit mode typing (e.g. function params). */
|
|
53
93
|
export type PrefabBucket2D<Specs extends Record<string, Prefab2DSpec> = {}> = PrefabBucket<'2d', Specs>;
|
|
54
94
|
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';
|
|
95
|
+
export type { CompositePrefab, CompositeSpec, CubePrefab, CubeSpec, GltfPrefab, GltfSpec, GridPrefab, GridSpec, PartOffset, Prefab2D, Prefab2DSpec, Prefab3D, Prefab3DSpec, PrefabFor, SpritesheetPrefab, SpritesheetSpec, } from './specs';
|
|
@@ -58,17 +58,27 @@ export type PrefabParser<Spec extends PrefabSpecBase = PrefabSpecBase, Prefab ex
|
|
|
58
58
|
export type PrefabParserMap<Spec extends PrefabSpecBase, Prefab extends PrefabBase> = Record<string, PrefabParser<Spec, Prefab>>;
|
|
59
59
|
export declare class BasePrefabBucket<M extends PrefabMode = PrefabMode, Spec extends PrefabSpecBase = PrefabSpecBase, Prefab extends PrefabBase = PrefabBase, Specs extends Record<string, Spec> = {}> {
|
|
60
60
|
readonly mode: M;
|
|
61
|
-
/** Shared notification channel
|
|
61
|
+
/** Shared notification channel - see `PrefabBucketEvents`. */
|
|
62
62
|
readonly events: EventSystem<PrefabBucketEvents>;
|
|
63
63
|
private parsers;
|
|
64
64
|
private pending;
|
|
65
65
|
private pendingIds;
|
|
66
66
|
private prefabs;
|
|
67
|
+
/** `groupName -> ordered list of final part ids`. Populated by `addGroup` on subclasses. */
|
|
68
|
+
protected groups: Map<string, string[]>;
|
|
67
69
|
constructor(mode: M, parsers?: PrefabParserMap<Spec, Prefab>);
|
|
68
|
-
/** Add a single spec. Throws if id is a duplicate or if the bucket is already loaded. */
|
|
70
|
+
/** Add a single spec. Throws if id is a duplicate, contains '.', or if the bucket is already loaded. */
|
|
69
71
|
add<const S extends Spec>(spec: S): BasePrefabBucket<M, Spec, Prefab, Specs & {
|
|
70
72
|
[K in S['id']]: S;
|
|
71
73
|
}>;
|
|
74
|
+
/**
|
|
75
|
+
* Internal add that skips the '.' validation. Used by `addGroup` on
|
|
76
|
+
* subclasses to register parts under group-path ids (e.g. `'campfire.logs'`)
|
|
77
|
+
* after the group itself has validated user input.
|
|
78
|
+
*/
|
|
79
|
+
protected addUnchecked<const S extends Spec>(spec: S): BasePrefabBucket<M, Spec, Prefab, Specs & {
|
|
80
|
+
[K in S['id']]: S;
|
|
81
|
+
}>;
|
|
72
82
|
/**
|
|
73
83
|
* Add multiple specs. Validates the whole batch (ids unique, not loaded) before
|
|
74
84
|
* committing, so the bucket never lands in a half-applied state.
|
|
@@ -53,7 +53,35 @@ export interface GridSpec {
|
|
|
53
53
|
/** Optional user-defined sidecar data (scale, speed, gameplay hints, etc). */
|
|
54
54
|
readonly metadata?: Record<string, unknown>;
|
|
55
55
|
}
|
|
56
|
-
|
|
56
|
+
/** Unit cube prefab centered at origin. Use the instance's `scale` to size it. */
|
|
57
|
+
export interface CubeSpec {
|
|
58
|
+
readonly type: 'cube';
|
|
59
|
+
readonly id: string;
|
|
60
|
+
/** Edge length. Defaults to 1. */
|
|
61
|
+
readonly size?: number;
|
|
62
|
+
readonly metadata?: Record<string, unknown>;
|
|
63
|
+
}
|
|
64
|
+
/** Local transform offset applied to a part inside a composite/group at spawn time. */
|
|
65
|
+
export interface PartOffset {
|
|
66
|
+
readonly position?: readonly [number, number, number];
|
|
67
|
+
readonly rotation?: readonly [number, number, number];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* A prefab that spawns several other prefabs at fixed local offsets. Created
|
|
71
|
+
* by `bucket.addGroup(...)`; not typically written by hand. Spawning a
|
|
72
|
+
* composite instance spawns one child per part, with each part's offset
|
|
73
|
+
* composed onto the instance's position/rotation.
|
|
74
|
+
*/
|
|
75
|
+
export interface CompositeSpec {
|
|
76
|
+
readonly type: 'composite';
|
|
77
|
+
readonly id: string;
|
|
78
|
+
readonly parts: readonly {
|
|
79
|
+
readonly partId: string;
|
|
80
|
+
readonly offset?: PartOffset;
|
|
81
|
+
}[];
|
|
82
|
+
readonly metadata?: Record<string, unknown>;
|
|
83
|
+
}
|
|
84
|
+
export type Prefab3DSpec = GltfSpec | GridSpec | CubeSpec | CompositeSpec;
|
|
57
85
|
/**
|
|
58
86
|
* Map a spec's `animations` tuple to a record-keyed-by-name. Used to type
|
|
59
87
|
* `GltfPrefab.animations` so `prefab.animations.Run` is a string literal
|
|
@@ -134,7 +162,22 @@ export interface GridPrefab<S extends GridSpec = GridSpec> {
|
|
|
134
162
|
readonly lineWidth: number;
|
|
135
163
|
readonly metadata: MetadataOf<S>;
|
|
136
164
|
}
|
|
137
|
-
export
|
|
165
|
+
export interface CubePrefab<S extends CubeSpec = CubeSpec> {
|
|
166
|
+
readonly type: 'cube';
|
|
167
|
+
readonly id: S['id'];
|
|
168
|
+
readonly size: number;
|
|
169
|
+
readonly metadata: MetadataOf<S>;
|
|
170
|
+
}
|
|
171
|
+
export interface CompositePrefab<S extends CompositeSpec = CompositeSpec> {
|
|
172
|
+
readonly type: 'composite';
|
|
173
|
+
readonly id: S['id'];
|
|
174
|
+
readonly parts: readonly {
|
|
175
|
+
readonly partId: string;
|
|
176
|
+
readonly offset?: PartOffset;
|
|
177
|
+
}[];
|
|
178
|
+
readonly metadata: MetadataOf<S>;
|
|
179
|
+
}
|
|
180
|
+
export type Prefab3D = GltfPrefab | GridPrefab | CubePrefab | CompositePrefab;
|
|
138
181
|
export interface SpritesheetSpec {
|
|
139
182
|
readonly type: 'spritesheet';
|
|
140
183
|
readonly id: string;
|
|
@@ -162,5 +205,5 @@ export type Prefab2D = SpritesheetPrefab;
|
|
|
162
205
|
* bucket's `get()` so `bucket.get('minion')` returns `GltfPrefab` directly,
|
|
163
206
|
* not the discriminated union.
|
|
164
207
|
*/
|
|
165
|
-
export type PrefabFor<S> = S extends GltfSpec ? GltfPrefab<S> : S extends GridSpec ? GridPrefab<S> : S extends SpritesheetSpec ? SpritesheetPrefab<S> : never;
|
|
208
|
+
export type PrefabFor<S> = S extends GltfSpec ? GltfPrefab<S> : S extends GridSpec ? GridPrefab<S> : S extends CubeSpec ? CubePrefab<S> : S extends CompositeSpec ? CompositePrefab<S> : S extends SpritesheetSpec ? SpritesheetPrefab<S> : never;
|
|
166
209
|
export {};
|
|
@@ -14,10 +14,12 @@ export interface Renderer2DOptions extends RendererOptions {
|
|
|
14
14
|
}
|
|
15
15
|
export interface Renderer3DOptions extends RendererOptions {
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* How many instances you intend to spawn at once. Sizes both the
|
|
18
|
+
* non-skinned instance pool directly and seeds the default for the
|
|
19
|
+
* skinned-instance budget. Optional when a prefab bucket is provided -
|
|
20
|
+
* the renderer derives a sensible default from the bucket.
|
|
19
21
|
*/
|
|
20
|
-
|
|
22
|
+
maxInstances?: number;
|
|
21
23
|
enableLighting?: boolean;
|
|
22
24
|
}
|
|
23
25
|
export interface Camera2DState {
|