From 03527c23d28e2e9c6acaad2118b0266bace2dc0d Mon Sep 17 00:00:00 2001 From: shnewto Date: Sun, 3 Mar 2024 16:21:55 -0700 Subject: [PATCH] starting in on a couple examples --- Cargo.toml | 11 +- README.md | 7 +- assets/car.png | Bin 0 -> 482 bytes car-debug.ron | 810 +++++++++++++++++++++++++++++++++++++ examples/bevy-collider.rs | 23 ++ examples/parry-collider.rs | 0 src/edges.rs | 59 ++- src/error.rs | 5 +- 8 files changed, 898 insertions(+), 17 deletions(-) create mode 100644 assets/car.png create mode 100644 car-debug.ron create mode 100644 examples/bevy-collider.rs create mode 100644 examples/parry-collider.rs diff --git a/Cargo.toml b/Cargo.toml index e8d90f4..b83a795 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,9 +14,6 @@ repository = "https://github.com/shnewto/edges" license = "MIT OR Apache-2.0" - - - [features] default=[] bevy=["dep:bevy"] @@ -30,3 +27,11 @@ thiserror = "1.0.57" version = "0.13.0" optional = true +[[example]] +name = "bevy-collider" +required-features = ["bevy"] + + +[[example]] +name = "parry-collider" +required-features = [] \ No newline at end of file diff --git a/README.md b/README.md index 8674c4e..edc7fcf 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,7 @@ get the edges of objects in images with transparency ## disclaimer -this existed first as implementation over in a crate called [bevy_collider_gen](). at the time, that's what it seemed most useful for. this crate represents me starting to wonder whether it's useful for something else, but at the moment it the api is a bit of a nuisance to use. - -i'm working through how to make it less of a nuisance, and if I succeed, I'll drop in into [bevy_collider_gen](). +this existed first as implementation over in a crate called [bevy_collider_gen](). at the time, that's what it seemed most useful for. this crate represents me starting to wonder whether it's useful for something else. ## how it works @@ -23,9 +21,8 @@ after that, we need to put the coordinates in some kind of "drawing order" so wh crate collects all pixels, in order, that are a distance of 1 from eachother. if there are pixels that have a distance greater than 1 from any pixel in an existing group, that pixel begins a new group. -## todo +## maybe todo? -- examples - allow input for specifying the pixel value you want to treat as "transparency" ## license diff --git a/assets/car.png b/assets/car.png new file mode 100644 index 0000000000000000000000000000000000000000..025d7e0eb2c418036c99e03e71bd540cefb1217a GIT binary patch literal 482 zcmV<80UiE{P)Px$oJmAMR9J=Wls!wsP!xur6frFbE?vaGPzM*KRj9RKEm%-$K}67{f`a0po8SkE zIMq$iMGzfy5bWXyVnv#QAYJ+k1a)?8hParv`Dl%4r5*CXh1{Ea&-*6loC^-ELNK_h zG(*?b4AGV{&}Oz6-z=v?0X)Ta+_I<{yGM&cBMb;o&c8Qg+)&McTNZH_Mb^${>M~L? zP$`~2$!IqDr$@-0-x&@s46NXmMV2lSwoMpnKrdd4!|VY7#}n7KJE-m=Oug&_a5{El z%Y?>2t*;LyVpZSm<+lO2j6D9?gbU1zuM)HT>)9x*1CSn;l>5O~%SKGw&<Gub|d{11ZGQiIt80`t0iUWL_tXXAQoHeY)y2B;$WIQUAQlOdu zkfbbZD<67D&dUf~u(z_WJ{-7f3EA*)nJ)o*}UQkX`Zris#_q;Lvcs Y0l+$oF_Ib?7ytkO07*qoM6N<$g5P%75dZ)H literal 0 HcmV?d00001 diff --git a/car-debug.ron b/car-debug.ron new file mode 100644 index 0000000..fa86bf5 --- /dev/null +++ b/car-debug.ron @@ -0,0 +1,810 @@ +EdgesDisplay { + raw: [ + [ + Vec2( + 1.0, + 7.0, + ), + Vec2( + 1.0, + 8.0, + ), + Vec2( + 1.0, + 9.0, + ), + Vec2( + 1.0, + 10.0, + ), + Vec2( + 1.0, + 11.0, + ), + Vec2( + 1.0, + 12.0, + ), + Vec2( + 1.0, + 13.0, + ), + Vec2( + 1.0, + 14.0, + ), + Vec2( + 1.0, + 15.0, + ), + Vec2( + 1.0, + 16.0, + ), + Vec2( + 1.0, + 17.0, + ), + Vec2( + 1.0, + 18.0, + ), + Vec2( + 1.0, + 19.0, + ), + Vec2( + 2.0, + 19.0, + ), + Vec2( + 2.0, + 20.0, + ), + Vec2( + 3.0, + 20.0, + ), + Vec2( + 3.0, + 21.0, + ), + Vec2( + 4.0, + 21.0, + ), + Vec2( + 4.0, + 22.0, + ), + Vec2( + 5.0, + 22.0, + ), + Vec2( + 6.0, + 22.0, + ), + Vec2( + 7.0, + 22.0, + ), + Vec2( + 7.0, + 21.0, + ), + Vec2( + 8.0, + 21.0, + ), + Vec2( + 8.0, + 20.0, + ), + Vec2( + 9.0, + 20.0, + ), + Vec2( + 10.0, + 20.0, + ), + Vec2( + 11.0, + 20.0, + ), + Vec2( + 12.0, + 20.0, + ), + Vec2( + 13.0, + 20.0, + ), + Vec2( + 14.0, + 20.0, + ), + Vec2( + 15.0, + 20.0, + ), + Vec2( + 16.0, + 20.0, + ), + Vec2( + 17.0, + 20.0, + ), + Vec2( + 18.0, + 20.0, + ), + Vec2( + 19.0, + 20.0, + ), + Vec2( + 20.0, + 20.0, + ), + Vec2( + 21.0, + 20.0, + ), + Vec2( + 22.0, + 20.0, + ), + Vec2( + 23.0, + 20.0, + ), + Vec2( + 23.0, + 21.0, + ), + Vec2( + 24.0, + 21.0, + ), + Vec2( + 24.0, + 22.0, + ), + Vec2( + 25.0, + 22.0, + ), + Vec2( + 26.0, + 22.0, + ), + Vec2( + 27.0, + 22.0, + ), + Vec2( + 27.0, + 21.0, + ), + Vec2( + 28.0, + 21.0, + ), + Vec2( + 28.0, + 20.0, + ), + Vec2( + 28.0, + 19.0, + ), + Vec2( + 29.0, + 19.0, + ), + Vec2( + 30.0, + 19.0, + ), + Vec2( + 30.0, + 18.0, + ), + Vec2( + 30.0, + 17.0, + ), + Vec2( + 31.0, + 17.0, + ), + Vec2( + 31.0, + 16.0, + ), + Vec2( + 31.0, + 15.0, + ), + Vec2( + 31.0, + 14.0, + ), + Vec2( + 30.0, + 14.0, + ), + Vec2( + 30.0, + 13.0, + ), + Vec2( + 29.0, + 13.0, + ), + Vec2( + 28.0, + 13.0, + ), + Vec2( + 27.0, + 13.0, + ), + Vec2( + 26.0, + 13.0, + ), + Vec2( + 25.0, + 13.0, + ), + Vec2( + 24.0, + 13.0, + ), + Vec2( + 23.0, + 13.0, + ), + Vec2( + 22.0, + 13.0, + ), + Vec2( + 21.0, + 13.0, + ), + Vec2( + 21.0, + 12.0, + ), + Vec2( + 20.0, + 12.0, + ), + Vec2( + 19.0, + 12.0, + ), + Vec2( + 19.0, + 11.0, + ), + Vec2( + 18.0, + 11.0, + ), + Vec2( + 18.0, + 10.0, + ), + Vec2( + 17.0, + 10.0, + ), + Vec2( + 17.0, + 9.0, + ), + Vec2( + 16.0, + 9.0, + ), + Vec2( + 16.0, + 8.0, + ), + Vec2( + 15.0, + 8.0, + ), + Vec2( + 15.0, + 7.0, + ), + Vec2( + 14.0, + 7.0, + ), + Vec2( + 13.0, + 7.0, + ), + Vec2( + 13.0, + 6.0, + ), + Vec2( + 12.0, + 6.0, + ), + Vec2( + 11.0, + 6.0, + ), + Vec2( + 10.0, + 6.0, + ), + Vec2( + 9.0, + 6.0, + ), + Vec2( + 8.0, + 6.0, + ), + Vec2( + 7.0, + 6.0, + ), + Vec2( + 6.0, + 6.0, + ), + Vec2( + 5.0, + 6.0, + ), + Vec2( + 5.0, + 7.0, + ), + Vec2( + 4.0, + 7.0, + ), + Vec2( + 3.0, + 7.0, + ), + Vec2( + 2.0, + 7.0, + ), + Vec2( + 2.0, + 6.0, + ), + Vec2( + 2.0, + 5.0, + ), + Vec2( + 2.0, + 4.0, + ), + Vec2( + 2.0, + 3.0, + ), + ], + ], + translated: [ + [ + Vec2( + 1.0, + 7.0, + ), + Vec2( + 1.0, + 8.0, + ), + Vec2( + 1.0, + 9.0, + ), + Vec2( + 1.0, + 10.0, + ), + Vec2( + 1.0, + 11.0, + ), + Vec2( + 1.0, + 12.0, + ), + Vec2( + 1.0, + 13.0, + ), + Vec2( + 1.0, + 14.0, + ), + Vec2( + 1.0, + 15.0, + ), + Vec2( + 1.0, + 16.0, + ), + Vec2( + 1.0, + 17.0, + ), + Vec2( + 1.0, + 18.0, + ), + Vec2( + 1.0, + 19.0, + ), + Vec2( + 2.0, + 19.0, + ), + Vec2( + 2.0, + 20.0, + ), + Vec2( + 3.0, + 20.0, + ), + Vec2( + 3.0, + 21.0, + ), + Vec2( + 4.0, + 21.0, + ), + Vec2( + 4.0, + 22.0, + ), + Vec2( + 5.0, + 22.0, + ), + Vec2( + 6.0, + 22.0, + ), + Vec2( + 7.0, + 22.0, + ), + Vec2( + 7.0, + 21.0, + ), + Vec2( + 8.0, + 21.0, + ), + Vec2( + 8.0, + 20.0, + ), + Vec2( + 9.0, + 20.0, + ), + Vec2( + 10.0, + 20.0, + ), + Vec2( + 11.0, + 20.0, + ), + Vec2( + 12.0, + 20.0, + ), + Vec2( + 13.0, + 20.0, + ), + Vec2( + 14.0, + 20.0, + ), + Vec2( + 15.0, + 20.0, + ), + Vec2( + 16.0, + 20.0, + ), + Vec2( + 17.0, + 20.0, + ), + Vec2( + 18.0, + 20.0, + ), + Vec2( + 19.0, + 20.0, + ), + Vec2( + 20.0, + 20.0, + ), + Vec2( + 21.0, + 20.0, + ), + Vec2( + 22.0, + 20.0, + ), + Vec2( + 23.0, + 20.0, + ), + Vec2( + 23.0, + 21.0, + ), + Vec2( + 24.0, + 21.0, + ), + Vec2( + 24.0, + 22.0, + ), + Vec2( + 25.0, + 22.0, + ), + Vec2( + 26.0, + 22.0, + ), + Vec2( + 27.0, + 22.0, + ), + Vec2( + 27.0, + 21.0, + ), + Vec2( + 28.0, + 21.0, + ), + Vec2( + 28.0, + 20.0, + ), + Vec2( + 28.0, + 19.0, + ), + Vec2( + 29.0, + 19.0, + ), + Vec2( + 30.0, + 19.0, + ), + Vec2( + 30.0, + 18.0, + ), + Vec2( + 30.0, + 17.0, + ), + Vec2( + 31.0, + 17.0, + ), + Vec2( + 31.0, + 16.0, + ), + Vec2( + 31.0, + 15.0, + ), + Vec2( + 31.0, + 14.0, + ), + Vec2( + 30.0, + 14.0, + ), + Vec2( + 30.0, + 13.0, + ), + Vec2( + 29.0, + 13.0, + ), + Vec2( + 28.0, + 13.0, + ), + Vec2( + 27.0, + 13.0, + ), + Vec2( + 26.0, + 13.0, + ), + Vec2( + 25.0, + 13.0, + ), + Vec2( + 24.0, + 13.0, + ), + Vec2( + 23.0, + 13.0, + ), + Vec2( + 22.0, + 13.0, + ), + Vec2( + 21.0, + 13.0, + ), + Vec2( + 21.0, + 12.0, + ), + Vec2( + 20.0, + 12.0, + ), + Vec2( + 19.0, + 12.0, + ), + Vec2( + 19.0, + 11.0, + ), + Vec2( + 18.0, + 11.0, + ), + Vec2( + 18.0, + 10.0, + ), + Vec2( + 17.0, + 10.0, + ), + Vec2( + 17.0, + 9.0, + ), + Vec2( + 16.0, + 9.0, + ), + Vec2( + 16.0, + 8.0, + ), + Vec2( + 15.0, + 8.0, + ), + Vec2( + 15.0, + 7.0, + ), + Vec2( + 14.0, + 7.0, + ), + Vec2( + 13.0, + 7.0, + ), + Vec2( + 13.0, + 6.0, + ), + Vec2( + 12.0, + 6.0, + ), + Vec2( + 11.0, + 6.0, + ), + Vec2( + 10.0, + 6.0, + ), + Vec2( + 9.0, + 6.0, + ), + Vec2( + 8.0, + 6.0, + ), + Vec2( + 7.0, + 6.0, + ), + Vec2( + 6.0, + 6.0, + ), + Vec2( + 5.0, + 6.0, + ), + Vec2( + 5.0, + 7.0, + ), + Vec2( + 4.0, + 7.0, + ), + Vec2( + 3.0, + 7.0, + ), + Vec2( + 2.0, + 7.0, + ), + Vec2( + 2.0, + 6.0, + ), + Vec2( + 2.0, + 5.0, + ), + Vec2( + 2.0, + 4.0, + ), + Vec2( + 2.0, + 3.0, + ), + ], + ], +} diff --git a/examples/bevy-collider.rs b/examples/bevy-collider.rs new file mode 100644 index 0000000..5ee8688 --- /dev/null +++ b/examples/bevy-collider.rs @@ -0,0 +1,23 @@ +use bevy::render::texture::{Image, ImageType}; +use edges::Edges; + +fn main() { + // in an actual bevy app, you wouldn't need all this building an Image from scratch logic, + // it'd be something closer to this: + // `let image = image_assets.get(handle).unwrap();` + // let e = Edges::from(image); + + // read png as bytes and manually construct a bevy Image + let image = Image::from_buffer( + include_bytes!("../assets/car.png"), // buffer + ImageType::Extension("png"), + Default::default(), + true, // + Default::default(), + Default::default(), + ); + + // get the image's edges + let edges = Edges::from(image.unwrap()); + println!("{:#?}", edges); +} diff --git a/examples/parry-collider.rs b/examples/parry-collider.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/edges.rs b/src/edges.rs index 34dd639..5a144d7 100644 --- a/src/edges.rs +++ b/src/edges.rs @@ -1,5 +1,8 @@ +use std::fmt; + use glam::Vec2; +#[derive(Default)] pub struct Edges { #[cfg(feature = "bevy")] i: bevy::prelude::Image, @@ -35,9 +38,9 @@ impl Edges { /// Takes a Bevy DynamicImage type and an boolean to indicate whether to translate /// the points you get back to either side of (0, 0) instead of everything in positive x and y pub fn image_to_edges(&self, translate: bool) -> Vec> { - let rows = (self.i.height()) as usize; - let cols = (self.i.width()) as usize; - let data: &[u8] = self.i.as_bytes(); + let rows = self.height(); + let cols = self.width(); + let data: &[u8] = self.bytes(); let mut byte_combine_step: usize = 1; if (rows * cols) < data.len() { byte_combine_step = data.len() / (rows * cols); @@ -190,6 +193,33 @@ impl Edges { .map(|p| self.xy_translate(p, rows, cols)) .collect() } + + fn width(&self) -> usize { + #[cfg(feature = "bevy")] + return self.i.size().x as usize; + + #[cfg(not(feature = "bevy"))] + return self.i.width() as usize; + } + + fn height(&self) -> usize { + #[cfg(feature = "bevy")] + return self.i.size().y as usize; + + #[cfg(not(feature = "bevy"))] + return self.i.height() as usize; + } + + + fn bytes(&self) -> &[u8] { + #[cfg(feature = "bevy")] + return &self.i.data; + + #[cfg(not(feature = "bevy"))] + return self.i.as_bytes(); + } + + } #[cfg(feature = "bevy")] @@ -201,8 +231,8 @@ impl From for Edges { #[cfg(feature = "bevy")] impl From<&bevy::prelude::Image> for Edges { - fn from(i: bevy::prelude::Image) -> Edges { - Edges { i } + fn from(i: &bevy::prelude::Image) -> Edges { + Edges { i: i.clone() } } } @@ -219,3 +249,22 @@ impl From<&image::DynamicImage> for Edges { Edges { i: i.clone() } } } + + + +impl fmt::Debug for Edges { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + #[derive(Debug)] + #[allow(dead_code)] + struct EdgesDisplay { + pub raw: Vec>, + pub translated: Vec>, + } + + let edges_display = EdgesDisplay { + raw: self.image_to_edges(false), + translated: self.image_to_edges(false), + }; + write!(f, "{:#?}", edges_display) + } +} \ No newline at end of file diff --git a/src/error.rs b/src/error.rs index 20cee03..43779ae 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,5 +1,2 @@ #[derive(thiserror::Error, Debug)] -pub enum Error { - #[error("failed to convert bevy image {0:?}")] - BevyImageConversion(String), -} +pub enum Error {}