avbd-babylon 0.2.0 → 0.4.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.
package/docs/HPLOC.md CHANGED
@@ -1,116 +1,120 @@
1
- # GPU tree collision detection
2
-
3
- `GpuHploc` in `gpuHploc.js` builds and traverses a GPU bounding-volume hierarchy.
4
- Its pairs feed the existing narrowphase and AVBD solver. Shapes, friction,
5
- rotation, solving rounds and contact equations stay the same; pinned upstream
6
- sources remain unchanged.
7
-
8
- This is a portable hierarchical PLOC treelet variant, based on the clustering
9
- family described in [H-PLOC](https://gpuopen.com/download/HPLOC.pdf), **not** the
10
- paper's single-launch wave implementation. `hplocpp.wgsl` builds the tree;
11
- `hplocSort.wgsl` sorts keys.
12
-
13
- ## Algorithm
14
-
15
- 1. Compute world AABBs from live GPU positions, quaternions and collider sizes.
16
- 2. Reduce scene bounds on the GPU, generate 30-bit Morton keys and sort them
17
- with stable radix passes. No fixed scene coordinates or lost duplicate keys.
18
- 3. Merge mutual nearest neighbours by surface-area cost in 16-cluster treelets.
19
- Construct hierarchy levels until one root remains. Dispatch boundaries
20
- publish global writes; barriers publish local merges. There are no
21
- cross-workgroup spin waits or relaxed-atomic publication assumptions.
22
- 4. Build escape links for stackless traversal. Dynamic queries find static and
23
- kinematic leaves; giant ground slabs do not traverse the whole tree.
24
- 5. Refit **every leaf and internal bound every step**. Rebuild ordering and
25
- clustering every 64 steps by default. Refitting preserves coverage after
26
- teleports; rebuilding improves traversal quality.
27
-
28
- Pair acceptance reuses the grid's masks, disabled-joint handling, bounding
29
- spheres, world AABBs, face-axis rejection and overflow accounting. Dynamic
30
- pairs are emitted once; dynamic/static pairs are emitted from the dynamic
31
- body. Hulls retain the canonical hull narrowphase.
32
-
33
- ## Selection and limits
34
-
35
- `AppGpuSolver3D` and `AvbdPhysics.create` accept `broadphase: "auto"`, `"grid"`
36
- or `"hploc"`, and `bvh: { rebuildInterval: 64 }`. The lab and browser benchmark
37
- have the same choices. Explicit selections let you compare on your GPU.
38
-
39
- Automatic selection uses a tree for at least 10,000 bodies when either:
40
-
41
- - Grid cells are at least four times a typical body's bounding-sphere diameter.
42
- - At least a quarter of dynamic bodies are thin plates, and there is at least
43
- one active constraint per body. This covers the rigid ragdoll net.
44
-
45
- For this policy, a thin plate has a shortest dimension no more than 40% of its
46
- middle dimension, with the middle dimension at least half the longest. Rods,
47
- spheres and convex hulls do not qualify as plates. Shape metadata is checked
48
- when bodies or active constraint counts change; positions are not downloaded.
49
-
50
- Body count alone does not select a tree. Adapter dispatch/storage limits are checked; automatic mode
51
- keeps the grid when unsupported. Explicit unsupported requests fail clearly.
52
-
53
- This is a conservative policy based on the measured 1K, 10K and 50K mixed-size workloads and the 24K ragdoll net,
54
- not a universal crossover point. Scene layout, size distribution and GPU matter.
55
-
56
- Extra buffers store nodes, links, sorting and clustering. JSON records primary
57
- buffer bytes, rebuild/refit counts and the first GPU step. Startup GPU time
58
- excludes CPU scene creation and shader compilation. Warm timing includes
59
- periodic rebuilds, but excludes the first build; inspect both. Grid buffers
60
- remain available for selection changes. This path adds no sleeping.
61
- Reported primary bytes exclude prefix-scan scratch, small uniforms and pipelines.
62
-
63
- ## Replication and checks
64
-
65
- Open `/tests/performance.html` and close other GPU workloads. Paired comparison
66
- alternates execution order every step and preserves each scene's settings.
67
- Every step checks overflow and solve-group conflicts.
68
-
69
- ```js
70
- try {
71
- const result = await __PERFORMANCE__.runPaired(
72
- "3d-mixed-sizes-50k",
73
- ["grid", "hploc"],
74
- 60,
75
- 60,
76
- );
77
- console.table(
78
- result.results.map((r) => ({
79
- method: r.broadphase,
80
- collisionMs: r.summary.collision.mean,
81
- physicsMs: r.summary.total.mean,
82
- extraBytes: r.bvh?.extraBytes ?? 0,
83
- })),
84
- );
85
- } finally {
86
- await __BENCHMARK_VIEW__.preview.load(document.querySelector("#scene").value);
87
- }
88
- ```
89
-
90
- Use `grid-detail` / `hploc-detail` to separate build/refit, pair search,
91
- narrowphase, body solving and contact-force updates. Extra pass boundaries
92
- affect timing, so compare matching detailed modes. Raw data retains rebuild
93
- spikes and noisy samples. An unchanged solve-stage difference over 10% is flagged.
94
-
95
- For the ragdoll net, compare `"showcase-ragdolls-on-cloth-24k"` with
96
- `["grid", "hploc"]`, 1440 warmup steps and 60 samples. This measures the scene
97
- after six simulated seconds at its full 240 Hz collision rate. Saved paired
98
- results on the RTX 4070 Laptop GPU use the same timestep and five AVBD iterations;
99
- see `test-results/solver-ragdoll-settled.json`. The separate
100
- `node scripts/check-ragdoll-net.mjs` regression checks every quarter-second
101
- through 30 simulated seconds with automatic selection. It checks whole limbs
102
- below the sheet and partial capsule/triangle intersections deeper than 5 mm.
103
- The net uses overlapping plates and excludes its eight immediate neighbors
104
- from self-collisions; distant folds still collide.
105
-
106
- Tests compare unique, complete pair sets against the grid for empty and partial
107
- treelets, duplicate keys, rotated hulls and boxes, spheres, giant statics,
108
- ignored and released joints, filters, teleports and added bodies. Physical regressions cover floor support,
109
- joints, sleeping and support removal; browser checks exercise motion and drawing.
110
-
111
- `node scripts/check-hploc-motion.mjs` checks 360 steps of the 10K/50K mixed-size
112
- scenes, 110K ring, 100K columns and half-million walls with the tree forced.
113
- It checks every step's capacity and scheduling counters, measures floor support
114
- and rotation, and captures four screenshots per scene. `npm run test:web`
115
- includes this check alongside all scene and benchmark views.
1
+ # GPU tree collision detection
116
2
 
3
+ [`GpuHploc`](../src/gpu/gpuHploc.js) in `src/gpu/` builds and traverses a GPU bounding-volume hierarchy.
4
+ Its pairs feed the existing narrowphase and AVBD solver. Shapes, friction,
5
+ rotation, solving rounds and contact equations stay the same; pinned upstream
6
+ sources remain unchanged.
7
+
8
+ This portable hierarchical PLOC treelet variant builds on the clustering family
9
+ described in [H-PLOC](https://gpuopen.com/download/HPLOC.pdf). It uses multiple
10
+ GPU dispatches to coordinate tree levels. `hplocpp.wgsl` builds the tree;
11
+ `hplocSort.wgsl` sorts keys.
12
+
13
+ ## Algorithm
14
+
15
+ 1. Compute world AABBs from live GPU positions, quaternions and collider sizes.
16
+ 2. Reduce scene bounds on the GPU, generate 30-bit Morton keys and sort them
17
+ with stable radix passes. No fixed scene coordinates or lost duplicate keys.
18
+ 3. Merge mutual nearest neighbours by surface-area cost in 16-cluster treelets.
19
+ Construct hierarchy levels until one root remains. Dispatch boundaries
20
+ publish global writes; barriers publish local merges. There are no
21
+ cross-workgroup spin waits or relaxed-atomic publication assumptions.
22
+ 4. Build escape links for stackless traversal. Dynamic queries find static and
23
+ kinematic leaves; giant ground slabs do not traverse the whole tree.
24
+ 5. Refit **every leaf and internal bound every step**. Rebuild ordering and
25
+ clustering every 64 steps by default. Refitting preserves coverage after
26
+ teleports; rebuilding improves traversal quality.
27
+
28
+ Refit steps update leaf boxes directly without the scene-bound reductions used
29
+ for Morton sorting. Every leaf and internal box still follows the current GPU
30
+ pose, including moved static bodies and teleports.
31
+
32
+ Pair acceptance reuses the grid's masks, disabled-joint handling, bounding
33
+ spheres, world AABBs, face-axis rejection and overflow accounting. Dynamic
34
+ pairs are emitted once; dynamic/static pairs are emitted from the dynamic
35
+ body. Hulls retain the canonical hull narrowphase.
36
+
37
+ ## Selection and limits
38
+
39
+ `AppGpuSolver3D` and `AvbdPhysics.create` accept `broadphase: "auto"`, `"grid"`
40
+ or `"hploc"`, and `bvh: { rebuildInterval: 64 }`. The lab and browser benchmark
41
+ have the same choices. Explicit selections let you compare on your GPU.
42
+
43
+ Automatic selection uses a tree for at least 10,000 bodies when either:
44
+
45
+ - Grid cells are at least four times a typical body's bounding-sphere diameter.
46
+ - At least a quarter of dynamic bodies are thin plates, and there is at least
47
+ one active constraint per body. This covers the rigid ragdoll net.
48
+
49
+ For this policy, a thin plate has a shortest dimension no more than 40% of its
50
+ middle dimension, with the middle dimension at least half the longest. Rods,
51
+ spheres and convex hulls do not qualify as plates. Shape metadata is checked
52
+ when bodies or active constraint counts change; positions are not downloaded.
53
+
54
+ Body count alone does not select a tree. Adapter dispatch/storage limits are checked; automatic mode
55
+ keeps the grid when unsupported. Explicit unsupported requests fail clearly.
56
+
57
+ The selection policy uses measurements from 1K, 10K and 50K mixed-size workloads
58
+ and the 24K ragdoll net. The crossover depends on scene layout, object sizes and
59
+ the GPU.
60
+
61
+ Extra buffers store nodes, links, sorting and clustering. JSON records primary
62
+ buffer bytes, rebuild/refit counts and the first GPU step. Startup GPU time
63
+ excludes CPU scene creation and shader compilation. Warm timing includes
64
+ periodic rebuilds, but excludes the first build; inspect both. Grid buffers
65
+ remain available for selection changes. Sleeping is configured separately from collision search.
66
+ Reported primary bytes exclude prefix-scan scratch, small uniforms and pipelines.
67
+
68
+ ## Replication and checks
69
+
70
+ Open `/tests/performance.html` and close other GPU workloads. Paired comparison
71
+ alternates execution order every step and preserves each scene's settings.
72
+ Every step checks overflow and solve-group conflicts.
73
+
74
+ ```js
75
+ try {
76
+ const result = await __PERFORMANCE__.runPaired(
77
+ "3d-mixed-sizes-50k",
78
+ ["grid", "hploc"],
79
+ 60,
80
+ 60,
81
+ );
82
+ console.table(
83
+ result.results.map((r) => ({
84
+ method: r.broadphase,
85
+ collisionMs: r.summary.collision.mean,
86
+ physicsMs: r.summary.total.mean,
87
+ extraBytes: r.bvh?.extraBytes ?? 0,
88
+ })),
89
+ );
90
+ } finally {
91
+ await __BENCHMARK_VIEW__.preview.load(document.querySelector("#scene").value);
92
+ }
93
+ ```
94
+
95
+ Use `grid-detail` / `hploc-detail` to separate build/refit, pair search,
96
+ narrowphase, body solving and contact-force updates. Extra pass boundaries
97
+ affect timing, so compare matching detailed modes. Raw data retains rebuild
98
+ spikes and noisy samples. An unchanged solve-stage difference over 10% is flagged.
99
+
100
+ For the ragdoll net, compare `"showcase-ragdolls-on-cloth-24k"` with
101
+ `["grid", "hploc"]`, 1440 warmup steps and 60 samples. This measures the scene
102
+ after six simulated seconds at its full 240 Hz collision rate. Saved paired
103
+ results on the RTX 4070 Laptop GPU use the same timestep and five AVBD iterations;
104
+ see `test-results/solver-ragdoll-settled.json`. The separate
105
+ `node scripts/check-ragdoll-net.mjs` regression checks every quarter-second
106
+ through 30 simulated seconds with automatic selection. It checks whole limbs
107
+ below the sheet and partial capsule/triangle intersections deeper than 5 mm.
108
+ The net uses overlapping plates and excludes its eight immediate neighbors
109
+ from self-collisions; distant folds still collide.
110
+
111
+ Tests compare unique, complete pair sets against the grid for empty and partial
112
+ treelets, duplicate keys, rotated hulls and boxes, spheres, giant statics,
113
+ ignored and released joints, filters, teleports and added bodies. Physical regressions cover floor support,
114
+ joints, sleeping and support removal; browser checks exercise motion and drawing.
115
+
116
+ `node scripts/check-hploc-motion.mjs` checks 360 steps of the 10K/50K mixed-size
117
+ scenes, 110K ring, 100K columns and half-million walls with the tree forced.
118
+ It checks every step's capacity and scheduling counters, measures floor support
119
+ and rotation, and captures four screenshots per scene. `npm run test:web`
120
+ includes this check alongside all scene and benchmark views.
package/docs/README.md CHANGED
@@ -11,6 +11,7 @@ Physics V2 plugin interface or install through `scene.enablePhysics()`.
11
11
 
12
12
  - [Install the library](#install-the-library)
13
13
  - [A complete small scene](#a-complete-small-scene)
14
+ - [Everyday body commands](#everyday-body-commands)
14
15
  - [Move, launch and reuse bodies](#move-launch-and-reuse-bodies)
15
16
  - [Choose a rendering path](#choose-a-rendering-path)
16
17
  - [Reproduce the collision and solver benchmarks](#reproduce-the-collision-and-solver-benchmarks)
@@ -19,10 +20,15 @@ Physics V2 plugin interface or install through `scene.enablePhysics()`.
19
20
 
20
21
  ## Install the library
21
22
 
22
- The package is named `avbd-babylon`. For a local build, run `npm install` and
23
- `npm run build` in this repository. From your
24
- Babylon project, run `npm install /absolute/path/to/avbd` or install the archive
25
- created by `npm pack`. Import from `avbd-babylon` using your normal bundler.
23
+ Install AVBD and Babylon in your project:
24
+
25
+ ```sh
26
+ npm install avbd-babylon @babylonjs/core
27
+ ```
28
+
29
+ Import from `avbd-babylon` using your normal bundler. For a local development
30
+ build, run `npm install` and `npm run build` in this repository, then install
31
+ its directory or the archive created by `npm pack` into your project.
26
32
  The ESM output already contains the solver and shader strings. No TypeScript
27
33
  source compilation or WGSL loader is needed in your project. The package has
28
34
  no Babylon runtime imports; it uses the mesh objects your project provides.
@@ -32,13 +38,21 @@ browser tests. `npm start` builds the library and serves the lab together.
32
38
  `npm run build:cdn` creates `dist/avbd.global.js`, which exposes `globalThis.AVBD`.
33
39
  Host that file yourself and load it with a normal script tag; use
34
40
  `const { AvbdPhysics, AvbdPhysicsAggregate, AvbdShapeType } = AVBD`.
35
- There is no public CDN release URL yet.
36
41
 
37
- WebGPU
38
- needs a supported browser and localhost or HTTPS. The default world requests
39
- 9 storage bindings, a 512 MiB storage binding limit and a 1 GiB buffer limit;
40
- unsupported adapters fail during creation. Babylon drawing can use either its
41
- WebGL or WebGPU engine when using the small-scene mesh bridge.
42
+ WebGPU needs a supported browser and localhost or HTTPS. The world prefers up to
43
+ 9 storage bindings, a 512 MiB storage binding limit and a 1 GiB buffer limit,
44
+ and adapts these requests to the adapter's available limits. Custom convex mesh
45
+ shapes require 9 storage bindings. Creation checks 3D floor contacts once and
46
+ selects a compatible GPU path when needed, including on supported mobile devices.
47
+ Babylon drawing can use either its WebGL or WebGPU engine with the small-scene
48
+ mesh bridge.
49
+
50
+ For CPU physics, use the [native pipeline examples](../README.md#choose-a-solver-backend-once).
51
+ Select the backend once; 2D and 3D scene builders, body commands, joints, triggers,
52
+ restitution, collision masks and state reads keep the same API. The package
53
+ supports WebGPU and CPU. The repository demos retain an experimental WebGL2
54
+ solver for comparisons; its measured performance was too poor to include in
55
+ the package. See the [backend benchmark](../README.md#backend-differences-and-benchmarks).
42
56
 
43
57
  ## A complete small scene
44
58
 
@@ -120,6 +134,36 @@ custom simulation loop, pass `autoAttach: false` and call `step()` yourself.
120
134
  `attachToScene()` is also available and does not attach a second observer when
121
135
  called again for the same scene.
122
136
 
137
+ ## Everyday body commands
138
+
139
+ Keep the aggregate and use its `body` handle for movement. Babylon `Vector3`
140
+ values work for velocity, impulses and forces; those calls also accept arrays.
141
+ Teleporting accepts a `Vector3` and an optional `Quaternion`.
142
+
143
+ | Task | Call |
144
+ | ------------------------------ | --------------------------------------------------------------------------------- |
145
+ | Set movement or spin | `body.setLinearVelocity(v)` / `body.setAngularVelocity(v)` |
146
+ | Give a sudden push | `body.applyImpulse(impulse, worldPoint)`; omit the point for a central push |
147
+ | Apply force for one fixed step | `body.applyForce(force, worldPoint)` / `body.applyTorque(torque)` |
148
+ | Move instantly | `body.teleport(position, rotation)`; omit rotation to retain the live orientation |
149
+ | Set bounce | `body.setRestitution(0.5)` |
150
+ | Set collision masks | `body.setCollisionGroups(group, collidesWith)` |
151
+ | Make an overlap sensor | `body.setTrigger(true)` |
152
+ | Allow sleeping or wake a body | `body.setSleepEnabled(true)` / `body.wakeUp()` |
153
+ | Read live physics state | `await body.readState()` |
154
+ | Remove physics participation | `aggregate.dispose()`; the mesh stays caller-owned |
155
+
156
+ Commands made before the next fixed step are batched automatically. Ordinary
157
+ per-body calls do not require a manual flush or pose download. State reads and
158
+ queries are asynchronous because they return current GPU results. Create the
159
+ world with `{ scene }` to attach stepping and disposal to Babylon's scene.
160
+
161
+ For another renderer or CPU compatibility, use the
162
+ [native 2D/3D examples](../README.md#native-physics-with-any-renderer). They use the
163
+ same movement, impulse, bounce, trigger, mask and sleep method names, with
164
+ two- or three-component coordinates. Native bulk edits and reusable packed
165
+ batches are shown in [bulk edits](../README.md#bulk-edits-and-gpu-dispatches).
166
+
123
167
  ## Move, launch and reuse bodies
124
168
 
125
169
  ```js
@@ -227,7 +271,7 @@ device stays alive when the world is disposed.
227
271
  Thin instances do not automatically create colliders. The aggregate API takes
228
272
  one mesh per physics body, which has a startup cost for very large scenes.
229
273
  For 100K bodies, the laboratory's native body/scene builders avoid creating
230
- 100K Babylon mesh objects; see [canonicalScenes.js](../demo/canonicalScenes.js).
274
+ 100K Babylon mesh objects; see [scene registry](../demo/lab/scenes.js).
231
275
  Import `AvbdScene2D` or `AvbdScene3D` from `avbd-babylon/native` for the same
232
276
  renderer-independent integration. Both expose live body handles, bulk commands,
233
277
  packed velocity uploads, selected pose reads, triggers, masks, restitution,
@@ -236,9 +280,9 @@ sleeping and contact events. See the package README's
236
280
  The direct-buffer renderer and small-scene aggregate bridge are separate
237
281
  integration paths.
238
282
 
239
- See [canonicalRenderer.js](../demo/canonicalRenderer.js) and
240
- [canonicalRender.wgsl](../demo/canonicalRender.wgsl) for the direct rendering path,
241
- and [mixedColliderDemo.js](../demo/mixedColliderDemo.js) for the Babylon mesh bridge.
283
+ See [canonicalRenderer.js](../demo/shared/rendering/canonicalRenderer.js) and
284
+ [canonicalRender.wgsl](../demo/shared/rendering/canonicalRender.wgsl) for the direct rendering path,
285
+ and [mixed collider demo](../demo/mixed-colliders/index.js) for the Babylon mesh bridge.
242
286
  The laboratory scene builders use z up; the Babylon adapter uses y up by
243
287
  default. Match your renderer's coordinates to the world you create.
244
288
 
package/docs/RELEASE.md CHANGED
@@ -5,6 +5,20 @@ portable scene builders and the browser demos. The package ships ESM, the `AVBD`
5
5
  browser global, declarations, documentation and license notices. It has no runtime
6
6
  dependencies; Babylon 9 is an optional peer for the integration API.
7
7
 
8
+ `avbd-babylon/utils` exposes the GPU timers, buffer recycler, surface particles,
9
+ contact sampling, startup coloring, custom GPU step passes and worker input/canvas
10
+ helpers used by the demos. These helpers are also available from the main entry.
11
+ `npm run benchmark:particles` measures visible D20 particle capacity and updates
12
+ the public report; its results are separate from AVBD rigid-body benchmarks.
13
+
14
+ Native 2D and 3D worlds select WebGPU or CPU at initialization and share
15
+ the scene and body APIs. The Babylon aggregate API uses WebGPU; native CPU
16
+ worlds can use Babylon drawing with synchronized poses. The experimental
17
+ WebGL2 implementation remains in the repository demos and benchmarks; it is
18
+ excluded from package exports, declarations and both production bundles.
19
+ Build and package checks enforce that separation. Its measured performance
20
+ was too poor for production; the README preserves the comparison.
21
+
8
22
  ## Validate the package
9
23
 
10
24
  ```sh
@@ -12,6 +26,7 @@ npm ci
12
26
  npm run build:all
13
27
  npm run test:complete
14
28
  npm run test:web
29
+ npm run test:compatibility
15
30
  npm run clean:results
16
31
  npm run clean:dist
17
32
  npm pack
@@ -49,6 +64,14 @@ collision searches. It uses only the existing local demo tab and saves
49
64
  `test-results/connected-phone-contacts.json`. Mobile viewport tests and physical
50
65
  phone tests have separate reports.
51
66
 
67
+ Run `npm run test:connected-demos` on the same connection for ten production
68
+ scene checks, screenshots and short physics/rendering measurements on the phone.
69
+ This includes 2D/3D hinges and sensors, terrain, tearable cloth and the 40,000-marble
70
+ Galton board. The saved `connected-phone-demos.json` distinguishes GPU physics
71
+ time from completion time. These short checks verify startup and motion; they
72
+ do not replace long settling tests or the complete Galton distribution test.
73
+ Sequential measurements can warm the phone and change its clock speeds.
74
+
52
75
  To compare PC performance with a saved package build, run
53
76
  `node scripts/check-contact-performance.mjs --baseline=/path/to/avbd.js`.
54
77
  It runs 10K and 100K native 3D bodies with five iterations, three alternating
@@ -143,8 +166,9 @@ See the [feature table](../README.md#feature-coverage) for exact coverage.
143
166
 
144
167
  These remain useful follow-up work rather than supported 0.2 features:
145
168
 
146
- - **Concave mesh collisions:** custom hulls fill cavities. Terrain and hollow
147
- objects need suitable convex pieces.
169
+ - **Dynamic concave bodies:** moving hollow objects need convex pieces. Static
170
+ triangle meshes and heightfields are supported through terrain cooking, which
171
+ preserves caves and overhangs. A single convex hull fills its cavities.
148
172
  - **Continuous collision detection:** contacts are discrete. Use smaller
149
173
  timesteps for fast objects; sphere/circle casts are queries, not automatic CCD.
150
174
  - **Full Babylon Physics V2 integration:** use AVBD aggregates, not
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "avbd-babylon",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "GPU AVBD rigid-body physics with a Babylon.js aggregate API",
5
5
  "main": "./dist/avbd.js",
6
6
  "types": "./dist/avbd.d.ts",
@@ -35,11 +35,36 @@
35
35
  "test:published": "node scripts/check-published.mjs",
36
36
  "test:mobile-contacts": "node scripts/build.mjs && node scripts/check-contact-portability.mjs && node scripts/check-contact-compatibility-features.mjs",
37
37
  "test:types": "tsc --noEmit --strict --skipLibCheck --module nodenext --target es2022 tests/package-api-types.ts",
38
+ "test:cpu": "node scripts/build.mjs && node scripts/check-cpu-demos.mjs && node scripts/check-cpu-features.mjs && node scripts/check-cpu-slingshot.mjs",
39
+ "test:webgl-collisions": "node scripts/check-webgl-broadphase.mjs && node --experimental-transform-types scripts/check-webgl-contacts.mjs",
40
+ "test:webgl": "npm run test:webgl-collisions && node scripts/check-webgl-coloring.mjs && node --experimental-transform-types scripts/check-webgl-solve.mjs && node --experimental-transform-types scripts/check-webgl-world.mjs && node --experimental-transform-types scripts/check-webgl-edits.mjs && node --experimental-transform-types scripts/check-webgl-bounce.mjs && node --experimental-transform-types scripts/check-webgl-sleeping.mjs && node scripts/check-webgl-scene-behavior.mjs && node scripts/check-backend-contract.mjs --webgl2",
41
+ "test:compatibility": "npm run build:all && node scripts/check-backend-contract.mjs --package && npm run test:cpu && npm run test:webgl && npm run test:webgl-scenes && npm run test:compatibility-performance",
42
+ "test:pipelines": "node scripts/check-backend-contract.mjs",
43
+ "benchmark:backends": "node scripts/build.mjs && node scripts/benchmark-backends.mjs",
38
44
  "benchmark:native": "node scripts/benchmark-package.mjs",
39
45
  "benchmark:sleeping": "node scripts/benchmark-package.mjs",
46
+ "benchmark:connected-sleep": "node scripts/benchmark-connected-sleep.mjs",
47
+ "benchmark:small-groups": "node scripts/benchmark-small-groups.mjs",
40
48
  "benchmark:native-edits": "node scripts/check-native-performance.mjs",
41
49
  "benchmark:renderers": "node scripts/build.mjs && node scripts/benchmark-renderers.mjs",
42
- "test:connected-phone": "node scripts/check-connected-contacts.mjs"
50
+ "benchmark:particles": "node scripts/build.mjs && node scripts/benchmark-particles.mjs && node scripts/report-particles.mjs",
51
+ "test:connected-phone": "node scripts/check-connected-contacts.mjs",
52
+ "test:connected-demos": "node scripts/check-connected-demos.mjs",
53
+ "test:webgl-scenes": "node scripts/build.mjs && node scripts/check-webgl-demos.mjs",
54
+ "test:compatibility-performance": "node scripts/build.mjs && node scripts/check-compatibility-performance.mjs",
55
+ "test:workers": "node scripts/build.mjs && node scripts/check-runtime-efficiency.mjs && node scripts/check-workers.mjs",
56
+ "benchmark:workers": "node scripts/build.mjs && node scripts/benchmark-workers.mjs && node scripts/report-workers.mjs && node scripts/report-solver.mjs",
57
+ "test:execution": "node scripts/build.mjs && node scripts/check-execution-ui.mjs",
58
+ "test:naval": "node scripts/build.mjs && node scripts/check-naval.mjs",
59
+ "benchmark:naval": "node scripts/build.mjs && node scripts/benchmark-naval.mjs",
60
+ "test:terrain": "node scripts/check-terrain-cooking.mjs && node scripts/build-library.mjs && node scripts/build.mjs && node scripts/check-terrain.mjs && node scripts/check-terrain-import.mjs",
61
+ "benchmark:hploc-refit": "node scripts/benchmark-hploc-refit.mjs",
62
+ "benchmark:gpu-uploads": "node scripts/benchmark-webgpu-uploads.mjs",
63
+ "benchmark:gpu-scheduling": "node scripts/benchmark-color-buckets.mjs",
64
+ "benchmark:movement": "node scripts/benchmark-movement-solve.mjs",
65
+ "benchmark:gpu-encoding": "node scripts/benchmark-command-encoding.mjs",
66
+ "test:playgrounds": "node scripts/build.mjs && node scripts/check-siege-damage.mjs && node scripts/check-galton-statistics.mjs && node scripts/check-galton-startup.mjs && node scripts/check-galton-pegs.mjs && node scripts/check-lab-timing.mjs && node scripts/check-lab-step-rate.mjs && node scripts/check-lab-sleep.mjs && node scripts/check-playgrounds.mjs && node scripts/check-slingshot-input.mjs && node scripts/check-slingshot-game.mjs",
67
+ "test:demo-startup": "node scripts/build.mjs && node scripts/check-demo-startup.mjs --all"
43
68
  },
44
69
  "license": "MIT",
45
70
  "repository": {
@@ -65,11 +90,12 @@
65
90
  "babylonjs"
66
91
  ],
67
92
  "devDependencies": {
93
+ "@babylonjs/core": "^9.13.0",
68
94
  "esbuild": "^0.28.2",
69
95
  "prettier": "^3.9.9",
70
96
  "tinybuild": "^1.0.6",
71
- "@babylonjs/core": "^9.13.0",
72
- "typescript": "^7.0.2"
97
+ "typescript": "^7.0.2",
98
+ "wgsl_reflect": "^1.6.0"
73
99
  },
74
100
  "module": "./dist/avbd.js",
75
101
  "exports": {
@@ -83,6 +109,11 @@
83
109
  "import": "./dist/native.js",
84
110
  "default": "./dist/native.js"
85
111
  },
112
+ "./utils": {
113
+ "types": "./dist/utilities.d.ts",
114
+ "import": "./dist/utilities.js",
115
+ "default": "./dist/utilities.js"
116
+ },
86
117
  "./global": {
87
118
  "types": "./dist/avbd.global.d.ts",
88
119
  "default": "./dist/avbd.global.js"
@@ -99,6 +130,9 @@
99
130
  "dist/native.js",
100
131
  "dist/native.d.ts",
101
132
  "dist/gpuDevice.d.ts",
133
+ "dist/solverPipeline.d.ts",
134
+ "dist/utilities.js",
135
+ "dist/utilities.d.ts",
102
136
  "dist/NOTICE",
103
137
  "LICENSE",
104
138
  "README.md",