Skip to content

Commit

Permalink
Merge pull request #24 from shnewto/dev
Browse files Browse the repository at this point in the history
0.4.0
  • Loading branch information
shnewto authored Jan 8, 2025
2 parents 135ba5d + e86c5ff commit 41f6b03
Show file tree
Hide file tree
Showing 15 changed files with 535 additions and 402 deletions.
44 changes: 44 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,47 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.4.0](/~https://github.com/shnewto/bevy_collider_gen/compare/0.3.0...0.4.0) - 2025-01-06

### Added

- Module `prelude` which contains all public structs and modules
([5be223b](/~https://github.com/shnewto/bevy_collider_gen/commit/5be223be29af4f52633121cdfdcdf2f4568bd973)).
- [`image`] dependency ([e7fe636](/~https://github.com/shnewto/bevy_collider_gen/commit/e7fe636a605673d0887983952a0bdbaa0a992334)).
- Structures
([e792bbb](/~https://github.com/shnewto/edges/commit/e792bbb4b5417e6da25feb7c5b2ba3e9c76eb8ac)):
- `AbstractCollidersBuilder`
- `AbstractCollider`

### Changed

- Upgrade dependencies
([5c03df1](/~https://github.com/shnewto/edges/commit/5c03df1e0e0ad56b329aacb377bbee5926915f16))
([786ab6d](/~https://github.com/shnewto/edges/commit/786ab6df0ca4358c3d3ba2168b50dc9af3ec31f9))
([a4cc65e](/~https://github.com/shnewto/edges/commit/a4cc65e5f18af0008c5885ceda3445b3518716d6))
([555756d](/~https://github.com/shnewto/edges/commit/555756dbd927899180b97b4ab8018bd2de2d35b5)):
- [`edges`] 0.7
- [`bevy`] 0.15
- [`bevy_rapier2d`] 0.28
- [`bevy_avian2d`] 0.2
- Dependencies [`bevy_math`] replaced by [`bevy`]
([555756d](/~https://github.com/shnewto/bevy_collider_gen/commit/555756dbd927899180b97b4ab8018bd2de2d35b5)).
- `ColliderType` moved to `prelude`
([e792bbb](/~https://github.com/shnewto/edges/commit/e792bbb4b5417e6da25feb7c5b2ba3e9c76eb8ac)).

### Removed

- Modules
([e792bbb](/~https://github.com/shnewto/edges/commit/e792bbb4b5417e6da25feb7c5b2ba3e9c76eb8ac)):
- `avian2d`
- `rapier2d`
- Functions
([e792bbb](/~https://github.com/shnewto/edges/commit/e792bbb4b5417e6da25feb7c5b2ba3e9c76eb8ac)):
- `generate_collider`
- `generate_colliders`
- [`rayon`] from dependencies
([e7fe636](/~https://github.com/shnewto/bevy_collider_gen/commit/e7fe636a605673d0887983952a0bdbaa0a992334)).

## [0.3.0](/~https://github.com/shnewto/bevy_collider_gen/compare/0.2.2...0.3.0) - 2024-11-20

### Added
Expand Down Expand Up @@ -93,6 +134,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[`avian2d`]: https://crates.io/crates/avian2d
[`rayon`]: https://crates.io/crates/rayon
[`edges`]: https://crates.io/crates/edges
[`image`]: https://crates.io/crates/image
[`thiserror`]: https://crates.io/crates/thiserror
[`bevy_prototype_lyon`]: https://crates.io/crates/bevy_prototype_lyon
[`bevy_xpbd_2d`]: https://crates.io/crates/bevy_xpbd_2d
[`bevy_rapier2d`]: https://crates.io/crates/bevy_rapier2d
[`bevy_avian2d`]: https://crates.io/crates/bevy_avian2d
28 changes: 13 additions & 15 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,39 +22,37 @@ pedantic = { level = "warn", priority = 0 }
default = ["rapier2d", "parallel"]
avian2d = ["dep:avian2d"]
rapier2d = ["dep:bevy_rapier2d"]
parallel = ["dep:rayon", "avian2d/parallel", "bevy_rapier2d/parallel"]
parallel = ["edges/parallel"]

[dependencies]
edges = "0.4"
bevy_math = { version = "0.14", default-features = false }
rayon = { version = "1", optional = true }
image = { version = "0.25", default-features = false }
edges = "0.7"
bevy = { version = "0.15", default-features = false, features = ["bevy_image"] }

[dependencies.bevy_rapier2d]
version = "0.27"
version = "0.28"
optional = true
default-features = false
features = ["dim2", "headless"]

[dependencies.avian2d]
version = "0.1"
version = "0.2"
optional = true
default-features = false
features = ["2d", "parry-f32"]

[dev-dependencies]
bevy = "0.14"
bevy_prototype_lyon = "0.12"
indoc = "2.0.4"
bevy = "0.15"
bevy_prototype_lyon = "0.13"
indoc = "2"

[dev-dependencies.bevy_rapier2d]
version = "0.27"
default-features = false
features = ["dim2", "headless", "debug-render-2d"]
version = "0.28"
features = ["debug-render-2d"]

[dev-dependencies.avian2d]
version = "0.1"
default-features = false
features = ["2d", "parry-f32", "debug-plugin"]
version = "0.2"
features = ["debug-plugin"]

[[example]]
name = "avian2d_colliders"
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ them with the edge coordinates from your image with something like this

```rust
let sprite_image = image_assets.get(sprite_handle.unwrap()).unwrap();
let edges = Edges::from(sprite_image)
let edge_coordinate_groups = edges.multi_image_edge_translated();
let edges = Edges::try_from(sprite_image).unwrap();
let edge_coordinate_groups = edges.multi_translated();
for coords in edge_coordinate_groups {
let indices: Vec<[u32; 2]> = (0..coords.len()).map(|i| [i as u32, i as u32]).collect();
let collider = Collider::convex_decomposition(&coords, &indices);
Expand Down
141 changes: 75 additions & 66 deletions examples/avian2d_colliders.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
#![allow(clippy::needless_pass_by_value)]
use avian2d::prelude::*;
use bevy::{asset::LoadState, color::palettes::css, prelude::*};
use bevy_collider_gen::{
avian2d::{generate_collider, generate_colliders},
edges::Edges,
ColliderType,
};
use bevy_collider_gen::prelude::*;
use bevy_prototype_lyon::{prelude::*, shapes};
use edges::EdgesIter;
use indoc::indoc;
use std::collections::HashMap;

Expand All @@ -30,22 +27,25 @@ fn custom_png_spawn(
return;
};
let sprite_image = image_assets.get(sprite_handle).unwrap();
let colliders = generate_colliders(sprite_image, ColliderType::ConvexPolyline, true);
let colliders = AbstractCollidersBuilder::try_from(sprite_image)
.unwrap()
.convex_polyline()
.multiple()
.into_iter()
.filter_map(AbstractCollider::to_avian);

commands.spawn(Sprite {
image: sprite_handle.clone(),
..default()
});

for collider in colliders {
commands.spawn((
collider.unwrap(),
RigidBody::Static,
SpriteBundle {
texture: sprite_handle.clone(),
..default()
},
DebugRender::default().with_collider_color(css::VIOLET.into()),
));
commands.spawn((collider, RigidBody::Static));
}
}

#[derive(Component)]
#[require(RigidBody, Transform(|| INITIAL_POSITION))]
pub struct Car;

/// Car: `convex_polyline` collider
Expand All @@ -59,16 +59,20 @@ fn car_spawn(
return;
};
let sprite_image = image_assets.get(sprite_handle).unwrap();
let collider = generate_collider(sprite_image, ColliderType::ConvexPolyline, true).unwrap();
let collider = AbstractCollidersBuilder::try_from(sprite_image)
.unwrap()
.convex_polyline()
.single()
.and_then(AbstractCollider::to_avian)
.unwrap();

commands.spawn((
Car,
collider,
RigidBody::Dynamic,
SpriteBundle {
texture: sprite_handle.clone(),
transform: INITIAL_POSITION,
Sprite {
image: sprite_handle.clone(),
..default()
},
Car,
DebugRender::default().with_collider_color(css::VIOLET.into()),
));
}
Expand All @@ -84,13 +88,18 @@ fn terrain_spawn(
return;
};
let sprite_image = image_assets.get(sprite_handle).unwrap();
let collider = generate_collider(sprite_image, ColliderType::Heightfield, true).unwrap();
let collider = AbstractCollidersBuilder::try_from(sprite_image)
.unwrap()
.heightfield()
.single()
.and_then(AbstractCollider::to_avian)
.unwrap();

commands.spawn((
collider,
RigidBody::Static,
SpriteBundle {
texture: sprite_handle.clone(),
Sprite {
image: sprite_handle.clone(),
..default()
},
DebugRender::default().with_collider_color(css::VIOLET.into()),
Expand All @@ -105,26 +114,32 @@ fn boulders_spawn(
game_assets: Res<GameAsset>,
image_assets: Res<Assets<Image>>,
) {
let sprite_handle = game_assets.image_handles.get("boulders");
if sprite_handle.is_none() {
let Some(sprite_handle) = game_assets.image_handles.get("boulders") else {
return;
}
let sprite_image = image_assets.get(sprite_handle.unwrap()).unwrap();

let edges = Edges::from(sprite_image);
let coord_group = edges.multi_image_edge_translated();
let colliders = generate_colliders(sprite_image, ColliderType::ConvexPolyline, true);
};
let sprite_image = image_assets.get(sprite_handle).unwrap();
let builder = AbstractCollidersBuilder::try_from(sprite_image)
.unwrap()
.absolute()
.convex_polyline();
let polygons = EdgesIter::new(builder.image());

for (coords, collider) in coord_group.into_iter().zip(colliders.into_iter()) {
let shape = shapes::Polygon {
points: coords,
for (polygon, collider) in polygons.zip(builder.multiple().into_iter()) {
let points = collider.points().unwrap().clone();
let pos = polygon.first().unwrap().as_vec2()
- points.first().unwrap()
- Vec2::new((sprite_image.width() / 2) as f32, -30.);
let collider = collider.to_avian().unwrap();
let path = GeometryBuilder::build_as(&shapes::Polygon {
points,
closed: true,
};
});

commands.spawn((
collider.unwrap(),
collider,
ShapeBundle {
path: GeometryBuilder::build_as(&shape),
path,
transform: Transform::from_xyz(pos.x, pos.y, 0.),
..default()
},
Fill::color(css::GRAY),
Expand Down Expand Up @@ -175,16 +190,15 @@ fn main() {
))
.init_state::<AppState>()
.insert_resource(GameAsset::default())
.insert_resource(Gravity(Vec2::NEG_Y * 500.))
.add_systems(Startup, load_assets)
.add_systems(
OnExit(AppState::Loading),
(
camera_spawn,
custom_png_spawn,
car_spawn,
terrain_spawn,
boulders_spawn,
custom_png_spawn,
controls_text_spawn,
),
)
Expand Down Expand Up @@ -243,40 +257,35 @@ pub fn controls_text_spawn(mut commands: Commands, game_assets: Res<GameAsset>)
"};

commands
.spawn(NodeBundle {
style: Style {
width: Val::Px(100.),
height: Val::Px(10.),
position_type: PositionType::Absolute,
justify_content: JustifyContent::FlexStart,
align_items: AlignItems::FlexStart,
left: Val::Px(80.),
bottom: Val::Px(600.),
..default()
},
..Default::default()
.spawn(Node {
width: Val::Px(100.),
height: Val::Px(10.),
position_type: PositionType::Absolute,
justify_content: JustifyContent::FlexStart,
align_items: AlignItems::FlexStart,
left: Val::Px(80.),
bottom: Val::Px(600.),
..default()
})
.with_children(|parent| {
parent.spawn(TextBundle {
text: Text {
sections: vec![TextSection {
value: tips_text.to_string(),
style: TextStyle {
font: game_assets.font_handle.clone(),
font_size: 20.,
color: Color::srgb(0.9, 0.9, 0.9),
},
}],
parent.spawn((
Text(tips_text.to_string()),
TextFont {
font: game_assets.font_handle.clone(),
font_size: 20.,
..Default::default()
},
TextColor(Color::srgb(0.9, 0.9, 0.9)),
TextLayout {
justify: JustifyText::Left,
..default()
..Default::default()
},
..Default::default()
});
));
});
}

pub fn camera_spawn(mut commands: Commands) {
commands.spawn(Camera2dBundle::default());
commands.spawn(Camera2d);
}

pub fn camera_movement(
Expand Down
Loading

0 comments on commit 41f6b03

Please sign in to comment.