shape_maker/src/infinite_grid.rs

87 lines
2.5 KiB
Rust

use bevy::prelude::*;
use bevy::reflect::TypeUuid;
use bevy::render::render_resource::AsBindGroup;
use bevy::sprite::{MaterialMesh2dBundle, Material2d, Mesh2dHandle};
use crate::MainCamera;
#[derive(AsBindGroup, TypeUuid, Debug, Clone)]
#[uuid = "b56a4075-b836-4866-a6f6-3e34ef3ae44f"]
pub struct GridMaterial {
#[uniform(0)]
width: f32,
#[uniform(1)]
size: Vec2,
#[uniform(2)]
visible: u32,
}
impl Material2d for GridMaterial {
fn fragment_shader() -> bevy::render::render_resource::ShaderRef {
"shaders/grid.wgsl".into()
}
}
pub fn spawn_grid(
mut coms: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut mats: ResMut<Assets<GridMaterial>>,
) {
coms.spawn().insert_bundle(MaterialMesh2dBundle {
mesh: meshes.add(Mesh::from(shape::Quad::new(Vec2::splat(100.0)))).into(),
material: mats.add(GridMaterial { width: 2.0, size: Vec2::splat(15.0), visible: 1 }),
..default()
});
}
pub fn update_grid_shader(
snap_grid: Res<crate::SnapGrid>,
handles: Query<&Handle<GridMaterial>>,
mut mats: ResMut<Assets<GridMaterial>>,
projection: Query<&OrthographicProjection, With<MainCamera>>,
) {
let zoom = projection.get_single().map(|p| p.scale).unwrap_or(1.0);
for h in handles.iter() {
if let Some(mut m) = mats.get_mut(h) {
m.size = Vec2::new(snap_grid.width, snap_grid.height);
m.visible = snap_grid.visible as u32;
m.width = zoom;
}
}
}
pub fn update_grid_position(
cam: Query<&GlobalTransform, With<MainCamera>>,
mut grid: Query<&mut Transform, With<Handle<GridMaterial>>>,
) {
let mut cam_pos = cam.get_single().map(|c| c.translation()).unwrap_or(Vec3::ZERO);
cam_pos.z = 0.0;
for mut t in grid.iter_mut() {
t.translation = cam_pos;
}
}
pub fn update_grid_size(
mut last_size: Local<Vec2>,
windows: Res<Windows>,
projection: Query<&OrthographicProjection, With<MainCamera>>,
grid: Query<&Mesh2dHandle, With<Handle<GridMaterial>>>,
mut meshes: ResMut<Assets<Mesh>>,
) {
let size = windows.get_primary().map(|w| Vec2::new(w.width(), w.height())).unwrap_or(Vec2::splat(100.0));
let zoom = projection.get_single().map(|p| p.scale).unwrap_or(1.0);
let size = size * zoom * Vec2::new(0.9, 1.0);
if size != *last_size {
for h in grid.iter() {
if let Some(m) = meshes.get_mut(&h.0) {
*m = Mesh::from(shape::Quad::new(size));
}
}
}
*last_size = size;
}