use crate::prelude::*;
use beet_core::prelude::*;
use beet_flow::prelude::*;
use std::marker::PhantomData;
#[derive(Debug, Clone, PartialEq, Component, Reflect)]
#[reflect(Default, Component)]
#[require(ContinueRun)]
pub struct Align<M> {
pub scalar: f32,
pub radius: f32,
#[reflect(ignore)]
phantom: PhantomData<M>,
}
impl<M> Default for Align<M> {
fn default() -> Self {
Self {
scalar: 1.,
radius: 0.5,
phantom: PhantomData,
}
}
}
impl<M> Align<M> {
pub fn new(scalar: f32) -> Self {
Self {
scalar,
..default()
}
}
pub fn scaled_dist(mut self, dist: f32) -> Self {
self.radius *= dist;
self
}
}
pub(crate) fn align<M: Component>(
boids: Query<(Entity, &Transform, &Velocity), With<M>>,
mut agents: AgentQuery<(Entity, &Transform, &mut Impulse)>,
query: Query<(Entity, &Align<M>), With<Running>>,
) -> Result {
for (action, align) in query.iter() {
let (entity, transform, mut impulse) = agents.get_mut(action)?;
**impulse +=
*align_impulse(entity, transform.translation, align, boids.iter());
}
Ok(())
}