@babylonjs/lite 1.7.0 → 1.8.0

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.
Files changed (78) hide show
  1. package/CHANGELOG.md +735 -0
  2. package/README.md +26 -1
  3. package/THIRD_PARTY_NOTICES.txt +139 -0
  4. package/dist/index.js +292 -277
  5. package/dist/index.js.map +1 -1
  6. package/index.d.ts +277 -11
  7. package/lib/_chunks/vendor/{manifold-Sh8xE2da.js → manifold-DtI3BJoR.js} +2 -2
  8. package/lib/_chunks/vendor/{manifold-Sh8xE2da.js.map → manifold-DtI3BJoR.js.map} +1 -1
  9. package/lib/animation/animation-group-task.js +1 -1
  10. package/lib/animation/animation-group-task.js.map +1 -1
  11. package/lib/animation/animation-group.js +20 -15
  12. package/lib/animation/animation-group.js.map +1 -1
  13. package/lib/animation/animation-tick.js +10 -0
  14. package/lib/animation/animation-tick.js.map +1 -0
  15. package/lib/animation/property-animation.js +2 -1
  16. package/lib/animation/property-animation.js.map +1 -1
  17. package/lib/animation/weighted-gltf-mixer.js +1 -1
  18. package/lib/animation/weighted-gltf-mixer.js.map +1 -1
  19. package/lib/animation/weighted-pointer-mixer.js +1 -1
  20. package/lib/animation/weighted-pointer-mixer.js.map +1 -1
  21. package/lib/engine/device-lost-recovery.js +1 -0
  22. package/lib/engine/device-lost-recovery.js.map +1 -1
  23. package/lib/engine/engine.js +1 -1
  24. package/lib/engine/null-engine.js +29 -0
  25. package/lib/engine/null-engine.js.map +1 -0
  26. package/lib/frame-graph/depth-pyramid.js +158 -0
  27. package/lib/frame-graph/depth-pyramid.js.map +1 -0
  28. package/lib/frame-graph/frame-graph-actions.js +10 -1
  29. package/lib/frame-graph/frame-graph-actions.js.map +1 -1
  30. package/lib/frame-graph/render-task.js +7 -0
  31. package/lib/frame-graph/render-task.js.map +1 -1
  32. package/lib/frame-graph/transmission-depth-grab.js +88 -0
  33. package/lib/frame-graph/transmission-depth-grab.js.map +1 -0
  34. package/lib/frame-graph/transmission.js +30 -1
  35. package/lib/frame-graph/transmission.js.map +1 -1
  36. package/lib/gizmo/bounding-box-gizmo.js +1 -1
  37. package/lib/index.js +8 -6
  38. package/lib/index.js.map +1 -1
  39. package/lib/loader-gltf/gltf-feature-gpu-instancing.js +1 -1
  40. package/lib/loader-gltf/gltf-interleave.js +1 -1
  41. package/lib/loader-gltf/load-gltf.js +1 -1
  42. package/lib/material/shader/shader-pipeline.js +1 -1
  43. package/lib/material/shader/shader-pipeline.js.map +1 -1
  44. package/lib/material/shader/shader-renderable.js +23 -8
  45. package/lib/material/shader/shader-renderable.js.map +1 -1
  46. package/lib/math/aabb.js +1 -1
  47. package/lib/math/compute-aabb.js +63 -1
  48. package/lib/math/compute-aabb.js.map +1 -1
  49. package/lib/math/index.js +1 -1
  50. package/lib/mesh/csg2.js +3 -2
  51. package/lib/mesh/csg2.js.map +1 -1
  52. package/lib/mesh/mesh-factories.js +1 -1
  53. package/lib/mesh/thin-instance-gpu-culling.js +4 -2
  54. package/lib/mesh/thin-instance-gpu-culling.js.map +1 -1
  55. package/lib/mesh/thin-instance.js +8 -1
  56. package/lib/mesh/thin-instance.js.map +1 -1
  57. package/lib/navigation/index.js +1 -1
  58. package/lib/navigation/navigation.js +9 -1
  59. package/lib/navigation/navigation.js.map +1 -1
  60. package/lib/physics/character-controller.js +2 -2
  61. package/lib/physics/character-controller.js.map +1 -1
  62. package/lib/physics/havok-floating-origin.js +2 -2
  63. package/lib/physics/havok-floating-origin.js.map +1 -1
  64. package/lib/physics/havok.js +40 -13
  65. package/lib/physics/havok.js.map +1 -1
  66. package/lib/picking/gpu-picker.js +16 -2
  67. package/lib/picking/gpu-picker.js.map +1 -1
  68. package/lib/scene/scene-core.js +9 -3
  69. package/lib/scene/scene-core.js.map +1 -1
  70. package/lib/scene/scene-remove.js +8 -0
  71. package/lib/scene/scene-remove.js.map +1 -1
  72. package/lib/texture/pixels-texture.js +31 -1
  73. package/lib/texture/pixels-texture.js.map +1 -1
  74. package/lib/vat/vat-baker.js +41 -2
  75. package/lib/vat/vat-baker.js.map +1 -1
  76. package/package.json +15 -3
  77. package/lib/_chunks/__vite-browser-external-BFTKbDcV.js +0 -68
  78. package/lib/_chunks/__vite-browser-external-BFTKbDcV.js.map +0 -1
package/index.d.ts CHANGED
@@ -160,6 +160,10 @@ export declare function addSpriteRendererLayer(sr: SpriteRenderer, layer: Sprite
160
160
  * or a SceneContext (the scene's default frame graph is used). */
161
161
  export declare function addTask(target: FrameGraph | SceneContext, task: Task): void;
162
162
 
163
+ /** Insert a task immediately AFTER another task in execute order. Accepts a FrameGraph or a SceneContext.
164
+ * If `after` is not found, the task is appended at the end (matching `addTaskBefore`'s fallback). */
165
+ export declare function addTaskAfter(target: FrameGraph | SceneContext, task: Task, after: Task): void;
166
+
163
167
  /** Insert a task at the START of user execute order. Built-in system tasks that must
164
168
  * precede all user work, such as the shadow adapter, keep their leading slot. */
165
169
  export declare function addTaskAtStart(target: FrameGraph | SceneContext, task: Task): void;
@@ -951,8 +955,9 @@ export declare function bakeTransformIntoVertices(mesh: GaussianSplattingMesh, t
951
955
  * @param engine - Engine context.
952
956
  * @param mesh - The skinned source mesh (must have `mesh.skeleton`).
953
957
  * @param groups - The animation clips to bake (e.g. a creature's gait clips).
958
+ * @param opts - Optional extras to capture during the bake (e.g. per-frame bone origins).
954
959
  */
955
- export declare function bakeVat(engine: EngineContext, mesh: Mesh, groups: AnimationGroup[]): VatBakeResult;
960
+ export declare function bakeVat(engine: EngineContext, mesh: Mesh, groups: AnimationGroup[], opts?: VatBakeOptions): VatBakeResult;
956
961
 
957
962
  /**
958
963
  * Additive blending for world-space billboards. The billboard's RGB, scaled by its own alpha, is
@@ -1903,6 +1908,16 @@ export declare function createDefaultTextData(font: Font, fontSizePx: number, te
1903
1908
  */
1904
1909
  export declare function createDepthOfFieldPostProcessTask(config: DepthOfFieldPostProcessTaskConfig, engine: EngineContext, scene?: SceneContext): DepthOfFieldPostProcessTask;
1905
1910
 
1911
+ /** Create a hierarchical depth pyramid sized `width`×`height`. Build it each frame from the live depth texture
1912
+ * (via `createDepthPyramidTask`, or `build()` directly). Owns its COPY/REDUCE pipelines + the mipped texture. */
1913
+ export declare function createDepthPyramid(engine: EngineContext, opts: DepthPyramidOptions): DepthPyramid;
1914
+
1915
+ /** Create a frame-graph task that rebuilds `pyramid` from `source()` into the FRAME command encoder each frame.
1916
+ * Order it right after the pass that produces the depth (e.g. `addTaskAfter(scene, task, depthPrepassTask)`) so
1917
+ * the pyramid reflects THIS frame's depth. Resize the pyramid to the source's size before the frame is recorded
1918
+ * (the source depth target only changes size on a canvas resize). */
1919
+ export declare function createDepthPyramidTask(engine: EngineContext, scene: SceneContext, opts: DepthPyramidTaskOptions): Task;
1920
+
1906
1921
  /** Create a frame-graph task that resolves `sourceTexture`'s multisampled depth into `targetTexture`'s
1907
1922
  * single-sample depth. Add it AFTER the source render task and BEFORE any depth-sampling consumer. */
1908
1923
  export declare function createDepthResolveTask(config: DepthResolveTaskConfig, engine: EngineContext, scene: SceneContext): Task;
@@ -2197,6 +2212,56 @@ export declare function createNavMeshFromSources(plugin: NavigationPlugin, sourc
2197
2212
  /** Create a no-color view over a NodeMaterial source. */
2198
2213
  export declare function createNodeNoColorMaterialView(source: NodeMaterial): MaterialView;
2199
2214
 
2215
+ /**
2216
+ * Create a **null engine** — a device-less, surface-less {@link EngineContext} that runs the
2217
+ * simulation half of Babylon Lite (physics stepping, animation evaluation, `onBeforeRender`
2218
+ * callbacks, transform updates) **without any GPU device or canvas**.
2219
+ *
2220
+ * This is the Babylon Lite analogue of Babylon.js `NullEngine`: it lets a scene be driven
2221
+ * headlessly on a server (plain Node, Deno, a Web Worker, a CI job) so you can run e.g. a Havok
2222
+ * physics simulation and read back body transforms with zero rendering.
2223
+ *
2224
+ * ### What works
2225
+ * - `createSceneContext(engine, { defaultRenderTask: false })` — a scene with **no** frame-graph
2226
+ * render task (so no swapchain / GPU resources are ever built).
2227
+ * - `onBeforeRender(scene, cb)` callbacks (physics `createHavokWorld` registers its step this way).
2228
+ * - `stepScene(engine, scene, deltaMs)` to advance one fixed step (replaces the browser
2229
+ * `requestAnimationFrame` loop that `startEngine` uses).
2230
+ * - Physics with **primitive** collider shapes (box/sphere/capsule/cylinder) whose geometry is
2231
+ * given explicitly or derived from `mesh.boundMin`/`boundMax`.
2232
+ *
2233
+ * ### What is NOT supported (throws or is undefined behaviour)
2234
+ * - Any rendering: `startEngine`, `renderFrame`, `captureScreenshot`, adding meshes **with
2235
+ * materials** (their deferred GPU builders dereference the absent `_device`), surfaces, RTTs.
2236
+ * - Mesh/convex-hull colliders that require `node.worldMatrix` (needs the render-side world-matrix
2237
+ * pass). This is a follow-up.
2238
+ * - High-precision / floating-origin matrices (they need the F64 allocator that `createEngine`
2239
+ * installs). This is a follow-up.
2240
+ *
2241
+ * @remarks
2242
+ * The returned object is deliberately a **partial** {@link EngineContext}: only the fields the
2243
+ * device-less simulation/update path reads are populated (`_device` is intentionally absent). The
2244
+ * single localized cast below is the whole cost of not yet splitting `EngineContext` from its
2245
+ * mandatory `_device`/`SurfaceContext` members — a larger, separate refactor. Every rendering code
2246
+ * path is unreachable on a null engine, so the missing GPU fields are never dereferenced.
2247
+ *
2248
+ * @example
2249
+ * ```ts
2250
+ * import { createNullEngine, stepScene } from "babylon-lite";
2251
+ * import { createSceneContext, onBeforeRender } from "babylon-lite";
2252
+ *
2253
+ * const engine = createNullEngine();
2254
+ * const scene = createSceneContext(engine, { defaultRenderTask: false });
2255
+ *
2256
+ * // e.g. real Havok physics — createHavokWorld registers its step via onBeforeRender
2257
+ * // const world = createHavokWorld(scene, await HavokPhysics());
2258
+ *
2259
+ * const stepMs = 1000 / 60;
2260
+ * for (let i = 0; i < 180; i++) stepScene(engine, scene, stepMs); // 3s, no rendering
2261
+ * ```
2262
+ */
2263
+ export declare function createNullEngine(_options?: NullEngineOptions): EngineContext;
2264
+
2200
2265
  /** Create a PbrMaterialProps with optional overrides. */
2201
2266
  export declare function createPbrMaterial(props?: Partial<PbrMaterialProps>): PbrMaterialProps;
2202
2267
 
@@ -2619,6 +2684,25 @@ export declare function createTextRenderer(surface: SurfaceContext, opts: TextRe
2619
2684
  */
2620
2685
  export declare function createTexture2DFromPixels(engine: EngineContext, data: Uint8Array, width: number, height: number, options?: PixelsTexture2DOptions): Texture2D;
2621
2686
 
2687
+ /**
2688
+ * Create a **3D** texture from a tightly-packed RGBA8 byte buffer — the volumetric analog of
2689
+ * `createTexture2DFromPixels`. The primary use is a colour-grading LUT (a `.cube`/HALD colour cube):
2690
+ * upload the N×N×N RGBA volume once and sample it trilinearly with a single `textureSample`.
2691
+ *
2692
+ * The default sampler is linear with clamp-to-edge on all three axes — exactly what a LUT wants (linear
2693
+ * = trilinear interpolation between grid points; clamp = no wrap at the cube faces). The returned handle
2694
+ * is a `Texture2D` (so it drops straight into `setEffectTexture`) with an extra `depth` field; its `view`
2695
+ * is created with `dimension:"3d"`.
2696
+ *
2697
+ * @param engine - Engine context.
2698
+ * @param data - `width * height * depth * 4` bytes, RGBA8, ordered x fastest, then y, then z (slice-major).
2699
+ * @param width - Cube size along R (\>= 1).
2700
+ * @param height - Cube size along G (\>= 1).
2701
+ * @param depth - Cube size along B (\>= 1).
2702
+ * @param options - Sampler / format overrides.
2703
+ */
2704
+ export declare function createTexture3DFromPixels(engine: EngineContext, data: Uint8Array, width: number, height: number, depth: number, options?: PixelsTexture3DOptions): Texture3D;
2705
+
2622
2706
  /** Create a torus mesh. Caller must assign material. */
2623
2707
  export declare function createTorus(engine: EngineContext, options?: TorusOptions): Mesh;
2624
2708
 
@@ -2875,6 +2959,49 @@ export declare interface DepthOfFieldPostProcessTaskConfig extends PostProcessTa
2875
2959
  depthNotNormalized?: boolean;
2876
2960
  }
2877
2961
 
2962
+ /** A rebuildable hierarchical depth pyramid. Create with `createDepthPyramid`; drive its per-frame build with
2963
+ * `createDepthPyramidTask` (in-frame) or by calling `build()` yourself. */
2964
+ export declare interface DepthPyramid {
2965
+ /** `r32float`, full mip chain, nearest sampler. Bind to a material; read `textureLoad(tex, coord, mip)`.
2966
+ * A `resize()` replaces this wrapper (new identity) — re-read it and re-bind after a resize. */
2967
+ readonly texture: Texture2D;
2968
+ /** Number of mip levels in the current pyramid. */
2969
+ readonly mipCount: number;
2970
+ /** Re-derive the pyramid from `depthTexture` (a `texture_depth_2d` of matching mip-0 size). Pass the frame
2971
+ * `encoder` to record the COPY/REDUCE passes in-frame (e.g. after a depth prepass, before the consumer that
2972
+ * samples the pyramid); omit it to run on a private encoder + submit immediately. */
2973
+ build(depthTexture: Texture2D, encoder?: GPUCommandEncoder): void;
2974
+ /** Reallocate the pyramid texture at a new mip-0 size (call when the source depth target resizes). No-op if
2975
+ * unchanged. Mint a new `texture` wrapper on a real change; safe to call any time (does not destroy the old
2976
+ * texture while a consumer still references it). */
2977
+ resize(width: number, height: number): void;
2978
+ /** Release the pyramid's base texture ref (frees the GPU texture once no consumer holds it). */
2979
+ dispose(): void;
2980
+ }
2981
+
2982
+ export declare interface DepthPyramidOptions {
2983
+ /** Mip-0 width — match the source depth texture. */
2984
+ width: number;
2985
+ /** Mip-0 height — match the source depth texture. */
2986
+ height: number;
2987
+ /** Child-texel combine: `max` (default; reverse-Z nearest-surface Hi-Z) or `min` (forward-Z, or
2988
+ * reverse-Z farthest-occluder for occlusion culling). */
2989
+ reduce?: DepthPyramidReduce;
2990
+ }
2991
+
2992
+ /** How each coarser pyramid level combines its four child texels. */
2993
+ export declare type DepthPyramidReduce = "min" | "max";
2994
+
2995
+ /** Options for `createDepthPyramidTask`. */
2996
+ export declare interface DepthPyramidTaskOptions {
2997
+ /** The pyramid to build each frame. The task ADOPTS it — the frame graph disposes it on graph dispose, so do
2998
+ * not also dispose it yourself. */
2999
+ pyramid: DepthPyramid;
3000
+ /** The live source depth texture for this frame (e.g. a depth-prepass target). Return `null` to skip the
3001
+ * build this frame (e.g. before the source exists, or when nothing consumes the pyramid). */
3002
+ source: () => Texture2D | null;
3003
+ }
3004
+
2878
3005
  /** Options for a depth-resolve frame-graph task. */
2879
3006
  export declare interface DepthResolveTaskConfig {
2880
3007
  name?: string;
@@ -3475,6 +3602,13 @@ export declare interface FadeAnimationWeightOptions {
3475
3602
  readonly from?: number;
3476
3603
  }
3477
3604
 
3605
+ /** Snap a position to the closest point on the navmesh within a search box, or null when no part of the
3606
+ * mesh lies inside it. Unlike getClosestPoint — which does not inspect the query's success flag, so a
3607
+ * position outside its fixed ±1-unit box returns an UNSPECIFIED point (whatever the query left in its
3608
+ * output) rather than signalling a miss — the search extent is explicit here and a failed query is
3609
+ * reported as null, so callers can distinguish "snapped" from "nothing nearby". */
3610
+ export declare function findClosestPointWithin(plugin: NavigationPlugin, position: Vec3, halfExtents: Vec3): Vec3 | null;
3611
+
3478
3612
  /** Return any random point on the navmesh. */
3479
3613
  export declare function findRandomPoint(plugin: NavigationPlugin): Vec3;
3480
3614
 
@@ -3956,12 +4090,21 @@ export declare function getPhysicsBodyLinearVelocity(world: PhysicsWorld, body:
3956
4090
  export declare function getPhysicsGravity(world: PhysicsWorld, worldPosition?: Vec3): Vec3;
3957
4091
 
3958
4092
  /**
3959
- * Returns the world's fixed simulation timestep in seconds.
4093
+ * Returns the world's fixed simulation timestep in **seconds** (`0` means the real per-frame delta
4094
+ * is used). See {@link getPhysicsTimestepMs} for the millisecond-based equivalent.
3960
4095
  * @param world - The physics world.
3961
- * @returns The timestep in seconds.
4096
+ * @returns The fixed step in seconds.
3962
4097
  */
3963
4098
  export declare function getPhysicsTimestep(world: PhysicsWorld): number;
3964
4099
 
4100
+ /**
4101
+ * Returns the world's fixed simulation timestep in **milliseconds** (`0` means the real per-frame
4102
+ * delta is used). See {@link getPhysicsTimestep} for the seconds-based equivalent.
4103
+ * @param world - The physics world.
4104
+ * @returns The fixed step in milliseconds.
4105
+ */
4106
+ export declare function getPhysicsTimestepMs(world: PhysicsWorld): number;
4107
+
3965
4108
  /**
3966
4109
  * Returns the world's current maximum linear and angular speed limits.
3967
4110
  * @param world - The physics world.
@@ -5180,6 +5323,18 @@ export declare function normalizeVec3Object(v: Vec3): Vec3;
5180
5323
  /** Normalize `v` into `out`, writing zero for degenerate input. */
5181
5324
  export declare function normalizeVec3ToRef(v: Vec3, out: Vec3, epsilon?: number): Vec3;
5182
5325
 
5326
+ /**
5327
+ * Options for {@link createNullEngine}.
5328
+ */
5329
+ export declare interface NullEngineOptions {
5330
+ /**
5331
+ * Reserved for future headless-driver options (e.g. variable-timestep control). No options are
5332
+ * consumed today; the property exists only to keep the option-bag shape stable and forbids
5333
+ * passing unknown fields.
5334
+ */
5335
+ reserved?: never;
5336
+ }
5337
+
5183
5338
  /**
5184
5339
  * A 4-component quaternion whose `x`/`y`/`z`/`w` setters fire an `onDirty` callback
5185
5340
  * when a component actually changes, letting the hierarchy system detect rotation updates.
@@ -5837,7 +5992,17 @@ export declare interface PhysicsViewerOptions {
5837
5992
  /** Pure-state handle to a Havok physics world: the WASM module, the native world, its bodies, and the timestep. */
5838
5993
  export declare interface PhysicsWorld {
5839
5994
 
5840
- /** Pick the mesh at CSS-space canvas coordinates, matching Babylon.js Scene.pick. Returns a PickingInfo. */
5995
+ /**
5996
+ * Pick the mesh at CSS-space canvas coordinates, matching Babylon.js Scene.pick. Returns a PickingInfo.
5997
+ *
5998
+ * A picker's 1×1 readback targets (`PickTargets1x1.colorStaging`/`depthStaging`) are lazily created ONCE
5999
+ * and reused for every pick — cheap, but it means two overlapping `pickAsync` calls on the SAME picker
6000
+ * race `mapAsync` on those shared buffers ("Buffer already has an outstanding map pending", since a
6001
+ * GPUBuffer allows only one pending map at a time). This is easy to trigger from a consumer: e.g. a
6002
+ * cursor-following hover preview that GPU-picks on every pointermove, racing a pick fired by a click that
6003
+ * lands before the hover's pick has unmapped. Queue concurrent calls per-picker instead of rejecting: each
6004
+ * pick's full map/unmap cycle completes before the next one starts.
6005
+ */
5841
6006
  export declare function pickAsync(picker: GpuPicker, x: number, y: number, options?: PickOptions): Promise<PickingInfo>;
5842
6007
 
5843
6008
  /**
@@ -5924,6 +6089,17 @@ export declare interface PixelsTexture2DOptions {
5924
6089
  srgb?: boolean;
5925
6090
  }
5926
6091
 
6092
+ /** Sampler / format overrides for `createTexture3DFromPixels()`. */
6093
+ export declare interface PixelsTexture3DOptions {
6094
+ /** Address mode U/V/W. Default 'clamp-to-edge' (the right choice for a colour LUT — the cube edges
6095
+ * must not wrap). */
6096
+ addressMode?: GPUAddressMode;
6097
+ /** Min/mag filter. Default 'linear' so a colour-grading LUT interpolates trilinearly in one sample. */
6098
+ filter?: GPUFilterMode;
6099
+ /** Use sRGB format (rgba8unorm-srgb). Leave false for a linear/display LUT. Default false. */
6100
+ srgb?: boolean;
6101
+ }
6102
+
5927
6103
  /** A viewport expressed in integer render-target pixels, with `y` measured from the top (WebGPU convention). */
5928
6104
  export declare interface PixelViewport {
5929
6105
  x: number;
@@ -6660,10 +6836,11 @@ export declare interface RenderTargetSignature {
6660
6836
  export declare interface RenderTask extends Task {
6661
6837
  readonly name: string;
6662
6838
  /** Render tasks are scene-bound because they consume scene camera, lights, and renderables. */
6663
- readonly scene: SceneContext;
6664
6839
  /** Add a mesh to this task's explicit render list with an optional per-pass material override.
6665
- * Resolved at `record()` time via `material._buildGroup._rebuildSingle`,
6666
- * so the mesh's material family must already have been registered with
6667
- * the scene (so its batch builder has run). */
6840
+ readonly scene: SceneContext;
6668
6841
  /** Add a mesh to this task's explicit render list with an optional per-pass material override. Resolved via
6842
+ * `material._buildGroup._rebuildSingle`, so the mesh's material family must already have been registered with the
6843
+ * scene (its batch builder has run). BEFORE the first `record()` the add is QUEUED and drained at record() time;
6844
+ * AFTER (a live/runtime add) it is resolved + re-bucketed into THIS task immediately, so the mesh renders on the
6845
+ * next frame without a `frameGraph.build()` (which would re-allocate shared GPU resources across all tasks). */
6669
6846
  addMesh(mesh: Mesh, opts?: {
6670
6847
  material?: Material;
6671
6848
  }): void;
@@ -6708,11 +6885,14 @@ export declare interface RenderTaskConfig {
6708
6885
  cs?: boolean;
6709
6886
  /** Scene-texture transmission settings. `copyCount: 0` copies before every transmissive draw.
6710
6887
  * `generateMipmaps: false` allocates only mip 0 for the refraction texture and skips mip generation.
6711
- * `mipLevelCount` caps the generated chain when a material only samples low explicit LODs. */
6888
+ * `mipLevelCount` caps the generated chain when a material only samples low explicit LODs.
6889
+ * `grabDepth: true` also snapshots the task's DEPTH attachment at the same mid-pass grab (see
6890
+ * `TransmissionOptions.grabDepth`). */
6712
6891
  transmission?: {
6713
6892
  copyCount?: number;
6714
6893
  generateMipmaps?: boolean;
6715
6894
  mipLevelCount?: number;
6895
+ grabDepth?: boolean;
6716
6896
  };
6717
6897
  }
6718
6898
 
@@ -6833,6 +7013,17 @@ export declare interface RotationGizmoOptions {
6833
7013
  thickness?: number;
6834
7014
  }
6835
7015
 
7016
+ /**
7017
+ * Convenience driver: advance a headless scene by a fixed number of steps at a fixed timestep.
7018
+ * Equivalent to calling {@link stepScene} `steps` times.
7019
+ *
7020
+ * @param engine - A null engine from {@link createNullEngine}.
7021
+ * @param scene - A scene created with `createSceneContext(engine, { defaultRenderTask: false })`.
7022
+ * @param steps - Number of fixed steps to advance.
7023
+ * @param deltaMs - The fixed timestep per step, in milliseconds (default `1000 / 60`).
7024
+ */
7025
+ export declare function runHeadlessSteps(engine: EngineContext, scene: SceneContext, steps: number, deltaMs?: number): void;
7026
+
6836
7027
  /** Composite scale gizmo made from X/Y/Z axis handles and a central uniform handle. */
6837
7028
  export declare interface ScaleGizmo {
6838
7029
  readonly xGizmo: AxisScaleGizmo;
@@ -6873,6 +7064,11 @@ export declare interface SceneColorGrab {
6873
7064
  * (e.g. on resize), so consumers that bind it to a custom material should re-bind when it
6874
7065
  * changes. */
6875
7066
  readonly texture: Texture2D | null;
7067
+ /** The live opaque-scene DEPTH grab (`grabDepth: true`): the task's depth attachment as of the moment
7068
+ * the first transmissive surface draws, resolved to a single-sample `r32float` (raw NDC depth as
7069
+ * stored; a cleared texel means no geometry). Null before the target builds or when `grabDepth` is
7070
+ * off. Identity changes when the task rebuilds (e.g. on resize) — re-bind on change. */
7071
+ readonly depthTexture: Texture2D | null;
6876
7072
  }
6877
7073
 
6878
7074
  /** Top-level scene context — pure state, no attached methods. */
@@ -7323,12 +7519,24 @@ export declare function setPhysicsShapeIsTrigger(world: PhysicsWorld, shape: Phy
7323
7519
  export declare function setPhysicsShapeMaterial(world: PhysicsWorld, shape: PhysicsShape, friction: number, restitution: number): void;
7324
7520
 
7325
7521
  /**
7326
- * Sets the fixed simulation timestep used by each world step.
7522
+ * Sets the fixed simulation timestep used by each world step, in **seconds**.
7523
+ *
7524
+ * Pass `0` to make the world step at the real per-frame delta instead of a fixed step.
7525
+ * See {@link setPhysicsTimestepMs} for the millisecond-based equivalent.
7327
7526
  * @param world - The physics world.
7328
- * @param dt - Timestep in seconds (e.g. `1 / 60`).
7527
+ * @param dt - Fixed step in seconds (e.g. `1 / 60`), or `0` to use the frame delta.
7329
7528
  */
7330
7529
  export declare function setPhysicsTimestep(world: PhysicsWorld, dt: number): void;
7331
7530
 
7531
+ /**
7532
+ * Sets the fixed simulation timestep used by each world step, in **milliseconds** (matching
7533
+ * {@link SceneContext.fixedDeltaMs}). Pass `0` to make the world step at the real per-frame delta
7534
+ * instead of a fixed step. See {@link setPhysicsTimestep} for the seconds-based equivalent.
7535
+ * @param world - The physics world.
7536
+ * @param fixedDeltaMs - Fixed step in milliseconds (e.g. `1000 / 60`), or `0` to use the frame delta.
7537
+ */
7538
+ export declare function setPhysicsTimestepMs(world: PhysicsWorld, fixedDeltaMs: number): void;
7539
+
7332
7540
  /**
7333
7541
  * Clamps the maximum linear and angular speeds of bodies in the world.
7334
7542
  * @param world - The physics world.
@@ -7558,6 +7766,20 @@ export declare function setThinInstanceColors(mesh: Mesh, colors: Float32Array):
7558
7766
  * array the mesh already references. No-op if the mesh isn't thin-instanced yet. */
7559
7767
  export declare function setThinInstanceCount(mesh: Mesh, count: number): void;
7560
7768
 
7769
+ /** Set an extra WORLD-SPACE radius added to every instance's GPU-culling sphere.
7770
+ *
7771
+ * The culler derives each instance's sphere from the prototype's authored vertex bounds, so a
7772
+ * vertex shader that DISPLACES geometry beyond them — terrain-following height offsets, tall wind
7773
+ * sway, growth animations — can move a visible instance outside its sphere and pop it at the
7774
+ * screen edge. The usual workaround is disabling culling for the whole mesh; padding the sphere
7775
+ * by the maximum shader displacement instead keeps culling both correct and enabled.
7776
+ *
7777
+ * The pad is in world units, applied after per-instance scaling. 0 restores the exact authored
7778
+ * bounds. Takes effect on the next culled pass (the culler reads it when writing its per-pass
7779
+ * params), so it can be changed live.
7780
+ */
7781
+ export declare function setThinInstanceCullBoundsPad(mesh: Mesh, pad: number): void;
7782
+
7561
7783
  /** Update one instance's matrix. */
7562
7784
  export declare function setThinInstanceMatrix(mesh: Mesh, index: number, matrix: Mat4): void;
7563
7785
 
@@ -8531,6 +8753,21 @@ export declare interface StencilState {
8531
8753
  readonly writeMask?: number;
8532
8754
  }
8533
8755
 
8756
+ /**
8757
+ * Advance one fixed simulation step of a headless scene created against a {@link createNullEngine}
8758
+ * engine. This is the server-side replacement for the `requestAnimationFrame` loop that
8759
+ * `startEngine` runs in the browser.
8760
+ *
8761
+ * It sets the frame delta and runs the scene's per-frame update, which fires all
8762
+ * `onBeforeRender(scene, …)` callbacks (physics step, animation evaluation, user logic). It does
8763
+ * **not** record or submit any GPU work.
8764
+ *
8765
+ * @param engine - A null engine from {@link createNullEngine}.
8766
+ * @param scene - A scene created with `createSceneContext(engine, { defaultRenderTask: false })`.
8767
+ * @param deltaMs - The fixed timestep for this step, in milliseconds (e.g. `1000 / 60`).
8768
+ */
8769
+ export declare function stepScene(engine: EngineContext, scene: SceneContext, deltaMs: number): void;
8770
+
8534
8771
  /** Options for {@link enableStereo}. */
8535
8772
  export declare interface StereoSoundOptions {
8536
8773
  /** Stereo pan in the range `[-1, 1]` (`-1` = full left, `1` = full right). Defaults to `0`. */
@@ -8951,6 +9188,12 @@ export declare interface Texture2DOptions {
8951
9188
  premultiplyAlpha?: boolean;
8952
9189
  }
8953
9190
 
9191
+ /** A `Texture2D` handle whose underlying GPU texture is `dimension:"3d"`, plus its depth. Bind it to a
9192
+ * fullscreen effect with `viewDimension:"3d"` and sample it in WGSL as `texture_3d<f32>`. */
9193
+ export declare type Texture3D = Texture2D & {
9194
+ depth: number;
9195
+ };
9196
+
8954
9197
  /** Thickness sub-feature. Controls how thick the material is at each point. */
8955
9198
  export declare interface ThicknessProps {
8956
9199
  /** Thickness map texture. R channel is sampled by default (matches
@@ -9077,6 +9320,14 @@ export declare interface TransmissionOptions {
9077
9320
  /** Cap the scene-colour grab mip chain. Use this when the material samples explicit low LODs only, so
9078
9321
  * unused tiny mips are not regenerated every frame. Ignored when `generateMipmaps` is false. */
9079
9322
  mipLevelCount?: number;
9323
+ /** When true, ALSO snapshot the task's DEPTH attachment at the same mid-pass grab, into a single-sample
9324
+ * `r32float` texture exposed as `SceneColorGrab.depthTexture` — the opaque scene depth as of the moment
9325
+ * the first transmissive surface draws. Lets a transmissive material depth-ray-march the opaque scene
9326
+ * (screen-space reflection / refraction) without re-rendering a separate depth prepass: the depth
9327
+ * attachment itself cannot be sampled while the transmissive draw has it bound (a WebGPU feedback loop),
9328
+ * which is exactly why the snapshot is taken at the pass break. MSAA sources resolve sample 0 (matching
9329
+ * `createDepthResolveTask`). No-op when the task's render target carries no depth attachment. */
9330
+ grabDepth?: boolean;
9080
9331
  }
9081
9332
 
9082
9333
  /** Options for `createTubeData`: a circular cross-section swept along a path. */
@@ -9299,6 +9550,14 @@ declare interface VariantMeshEntry {
9299
9550
 
9300
9551
  declare interface Varying {
9301
9552
 
9553
+ /** Optional extras to capture while baking (nothing is captured unless requested). */
9554
+ export declare interface VatBakeOptions {
9555
+ /** Bone indices whose posed ORIGIN should be sampled per baked frame (e.g. a hand joint for a held
9556
+ * item, a muzzle, an FX socket). Bone index = position in the skeleton's joint list = the bone's row
9557
+ * block in the baked texture. See {@link VatBakeResult.boneOrigins}. */
9558
+ readonly captureBoneOrigins?: readonly number[];
9559
+ }
9560
+
9302
9561
  /** Result of baking — the GPU texture plus a per-clip row map for choosing playback params. */
9303
9562
  export declare interface VatBakeResult {
9304
9563
  readonly texture: GPUTexture;
@@ -9306,6 +9565,13 @@ export declare interface VatBakeResult {
9306
9565
  readonly frameCount: number;
9307
9566
  /** Clip name → row range, for building the per-mesh/per-instance (fromRow,toRow,offset,fps) params. */
9308
9567
  readonly clips: Record<string, VatClip>;
9568
+ /** Present only when `captureBoneOrigins` was passed: bone index → the bone's posed origin per baked
9569
+ * frame, as `frameCount * 3` xyz floats (frame `row` at offset `row*3`, matching the texture rows /
9570
+ * `clips[].fromRow`). The point is in the mesh's SKIN output space — i.e. the space the VAT vertex path
9571
+ * produces before the `world` uniform — so a consumer gets world space with `instance · mesh.world · p`.
9572
+ * Lets a caller attach geometry to a moving joint (a carried prop, a socketed effect) without a live
9573
+ * skeleton. */
9574
+ readonly boneOrigins?: Record<number, Float32Array>;
9309
9575
  }
9310
9576
 
9311
9577
  /** Where one clip landed in the baked texture: its first row, its frame count, and its native fps. */
@@ -16,7 +16,7 @@ var Module = (() => {
16
16
  typeof process.versions == 'object' &&
17
17
  typeof process.versions.node == 'string' && process.type != 'renderer';
18
18
  if (ENVIRONMENT_IS_NODE) {
19
- const {createRequire} = await import('../__vite-browser-external-BFTKbDcV.js').then(n => n._);
19
+ const {createRequire} = await Promise.resolve({ createRequire: () => () => { throw new Error("require() is not available in the browser build of @babylonjs/lite"); } });
20
20
  var require = createRequire(import.meta.url);
21
21
  }
22
22
  var _ManifoldInitialized = false;
@@ -2999,4 +2999,4 @@ const manifold$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty
2999
2999
  }, Symbol.toStringTag, { value: 'Module' }));
3000
3000
 
3001
3001
  export { manifold$1 as a, manifold$2 as m };
3002
- //# sourceMappingURL=manifold-Sh8xE2da.js.map
3002
+ //# sourceMappingURL=manifold-DtI3BJoR.js.map