Skip to content

Commit

Permalink
Rust 1.72.0 (#19)
Browse files Browse the repository at this point in the history
- Fix new clippy warnings
- Rustfmt config
- Added vertex color in flag example
  • Loading branch information
ManevilleF authored Aug 25, 2023
1 parent 5af1904 commit bb7206c
Show file tree
Hide file tree
Showing 19 changed files with 341 additions and 291 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@nightly
with:
components: "rustfmt"
- name: Check Formatting
run: cargo fmt --all -- --check

Expand Down
6 changes: 6 additions & 0 deletions .rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
reorder_imports = true
format_code_in_doc_comments = true
normalize_doc_attributes = true
wrap_comments = true
format_strings = true
imports_granularity = "Crate"
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [Unreleased]

* Fixed clippy warnings for rust 1.72.0 (#19)
* Added rustfmt config (#19)
* Added vertex colors in flag example (#19)

## 0.6.0

* Bump `bevy` to `0.11.x`
Expand Down
73 changes: 46 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,13 @@ fn main() {

### Add cloth to a mesh

For a mesh to be used as cloth, add the `ClothBuilder` component to any entity with a `Handle<Mesh>` component.
For a mesh to be used as cloth, add the `ClothBuilder` component to any
entity with a `Handle<Mesh>` component.

> Note: `Transform` and `GlobalTransform` are also required
cloth data which will be populated automatically from the associated `Handle<Mesh>`.
cloth data which will be populated automatically from the associated
`Handle<Mesh>`.

```rust
use bevy::prelude::*;
Expand All @@ -79,18 +81,19 @@ fn spawn(mut commands: Commands) {
// Defines the sticks target length option
.with_stick_length(StickLen::Auto)
// The cloth will compute flat mesh normals
.with_flat_normals()
// ...
.with_flat_normals(),
));
}
```

#### Vertex anchoring

Specifying vertex anchors allows to pin some cloth vertices to various entities.
The `ClothBuilder` has multiple methods allowing to anchor vertices through their id or color.
Specifying vertex anchors allows to pin some cloth vertices to various
entities. The `ClothBuilder` has multiple methods allowing to anchor
vertices through their id or color.

For example you can pin some cloth vertices to the cloth entity's `GlobalTransform`:
For example you can pin some cloth vertices to the cloth entity's
`GlobalTransform`:

```rust
use bevy::prelude::Color;
Expand All @@ -109,7 +112,8 @@ let cloth = ClothBuilder::new()
.with_pinned_vertex_positions(|pos| pos.x > 0.0 && pos.z <= 5.0);
```

For more anchoring options, for example to specify a custom entity to pin the vertices to:
For more anchoring options, for example to specify a custom entity to pin
the vertices to:

```rust
use bevy::prelude::*;
Expand Down Expand Up @@ -150,13 +154,15 @@ fn spawn(mut commands: Commands) {

Custom anchoring allows to :
- pin vertices to various entities, like skeletal mesh joints
- define custom offsets to customize the distance between the anchored vertices an the target
- define custom offsets to customize the distance between the anchored
vertices an the target
- use world space pinning and ignore the target's rotation for example
- override the vertex positions, using only the offset

### Configuration

You can customize the global cloth physics by inserting the `ClothConfig` resource to your app:
You can customize the global cloth physics by inserting the `ClothConfig`
resource to your app:

```rust no_run
use bevy::prelude::*;
Expand All @@ -177,15 +183,19 @@ fn main() {
}
```

`ClothConfig` can also be used as a *component* to override the global configuration.
`ClothConfig` can also be used as a *component* to override the global
configuration.

## Wind

You may add wind forces to the simulation for a more dynamic clothing effect, for each force you may choose from:
You may add wind forces to the simulation for a more dynamic clothing
effect, for each force you may choose from:
- `Wind::Constant` for constant wind force
- `Wind::SinWave` for a sin wave following wind intensity with custom force and frequency.
- `Wind::SinWave` for a sin wave following wind intensity with custom force
and frequency.

`Wind` forces can be added as a resource to your app through the `Winds` container:
`Wind` forces can be added as a resource to your app through the `Winds`
container:

```rust no_run
use bevy::prelude::*;
Expand All @@ -212,8 +222,9 @@ fn main() {
## Collisions

Enabling the `rapier_collisions` features enable cloth interaction with other colliders.
Add the `bevy_rapier3d::RapierPhysicsPlugin` to your app and a `ClothCollider` to your entity to enable collisions:
Enabling the `rapier_collisions` features enable cloth interaction with
other colliders. Add the `bevy_rapier3d::RapierPhysicsPlugin` to your app
and a `ClothCollider` to your entity to enable collisions:

```rust
use bevy::prelude::*;
Expand All @@ -226,35 +237,43 @@ fn spawn(mut commands: Commands) {
..Default::default()
},
ClothBuilder::new(),
ClothCollider::default()
ClothCollider::default(),
));
}
```

Three [`bevy_rapier`](https://github.com/dimforge/bevy_rapier) components will be automatically inserted:
- a `RigidBody::KinematicPositionBased`
- a `Collider` which will be updated every frame to follow the cloth bounds (AABB)
- a `SolverGroup` set to 0 (`Group::NONE`) in everything, avoiding default collision solving.
- a `Collider` which will be updated every frame to follow the cloth bounds
(AABB)
- a `SolverGroup` set to 0 (`Group::NONE`) in everything, avoiding default
collision solving.

You can customize what collisions will be checked through a `CollisionGroups` (See the [rapier docs](https://rapier.rs/docs/user_guides/bevy_plugin/colliders#collision-groups-and-solver-groups)).

> Note: Collision support is still experimental for now and is not suited for production use. Feedback is welcome !
> Note: Collision support is still experimental for now and is not suited
> for production use. Feedback is welcome !
## Mesh utils

`bevy_silk` provides a plane mesh generation function `rectangle_mesh` useful for classic cloth uses like flags or capes
`bevy_silk` provides a plane mesh generation function `rectangle_mesh`
useful for classic cloth uses like flags or capes

## Q&A

- `My mesh falls immediately and infinitely when I add a Cloth component, how to fix it?`

You probably didn't specify any *pinned points*, meaning there are no vertices anchored to your entity's `GlobalTransform`.
- `My mesh falls immediately and infinitely when I add a Cloth component,
how to fix it?`

- `My cloth jitters a lot/ suddenly falls down/ has strange sudden behaviour`
You probably didn't specify any *pinned points*, meaning there are no
vertices anchored to your entity's `GlobalTransform`.

Gravity and winds are by default smoothed out by the framerate, if the framerate drops suddenly gravity and wind get much stronger.
If your simulation suffers from this you can specify a custom smooth value in `ClothConfig::acceleration_smoothing`.
- `My cloth jitters a lot/ suddenly falls down/ has strange sudden
behaviour`

Gravity and winds are by default smoothed out by the framerate, if the
framerate drops suddenly gravity and wind get much stronger.
If your simulation suffers from this you can specify a custom smooth value
in `ClothConfig::acceleration_smoothing`.

<!-- cargo-sync-readme end -->

Expand Down
8 changes: 5 additions & 3 deletions examples/camera_plugin.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use bevy::input::mouse::{MouseMotion, MouseWheel};
use bevy::log;
use bevy::prelude::*;
use bevy::{
input::mouse::{MouseMotion, MouseWheel},
log,
prelude::*,
};

pub struct CameraPlugin;

Expand Down
53 changes: 26 additions & 27 deletions examples/flag_example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ fn spawn_cloth(
PbrBundle {
mesh: meshes.add(mesh.clone()),
material: material.clone(),
transform: Transform::from_xyz(0.0, 8.0, 5.0),
transform: Transform::from_xyz(0.0, 8.0, 10.0),
..Default::default()
},
cloth,
Expand All @@ -101,36 +101,35 @@ fn spawn_cloth(
.with_flat_normals();
commands.spawn((
PbrBundle {
mesh: meshes.add(mesh),
material,
transform: Transform::from_xyz(0.0, 8.0, -5.0),
mesh: meshes.add(mesh.clone()),
material: material.clone(),
transform: Transform::from_xyz(0.0, 8.0, 0.0),
..Default::default()
},
cloth,
Name::new("Regular Flat Flag"),
));

// TODO: enable when bevy releases vertex color support
// color flag
// let mut mesh = mesh;
// if let Some(VertexAttributeValues::Float32x3(positions)) =
// mesh.attribute(Mesh::ATTRIBUTE_POSITION)
// {
// let colors: Vec<[f32; 4]> = positions
// .iter()
// .map(|[r, g, b]| [(1. - *r) / 2., (1. - *g) / 2., (1. - *b) / 2., 1.])
// .collect();
// println!("{}", colors.len());
// mesh.insert_attribute(Mesh::ATTRIBUTE_COLOR, colors);
// }
// let cloth = ClothBuilder::new().with_pinned_vertex_ids((0..size_y).map(|i| i * size_x));
// commands
// .spawn_bundle(PbrBundle {
// mesh: meshes.add(mesh),
// material,
// transform: Transform::from_xyz(0.0, 8.0, -5.0),
// ..Default::default()
// })
// .insert(cloth)
// .insert(Name::new("Colored smooth Flag"));
// Color flag
let mut mesh = mesh;
let colors: Vec<[f32; 4]> = (0..size_y)
.flat_map(|_| {
(0..size_x).map(|v| {
let v = v as f32 / size_x as f32;
[1.0, v, v, 1.0]
})
})
.collect();
mesh.insert_attribute(Mesh::ATTRIBUTE_COLOR, colors);
let cloth = ClothBuilder::new().with_pinned_vertex_color(Color::RED);
commands.spawn((
PbrBundle {
mesh: meshes.add(mesh),
material,
transform: Transform::from_xyz(0.0, 8.0, -10.0),
..Default::default()
},
cloth,
Name::new("Colored smooth Flag"),
));
}
3 changes: 2 additions & 1 deletion examples/moving_example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ fn spawn_cloth(
material: materials.add(StandardMaterial {
base_color_texture: Some(flag_texture),
cull_mode: None, // Option required to render back faces correctly
double_sided: true, // Option required to render back faces correctly
double_sided: true, /* Option required to render back faces
* correctly */
..Default::default()
}),
transform: Transform::from_xyz(-1.0, 1.0, 1.01),
Expand Down
46 changes: 30 additions & 16 deletions src/components/cloth.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use crate::stick::{StickGeneration, StickLen, StickMode};
use crate::vertex_anchor::VertexAnchor;
use bevy::ecs::prelude::Component;
use bevy::log;
use bevy::math::{Mat4, Vec3};
use bevy::prelude::{Entity, GlobalTransform};
use bevy::utils::HashMap;
use crate::{
stick::{StickGeneration, StickLen, StickMode},
vertex_anchor::VertexAnchor,
};
use bevy::{
ecs::prelude::Component,
log,
math::{Mat4, Vec3},
prelude::{Entity, GlobalTransform},
utils::HashMap,
};

/// A stick is defined by the two ids of the connectecte points
pub type StickId = [usize; 2];
Expand Down Expand Up @@ -70,8 +74,9 @@ impl Cloth {
.map(move |p| matrix.transform_point3(*p))
}

/// Creates a new cloth from a mesh. Points positions will be directly extracted from the given vertex positions
/// and the sticks will be extracted from the given `indices` (triangles) according to
/// Creates a new cloth from a mesh. Points positions will be directly
/// extracted from the given vertex positions and the sticks will be
/// extracted from the given `indices` (triangles) according to
/// the associated [`StickGeneration`] and [`StickLen`].
///
/// # Arguments
Expand All @@ -81,7 +86,8 @@ impl Cloth {
/// * `anchored_points` - the pinned vertex position indices
/// * `stick_generation` - The stick generation mode
/// * `stick_len` - The stick length option
/// * `transform_matrix` - the transform matrix of the associated `GlobalTransform`
/// * `transform_matrix` - the transform matrix of the associated
/// `GlobalTransform`
///
/// # Panics
///
Expand Down Expand Up @@ -153,8 +159,8 @@ impl Cloth {
}
}

/// Adds an extra point to the cloth (Not included in the base mesh) and returns its id and
/// associated stick ids.
/// Adds an extra point to the cloth (Not included in the base mesh) and
/// returns its id and associated stick ids.
pub fn add_point(
&mut self,
pos: Vec3,
Expand Down Expand Up @@ -193,7 +199,8 @@ impl Cloth {
///
/// # Arguments
///
/// * `solve_point` - function taking a cloth point and returning the new solved point
/// * `solve_point` - function taking a cloth point and returning the new
/// solved point
pub fn solve_collisions(&mut self, solve_point: impl Fn(&Vec3) -> Option<Vec3>) {
for (point, new_point) in self
.current_point_positions
Expand All @@ -211,7 +218,8 @@ impl Cloth {
/// # Arguments
///
/// * `transform` - The `GlobalTransform` associated to the cloth entity
/// * `anchor_query` - A function allowing to retrieve the `GlobalTransform` of a given entity
/// * `anchor_query` - A function allowing to retrieve the `GlobalTransform`
/// of a given entity
pub fn update_anchored_points<'a>(
&mut self,
transform: &GlobalTransform,
Expand All @@ -223,7 +231,8 @@ impl Cloth {
}
}

/// Updates the cloth points according to their own velocity and external friction and acceleration
/// Updates the cloth points according to their own velocity and external
/// friction and acceleration
///
/// # Arguments
///
Expand Down Expand Up @@ -277,7 +286,12 @@ impl Cloth {
let center = (position_b + position_a) / 2.0;
let direction = match (position_b - position_a).try_normalize() {
None => {
log::warn!("Failed handle stick between points {} and {} which are too close to each other", *id_a, *id_b);
log::warn!(
"Failed handle stick between points {} and {} which are too close to \
each other",
*id_a,
*id_b
);
continue;
}
Some(dir) => dir * target_len / 2.0,
Expand Down
Loading

0 comments on commit bb7206c

Please sign in to comment.