use lyon::{
lyon_tessellation::GeometryBuilder,
path::Path,
math::*,
tessellation::{
FillVertex,
},
};
use crate::*;
pub fn get_side(a: &Point, b: &Point, c: &Point) -> i32 {
num_traits::sign::signum((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x)) as i32
}
pub fn tesselate_line2<'a, 'l>(path: &Path, builder: &'a mut MeshBuilder<'l>, z: u32) {
GeometryBuilder::<FillVertex>::begin_geometry(builder);
let points = path.points();
let width_factor = 2f32.powi(z as i32 - 14);
let first = points[0];
let second = points[1];
let mut last_line = second.to_vector() - first.to_vector();
let normal = vector(last_line.y, -last_line.x);
let mut last_normal = if points.len() > 2 {
let third = points[2];
let next_line = third.to_vector() - second.to_vector();
let dot = normal.dot(last_line.normalize() + next_line.normalize());
if dot <= 1.0 && dot >= 0.0 {
normal
} else {
-normal
}
} else {
normal
}.normalize() * width_factor;
let (vl, vr) = {
let v1 = (first, last_normal);
let v2 = (first, -last_normal);
if get_side(&second, &first, &(first + last_normal)) == 1 {
(v1, v2)
} else {
(v2, v1)
}
};
let mut last_vertex_left = builder.add_vertex(FillVertex {
position: vl.0,
normal: vl.1,
}).unwrap();
let mut last_vertex_right = builder.add_vertex(FillVertex {
position: vr.0,
normal: vr.1,
}).unwrap();
if points.len() > 2 {
for i in 0..points.len() - 2 {
let previous = points[i];
let current = points[i + 1];
let next = points[i + 2];
let current_line = current.to_vector() - previous.to_vector();
let next_line = current.to_vector() - next.to_vector();
let normal = current_line.normalize() + next_line.normalize();
let local_normal = vector(last_line.y, -last_line.x);
let dot = local_normal.dot(last_normal);
let local_normal = if dot <= 1.0 && dot >= 0.0 {
local_normal
} else {
-local_normal
}.normalize();
let dot = local_normal.dot(normal);
let normal = if dot == 0.0 {
local_normal
} else {
normal
}.normalize() * width_factor;
let factor = (1.0 / normal.dot(local_normal).abs()).min(3.0);
let (vl, vr) = {
let v1 = (current, normal * factor);
let v2 = (current, -normal * factor);
if get_side(¤t, &previous, &(current + normal)) == 1 {
(v1, v2)
} else {
(v2, v1)
}
};
let vertex_left = builder.add_vertex(FillVertex {
position: vl.0,
normal: vl.1,
}).unwrap();
let vertex_right = builder.add_vertex(FillVertex {
position: vr.0,
normal: vr.1,
}).unwrap();
GeometryBuilder::<FillVertex>::add_triangle(
builder,
last_vertex_left,
last_vertex_right,
vertex_left
);
GeometryBuilder::<FillVertex>::add_triangle(
builder,
last_vertex_right,
vertex_right,
vertex_left
);
last_vertex_left = vertex_left;
last_vertex_right = vertex_right;
last_normal = normal;
last_line = next_line;
}
}
let last = points[points.len() - 1];
let second_last = points[points.len() - 2];
let line = last.to_vector() - second_last.to_vector();
let normal: Vector = vector(line.y, -line.x).normalize() * width_factor;
let dot = normal.dot(last_line.normalize() + line.normalize());
let normal = if dot <= 1.0 && dot >= 0.0 {
normal
} else {
-normal
};
let (vl, vr) = {
let v1 = (last, normal);
let v2 = (last, -normal);
if get_side(&last, &second_last, &(last + normal * width_factor)) == 1 {
(v1, v2)
} else {
(v2, v1)
}
};
let vertex_left = builder.add_vertex(FillVertex {
position: vl.0,
normal: vl.1,
}).unwrap();
let vertex_right = builder.add_vertex(FillVertex {
position: vr.0,
normal: vr.1,
}).unwrap();
GeometryBuilder::<FillVertex>::add_triangle(
builder,
last_vertex_left,
last_vertex_right,
vertex_left
);
GeometryBuilder::<FillVertex>::add_triangle(
builder,
last_vertex_right,
vertex_right,
vertex_left
);
GeometryBuilder::<FillVertex>::end_geometry(builder);
}