1use std::sync::Arc;
2
3use easygpu::color::Rgba;
4use easygpu::renderer::Renderer;
5use lyon_tessellation::math::Point;
6use lyon_tessellation::path::Path;
7use lyon_tessellation::{
8 FillOptions, FillTessellator, GeometryBuilderError, StrokeOptions, StrokeTessellator,
9 TessellationError, VertexId,
10};
11
12use crate::shape::{Shape, Vertex};
13
14mod lyon_builders;
15
16#[derive(Default, Debug)]
17pub struct ShapeBuilder {
19 zdepth: f32,
20 vertices: Vec<Vertex>,
21 indicies: Vec<u16>,
22
23 pub default_color: [f32; 4],
26}
27
28impl ShapeBuilder {
29 pub fn new(zdepth: f32, default_color: [f32; 4]) -> Self {
35 Self {
36 zdepth,
37 default_color,
38 ..Default::default()
39 }
40 }
41
42 pub fn prepare(&self, renderer: &Renderer) -> Shape {
47 let verticies = renderer.device.create_buffer(&self.vertices);
48 let indicies = renderer.device.create_index(&self.indicies);
49
50 Shape {
51 index_count: self.indicies.len() as u32,
52 vertices: Arc::new(verticies),
53 indices: Arc::new(indicies),
54 }
55 }
56
57 pub fn fill(&mut self, path: &Path, options: &FillOptions) -> Result<(), TessellationError> {
59 let mut tesselator = FillTessellator::new();
60 tesselator.tessellate_with_ids(path.id_iter(), path, Some(path), options, self)?;
61 Ok(())
62 }
63
64 pub fn stroke(
66 &mut self,
67 path: &Path,
68 options: &StrokeOptions,
69 ) -> Result<(), TessellationError> {
70 let mut tesselator = StrokeTessellator::new();
71 tesselator.tessellate_with_ids(path.id_iter(), path, Some(path), options, self)?;
72 Ok(())
73 }
74
75 fn new_vertex(&mut self, point: Point, attributes: &[f32]) -> Vertex {
76 let attributes = if attributes.is_empty() {
77 &self.default_color
78 } else {
79 attributes
80 };
81
82 assert!(attributes.len() == 4, "Attributes should be RGBA");
83
84 Vertex {
85 color: Rgba {
86 r: attributes[0],
87 g: attributes[1],
88 b: attributes[2],
89 a: attributes[3],
90 }
91 .into(),
92 position: [point.x, point.y, self.zdepth],
93 }
94 }
95
96 fn add_vertex(
97 &mut self,
98 point: Point,
99 attributes: &[f32],
100 ) -> Result<VertexId, GeometryBuilderError> {
101 let vertex = self.new_vertex(point, attributes);
102 let new_id = VertexId(self.vertices.len() as u32);
103 self.vertices.push(vertex);
104 if self.vertices.len() > u16::MAX as usize {
105 return Err(GeometryBuilderError::TooManyVertices);
106 }
107
108 Ok(new_id)
109 }
110}