blast-stress-solver
Rust bindings for the Blast stress solver, packaged for straightforward native and WebAssembly consumption from Cargo.
This crate gives you two main layers:
ExtStressSolverfor Blast-only stress, bond failure, and split handlingblast_stress_solver::rapier::DestructibleSetfor keeping Blast actors and Rapier rigid bodies in sync
Installation
Core solver only:
[]
= "0.1.1"
With built-in scenario builders:
[]
= { = "0.1.1", = ["scenarios"] }
With Rapier integration and scenario builders:
[]
= { = "0.1.1", = ["rapier", "scenarios"] }
= { = "0.30", = false, = ["dim3", "f32"] }
Target support
The published crate currently ships packaged backends for:
aarch64-apple-darwinwasm32-unknown-unknown
For other Apple/Linux native targets, the published crate falls back to compiling the bundled Blast C++ sources on the consumer machine with a normal C++17 toolchain. That removes the need to vendor the PhysX monorepo just to support x86_64 macOS or Linux consumers.
wasm32-unknown-unknown intentionally stays prepackaged: downstream web builds
do not need Emscripten, wasi-sdk, or a second Blast-side wasm/JS loader.
Advanced overrides:
BLAST_STRESS_SOLVER_STATIC_LIB_PATH=/abs/path/to/libblast_stress_solver_ffi.aBLAST_STRESS_SOLVER_LIB_DIR=/abs/path/to/lib/dirBLAST_STRESS_SOLVER_FORCE_SOURCE_BUILD=1for the bundled Apple/Linux native fallback
Quick Start
The easiest way to understand the API is in two steps:
- Build a destructible wall and drive the Blast solver directly.
- Take the same wall and let
DestructibleSetkeep it synchronized with Rapier rigid bodies.
The examples below are intentionally explicit about which code belongs to your
application and which code is specific to blast-stress-solver.
1. Blast-only example: build and collapse a simple wall
This version does not use Rapier yet. It shows the minimum Blast-side workflow:
- Build a wall scenario.
- Create
ExtStressSolverfrom its nodes and bonds. - Apply gravity and an impact force.
- Ask Blast for fracture commands and apply them.
use ;
use ;
What to notice:
build_wall_scenario(...)is optional convenience. If you already have your own nodes and bonds, you can skip thescenariosfeature and buildNodeDesc/BondDescdirectly.- The bottom row of the built-in wall is automatically marked as support
(
mass == 0.0), so the wall has something fixed to break away from. ExtStressSolverowns the Blast family/actor state. After fractures are applied,actor_count()grows as disconnected pieces split apart.
2. Rapier example: the same wall, now backed by rigid bodies
This version shows where Rapier is actually integrated.
DestructibleSet does not replace Rapier. Your app still owns the Rapier
world, the physics pipeline, and the frame loop. blast-stress-solver handles
the destruction-specific part:
- keep a Blast stress graph for the structure
- detect failed bonds
- split Blast actors
- create/update/destroy the corresponding Rapier bodies and colliders
use ;
use ;
use ;
use *;
What to notice:
- Your app still owns
RigidBodySet,ColliderSet, the Rapier pipeline, and the main frame loop. DestructibleSet::initialize(...)is the point where Blast’s initial actor graph becomes actual Rapier bodies and colliders.DestructibleSet::step(...)is the integration point. That is where this crate applies gravity to the stress graph, breaks bonds, and rewrites the Rapier body/collider layout when actors split.physics_pipeline.step(...)is still your responsibility. This crate does not hide Rapier from you.
WebAssembly
This crate supports downstream Rust applications that build for
wasm32-unknown-unknown.
The intended model is:
- your application depends on
blast-stress-solveras a normal Rust dependency - your application builds one final wasm output
- no Blast-specific sidecar wasm or JS loader is required
Downstream wasm-bindgen example
[]
= ["cdylib"]
[]
= "0.1.1"
= "0.2"
use ;
use *;
That build still emits one final application wasm file. There is no extra Blast runtime bundle to host or load manually.
Features
rapier: enables Rapier3D integration helpersscenarios: enables built-in wall, tower, and bridge scenario builders
Publishing
Do not run cargo publish directly against
blast/blast-stress-solver-rs/Cargo.toml. The source crate is marked
publish = false on purpose so local publishes cannot accidentally ship the
monorepo build layout.
Local crates.io preflight:
Local publish:
Tag-driven GitHub Actions release:
- bump
versioninblast/blast-stress-solver-rs/Cargo.toml - commit and push the branch
- push a matching tag such as:
That workflow stages the crate, runs the packaged native/wasm/demo-consumer proofs, dry-runs publish, publishes to crates.io, and creates a GitHub release.
Notes
- Local publish-style proof:
scripts/assemble-blast-stress-solver-package.sh --verify-demo-consumerstages the crate, verifies the packaged native and wasm smoke consumers, and runs the realblast/blast-stress-demo-rsheadless fracture test against the staged package. - The published crate is distributed as packaged Rust source plus:
- prebuilt backend artifacts for
aarch64-apple-darwinandwasm32-unknown-unknown - bundled native C++ sources for the Apple/Linux source-build fallback
- prebuilt backend artifacts for
- The monorepo development setup can still build the backend from source, but consumers no longer need to vendor the monorepo to get that native fallback.