Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
a8818a5
feat: add basic CPIC implementation
sebcrozet Jan 25, 2025
824d895
feat: support one-way coupling with CPIC
sebcrozet Jan 31, 2025
7d592ef
feat: kinematic body coupling with rapier
sebcrozet Feb 3, 2025
a716219
feat: implement two-ways coupling with cpic
sebcrozet Feb 4, 2025
61d6973
fix incorrect stress calculation for neo-hookean (was cauchy instead …
sebcrozet Feb 5, 2025
754a4fd
feat: some adjustments for two-ways coupling
sebcrozet Feb 5, 2025
2357555
feat: support more geometric primitives
sebcrozet Feb 5, 2025
8b1c159
Fix 3D
sebcrozet Feb 6, 2025
f5fc1c2
Fix timestamps
sebcrozet Feb 6, 2025
4ef05b0
feat(wgsparkl2d): support polyline colliders
sebcrozet Feb 12, 2025
0a31f8a
feat(wgsparkl3d): support trimesh colliders
sebcrozet Feb 14, 2025
643ae49
feat: support kinematic bodies for rigid particles + misc coupling fixes
sebcrozet Feb 15, 2025
58b75fd
feat: make the DruckerPrager fields public
sebcrozet Feb 15, 2025
f457777
chore: cargo fmt
sebcrozet Feb 15, 2025
6114a73
fix: move path deps to cargo patches
sebcrozet Feb 15, 2025
409abe9
fix 2D simulations
sebcrozet Feb 17, 2025
f64d391
Fix support of non-macos platforms
sebcrozet Feb 17, 2025
aad0361
fix: disable the wireframe plugin on web
sebcrozet Feb 17, 2025
6a9e0b0
feat(wasm): group some of the particle properties to reduce the numbe…
sebcrozet Feb 17, 2025
3afe2e9
feat: further reduce storage binding counts to fix web support
sebcrozet Feb 17, 2025
5b3876c
feat: add COPY_SRC to the particle position flags
sebcrozet Feb 19, 2025
70c8ffc
fix dependencies to compile
ThierryBerger Mar 24, 2025
7c6d66f
chore: switch to wgmath/main
sebcrozet Apr 7, 2025
45aba34
chore: add CI
sebcrozet Apr 7, 2025
805f5fd
chore: clippy fixes
sebcrozet Apr 7, 2025
cc63d62
chore: fix tests
sebcrozet Apr 7, 2025
69d85d7
chore: don’t run tests on CI, they will fail because there is no gpu
sebcrozet Apr 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
[target.wasm32-unknown-unknown]
runner = "wasm-server-runner"
runner = "wasm-server-runner"
# Needed for getrandom/uuid: https://github.com/uuid-rs/uuid/issues/792
rustflags = ['--cfg', 'getrandom_backend="wasm_js"']
78 changes: 78 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: CI

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

env:
CARGO_TERM_COLOR: always
RUSTFLAGS: --deny warnings
RUSTDOCFLAGS: --deny warnings

jobs:
# Run clippy lints.
clippy:
name: Clippy
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: clippy

- name: Install dependencies
run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev libxkbcommon-dev

- name: Populate target directory from cache
uses: Leafwing-Studios/cargo-cache@v2
with:
sweep-cache: true

- name: Run clippy lints
run: cargo clippy --locked --workspace --all-targets --all-features -- --deny warnings

# Check formatting.
format:
name: Format
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt

- name: Run cargo fmt
run: cargo fmt --all -- --check

# Check documentation.
doc:
name: Docs
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable

- name: Install dependencies
run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev libxkbcommon-dev

- name: Populate target directory from cache
uses: Leafwing-Studios/cargo-cache@v2
with:
sweep-cache: true

- name: Check documentation
run: cargo doc --locked --workspace --all-features --document-private-items --no-deps
13 changes: 11 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@ resolver = "2"
nalgebra = { version = "0.33", features = ["convert-bytemuck"] }
wgpu = { version = "23", features = ["naga-ir"] }
bytemuck = { version = "1", features = ["derive"] }
anyhow = "1"
async-channel = "2"
naga_oil = "0.16"
thiserror = "1"
encase = { version = "0.10.0", features = ["nalgebra"] }

[workspace.lints]
Expand All @@ -23,6 +21,17 @@ rust.unexpected_cfgs = { level = "warn", check-cfg = [
] }

[patch.crates-io]
parry2d = { git = "https://github.com/dimforge/parry.git", rev = "407fb449504dde7ba0a3d80a8de7e37ac991a77a" }
parry3d = { git = "https://github.com/dimforge/parry.git", rev = "407fb449504dde7ba0a3d80a8de7e37ac991a77a" }
encase = { git = "https://github.com/sebcrozet/encase.git", rev = "6755c1414c225cbeac9fde1ff9394b70d3b05404" }
wgcore = { git = "https://github.com/dimforge/wgmath.git", rev = "6d17942bd841efdfcc696d8455b22be3a8ddfe8d" }
wgcore-derive = { git = "https://github.com/dimforge/wgmath.git", rev = "6d17942bd841efdfcc696d8455b22be3a8ddfe8d" }
wgebra = { git = "https://github.com/dimforge/wgmath.git", rev = "6d17942bd841efdfcc696d8455b22be3a8ddfe8d" }
wgparry3d = { git = "https://github.com/dimforge/wgmath.git", rev = "6d17942bd841efdfcc696d8455b22be3a8ddfe8d" }
wgparry2d = { git = "https://github.com/dimforge/wgmath.git", rev = "6d17942bd841efdfcc696d8455b22be3a8ddfe8d" }
wgrapier3d = { git = "https://github.com/dimforge/wgmath.git", rev = "6d17942bd841efdfcc696d8455b22be3a8ddfe8d" }
wgrapier2d = { git = "https://github.com/dimforge/wgmath.git", rev = "6d17942bd841efdfcc696d8455b22be3a8ddfe8d" }
rapier3d = { git = "https://github.com/vrixyz/rapier.git", branch = "uber_physics_context" }

[profile.release]
opt-level = 'z'
24 changes: 16 additions & 8 deletions crates/wgsparkl-testbed2d/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ required-features = ["dim2"]

[features]
dim2 = []
default_features = ["dim2"]
default = ["dim2"]

[dependencies]
nalgebra = { workspace = true, features = ["rand"] }
Expand All @@ -23,17 +23,25 @@ naga_oil = { workspace = true }
bytemuck = { workspace = true }
async-channel = { workspace = true }

wgcore = { version = "0.2", path = "../../../wgmath/crates/wgcore" }
wgebra = { version = "0.2", path = "../../../wgmath/crates/wgebra" }
wgparry2d = { version = "0.2", path = "../../../wgmath/crates/wgparry/crates/wgparry2d" }
wgcore = "0.2"
wgebra = "0.2"
wgparry2d = "0.2"

futures-test = "0.3"
serial_test = "3"
approx = "0.5"
async-std = { version = "1", features = ["attributes"] }
bevy = { version = "0.15.0", features = ["shader_format_glsl", "shader_format_spirv", "webgpu"] }
bevy = { version = "0.15.0", features = [
"shader_format_glsl",
"shader_format_spirv",
"webgpu",
] }
#bevy_wasm_window_resize = "0.4"
#bevy_editor_cam = "0.3"
#bevy_mod_picking = { version = "0.20", default-features = false }
bevy_egui = { version = "0.31", default-features = false, features = ["default_fonts", "render"] }
bevy_editor_cam = "0.5"
bevy_egui = { version = "0.31", default-features = false, features = [
"default_fonts",
"render",
] }
bevy_sprite = "0.15"
wgsparkl2d = { path = "../wgsparkl2d" }
futures = "0.3"
22 changes: 15 additions & 7 deletions crates/wgsparkl-testbed3d/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ required-features = ["dim3"]

[features]
dim3 = []
default_features = ["dim3"]
default = ["dim3"]

[dependencies]
nalgebra = { workspace = true, features = ["rand"] }
Expand All @@ -23,17 +23,25 @@ naga_oil = { workspace = true }
bytemuck = { workspace = true }
async-channel = { workspace = true }

wgcore = { version = "0.2", path = "../../../wgmath/crates/wgcore" }
wgebra = { version = "0.2", path = "../../../wgmath/crates/wgebra" }
wgparry3d = { version = "0.2", path = "../../../wgmath/crates/wgparry/crates/wgparry3d" }
wgcore = "0.2"
wgebra = "0.2"
wgparry3d = "0.2"

futures-test = "0.3"
serial_test = "3"
approx = "0.5"
async-std = { version = "1", features = ["attributes"] }
bevy = { version = "0.15.0", features = ["shader_format_glsl", "shader_format_spirv", "webgpu"] }
#bevy_editor_cam = "0.3"
bevy = { version = "0.15.0", features = [
"shader_format_glsl",
"shader_format_spirv",
"webgpu",
] }
bevy_editor_cam = "0.5"
#bevy_mod_picking = { version = "0.20", default-features = false }
#bevy_wasm_window_resize = "0.4"
bevy_egui = { version = "0.31", default-features = false, features = ["default_fonts", "render"] }
bevy_egui = { version = "0.31", default-features = false, features = [
"default_fonts",
"render",
] }
wgsparkl3d = { path = "../wgsparkl3d" }
futures = "0.3"
17 changes: 12 additions & 5 deletions crates/wgsparkl2d/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,17 @@ naga_oil = { workspace = true }
bytemuck = { workspace = true }
encase = { workspace = true }

wgcore = { version = "0.2", path = "../../../wgmath/crates/wgcore", features = ["hot_reloading"] }
wgebra = { version = "0.2", path = "../../../wgmath/crates/wgebra" }
wgparry2d = { version = "0.2", path = "../../../wgmath/crates/wgparry/crates/wgparry2d" }
wgrapier2d = { version = "0.2", path = "../../../wgmath/crates/wgrapier/crates/wgrapier2d" }
wgcore = "0.2"
wgebra = "0.2"
wgparry2d = "0.2"
wgrapier2d = "0.2"

# TODO: make rapier optional?
rapier2d = "0.23"

# For wasm?
getrandom = { version = "0.3.1", features = ["wasm_js"] }
uuid = { version = "1", features = ["js"] }

[dev-dependencies]
nalgebra = { version = "0.33", features = ["rand"] }
Expand All @@ -35,4 +42,4 @@ serial_test = "3"
approx = "0.5"
async-std = { version = "1", features = ["attributes"] }
bevy = { version = "0.15.0", features = ["shader_format_glsl", "shader_format_spirv", "webgpu"] }
wgsparkl_testbed2d = { path = "../wgsparkl-testbed2d" }
wgsparkl_testbed2d = { path = "../wgsparkl-testbed2d", features = ["dim2"] }
123 changes: 123 additions & 0 deletions crates/wgsparkl2d/examples/elastic_cut2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
use wgsparkl_testbed2d::{wgsparkl, RapierData};

use bevy::prelude::*;
use bevy::render::renderer::RenderDevice;
use nalgebra::{point, vector, Vector2};
use rapier2d::prelude::{ColliderBuilder, RigidBodyBuilder};
use wgsparkl::solver::ParticlePhase;
use wgsparkl::{
models::ElasticCoefficients,
pipeline::MpmData,
solver::{Particle, SimulationParams},
};
use wgsparkl2d::solver::ParticleDynamics;
use wgsparkl_testbed2d::{AppState, PhysicsContext};

#[allow(dead_code)]
fn main() {
panic!("Run the `testbed3` example instead.");
}

pub fn elastic_cut_demo(
mut commands: Commands,
device: Res<RenderDevice>,
mut app_state: ResMut<AppState>,
) {
let mut rapier_data = RapierData::default();
let device = device.wgpu_device();

let offset_y = 46.0;
// let cell_width = 0.1;
let cell_width = 0.2;
let mut particles = vec![];
for i in 0..700 {
for j in 0..700 {
let position = vector![i as f32 + 0.5, j as f32 + 0.5] * cell_width / 2.0
+ Vector2::y() * offset_y;
let density = 1000.0;
let radius = cell_width / 4.0;
particles.push(Particle {
position,
dynamics: ParticleDynamics::with_density(radius, density),
model: ElasticCoefficients::from_young_modulus(5_000_000.0, 0.2),
plasticity: None,
phase: Some(ParticlePhase {
phase: 1.0,
max_stretch: f32::MAX,
}),
});
}
}

if !app_state.restarting {
app_state.num_substeps = 15;
app_state.gravity_factor = 1.0;
};

let params = SimulationParams {
gravity: vector![0.0, -9.81] * app_state.gravity_factor,
dt: (1.0 / 60.0) / (app_state.num_substeps as f32),
padding: 0.0,
};

// const ANGVEL: f32 = 1.0; // 2.0;

/*
* Static platforms.
*/
let rb = RigidBodyBuilder::fixed().translation(vector![35.0, 20.0]);
let rb_handle = rapier_data.bodies.insert(rb);
let co = ColliderBuilder::cuboid(70.0, 1.0);
rapier_data
.colliders
.insert_with_parent(co, rb_handle, &mut rapier_data.bodies);

let mut polyline = vec![];
let subdivs = 100;
let length = 84.0;
let start = point![35.0, 70.0] - vector![length / 2.0, 0.0];

for i in 0..=subdivs {
let step = length / (subdivs as f32);
let dx = i as f32 * step;
polyline.push(start + vector![dx, dx.sin()])
}

let rb = RigidBodyBuilder::fixed();
let rb_handle = rapier_data.bodies.insert(rb);
let co = ColliderBuilder::polyline(polyline, None).build();
rapier_data
.colliders
.insert_with_parent(co, rb_handle, &mut rapier_data.bodies);

for k in 0..6 {
let rb = RigidBodyBuilder::fixed();
let rb_handle = rapier_data.bodies.insert(rb);
let co = ColliderBuilder::polyline(
vec![
point![0.0 + k as f32 * 15.0, 20.0],
point![-10.0 + k as f32 * 15.0, 45.0],
],
None,
)
.build();
rapier_data
.colliders
.insert_with_parent(co, rb_handle, &mut rapier_data.bodies);
}

let data = MpmData::new(
device,
params,
&particles,
&rapier_data.bodies,
&rapier_data.colliders,
cell_width,
60_000,
);
commands.insert_resource(PhysicsContext {
data,
rapier_data,
particles,
});
}
Loading