use crate::draw;
use crate::geom::Point2;
use crate::glam::Mat4;
use lyon::tessellation::geometry_builder::{
self, FillGeometryBuilder, GeometryBuilder, StrokeGeometryBuilder,
};
use lyon::tessellation::{FillVertex, GeometryBuilderError, StrokeVertex, VertexId};
pub struct MeshBuilder<'a, A> {
mesh: &'a mut draw::Mesh,
begin_vertex_count: u32,
begin_index_count: u32,
transform: Mat4,
attributes: A,
}
pub struct SingleColor(draw::mesh::vertex::Color);
pub struct ColorPerPoint;
pub struct TexCoordsPerPoint;
impl<'a, A> MeshBuilder<'a, A> {
fn new(mesh: &'a mut draw::Mesh, transform: Mat4, attributes: A) -> Self {
MeshBuilder {
mesh,
begin_vertex_count: 0,
begin_index_count: 0,
transform,
attributes,
}
}
}
impl<'a> MeshBuilder<'a, SingleColor> {
pub fn single_color(
mesh: &'a mut draw::Mesh,
transform: Mat4,
color: draw::mesh::vertex::Color,
) -> Self {
Self::new(mesh, transform, SingleColor(color))
}
}
impl<'a> MeshBuilder<'a, ColorPerPoint> {
pub fn color_per_point(mesh: &'a mut draw::Mesh, transform: Mat4) -> Self {
Self::new(mesh, transform, ColorPerPoint)
}
}
impl<'a> MeshBuilder<'a, TexCoordsPerPoint> {
pub fn tex_coords_per_point(mesh: &'a mut draw::Mesh, transform: Mat4) -> Self {
Self::new(mesh, transform, TexCoordsPerPoint)
}
}
impl<'a, A> GeometryBuilder for MeshBuilder<'a, A> {
fn begin_geometry(&mut self) {
self.begin_vertex_count = self.mesh.points().len() as u32;
self.begin_index_count = self.mesh.indices().len() as u32;
}
fn end_geometry(&mut self) -> geometry_builder::Count {
geometry_builder::Count {
vertices: self.mesh.points().len() as u32 - self.begin_vertex_count,
indices: self.mesh.indices().len() as u32 - self.begin_index_count,
}
}
fn add_triangle(&mut self, a: VertexId, b: VertexId, c: VertexId) {
self.mesh.push_index(a.to_usize() as u32);
self.mesh.push_index(b.to_usize() as u32);
self.mesh.push_index(c.to_usize() as u32);
}
fn abort_geometry(&mut self) {
unimplemented!();
}
}
impl<'a> FillGeometryBuilder for MeshBuilder<'a, SingleColor> {
fn add_fill_vertex(&mut self, vertex: FillVertex) -> Result<VertexId, GeometryBuilderError> {
let id = VertexId::from_usize(self.mesh.points().len());
let position = vertex.position();
let p = Point2::new(position.x, position.y).extend(0.0);
let point = self.transform.transform_point3(p);
let SingleColor(color) = self.attributes;
let tex_coords = draw::mesh::vertex::default_tex_coords();
let vertex = draw::mesh::vertex::new(point, color, tex_coords);
self.mesh.push_vertex(vertex);
Ok(id)
}
}
impl<'a> StrokeGeometryBuilder for MeshBuilder<'a, SingleColor> {
fn add_stroke_vertex(
&mut self,
vertex: StrokeVertex,
) -> Result<VertexId, GeometryBuilderError> {
let id = VertexId::from_usize(self.mesh.points().len());
let position = vertex.position();
let p = Point2::new(position.x, position.y).extend(0.0);
let point = self.transform.transform_point3(p);
let SingleColor(color) = self.attributes;
let tex_coords = draw::mesh::vertex::default_tex_coords();
let vertex = draw::mesh::vertex::new(point, color, tex_coords);
self.mesh.push_vertex(vertex);
Ok(id)
}
}
impl<'a> FillGeometryBuilder for MeshBuilder<'a, ColorPerPoint> {
fn add_fill_vertex(
&mut self,
mut vertex: FillVertex,
) -> Result<VertexId, GeometryBuilderError> {
let id = VertexId::from_usize(self.mesh.points().len());
let position = vertex.position();
let p = Point2::new(position.x, position.y).extend(0.0);
let point = self.transform.transform_point3(p);
let col = vertex.interpolated_attributes();
let color: draw::mesh::vertex::Color = (col[0], col[1], col[2], col[3]).into();
let tex_coords = draw::mesh::vertex::default_tex_coords();
let vertex = draw::mesh::vertex::new(point, color, tex_coords);
self.mesh.push_vertex(vertex);
Ok(id)
}
}
impl<'a> StrokeGeometryBuilder for MeshBuilder<'a, ColorPerPoint> {
fn add_stroke_vertex(
&mut self,
mut vertex: StrokeVertex,
) -> Result<VertexId, GeometryBuilderError> {
let id = VertexId::from_usize(self.mesh.points().len());
let position = vertex.position();
let p = Point2::new(position.x, position.y).extend(0.0);
let point = self.transform.transform_point3(p);
let col = vertex.interpolated_attributes();
let color: draw::mesh::vertex::Color = (col[0], col[1], col[2], col[3]).into();
let tex_coords = draw::mesh::vertex::default_tex_coords();
let vertex = draw::mesh::vertex::new(point, color, tex_coords);
self.mesh.push_vertex(vertex);
Ok(id)
}
}
impl<'a> FillGeometryBuilder for MeshBuilder<'a, TexCoordsPerPoint> {
fn add_fill_vertex(
&mut self,
mut vertex: FillVertex,
) -> Result<VertexId, GeometryBuilderError> {
let id = VertexId::from_usize(self.mesh.points().len());
let position = vertex.position();
let p = Point2::new(position.x, position.y).extend(0.0);
let point = self.transform.transform_point3(p);
let tc = vertex.interpolated_attributes();
let tex_coords: draw::mesh::vertex::TexCoords = (tc[0], tc[1]).into();
let color = draw::mesh::vertex::DEFAULT_VERTEX_COLOR;
let vertex = draw::mesh::vertex::new(point, color, tex_coords);
self.mesh.push_vertex(vertex);
Ok(id)
}
}
impl<'a> StrokeGeometryBuilder for MeshBuilder<'a, TexCoordsPerPoint> {
fn add_stroke_vertex(
&mut self,
mut vertex: StrokeVertex,
) -> Result<VertexId, GeometryBuilderError> {
let id = VertexId::from_usize(self.mesh.points().len());
let position = vertex.position();
let p = Point2::new(position.x, position.y).extend(0.0);
let point = self.transform.transform_point3(p);
let tc = vertex.interpolated_attributes();
let tex_coords: draw::mesh::vertex::TexCoords = (tc[0], tc[1]).into();
let color = draw::mesh::vertex::DEFAULT_VERTEX_COLOR;
let vertex = draw::mesh::vertex::new(point, color, tex_coords);
self.mesh.push_vertex(vertex);
Ok(id)
}
}