Skip to content

About

No description, website, or topics provided.

Resources

Security policy

Stars

5 stars

Watchers

0 watching

Forks

Latest commit

 

History

1,515 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

draco-rust

Rust CI Fuzz License

Draco geometry compression in pure Rust, with the file formats and glTF scene handling around it. Nothing here links the original library; bitstream compatibility is a property of the implementation, checked against reference fixtures and the upstream binaries themselves.

This project is independent and is not an official Google Draco release.

Try it in a browser

Draco 3D Studio — a converter and viewer for the crates below, running at filyus.github.io/draco-rust. No upload, no server: the WASM modules do the work in the page, and the files never leave the machine.

Open an OBJ, PLY, STL, DRC, FBX or glTF/GLB asset and it reports what the file actually contains — hierarchy, materials, skins, morph targets, animation clips — renders it, and exports any of them back out, with Draco compression optional along the way.

Converting between formats loses things, and the per-format conversion rules say which: what survives an FBX to glTF trip, what has no equivalent to survive into, and where the viewer's limits are narrower than the exporter's.

Crates

crates.io docs.rs

The codec: Draco bitstream encode and decode for triangle meshes and point clouds, and the geometry model everything else speaks.

crates.io docs.rs

Formats: OBJ, PLY, STL, binary and ASCII FBX. Each carries geometry in its own encoding, so nothing here touches the Draco codec.

crates.io docs.rs

Whole glTF 2.0 and pinned 2.1-draft documents, losslessly: typed scene views, packed-geometry read/write, document-preserving Draco compression, GLB v2/v3, plus the strict GLB/container parser, resource policy and accessor contracts underneath them.

Anything glTF depends on this crate alone. glTF is the one format in the workspace that embeds a Draco bitstream, so it is also the only place where a file format meets the codec; draco-io covers the formats that do not, and the two no longer depend on each other.

draco-texture (KTX2 and Basis Universal transcoding) is part of the repository but not published.

JavaScript and WebAssembly

The codec and the formats are also on npm, as WebAssembly modules for the browser, bundlers and Node. Each package and subpath is a module of its own, so an application downloads only the one it imports:

package what it does
@draco-rust/decoder Draco decode; ./mesh, ./point-cloud and ./legacy cut it to what you need
@draco-rust/encoder Draco encode
@draco-rust/gltf glTF and GLB, with ./validate and ./writer
@draco-rust/fbx, obj, ply, stl the formats, read and write
npm install @draco-rust/decoder

Or straight from jsDelivr, without a bundler:

import init, { parse_drc_bytes } from "https://cdn.jsdelivr.net/npm/@draco-rust/decoder@0.3/mesh/index.js";
await init();

The packages share one version and are built and published from CI with npm provenance; web/README.md says what each entry holds.

Getting started

[dependencies]
draco-gltf = "0.7"

Read a primitive, whether or not it arrived Draco-compressed:

use draco_gltf::{MeshIndex, PrimitiveIndex};

let scene = draco_gltf::import("model.glb")?;
let geometry = scene.read_primitive(PrimitiveIndex::new(MeshIndex(0), 0))?;
println!("{} vertices", geometry.vertex_count());
# Ok::<(), draco_gltf::Error>(())

Or stay at the format layer and convert geometry between files:

[dependencies]
draco-io = { version = "0.6", default-features = false, features = ["ply-reader", "obj-writer"] }

Every crate is feature-gated down to what an application actually calls, which matters most on wasm32: the format readers, the writers, the codec halves and the strict-validation passes are all separable. Each crate's README lists its features and what they cost.

Compatibility and status

draco-core is past 1.0 and its public API is covered by SemVer. Point clouds, sequential meshes and both EdgeBreaker traversals encode and decode, and point clouds can use several threads on request. The per-algorithm matrix lives in crates/draco-core/SUPPORT_MATRIX.md.

Where this port deliberately behaves differently from C++ Draco — what the difference is and what it means for a file — is recorded in COMPATIBILITY.md.

draco-io and draco-gltf are pre-1.0 and still move: a breaking change bumps the minor, which is the breaking field for a 0.x crate. Each crate keeps its own changelog and its own release tags; the web converter keeps web/CHANGELOG.md, since its wrappers ship as release assets rather than as crates.

Beyond KHR_draco_mesh_compression, glTF reading covers EXT_meshopt_compression, and Draco compression preserves the extensions a document carries rather than refusing the file — including feature IDs, GPU instancing and structural metadata.

Safety

Decoders here are assumed to be pointed at untrusted bytes. Malformed input must fail as a typed error rather than panic, hang, or allocate without bound, and decode limits are the caller's to set.

  • SECURITY.md — threat model, what is guaranteed, and the resource limits a caller should enforce.
  • FUZZING.md — how the decode paths are fuzzed. Targets cover .drc decode and encode, glTF import and compression, OBJ/PLY/STL and FBX read and round-trip, and KTX2 transcode; they run as a smoke gate per push and as a soak every night, and through ClusterFuzzLite.

Building the converter locally

./build.ps1 -Serve            # from web/, builds the WASM modules and serves the app
cd web && npm ci && bash ./build.sh --app

build.sh defaults to the lightweight release profile that the size budget is measured against; --app is the converter profile, which the front-end needs. The web workspace guide covers the module features, the TypeScript build, and the Node and Playwright suites.

Performance

The crates build like any Rust library (-Copt-level=3) and carry no runtime knobs. Decode and encode are CPU-bound and branchy.

  • PERFORMANCE.md — how to benchmark and profile decode/encode, the Rust-vs-C++ speed snapshot, and per-stage breakdowns.
  • PGO.md — profile-guided optimisation: how it relates to a source library, the two-pass build, training-corpus guidance, expected benefit, and the WASM-target tradeoff.
  • TRICKS.md — dated, code-level optimization techniques found in this repo, each with a real before/after snippet: dispatch, error layout, corner-table and entropy-coding tricks, a five-commit KD-tree case study, and what was measured and rejected.

Repository layout

Path Contents
crates/ The published crates, plus draco-texture and the C++ test bridge.
web/ WASM wrappers, the converter front-end, and its Node and Playwright suites.
fuzz/, .clusterfuzzlite/ Fuzz targets and the continuous fuzzing setup.
testdata/, tools/ Fixtures and development tooling.

License

Apache-2.0. See LICENSE.

About

No description, website, or topics provided.

Resources

Security policy

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages