Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
112 changes: 112 additions & 0 deletions examples2d/src/dynamic_add.rs
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename with postfix 2

Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
use wgsparkl2d::rapier::prelude::{ColliderBuilder, RigidBodyBuilder};
use wgsparkl_testbed2d::{wgsparkl, Callbacks, RapierData};

use bevy::render::renderer::RenderDevice;
use nalgebra::{vector, Vector2};
use wgsparkl::models::DruckerPrager;
use wgsparkl::{
models::ElasticCoefficients,
pipeline::MpmData,
solver::{Particle, SimulationParams},
};
use wgsparkl2d::solver::ParticleDynamics;
use wgsparkl_testbed2d::{AppState, PhysicsContext};

pub fn dynamic_demo(
device: RenderDevice,
app_state: &mut AppState,
callbacks: &mut Callbacks,
) -> PhysicsContext {
let mut rapier_data = RapierData::default();
let device = device.wgpu_device();

let offset_y = 46.0;
let cell_width = 0.2;
let mut particles = vec![];
let position =
vector![-20f32, 0.0] + vector![0.5, 0.5] * cell_width / 2.0 + Vector2::y() * offset_y;
let density = 1000.0;
let radius = cell_width / 4f32;
let particle_proto = Particle {
position,
dynamics: ParticleDynamics::with_density(radius, density),
model: ElasticCoefficients::from_young_modulus(10_000_000.0, 0.2),
plasticity: Some(DruckerPrager::new(10_000_000.0, 0.2)),
phase: None,
color: None,
};
particles.push(particle_proto);
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todo: fix bug where we access particles[0]


if !app_state.restarting {
app_state.num_substeps = 10;
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,
};

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

let rb = RigidBodyBuilder::fixed()
.translation(vector![-25.0, 45.0])
.rotation(0.5);
let rb_handle = rapier_data.bodies.insert(rb);
let co = ColliderBuilder::cuboid(1.0, 52.0);
rapier_data
.colliders
.insert_with_parent(co, rb_handle, &mut rapier_data.bodies);

let rb = RigidBodyBuilder::fixed()
.translation(vector![95.0, 45.0])
.rotation(-0.5);
let rb_handle = rapier_data.bodies.insert(rb);
let co = ColliderBuilder::cuboid(1.0, 52.0);
rapier_data
.colliders
.insert_with_parent(co, rb_handle, &mut rapier_data.bodies);

let mut tick = 0;
callbacks.0.push(Box::new(
move |_, physics: &mut PhysicsContext, _, _, queue| {
tick += 1;
if tick % 2 != 0 {
// Do not add particles each frame, to avoid clumping particles together.
return;
}
for i in 0..500 {
let mut particle = particle_proto.clone();
particle.position += vector![1.0, 0.0] * (i as f32) * cell_width * 1.1;
physics.push_particle(queue, &particle);
}
physics.reset_graphics = true;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todo: cleaner way to update graphics with same strategy.

},
));

let data = MpmData::new(
device,
params,
&particles,
100_000,
&rapier_data.bodies,
&rapier_data.colliders,
cell_width,
60_000,
);
PhysicsContext {
data,
rapier_data,
particles,
reset_graphics: false,
}
}
2 changes: 2 additions & 0 deletions examples2d/src/elastic_cut2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ pub fn elastic_cut_demo(
device,
params,
&particles,
particles.len(),
&rapier_data.bodies,
&rapier_data.colliders,
cell_width,
Expand All @@ -112,5 +113,6 @@ pub fn elastic_cut_demo(
data,
rapier_data,
particles,
reset_graphics: false,
}
}
2 changes: 2 additions & 0 deletions examples2d/src/elasticity2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ pub fn elastic_demo(
device,
params,
&particles,
particles.len(),
&rapier_data.bodies,
&rapier_data.colliders,
cell_width,
Expand All @@ -94,5 +95,6 @@ pub fn elastic_demo(
data,
rapier_data,
particles,
reset_graphics: false,
}
}
5 changes: 5 additions & 0 deletions examples2d/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use bevy::prelude::*;
use wgsparkl_testbed2d::{init_testbed, SceneInitFn, SceneInits};

mod dynamic_add;
mod elastic_cut2;
mod elasticity2;
mod sand2;
Expand All @@ -20,6 +21,10 @@ pub fn main() {
fn register_scenes(world: &mut World) {
let scenes: Vec<(String, SceneInitFn)> = vec![
("sand".to_string(), Box::new(sand2::sand_demo)),
(
"dynamic add".to_string(),
Box::new(dynamic_add::dynamic_demo),
),
("elastic".to_string(), Box::new(elasticity2::elastic_demo)),
(
"elastic cut".to_string(),
Expand Down
2 changes: 2 additions & 0 deletions examples2d/src/sand2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ pub fn sand_demo(
device,
params,
&particles,
particles.len(),
&rapier_data.bodies,
&rapier_data.colliders,
cell_width,
Expand All @@ -172,5 +173,6 @@ pub fn sand_demo(
data,
rapier_data,
particles,
reset_graphics: false,
}
}
3 changes: 2 additions & 1 deletion examples3d/src/banana3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ pub fn demo(
device.wgpu_device(),
params,
&particles,
particles.len(),
&rapier_data.bodies,
&rapier_data.colliders,
1f32 / default_scene::SAMPLE_PER_UNIT,
Expand All @@ -134,7 +135,7 @@ pub fn demo(
fn move_knife_function(body_handle: RigidBodyHandle) -> Callback {
let mut ticks = 0;
Box::new(
move |_render, physics: &mut PhysicsContext, _timestamps, _app_state: &AppState| {
move |_render, physics: &mut PhysicsContext, _timestamps, _app_state: &AppState, _| {
let t = ticks as f32 * physics.rapier_data.integration_parameters.dt;
ticks += 1;

Expand Down
69 changes: 69 additions & 0 deletions examples3d/src/dynamic_add.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use wgsparkl_testbed3d::{wgsparkl, Callbacks, RapierData};

use bevy::render::renderer::RenderDevice;
use nalgebra::vector;
use wgsparkl::models::DruckerPrager;
use wgsparkl::{
models::ElasticCoefficients,
pipeline::MpmData,
solver::{Particle, ParticleDynamics, SimulationParams},
};
use wgsparkl_testbed3d::{AppState, PhysicsContext};

use crate::utils::default_scene;

pub fn dynamic_demo(
device: RenderDevice,
app_state: &mut AppState,
callbacks: &mut Callbacks,
) -> PhysicsContext {
let mut rapier_data = RapierData::default();
let device = device.wgpu_device();

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

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

default_scene::spawn_ground_and_walls(&mut rapier_data);
let cell_width = 1.0;

let position = vector![0.0, 10f32, 0.0];
callbacks.0.push(Box::new(
move |_, physics: &mut PhysicsContext, _, _, queue| {
physics.data.particles.push(
queue,
&Particle {
position,
dynamics: ParticleDynamics::with_density(cell_width / 4.0, 2700.0),
model: ElasticCoefficients::from_young_modulus(2_000_000_000.0, 0.2),
plasticity: Some(DruckerPrager::new(2_000_000_000.0, 0.2)),
phase: None,
color: None,
},
)
},
));

let particles = vec![];
let data = MpmData::new(
device,
params,
&particles,
1_000,
&rapier_data.bodies,
&rapier_data.colliders,
cell_width,
60_000,
);
PhysicsContext {
data,
rapier_data,
particles,
}
}
1 change: 1 addition & 0 deletions examples3d/src/elastic_cut3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ pub fn elastic_cut_demo(
device,
params,
&particles,
particles.len(),
&rapier_data.bodies,
&rapier_data.colliders,
cell_width,
Expand Down
1 change: 1 addition & 0 deletions examples3d/src/glb_to_point_cloud_color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub fn elastic_color_model_demo(
device.wgpu_device(),
params,
&particles,
particles.len(),
&rapier_data.bodies,
&rapier_data.colliders,
1f32 / default_scene::SAMPLE_PER_UNIT,
Expand Down
1 change: 1 addition & 0 deletions examples3d/src/heightfield3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub fn heightfield_demo(
device,
params,
&particles,
particles.len(),
&rapier_data.bodies,
&rapier_data.colliders,
cell_width,
Expand Down
5 changes: 5 additions & 0 deletions examples3d/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use wgsparkl_testbed3d::{init_testbed, SceneInitFn, SceneInits};
pub mod utils;

mod banana3;
mod dynamic_add;
mod elastic_cut3;
mod glb_to_point_cloud_color;
mod heightfield3;
Expand All @@ -24,6 +25,10 @@ pub fn main() {
fn register_scenes(world: &mut World) {
let scenes: Vec<(String, SceneInitFn)> = vec![
("sand".to_string(), Box::new(sand3::sand_demo)),
(
"dynamic addition".to_string(),
Box::new(dynamic_add::dynamic_demo),
),
(
"heightfield".to_string(),
Box::new(heightfield3::heightfield_demo),
Expand Down
1 change: 1 addition & 0 deletions examples3d/src/sand3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ pub fn sand_demo(
device,
params,
&particles,
particles.len(),
&rapier_data.bodies,
&rapier_data.colliders,
cell_width,
Expand Down
27 changes: 20 additions & 7 deletions src/grid/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,14 @@ impl WgGrid {
(grid.debug.buffer(), 8),
],
)
.bind(1, [particles.positions.buffer()])
.queue((particles.len() as u32).div_ceil(GRID_WORKGROUP_SIZE));
.bind(
1,
[
particles.current_size.buffer(),
particles.positions.buffer(),
],
)
.queue(particles.current_size_cached.div_ceil(GRID_WORKGROUP_SIZE));

// Ensure blocks exist wherever we have rigid particles that might affect
// other blocks. This is done in two passes:
Expand Down Expand Up @@ -113,7 +119,6 @@ impl WgGrid {
)
.queue((rigid_particles.len() as u32).div_ceil(GRID_WORKGROUP_SIZE));

// TODO: handle grid buffer resizing
sparse_grid_has_the_correct_size = true;
}

Expand Down Expand Up @@ -149,15 +154,21 @@ impl WgGrid {
grid.active_blocks.buffer(),
],
)
.bind(1, [particles.positions.buffer()])
.bind(
1,
[
particles.current_size.buffer(),
particles.positions.buffer(),
],
)
.queue(n_groups);

KernelInvocationBuilder::new(queue, &sort_module.copy_particles_len_to_scan_value)
.bind_at(
0,
[(grid.meta.buffer(), 0), (grid.active_blocks.buffer(), 2)],
)
.bind_at(1, [(grid.scan_values.buffer(), 1)])
.bind_at(1, [(grid.scan_values.buffer(), 2)])
.queue_indirect(n_block_groups.clone());

prefix_sum_module.queue(queue, prefix_sum, &grid.scan_values);
Expand All @@ -167,7 +178,7 @@ impl WgGrid {
0,
[(grid.meta.buffer(), 0), (grid.active_blocks.buffer(), 2)],
)
.bind_at(1, [(grid.scan_values.buffer(), 1)])
.bind_at(1, [(grid.scan_values.buffer(), 2)])
.queue_indirect(n_block_groups.clone());

// Reset here so the linked list heads get reset before `finalize_particles_sort` which
Expand Down Expand Up @@ -196,6 +207,7 @@ impl WgGrid {
.bind(
1,
[
particles.current_size.buffer(),
particles.positions.buffer(),
grid.scan_values.buffer(),
particles.sorted_ids.buffer(),
Expand Down Expand Up @@ -370,7 +382,8 @@ mod test {
}
}

let particles = GpuParticles::from_particles(gpu.device(), &cpu_particles);
let particles =
GpuParticles::from_particles(gpu.device(), &cpu_particles, cpu_particles.len());
let grid = GpuGrid::with_capacity(gpu.device(), 100_000, cell_width);
let mut prefix_sum = PrefixSumWorkspace::with_capacity(gpu.device(), 100_000);
let mut queue = KernelInvocationQueue::new(gpu.device());
Expand Down
Loading