minidraco 0.1.0 → 0.2.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/README.md +50 -20
- package/dist/index.d.ts +1 -2
- package/dist/index.js +234 -139
- package/dist/three.d.ts +26 -7
- package/dist/three.js +381 -176
- package/dist/worker.js +287 -169
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -21,10 +21,29 @@ gltfLoader.setDRACOLoader(new MiniDRACOLoader())
|
|
|
21
21
|
gltfLoader.load('model.glb', gltf => scene.add(gltf.scene))
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
`MiniDRACOLoader` is
|
|
25
|
-
|
|
26
|
-
`
|
|
27
|
-
|
|
24
|
+
`MiniDRACOLoader` is a structural drop-in for `THREE.DRACOLoader`: it's assignable to it with no
|
|
25
|
+
cast on any three version (`setDecoderPath` and friends are no-ops), so
|
|
26
|
+
`gltfLoader.setDRACOLoader(new MiniDRACOLoader())` just type-checks.
|
|
27
|
+
|
|
28
|
+
Decoding runs in a pool of module workers by default (parallel across primitives, main thread
|
|
29
|
+
stays free). If workers can't be spawned (SSR, exotic bundlers), it falls back to synchronous
|
|
30
|
+
decoding automatically. Configure it at construction or with fluent setters:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
new MiniDRACOLoader({ workers: false }) // decode synchronously on the main thread
|
|
34
|
+
new MiniDRACOLoader({ workerLimit: 8 }) // pool size (default 4)
|
|
35
|
+
new MiniDRACOLoader(loadingManager) // a three.js LoadingManager, as usual
|
|
36
|
+
|
|
37
|
+
const loader = new MiniDRACOLoader()
|
|
38
|
+
loader.setWorkers(false) // ...or toggle later (same as setWorkerLimit(0))
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Serving JS from a CDN origin** (Next.js `assetPrefix`, etc.) works out of the box: browsers
|
|
42
|
+
refuse to construct a Worker from a cross-origin script, so minidraco bootstraps the worker
|
|
43
|
+
through a same-origin blob module that imports the hashed CDN asset (a CORS request — your CDN
|
|
44
|
+
must send `Access-Control-Allow-Origin`, which it already does if you load models or fonts from
|
|
45
|
+
it). If even that fails, decoding falls back to the main thread rather than erroring.
|
|
46
|
+
`setWorkerUrl(url)` exists as a manual override for exotic setups.
|
|
28
47
|
|
|
29
48
|
Or decode a raw Draco bitstream without Three.js:
|
|
30
49
|
|
|
@@ -48,24 +67,35 @@ const mesh = decodeDracoMesh(new Uint8Array(bytes))
|
|
|
48
67
|
|
|
49
68
|
## Performance
|
|
50
69
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
70
|
+
Full cross-decoder results — the production bundles plus the 17 sample models shipped with
|
|
71
|
+
[mrdoob/draco.js](https://github.com/mrdoob/draco.js) — are in
|
|
72
|
+
[BENCH.md](https://github.com/verekia/minidraco/blob/main/BENCH.md), regenerated by
|
|
73
|
+
`bun run bench` (with machine-readable
|
|
74
|
+
[BENCH.json](https://github.com/verekia/minidraco/blob/main/BENCH.json) alongside for diffing
|
|
75
|
+
perf work). Highlights, decoding the production bundle GLBs in
|
|
76
|
+
`example/public/models` (Apple Silicon, medians). Raw single-threaded decode, bun/JSC:
|
|
77
|
+
|
|
78
|
+
| file (points / faces) | minidraco | draco.js | draco3d wasm |
|
|
79
|
+
| ---------------------------------------------- | --------- | -------- | ------------ |
|
|
80
|
+
| manablade-characters (5.1k / 2.5k) | 1.9 ms | 1.7 ms | 1.2 ms |
|
|
81
|
+
| manablade-static (291k / 221k, 488 primitives) | **50 ms** | 55 ms | 51 ms |
|
|
82
|
+
|
|
83
|
+
The `/bench` page of the example runs the same fair comparison in the browser (V8): a raw
|
|
84
|
+
single-threaded mode where all three decoders decode on the main thread, over the bundles plus
|
|
85
|
+
the draco.js sample models (synced locally by `bun dev`, never deployed). Browser runs — both
|
|
86
|
+
the single-threaded mode and the multi-threaded GLTFLoader wall clock — are tracked in
|
|
87
|
+
[BENCH.browser.json](https://github.com/verekia/minidraco/blob/main/BENCH.browser.json) via the
|
|
88
|
+
page's "Save to BENCH.browser.json" button (local dev only).
|
|
59
89
|
|
|
60
90
|
In the browser the worker pool changes the story for real scenes — wall-clock
|
|
61
|
-
`GLTFLoader.parse` of the 488-primitive static bundle (Chromium, warm loaders, `/bench`
|
|
62
|
-
the example):
|
|
91
|
+
`GLTFLoader.parse` of the 488-primitive manablade-static bundle (Chromium, warm loaders, `/bench`
|
|
92
|
+
page of the example):
|
|
63
93
|
|
|
64
|
-
| decoder | static
|
|
65
|
-
| ------------------------ |
|
|
66
|
-
| minidraco (4 workers) | ~51 ms
|
|
67
|
-
| draco.js (main thread) | ~72 ms
|
|
68
|
-
| draco3d wasm (4 workers) | ~23 ms
|
|
94
|
+
| decoder | manablade-static | main thread |
|
|
95
|
+
| ------------------------ | ---------------- | ----------- |
|
|
96
|
+
| minidraco (4 workers) | ~51 ms | free |
|
|
97
|
+
| draco.js (main thread) | ~72 ms | blocked |
|
|
98
|
+
| draco3d wasm (4 workers) | ~23 ms | free |
|
|
69
99
|
|
|
70
100
|
And unlike the wasm decoder there is nothing to host or fetch: the first decode doesn't pay the
|
|
71
101
|
~50–70 ms wasm download + compile + worker bootstrap, which typically makes minidraco the fastest
|
|
@@ -99,7 +129,7 @@ decode, while the JS decoders ship inside your existing bundle chunks.
|
|
|
99
129
|
bun install
|
|
100
130
|
bun dev # library watch build + example dev server
|
|
101
131
|
bun run all # format check, lint, typecheck, warden, tests
|
|
102
|
-
bun run bench # decoder comparison benchmark (bun)
|
|
132
|
+
bun run bench # decoder comparison benchmark (bun) — rewrites BENCH.md
|
|
103
133
|
```
|
|
104
134
|
|
|
105
135
|
The test suite decodes every Draco primitive of the bundle GLBs with minidraco and the official
|
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ declare class DecoderBuffer {
|
|
|
25
25
|
decodeFloat32(): number | undefined;
|
|
26
26
|
decodeUint64(): number | undefined;
|
|
27
27
|
decodeBytes(size: number): Uint8Array | undefined;
|
|
28
|
+
decodeBytesView(size: number): Uint8Array | undefined;
|
|
28
29
|
startBitDecoding(decodeSize: boolean): number | undefined;
|
|
29
30
|
endBitDecoding(): void;
|
|
30
31
|
decodeLeastSignificantBits32(nbits: number): number | undefined;
|
|
@@ -162,8 +163,6 @@ declare class Mesh extends PointCloud {
|
|
|
162
163
|
elementType: number;
|
|
163
164
|
}[];
|
|
164
165
|
constructor();
|
|
165
|
-
_ensureFaceCapacity(numFaces: number): void;
|
|
166
|
-
addFace(face: ArrayLike<number>): void;
|
|
167
166
|
setNumFaces(numFaces: number): void;
|
|
168
167
|
numFaces(): number;
|
|
169
168
|
face(faceId: number): number[];
|