Skip to content

Instantly share code, notes, and snippets.

@rparrett
Last active October 16, 2023 23:48
Show Gist options
  • Save rparrett/426b67345ee4188fa0337be89d1bc615 to your computer and use it in GitHub Desktop.
Save rparrett/426b67345ee4188fa0337be89d1bc615 to your computer and use it in GitHub Desktop.
Bevy 0.11 single 2D line segment mesh
// License: Apache-2.0 / MIT
// Note: this is not a good strategy for performance if you need a lot of these things.
// Consider using rotated sprites which Bevy is heavily optimized for, or its "line gizmos."
use bevy::{
prelude::*,
render::{mesh::Indices, render_resource::PrimitiveTopology},
sprite::MaterialMesh2dBundle,
};
pub struct LineSegment {
pub start: Vec2,
pub end: Vec2,
pub thickness: f32,
}
impl From<LineSegment> for Mesh {
fn from(segment: LineSegment) -> Self {
let LineSegment {
start,
end,
thickness,
} = segment;
let dir = (start - end).normalize();
let perp = Vec2::new(-dir.y, dir.x);
let s1 = start + perp * -thickness;
let s2 = start + perp * thickness;
let e1 = end + perp * -thickness;
let e2 = end + perp * thickness;
let vertices = [
([s1.x, s1.y, 0.0], [0.0, 0.0, 1.0], [0.0, 1.0]),
([s2.x, s2.y, 0.0], [0.0, 0.0, 1.0], [0.0, 0.0]),
([e1.x, e1.y, 0.0], [0.0, 0.0, 1.0], [1.0, 0.0]),
([e2.x, e2.y, 0.0], [0.0, 0.0, 1.0], [1.0, 1.0]),
];
let indices = Indices::U32(vec![0, 1, 2, 1, 3, 2]);
let positions: Vec<_> = vertices.iter().map(|(p, _, _)| *p).collect();
let normals: Vec<_> = vertices.iter().map(|(_, n, _)| *n).collect();
let uvs: Vec<_> = vertices.iter().map(|(_, _, uv)| *uv).collect();
let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
mesh.set_indices(Some(indices));
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, positions);
mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, normals);
mesh.insert_attribute(Mesh::ATTRIBUTE_UV_0, uvs);
mesh
}
}
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.run();
}
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
commands.spawn(Camera2dBundle::default());
commands.spawn(MaterialMesh2dBundle {
mesh: meshes
.add(Mesh::from(LineSegment {
start: Vec2::new(0., 0.),
end: Vec2::new(100., 100.),
thickness: 2.0,
}))
.into(),
material: materials.add(ColorMaterial::from(Color::PURPLE)),
..default()
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment