avbd-babylon 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3366 -2795
- package/dist/avbd.d.ts +1 -0
- package/dist/avbd.global.js +675 -143
- package/dist/avbd.js +675 -143
- package/dist/babylonAvbd.d.ts +31 -6
- package/dist/native.js +1 -1
- package/dist/nativeScenes.d.ts +83 -8
- package/dist/utilities.d.ts +161 -0
- package/dist/utilities.js +1 -0
- package/docs/BABYLON_API.md +48 -5
- package/docs/HPLOC.md +119 -115
- package/docs/README.md +503 -465
- package/docs/RELEASE.md +191 -176
- package/package.json +149 -124
- package/tests/README.md +341 -218
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.
|