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.
@@ -25,6 +25,8 @@ export interface MeshInstanceHandle {
25
25
  setScale(x: number, y: number, z: number): void;
26
26
  play?(name: string, opts?: PlayOptions): void;
27
27
  stop?(): void;
28
+ /** Free this instance's renderer slot. Safe to call once per handle. */
29
+ destroy(): void;
28
30
  }
29
31
  /** A loaded glTF model — may contain multiple mesh parts that share a skeleton. */
30
32
  export interface GltfModel {
@@ -44,6 +46,8 @@ export interface InstanceHandle {
44
46
  play?(name: string, opts?: PlayOptions): void;
45
47
  stop?(): void;
46
48
  readonly skinned: boolean;
49
+ /** Free this instance's renderer slot(s). Safe to call once per handle. */
50
+ destroy(): void;
47
51
  }
48
52
  export interface MeshInstanceOptions {
49
53
  /**
@@ -75,11 +79,13 @@ export interface WebGPU3DRendererOptions extends Renderer3DOptions {
75
79
  */
76
80
  prefabs?: PrefabBucket3D;
77
81
  /**
78
- * How many instances you intend to spawn. Used together with `prefabs` to
79
- * size the skinned-instance budget. Ignored if `maxSkinnedInstances` is set
80
- * explicitly. Defaults to `maxModels` when only `prefabs` is provided.
82
+ * Max distance (world units) at which skeletal animation is computed for
83
+ * skinned instances. Past this, instances still render but reuse their
84
+ * last bone matrices; their internal animation clocks keep ticking on
85
+ * CPU. See `renderer.setAnimationCullDistance` to change at runtime.
86
+ * Set to `Infinity` to disable. Default 50.
81
87
  */
82
- maxInstances?: number;
88
+ animationCullDistance?: number;
83
89
  }
84
90
  export declare class WebGPU3DRenderer extends Base3DRenderer {
85
91
  private root;
@@ -136,12 +142,20 @@ export declare class WebGPU3DRenderer extends Base3DRenderer {
136
142
  private skinnedFreeList;
137
143
  private skinnedBatcher;
138
144
  private skinnedStaticDirty;
145
+ private skinnedStaticDV;
139
146
  private skinnedInstanceModelIds;
140
147
  private skinnedInstanceBoneOffsets;
141
148
  private skinnedAnimStates;
142
149
  private nextBoneOffset;
150
+ /** Reusable bone-offset blocks per skinIndex. Pushed on remove, popped on add. Indexed by skinIndex (low cardinality), so a Map of lists is fine. */
151
+ private freedBoneOffsets;
152
+ /** Per-bone-offset refcount. Linked multi-part instances share a block; freed when refcount hits 0. Indexed by boneOffset (< maxTotalBones). */
153
+ private boneOffsetRefcount;
154
+ /** Per-bone-offset skinIndex tag, so we can return the block to the right per-skin freelist on remove. */
155
+ private boneOffsetSkinIndex;
143
156
  private readonly maxSkinnedInstances;
144
157
  private readonly maxBonesPerSkin;
158
+ private animationCullDistanceSq;
145
159
  private rawSkinnedDynamicBuffer;
146
160
  private rawSkinnedStaticBuffer;
147
161
  private rawSkinnedUniformBuffer;
@@ -167,6 +181,30 @@ export declare class WebGPU3DRenderer extends Base3DRenderer {
167
181
  */
168
182
  onResize(callback: (width: number, height: number) => void): void;
169
183
  createCompute(name: string, options: ComputeOptions): ComputeBuilder;
184
+ /**
185
+ * Set the maximum distance (in world units) at which the renderer keeps
186
+ * computing skeletal animation. Skinned instances farther than this are
187
+ * still drawn, but with their last-computed bone matrices instead of
188
+ * fresh ones, which saves GPU compute work. Their internal animation
189
+ * clocks keep ticking on CPU, so when they come back into range they
190
+ * resume in sync.
191
+ *
192
+ * Lower values trade visual smoothness on distant characters for FPS.
193
+ * Pass `Infinity` to disable culling entirely (always animate).
194
+ *
195
+ * Safe to call any time; takes effect on the next frame.
196
+ *
197
+ * @param distance Max distance to animate at, in world units.
198
+ */
199
+ setAnimationCullDistance(distance: number): void;
200
+ /** Current animation cull distance (in world units). See `setAnimationCullDistance`. */
201
+ get animationCullDistance(): number;
202
+ /**
203
+ * Max skinned instances the renderer was sized for at construction.
204
+ * Independent budget from `maxInstances` since skinned characters use a
205
+ * separate set of GPU buffers. Read-only.
206
+ */
207
+ get maxSkinned(): number;
170
208
  /**
171
209
  * Create a flat grid mesh on the XZ plane at Y=0.
172
210
  *
@@ -180,6 +218,18 @@ export declare class WebGPU3DRenderer extends Base3DRenderer {
180
218
  step?: number;
181
219
  lineWidth?: number;
182
220
  }): ModelHandle;
221
+ /**
222
+ * Create a unit-cube mesh centered at the origin. Pass `size` to scale the
223
+ * edge length, or keep size = 1 and scale at the instance level.
224
+ *
225
+ * ```ts
226
+ * const cube = renderer.createCube();
227
+ * renderer.addInstance({ model: cube, color: [1, 0.5, 0.2], scale: 2 });
228
+ * ```
229
+ */
230
+ createCube(opts?: {
231
+ size?: number;
232
+ }): ModelHandle;
183
233
  /**
184
234
  * Register a model. Returns a handle for addInstance().
185
235
  *
@@ -229,6 +279,13 @@ export declare class WebGPU3DRenderer extends Base3DRenderer {
229
279
  */
230
280
  addInstance(opts: MeshInstanceOptions): InstanceHandle;
231
281
  private addGltfInstance;
282
+ /**
283
+ * Spawn a composite prefab by spawning each of its parts at the composed
284
+ * (instance + offset) transform. The returned handle broadcasts subsequent
285
+ * `setPosition` / `setRotation` to every child, keeping each child's
286
+ * baked offset applied on top of the new value.
287
+ */
288
+ private addCompositeInstance;
232
289
  private addSkinnedInstance;
233
290
  /**
234
291
  * Drain pending resyncs from the coordinator. Per affected skin: rebuild
@@ -248,8 +305,19 @@ export declare class WebGPU3DRenderer extends Base3DRenderer {
248
305
  * Update skeletal animations for all skinned instances. Call once per tick.
249
306
  */
250
307
  private updatedBoneOffsets;
308
+ /**
309
+ * Returns true if a skinned instance's bone-matrix compute should be
310
+ * dispatched this frame. Combines frustum culling (scaled bounding sphere)
311
+ * and a configurable distance cull from the camera. Callers pass the
312
+ * camera position + cullDistSq once outside the loop to avoid re-reading.
313
+ */
314
+ private shouldDispatchSkinning;
251
315
  private updateAnimations;
252
- removeInstance(handle: MeshInstanceHandle): void;
316
+ /**
317
+ * Free an instance's renderer slot. Equivalent to `handle.destroy()` -
318
+ * kept as a convenience for direct lookup. Safe to call multiple times.
319
+ */
320
+ removeInstance(handle: InstanceHandle): void;
253
321
  storePreviousState(): void;
254
322
  render(alpha: number): void;
255
323
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "murow",
3
- "version": "0.0.72",
3
+ "version": "0.0.73",
4
4
  "description": "A lightweight TypeScript game engine for server-authoritative multiplayer games",
5
5
  "types": "dist/types/index.d.ts",
6
6
  "type": "module",