use bevy::{color::palettes::tailwind, prelude::*};
mod plugin;
pub mod rendering;
pub mod systems;
pub use plugin::*;
use rendering::*;
use systems::*;
pub mod prelude {
pub use crate::plugin::*;
pub use super::{
Grid,
SubGrid,
GridAlignment,
GridAxis,
TrackedGrid,
};
}
#[derive(Component, Clone, Debug)]
pub struct Grid {
pub spacing: f32,
pub count: usize,
pub color: Color,
pub alpha_mode: AlphaMode,
}
impl Grid {
pub const DEFAULT_SRGBA: Srgba = tailwind::GRAY_400;
pub const DEFAULT_ALPHA: f32 = 0.5_f32;
}
impl Default for Grid {
fn default() -> Self {
Self {
spacing: 0.25_f32,
count: 8,
color: Color::Srgba(Self::DEFAULT_SRGBA.with_alpha(Self::DEFAULT_ALPHA)),
alpha_mode: AlphaMode::Blend,
}
}
}
#[derive(Component)]
pub struct GridChild;
#[derive(Component, Clone, Debug)]
pub struct SubGrid {
pub count: usize,
pub color: Color,
}
impl SubGrid {
pub const DEFAULT_SRGBA: Srgba = tailwind::GRAY_500;
}
impl Default for SubGrid {
fn default() -> Self {
Self {
count: 9,
color: Color::Srgba(Self::DEFAULT_SRGBA.with_alpha(Grid::DEFAULT_ALPHA)),
}
}
}
#[derive(Component)]
pub struct SubGridChild;
#[derive(Component, Default, Debug, Copy, Clone, PartialEq, Eq)]
pub enum GridAlignment {
X,
#[default]
Y,
Z,
}
impl GridAlignment {
pub const fn to_axis_vec3(&self) -> Vec3 {
match self {
Self::X => Vec3::X,
Self::Y => Vec3::Y,
Self::Z => Vec3::Z,
}
}
pub fn to_inverted_axis_vec3(&self) -> Vec3 {
Vec3::ONE - self.to_axis_vec3()
}
pub const fn shift_vec3(&self, input: Vec3) -> Vec3 {
match self {
Self::X => Vec3::new(input.y, input.z, input.x),
Self::Y => input,
Self::Z => Vec3::new(input.z, input.x, input.y),
}
}
}
impl From<GridAlignment> for Vec3 {
fn from(val: GridAlignment) -> Self {
val.to_inverted_axis_vec3()
}
}
#[derive(Component, Clone, Debug)]
pub struct GridAxis {
pub x: Option<Color>,
pub y: Option<Color>,
pub z: Option<Color>,
}
impl GridAxis {
pub const fn new_empty() -> Self {
Self {
x: None,
y: None,
z: None,
}
}
pub const fn new_rgb() -> Self {
Self {
x: Some(Color::Srgba(tailwind::RED_500)),
y: Some(Color::Srgba(tailwind::GREEN_500)),
z: Some(Color::Srgba(tailwind::BLUE_500)),
}
}
pub fn create_single_axis(size: f32, alignment: GridAlignment) -> [Vec3; 2] {
[
alignment.shift_vec3(Vec3::new(0.0_f32, size, 0.0_f32)),
alignment.shift_vec3(Vec3::new(0.0_f32, -size, 0.0_f32)),
]
}
pub fn create_axis(&self) -> (Vec<(GridAlignment, Color)>, Vec<GridAlignment>) {
let mut axis = Vec::new();
let mut unused = Vec::new();
if let Some(color) = self.x {
axis.push((GridAlignment::X, color));
} else {
unused.push(GridAlignment::X);
}
if let Some(color) = self.y {
axis.push((GridAlignment::Y, color));
}
if let Some(color) = self.z {
axis.push((GridAlignment::Z, color));
} else {
unused.push(GridAlignment::Z);
}
(axis, unused)
}
pub const fn default_axis() -> [GridAlignment; 2] {
[GridAlignment::X, GridAlignment::Z]
}
pub const fn get_by_alignment(&self, alignment: &GridAlignment) -> Option<Color> {
match alignment {
GridAlignment::X => self.x,
GridAlignment::Y => self.y,
GridAlignment::Z => self.z,
}
}
}
impl Default for GridAxis {
fn default() -> Self {
Self::new_empty()
}
}
#[derive(Component)]
pub struct GridAxisChild;
#[derive(Component, Clone, Debug, Default)]
pub struct TrackedGrid {
pub alignment: GridAlignment,
pub offset: f32,
pub tracking_override: Option<Entity>,
}