Skip to content

Commit

Permalink
Improved parallelism and examples (#4)
Browse files Browse the repository at this point in the history
- Reworked cutting example
- removed parallelisme on sticks
- new demo gif
- Fixed examples windows
  • Loading branch information
ManevilleF committed Oct 16, 2021
1 parent bae5624 commit 4f3e02a
Show file tree
Hide file tree
Showing 15 changed files with 116 additions and 122 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ exclude = ["examples", "docs"]
description = "Verlet physics implementation in bevy"
keywords = ["verlet", "physics", "bevy", "cloth"]
categories = ["game-engines", "game-development"]
readme = "README.md"
documentation = "https://docs.rs/bevy_verlet"

[features]
default = []
Expand Down
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,12 @@ This feature will add a *system* drawing debug lines for every stick using [bevy

4. 2D cloth cutting

`cargo run --example 2d_cloth_cutter --features "debug"`

*Cutting cloth without max tension*
`cargo run --example 2d_cloth_cutter --features "debug" --release`

> Note: the release flag is necessary for smooth running
![Alt](./docs/demo_cloth_cutting.gif "demo gif")

*Sticks breaking on max tension*
![Alt](./docs/demo_cloth_ripping.gif "demo gif")

### 3D

* `cargo run --example 3d_line --features "debug"`
Expand Down
Binary file modified docs/demo_cloth_cutting.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/demo_cloth_cutting.mp4
Binary file not shown.
9 changes: 5 additions & 4 deletions examples/2d_cloth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ use bevy_verlet::{BevyVerletPlugin, VerletLocked, VerletPoint, VerletStick};

fn main() {
App::build()
.add_plugins(DefaultPlugins)
.add_plugin(BevyVerletPlugin::default())
.insert_resource(WindowDescriptor {
title: "2D cloth".to_string(),
width: 1000.,
height: 800.,
..Default::default()
})
.add_plugins(DefaultPlugins)
.add_plugin(BevyVerletPlugin::default())
.add_startup_system(setup.system())
.run();
}
Expand All @@ -20,7 +21,7 @@ fn setup(mut commands: Commands, mut materials: ResMut<Assets<ColorMaterial>>) {
let fixed_material = materials.add(Color::RED.into());
let stick_length: f32 = 35.;
let (origin_x, origin_y) = (-450., 350.);
let (points_x_count, points_y_count) = (20, 15);
let (points_x_count, points_y_count) = (30, 15);
let mut entities = Vec::new();
for j in 0..points_y_count {
for i in 0..points_x_count {
Expand All @@ -29,7 +30,7 @@ fn setup(mut commands: Commands, mut materials: ResMut<Assets<ColorMaterial>>) {
material: material.clone(),
transform: Transform::from_xyz(
origin_x + (30. * i as f32),
origin_y + (-30. * (j + i / 2) as f32),
origin_y + (-30. * (j + i / 3) as f32),
0.,
),
..Default::default()
Expand Down
51 changes: 26 additions & 25 deletions examples/2d_cloth_cutter.rs
Original file line number Diff line number Diff line change
@@ -1,46 +1,47 @@
use bevy::prelude::*;
use bevy_verlet::{
BevyVerletPlugin, VerletLocked, VerletPoint, VerletStick, VerletStickMaxTension,
BevyVerletPlugin, VerletConfig, VerletLocked, VerletPoint, VerletStick, VerletStickMaxTension,
};

fn main() {
App::build()
.add_plugins(DefaultPlugins)
.add_plugin(BevyVerletPlugin::default())
.insert_resource(VerletConfig {
parallel_processing_batch_size: Some(1000),
sticks_computation_depth: 2,
..Default::default()
})
.insert_resource(WindowDescriptor {
width: 800.,
height: 1000.,
title: "2D Cloth cutter".to_string(),
width: 1400.,
height: 900.,
..Default::default()
})
.add_plugins(DefaultPlugins)
.add_plugin(BevyVerletPlugin::default())
.add_startup_system(setup.system())
.add_system(cut_sticks.system())
.run();
}

fn setup(mut commands: Commands, mut materials: ResMut<Assets<ColorMaterial>>) {
fn setup(mut commands: Commands) {
commands.spawn_bundle(OrthographicCameraBundle::new_2d());
let material = materials.add(Color::WHITE.into());
let fixed_material = materials.add(Color::RED.into());
let stick_length: f32 = 31.;
let (origin_x, origin_y) = (-450., 350.);
let (points_x_count, points_y_count) = (31, 20);
let stick_length: f32 = 11.;
let (origin_x, origin_y) = (-600., 420.);
let (points_x_count, points_y_count) = (121, 60);
let mut entities = Vec::new();
for j in 0..points_y_count {
for i in 0..points_x_count {
let mut cmd = commands.spawn_bundle(SpriteBundle {
sprite: Sprite::new(Vec2::splat(10.)),
material: material.clone(),
transform: Transform::from_xyz(
origin_x + (30. * i as f32),
origin_y + (-30. * j as f32),
0.,
),
..Default::default()
});
cmd.insert(VerletPoint::default())
.insert(Name::new(format!("Point {}", i)));
let mut cmd = commands.spawn();
cmd.insert(Transform::from_xyz(
origin_x + (10. * i as f32),
origin_y + (-10. * j as f32),
0.,
))
.insert(GlobalTransform::default())
.insert(VerletPoint::default())
.insert(Name::new(format!("Point {}", i)));
if j == 0 && i % 2 == 0 {
cmd.insert(VerletLocked {}).insert(fixed_material.clone());
cmd.insert(VerletLocked {});
}
entities.push(cmd.id());
}
Expand Down Expand Up @@ -73,7 +74,7 @@ fn spawn_stick(
point_b_entity: *other_entity,
length,
})
.insert(VerletStickMaxTension(2.));
.insert(VerletStickMaxTension(5.));
}
}

Expand Down
7 changes: 4 additions & 3 deletions examples/2d_line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ use bevy_verlet::{BevyVerletPlugin, VerletLocked, VerletPoint, VerletStick};

fn main() {
App::build()
.add_plugins(DefaultPlugins)
.add_plugin(BevyVerletPlugin::default())
.insert_resource(WindowDescriptor {
title: "2D line".to_string(),
width: 1000.,
height: 500.,
height: 800.,
..Default::default()
})
.add_plugins(DefaultPlugins)
.add_plugin(BevyVerletPlugin::default())
.add_startup_system(setup_camera.system())
.add_startup_system(setup_free_line.system())
.add_startup_system(setup_fixed_line.system())
Expand Down
5 changes: 3 additions & 2 deletions examples/3d_cloth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ use bevy_verlet::{BevyVerletPlugin, VerletConfig, VerletLocked, VerletPoint, Ver

fn main() {
App::build()
.add_plugins(DefaultPlugins)
.add_plugin(BevyVerletPlugin::default())
.insert_resource(WindowDescriptor {
title: "3D cloth".to_string(),
width: 1000.,
height: 800.,
..Default::default()
})
.add_plugins(DefaultPlugins)
.add_plugin(BevyVerletPlugin::default())
.add_startup_system(setup.system())
.insert_resource(VerletConfig {
sticks_computation_depth: 5,
Expand Down
7 changes: 4 additions & 3 deletions examples/3d_line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ use bevy_verlet::{BevyVerletPlugin, VerletConfig, VerletLocked, VerletPoint, Ver

fn main() {
App::build()
.add_plugins(DefaultPlugins)
.add_plugin(BevyVerletPlugin::default())
.insert_resource(WindowDescriptor {
title: "3D line".to_string(),
width: 1000.,
height: 500.,
height: 800.,
..Default::default()
})
.add_plugins(DefaultPlugins)
.add_plugin(BevyVerletPlugin::default())
.add_startup_system(setup_camera.system())
.add_startup_system(setup_free_line.system())
.add_startup_system(setup_fixed_line.system())
Expand Down
4 changes: 3 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ mod systems;

use crate::verlet_time_step::VerletTimeStep;
use bevy::core::FixedTimestep;
use bevy::log;
use bevy::prelude::*;
#[cfg(feature = "debug")]
use bevy_prototype_debug_lines::DebugLinesPlugin;
Expand Down Expand Up @@ -76,8 +77,9 @@ impl Plugin for BevyVerletPlugin {
#[cfg(feature = "debug")]
{
app.add_plugin(DebugLinesPlugin);
app.add_system(systems::sticks::debug_draw_sticks.system().after("sticks"));
app.add_system(systems::debug::debug_draw_sticks.system());
}
log::info!("Loaded verlet plugin");
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/resources/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub struct VerletConfig {
/// Sets the number of sticks computation iteration.
/// The higher the value, the more precision and less elasticity for the sticks but the cost is increased
pub sticks_computation_depth: u8,
/// Enables parallel computing for sticks and points, setting the parallel batch size
/// Enables parallel computing for points, setting the parallel batch size
pub parallel_processing_batch_size: Option<usize>,
}

Expand Down
39 changes: 39 additions & 0 deletions src/systems/debug.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use crate::{VerletPoint, VerletStick};
use bevy::log;
use bevy::prelude::*;
use bevy_prototype_debug_lines::DebugLines;

macro_rules! get_point_debug {
($res:expr) => {
match $res {
Ok(p) => p,
Err(e) => {
log::warn!("Could not find point entity to draw debug stick: {}", e);
return None;
}
}
};
}

#[cfg(feature = "debug")]
fn draw_stick(
stick: &VerletStick,
points_query: &Query<&Transform, With<VerletPoint>>,
) -> Option<(Vec3, Vec3)> {
let transform_a = get_point_debug!(points_query.get(stick.point_a_entity));
let transform_b = get_point_debug!(points_query.get(stick.point_b_entity));
Some((transform_a.translation, transform_b.translation))
}

#[cfg(feature = "debug")]
pub fn debug_draw_sticks(
mut lines: ResMut<DebugLines>,
sticks_query: Query<&VerletStick>,
points_query: Query<&Transform, With<VerletPoint>>,
) {
for stick in sticks_query.iter() {
if let Some((a, b)) = draw_stick(stick, &points_query) {
lines.line(a, b, 0.);
}
}
}
2 changes: 2 additions & 0 deletions src/systems/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
#[cfg(feature = "debug")]
pub(crate) mod debug;
pub mod points;
pub mod sticks;
15 changes: 5 additions & 10 deletions src/systems/points.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,14 @@ use bevy::prelude::*;
use bevy::tasks::ComputeTaskPool;
use std::ops::Deref;

fn update_point(
transform: &mut Transform,
point: &mut VerletPoint,
down_force: Vec3,
friction: f32,
) {
fn update_point(transform: &mut Transform, point: &mut VerletPoint, gravity: Vec3, friction: f32) {
let position = transform.translation;
let velocity = if let Some(pos) = point.old_position {
position - pos
} else {
Vec3::ZERO
};
transform.translation += velocity * friction + down_force;
transform.translation += velocity * friction + gravity;
point.old_position = Some(position);
}

Expand All @@ -33,15 +28,15 @@ pub fn update_points(
VerletTimeStep::DeltaTime => time.delta_seconds(),
VerletTimeStep::FixedDeltaTime(dt) => *dt as f32,
};
let down_force = config.gravity * delta_time;
let gravity = config.gravity * delta_time;
let friction = config.friction_coefficient();
if let Some(batch_size) = config.parallel_processing_batch_size {
points_query.par_for_each_mut(&pool, batch_size, |(mut transform, mut point)| {
update_point(&mut transform, &mut point, down_force, friction);
update_point(&mut transform, &mut point, gravity, friction);
});
} else {
for (mut transform, mut point) in points_query.iter_mut() {
update_point(&mut transform, &mut point, down_force, friction);
update_point(&mut transform, &mut point, gravity, friction);
}
}
}
Loading

0 comments on commit 4f3e02a

Please sign in to comment.