diff --git a/doc/image.png b/doc/image.png new file mode 100644 index 0000000..d77529d Binary files /dev/null and b/doc/image.png differ diff --git a/src/main.rs b/src/main.rs index 7a669e4..082ce2f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,13 @@ -#![allow(unused)] - -use bevy::{prelude::*, sprite::MaterialMesh2dBundle}; +use bevy::{ + color::palettes::tailwind, + prelude::*, + render::{ + mesh::{Indices, PrimitiveTopology}, + render_asset::RenderAssetUsages, + }, + sprite::{MaterialMesh2dBundle, Mesh2dHandle}, +}; +use std::f32::consts::FRAC_PI_2; fn main() { App::new() @@ -13,8 +20,7 @@ fn main() { struct Boid; struct BoidBundle { - outer_mesh: MaterialMesh2dBundle, - inner_mesh: MaterialMesh2dBundle, + mesh: MaterialMesh2dBundle, position: TransformBundle, velocity: Vec2, } @@ -25,4 +31,68 @@ fn setup( mut materials: ResMut>, ) { commands.spawn(Camera2dBundle::default()); + + let boid_mesh = make_boid_mesh(); + + let boid_color = Color::from(tailwind::NEUTRAL_50); + commands.spawn(MaterialMesh2dBundle { + mesh: Mesh2dHandle(meshes.add(boid_mesh)), + material: materials.add(boid_color), + transform: Transform::from_scale(Vec3::splat(2.5)), + ..default() + }); +} + +fn make_boid_mesh() -> Mesh { + const TRIANGLE_HEIGHT: f32 = 10.; + const TRIANGLE_WIDTH: f32 = 5.; + const STROKE_WIDTH: f32 = 0.25; + + const HALF_HEIGHT: f32 = TRIANGLE_HEIGHT / 2.0; + const HALF_WIDTH: f32 = TRIANGLE_WIDTH / 2.0; + + let w2 = (HALF_WIDTH * HALF_WIDTH + TRIANGLE_HEIGHT * TRIANGLE_HEIGHT).sqrt(); + let c = STROKE_WIDTH / (HALF_WIDTH / w2); + + let alpha: f32 = (TRIANGLE_HEIGHT / HALF_WIDTH).atan(); + let b: f32 = STROKE_WIDTH * (FRAC_PI_2 - (alpha / 2.)).tan(); + + let mut boid_mesh = Mesh::new( + PrimitiveTopology::TriangleList, + RenderAssetUsages::RENDER_WORLD, + ); + + #[rustfmt::skip] + let verts = vec![ + [0.0, HALF_HEIGHT - c, 0.0], + [0.0, HALF_HEIGHT, 0.0], + [ + HALF_WIDTH - b, + -HALF_HEIGHT + STROKE_WIDTH, + 0.0, + ], + [HALF_WIDTH, -HALF_HEIGHT, 0.0], + [ + -HALF_WIDTH + b, + -HALF_HEIGHT + STROKE_WIDTH, + 0.0, + ], + [-HALF_WIDTH, -HALF_HEIGHT, 0.0], + ]; + + boid_mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, verts); + + #[rustfmt::skip] + let indices = vec![ + 0, 1, 5, + 0, 2, 1, + 1, 2, 3, + 0, 5, 4, + 3, 4, 5, + 2, 4, 3 + ]; + + boid_mesh.insert_indices(Indices::U32(indices)); + + boid_mesh }