diff --git a/examples/2d_cloth_cutter.rs b/examples/2d_cloth_cutter.rs index 6d64538..d4da3af 100644 --- a/examples/2d_cloth_cutter.rs +++ b/examples/2d_cloth_cutter.rs @@ -1,4 +1,4 @@ -use bevy::{prelude::*, window::PrimaryWindow}; +use bevy::{math::Vec3Swizzles, prelude::*, window::PrimaryWindow}; use bevy_verlet::prelude::*; fn main() { @@ -20,8 +20,8 @@ fn main() { fn setup(mut commands: Commands) { commands.spawn(Camera2dBundle::default()); let stick_length: f32 = 11.; - let (origin_x, origin_y) = (-600., 420.); - let (points_x_count, points_y_count) = (121, 60); + let (origin_x, origin_y) = (-690., 420.); + let (points_x_count, points_y_count) = (139, 80); let mut entities = Vec::new(); for j in 0..points_y_count { for i in 0..points_x_count { @@ -96,12 +96,10 @@ fn cut_sticks( }; let l = 20.; for (entity, stick) in sticks.iter() { - let point_a = points.get(stick.point_a_entity).unwrap(); - let point_b = points.get(stick.point_b_entity).unwrap(); - let (a, b) = ( - Vec2::new(point_a.translation.x, point_a.translation.y), - Vec2::new(point_b.translation.x, point_b.translation.y), - ); + let [a, b] = points + .get_many(stick.entities()) + .map(|v| v.map(|t| t.translation.xy())) + .unwrap(); let distance_a = p.distance(a); let distance_b = p.distance(b); if distance_a > 0. && distance_a <= l && distance_b > 0. && distance_b <= l { diff --git a/src/components/stick.rs b/src/components/stick.rs index 8ae0607..437d5e7 100644 --- a/src/components/stick.rs +++ b/src/components/stick.rs @@ -12,3 +12,12 @@ pub struct VerletStick { /// Target stick length pub length: f32, } + +impl VerletStick { + #[inline] + #[must_use] + /// Returns [`point_a_entity`, `point_b_entity`] + pub const fn entities(&self) -> [Entity; 2] { + [self.point_a_entity, self.point_b_entity] + } +} diff --git a/src/systems/debug.rs b/src/systems/debug.rs index 41d66a0..0db7b0a 100644 --- a/src/systems/debug.rs +++ b/src/systems/debug.rs @@ -1,28 +1,6 @@ use crate::{VerletPoint, VerletStick}; -use bevy::log; use bevy::prelude::*; -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; - } - } - }; -} - -fn draw_stick( - stick: &VerletStick, - points_query: &Query<&GlobalTransform, With>, -) -> 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())) -} - #[allow(clippy::needless_pass_by_value)] pub fn debug_draw_sticks( mut gizmos: Gizmos, @@ -30,8 +8,8 @@ pub fn debug_draw_sticks( points_query: Query<&GlobalTransform, With>, ) { for stick in sticks_query.iter() { - if let Some((a, b)) = draw_stick(stick, &points_query) { - gizmos.line(a, b, Color::WHITE); + if let Ok([a, b]) = points_query.get_many(stick.entities()) { + gizmos.line(a.translation(), b.translation(), Color::WHITE); } } } diff --git a/src/systems/sticks.rs b/src/systems/sticks.rs index e55b11e..0cadb01 100644 --- a/src/systems/sticks.rs +++ b/src/systems/sticks.rs @@ -49,32 +49,20 @@ pub fn update_sticks( } } -fn handle_stick_constraint( - entity: Entity, +fn should_delete_stick( stick: &VerletStick, max_tension: f32, points_query: &Query<&Transform, With>, -) -> Option { - let point_a = match points_query.get(stick.point_a_entity) { - Ok(p) => p, +) -> bool { + let [point_a, point_b] = match points_query.get_many(stick.entities()) { + Ok(v) => v, Err(e) => { - log::error!("Could not find point_a entity for stick: {}", e); - return None; + log::error!("Could not find points entities for stick: {}", e); + return false; } }; - let point_b = match points_query.get(stick.point_b_entity) { - Ok(p) => p, - Err(e) => { - log::error!("Could not find point_b entity for stick: {}", e); - return None; - } - }; - let distance = point_a.translation.distance(point_b.translation); - if distance > stick.length * max_tension { - Some(entity) - } else { - None - } + let distance = point_a.translation.distance_squared(point_b.translation); + distance > (stick.length * max_tension).powi(2) } pub fn handle_stick_constraints( @@ -88,9 +76,7 @@ pub fn handle_stick_constraints( sticks_query .par_iter() .for_each(|(entity, stick, max_tension)| { - if let Some(entity) = - handle_stick_constraint(entity, stick, **max_tension, &points_query) - { + if should_delete_stick(stick, **max_tension, &points_query) { par_commands.command_scope(|mut cmd| { cmd.entity(entity).despawn_recursive(); }); @@ -98,9 +84,7 @@ pub fn handle_stick_constraints( }); } else { for (entity, stick, max_tension) in sticks_query.iter() { - if let Some(entity) = - handle_stick_constraint(entity, stick, **max_tension, &points_query) - { + if should_delete_stick(stick, **max_tension, &points_query) { commands.entity(entity).despawn_recursive(); } }