use bevy::render::{
mesh::{
VertexAttribute,
Mesh
},
pipeline::PrimitiveTopology,
};
use lyon::{
math::{
self,
Point
},
tessellation as tess,
};
use super::shapes::LyonShapeBuilder;
pub type BevyIndex = u32;
pub type BevyVertexBuffers = tess::VertexBuffers<BevyVertex, BevyIndex>;
pub type BevyBuffersBuilder<'a> = tess::BuffersBuilder<'a, BevyVertex, BevyIndex, BevyVertexConstructor>;
#[derive(Debug, Clone)]
pub struct LyonMeshBuilder
{
geometry: BevyVertexBuffers
}
impl LyonMeshBuilder
{
pub fn new() -> Self
{
LyonMeshBuilder {
geometry: BevyVertexBuffers::new()
}
}
pub fn build(self) -> Mesh
{
self.build_with_topology(PrimitiveTopology::TriangleStrip)
}
pub fn build_with_topology(self, topology: PrimitiveTopology) -> Mesh
{
Mesh {
primitive_topology: topology,
attributes: self.verts_to_attributes(),
indices: Some(self.geometry.indices),
}
}
pub fn with(mut self, shape: impl LyonShapeBuilder) -> Self
{
shape.build(&mut self.buffers_builder());
self
}
pub fn with_only(shape: impl LyonShapeBuilder) -> Mesh
{
LyonMeshBuilder::new()
.with(shape)
.build()
}
fn buffers_builder(&mut self) -> tess::BuffersBuilder<BevyVertex, BevyIndex, BevyVertexConstructor>
{
tess::BuffersBuilder::new(&mut self.geometry, BevyVertexConstructor)
}
fn verts_to_attributes(&self) -> Vec<VertexAttribute>
{
let mut positions = vec![];
let mut normals = vec![];
let mut uvs = vec![];
for vertex in &self.geometry.vertices
{
positions.push(vertex.pos);
normals.push(vertex.norm);
uvs.push(vertex.uv);
}
vec![
VertexAttribute::position(positions),
VertexAttribute::normal(normals),
VertexAttribute::uv(uvs),
]
}
}
pub struct BevyVertexConstructor;
impl tess::BasicVertexConstructor<BevyVertex> for BevyVertexConstructor
{
fn new_vertex(&mut self, point: Point) -> BevyVertex
{
point.into()
}
}
impl tess::FillVertexConstructor<BevyVertex> for BevyVertexConstructor
{
fn new_vertex(&mut self, point: Point, _: tess::FillAttributes) -> BevyVertex
{
point.into()
}
}
impl tess::StrokeVertexConstructor<BevyVertex> for BevyVertexConstructor
{
fn new_vertex(&mut self, point: Point, _: tess::StrokeAttributes) -> BevyVertex
{
point.into()
}
}
#[derive(Debug, Clone)]
pub struct BevyVertex
{
pub pos: [f32; 3],
pub norm: [f32; 3],
pub uv: [f32; 2],
}
impl From<math::Point> for BevyVertex
{
fn from(point: math::Point) -> Self
{
BevyVertex {
pos: [point.x, point.y, 0.0],
norm: [0.0, 0.0, 1.0],
uv: [point.x, point.y],
}
}
}