codecraft 0.1.1

A minimalist 3D game engine built on parts of Bevy (ECS, color) with wgpu and winit: OpenPBR materials, clustered lighting, an immediate-mode UI, audio and gamepad haptics
Documentation
use crate::ecs::{Component, Entity, World};
use crate::scene::SceneEntity;
use crate::ui::icons::path;
use crate::ui::{Color, Widget};
use crate::{AppState, Category, SceneObject};

/// The ground grid: an infinite plane of lines, drawn by the shader rather
/// than built as geometry, so it stays a pixel wide at any distance.
///
/// ```no_run
/// # use codecraft::{AppState, gizmos};
/// # fn demo(app: &mut AppState) {
/// app.spawn(gizmos::grid());
/// # }
/// ```
#[derive(Component, Clone, Copy, Debug)]
pub struct Grid {
    /// World units between lines. One, by default: a line to the unit.
    pub spacing: f32,
    /// How many cells to a heavy line.
    pub major_every: f32,
    /// The height the plane sits at.
    pub height: f32,
    /// Where the grid starts fading, and where it has gone entirely.
    pub fade_from: f32,
    pub fade_to: f32,
    pub line: Color,
    pub major_line: Color,
    /// The lines through the origin, which name the axes. Red across and blue
    /// into the screen, as in Blender.
    pub x_axis: Color,
    pub z_axis: Color,
}

impl SceneObject for Grid {
    fn label(&self) -> &'static str {
        "Grid"
    }

    fn icon(&self) -> &'static str {
        path::GRID_NINE
    }

    fn category(&self) -> Category {
        Category::Utilities
    }

    /// This grid's own settings, not a fresh one: a grid *is* its spacing and
    /// its fade, so there is nothing left over to place afterwards.
    fn spawn(&self, app: &mut AppState) -> Entity {
        app.spawn(*self)
    }
}

impl Default for Grid {
    fn default() -> Self {
        Self {
            spacing: 1.0,
            major_every: 10.0,
            height: 0.0,
            fade_from: 30.0,
            fade_to: 90.0,
            line: Color::srgba(0.45, 0.45, 0.50, 0.45),
            major_line: Color::srgba(0.62, 0.62, 0.68, 0.75),
            x_axis: Color::srgba(0.80, 0.25, 0.30, 0.95),
            z_axis: Color::srgba(0.25, 0.42, 0.85, 0.95),
        }
    }
}

impl Grid {
    pub fn spacing(mut self, units: f32) -> Self {
        self.spacing = units;
        self
    }

    /// The height the plane sits at.
    pub fn at_height(mut self, y: f32) -> Self {
        self.height = y;
        self
    }

    /// How far out the grid is still drawn.
    pub fn fade(mut self, from: f32, to: f32) -> Self {
        self.fade_from = from;
        self.fade_to = to;
        self
    }
}

/// A ground grid with the usual settings — one line to the unit.
pub fn grid() -> Grid {
    Grid::default()
}

impl Widget for Grid {
    type Output = Entity;

    fn spawn(self, world: &mut World, _screen_width: f32, _screen_height: f32) -> Entity {
        world.spawn((self, SceneEntity)).id()
    }
}