Skip to content

Commit

Permalink
Merge pull request #7 from salam99823/main
Browse files Browse the repository at this point in the history
Update to bevy 0.15
  • Loading branch information
shnewto authored Dec 3, 2024
2 parents 693ba9a + 702d7ef commit 5a8148d
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 105 deletions.
13 changes: 9 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pedantic = { level = "warn", priority = 0 }
[features]
default = ["bevy"]
glam-latest = ["dep:glam"]
bevy = ["dep:bevy_math", "dep:bevy_render"]
bevy = ["dep:bevy_math", "dep:bevy_image"]

[dependencies]
image = "0.25"
Expand All @@ -32,19 +32,24 @@ version = "0.29"
optional = true

[dependencies.bevy_math]
version = "0.14"
version = "0.15"
default-features = false
optional = true

[dependencies.bevy_render]
version = "0.14"
[dependencies.bevy_image]
version = "0.15"
default-features = false
features = ["png"]
optional = true

[dev-dependencies]
raqote = "0.8"
open = "5.1"

[dev-dependencies.bevy_render]
version = "0.15"
default-features = false

[[example]]
name = "bevy-image"
required-features = ["bevy"]
Expand Down
19 changes: 8 additions & 11 deletions examples/bevy-image.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use bevy_render::{
prelude::Image,
render_asset::RenderAssetUsages,
texture::{CompressedImageFormats, ImageSampler, ImageType},
};
use bevy_image::{prelude::Image, CompressedImageFormats, ImageSampler, ImageType};
use bevy_render::render_asset::RenderAssetUsages;
use edges::Edges;
use raqote::{DrawOptions, DrawTarget, PathBuilder, SolidSource, Source, StrokeStyle};
// in an actual bevy app, you wouldn't need all this building an Image from scratch logic,
Expand Down Expand Up @@ -53,23 +50,23 @@ fn draw_png(image: &Image, img_path: &str) {

let scale = 8;
let (width, height) = (
i32::try_from(image.width()).expect("Image to wide.") * scale,
i32::try_from(image.height()).expect("Image to tall.") * scale,
i32::try_from(image.width() * scale).expect("Image to wide."),
i32::try_from(image.height() * scale).expect("Image to tall."),
);

// draw the edges to a png
let mut dt = DrawTarget::new(width, height);

let objects = edges.multi_image_edges_raw();
let objects = edges.multi_image_edge_raw();

for object in objects {
let mut pb = PathBuilder::new();
let mut edges_iter = object.into_iter();

if let Some(first_edge) = edges_iter.next() {
pb.move_to(first_edge.x * scale as f32, first_edge.y * scale as f32);
pb.move_to((first_edge.x * scale) as f32, (first_edge.y * scale) as f32);
for edge in edges_iter {
pb.line_to(edge.x * scale as f32, edge.y * scale as f32);
pb.line_to((edge.x * scale) as f32, (edge.y * scale) as f32);
}
}

Expand All @@ -83,7 +80,7 @@ fn draw_png(image: &Image, img_path: &str) {
a: 0xff,
}),
&StrokeStyle {
width: 1.,
width: scale as f32,
..StrokeStyle::default()
},
&DrawOptions::new(),
Expand Down
10 changes: 5 additions & 5 deletions examples/dynamic-image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ fn draw_png(img_path: &str) {

let scale = 8;
let (width, height) = (
i32::try_from(image.width()).expect("Image to wide.") * scale,
i32::try_from(image.height()).expect("Image to tall.") * scale,
i32::try_from(image.width() * scale).expect("Image to wide."),
i32::try_from(image.height() * scale).expect("Image to tall."),
);

// draw the edges to a png
Expand All @@ -25,9 +25,9 @@ fn draw_png(img_path: &str) {

let mut edges_iter = edges.single_image_edge_raw().into_iter();
let first_edge = edges_iter.next().unwrap();
pb.move_to(first_edge.x * scale as f32, first_edge.y * scale as f32);
pb.move_to((first_edge.x * scale) as f32, (first_edge.y * scale) as f32);
for edge in edges_iter {
pb.line_to(edge.x * scale as f32, edge.y * scale as f32);
pb.line_to((edge.x * scale) as f32, (edge.y * scale) as f32);
}

let path = pb.finish();
Expand All @@ -40,7 +40,7 @@ fn draw_png(img_path: &str) {
a: 0xff,
}),
&StrokeStyle {
width: 1.,
width: scale as f32,
..StrokeStyle::default()
},
&DrawOptions::new(),
Expand Down
67 changes: 38 additions & 29 deletions src/bin_image.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::fmt::Display;

use crate::{utils::is_corner, UVec2, Vec2};
use rayon::prelude::*;
pub mod neighbors {
Expand All @@ -11,6 +13,8 @@ pub mod neighbors {
pub const SOUTHWEST: u8 = 0b0000_0001;
}

/// A struct representing a binary image.
#[derive(Clone, Debug, Default)]
pub struct BinImage {
data: Vec<u8>,
height: u32,
Expand All @@ -31,7 +35,7 @@ impl BinImage {
///
/// This function will panic if the length of `data` is less than `height * width`.
pub fn new(height: u32, width: u32, data: &[u8]) -> Self {
assert!(
debug_assert!(
data.len() >= (height * width) as usize,
"data must not be smaller than image dimensions"
);
Expand Down Expand Up @@ -64,27 +68,24 @@ impl BinImage {
/// Returns `true` if the pixel is "on" (1), and `false` if it is "off" (0) or out of bounds.
pub fn get(&self, p: UVec2) -> bool {
if p.x >= self.width {
return false;
}
let index = p.y * self.width + p.x;
if let Some(mut byte) = self
.data
.get((index / 8) as usize) // index of byte
.copied()
{
byte >>= index % 8; // index of bit
byte & 1 > 0
} else {
false
} else {
let index = p.y * self.width + p.x;
if let Some(mut byte) = self
.data
.get((index / 8) as usize) // index of byte
.copied()
{
byte >>= index % 8; // index of bit
byte & 1 > 0
} else {
false
}
}
}

/// Gets the values of the neighboring pixels (8-connectivity) around the given coordinate.
///
/// # Arguments
///
/// * `p` - A `UVec2` representing the coordinates of the center pixel.
///
/// # Returns
///
/// An byte representing the state of the neighboring pixels.
Expand Down Expand Up @@ -119,35 +120,27 @@ impl BinImage {
}

pub fn is_corner(&self, p: UVec2) -> bool {
is_corner(self.get_neighbors(p))
self.get(p) && is_corner(self.get_neighbors(p))
}

/// Translates a point in positive (x, y) coordinates to a coordinate system centered at (0, 0).
///
/// # Arguments
///
/// * `p` - A `Vec2` representing the point to translate.
///
/// # Returns
///
/// A new `Vec2` representing the translated coordinates
fn translate_point(&self, p: Vec2) -> Vec2 {
const fn translate_point(&self, p: UVec2) -> Vec2 {
Vec2::new(
p.x - ((self.width / 2) as f32 - 1.0),
((self.height / 2) as f32 - 1.0) - p.y,
p.x as f32 - (self.width / 2) as f32,
(self.height / 2) as f32 - p.y as f32,
)
}

/// Translates an `Vec` of points in positive (x, y) coordinates to a coordinate system centered at (0, 0).
///
/// # Arguments
///
/// * `v` - An `Vec` of `Vec2` points to translate.
///
/// # Returns
///
/// A vector of `Vec2` representing the translated coordinates.
pub fn translate(&self, v: Vec<Vec2>) -> Vec<Vec2> {
pub fn translate(&self, v: Vec<UVec2>) -> Vec<Vec2> {
v.into_par_iter().map(|p| self.translate_point(p)).collect()
}

Expand All @@ -159,3 +152,19 @@ impl BinImage {
self.width
}
}

impl Display for BinImage {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for y in 0..self.height() {
for x in 0..self.width() {
if self.get(UVec2::new(x, y)) {
write!(f, "█")?;
} else {
write!(f, "-")?;
}
}
writeln!(f)?;
}
Ok(())
}
}
Loading

0 comments on commit 5a8148d

Please sign in to comment.