@bitruvius/meshopt
v0.3.1
Published
meshopt decoder seam for @bitruvius/gltf: decode-only meshoptimizer wasm (EXT_meshopt_compression), vendored self-contained
Readme
@bitruvius/meshopt
Decodes EXT_meshopt_compression glTF buffer views in place, with no wasm file to fetch, host or configure.
Internal building block. This package exists so that
@bitruvius/sdk-maplibreand the Bitruvius codecs can resolve their dependencies on npm. It has no standalone product story. Unless you are deliberately building against it, install the SDK instead.
This is the meshopt decode seam for
@bitruvius/gltf. It wraps the vendored,
decode-only meshoptimizer wasm and satisfies the MeshoptDecoder contract from
@bitruvius/geo-core. You construct one and inject it into GltfMeshDecoder.
import { MeshoptGltfDecoder } from '@bitruvius/meshopt';
import { GltfMeshDecoder } from '@bitruvius/gltf';
// Inject the seam; the glTF parser stays codec-agnostic.
const decoder = new GltfMeshDecoder({ meshopt: new MeshoptGltfDecoder() });Why it is its own package
The glTF parser must not know which third-party codecs exist. So the contract and the codec
are deliberately split: the MeshoptDecoder interface lives in @bitruvius/geo-core, and the
implementation that carries the wasm lives here. This package depends only on
@bitruvius/geo-core, never on the parser, and the parser never depends on a vendor's wasm.
Add a codec, and nothing upstream of it changes.
That split also keeps the third-party code where you can see it. meshoptimizer is MIT-licensed
work by somebody else, and it ships in its own npm package with its own NOTICES and licence
texts rather than being buried inside the SDK bundle. Only the decoder is vendored; the encoder
is not distributed. If your application never meets a meshopt-compressed tile, this package and
its wasm never enter your build.
What is in it
MeshoptGltfDecoder, a class with one method:
decodeGltfBuffer(req: MeshoptDecodeRequest): Promise<void>It decodes one buffer view in place into req.target, so there is no allocation beyond the
buffer the caller already owns and no intermediate copies. req.count is the element or vertex
count, not a byte count, and req.byteStride is the bytes per element. req.mode is the
EXT_meshopt_compression mode key (ATTRIBUTES, TRIANGLES or INDICES), and req.filter
(NONE, OCTAHEDRAL, QUATERNION or EXPONENTIAL) defaults to NONE. A corrupt, truncated
or unsupported-version source rejects with Malformed buffer data: <code>, which propagates
through the seam to the parser.
The MeshoptDecoder and MeshoptDecodeRequest types are re-exported here for convenience, so
an implementer does not have to reach into @bitruvius/geo-core for them.
The wasm is base64-inlined into a self-contained ESM module. There is no separate .wasm
request, no CDN path to configure and no wasm-host init, which is why the Bitruvius decode
worker constructs this seam with no arguments while it has to forward bytes or URLs for the
other codecs. It runs on the main thread or inside a worker without changing anything.
Correctness is pinned to the upstream oracle rather than to a snapshot of our own output: the
test suite drives the golden vector lifted verbatim from meshoptimizer's own decoder tests
(zeux/meshoptimizer v1.1.1, js/meshopt_decoder.test.js) straight through this seam, and
asserts that a malformed source rejects instead of quietly yielding wrong geometry.
How it fits
@bitruvius/tiles3d-mesh depends on it and wires it into both the main-thread and worker mesh
decoders, alongside the Draco and KTX2 seams. Everything above that, including
@bitruvius/sdk-maplibre, gets meshopt support without naming this package.
Depend on it directly only if you are composing your own GltfMeshDecoder and need
EXT_meshopt_compression support in it.
Third-party attribution
The wasm is meshoptimizer's decoder (Arseny Kapoulkine / zeux), MIT-licensed, vendored
decode-only as self-contained ESM with the wasm base64-inlined. See
wasm/NOTICES for the copyrights and the full licence text, which ships in
the published package. Decoding is free and ungated.
Trademarks
glTF and KTX are trademarks of The Khronos Group Inc. Cesium and 3D Tiles are trademarks of Cesium GS, Inc. Draco and Google are trademarks of Google LLC. MapLibre is a trademark of the MapLibre organization. All other marks are the property of their respective owners.
These names are used solely to describe the data formats this software interoperates with. Bitruvius is not affiliated with, sponsored by, or endorsed by any of them, and no such relationship is implied.
License
Proprietary. The full terms ship as LICENSE inside this package, and are readable
before installing at cdn.bitruvius.com/legal/sdk-license-v1.txt.
© Bitruvius, Inc.
