Skip to content

Commit

Permalink
[WIP] lyon 2D tessellation integration - polyline improvements
Browse files Browse the repository at this point in the history
This is a working WIP that replaces the old polyline implementation with
lyon's polyline tessellation.

The following commits will continue to replace the tessellation
approaches of all 2D shapes in favour of lyon tessellation.

Closes nannou-org#185.
Closes nannou-org#281.
Closes nannou-org#335.
  • Loading branch information
mitchmindtree committed Aug 3, 2019
1 parent 4c4cb95 commit 2e87b30
Show file tree
Hide file tree
Showing 9 changed files with 533 additions and 126 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ conrod_vulkano = "0.66"
daggy = "0.6"
find_folder = "0.3"
image = "0.21"
lyon = "0.14"
noise = "0.5"
palette = "0.4"
pennereq = "0.3"
Expand Down
4 changes: 2 additions & 2 deletions examples/simple_polyline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn view(app: &App, frame: &Frame) {

// Decide on a number of points and a thickness.
let n_points = 10;
let half_thickness = 4.0;
let thickness = 8.0;
let hz = ((app.mouse.x + win.right()) / win.w()).powi(4) * 1000.0;
let vertices = (0..n_points)
// A sine wave mapped to the range of the window.
Expand All @@ -39,7 +39,7 @@ fn view(app: &App, frame: &Frame) {
});

// Draw the polyline.
draw.polyline().vertices(half_thickness, vertices);
draw.polyline().thickness(thickness).vertices(vertices);

// Write the result of our drawing to the window's frame.
draw.to_frame(app, &frame).unwrap();
Expand Down
152 changes: 152 additions & 0 deletions src/draw/mesh/intermediary.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
use crate::draw::mesh;
use crate::geom;
use crate::mesh::vertex::{WithColor, WithTexCoords};
use lyon::tessellation::geometry_builder::{self, GeometryBuilder, GeometryBuilderError, VertexId};
use std::ops;

/// A set of intermediary buffers for collecting geometry point data for geometry types that may
/// produce a dynamic number of vertices that may or not also contain colour or texture data.
#[derive(Clone, Debug)]
pub struct IntermediaryVertexData<S = geom::scalar::Default> {
pub(crate) points: Vec<mesh::vertex::Point<S>>,
pub(crate) colors: Vec<mesh::vertex::Color>,
pub(crate) tex_coords: Vec<mesh::vertex::TexCoords<S>>,
}

/// An intermediary mesh to which drawings-in-progress may store vertex data and indices until they
/// are submitted to the **Draw**'s inner mesh.
#[derive(Clone, Debug)]
pub struct IntermediaryMesh<S = geom::scalar::Default> {
pub(crate) vertex_data: IntermediaryVertexData<S>,
pub(crate) indices: Vec<usize>,
}

/// A set of ranges into the **IntermediaryVertexData**.
///
/// This allows polygons, polylines, etc to track which slices of data are associated with their
/// own instance.
#[derive(Clone, Debug)]
pub struct IntermediaryVertexDataRanges {
pub points: ops::Range<usize>,
pub colors: ops::Range<usize>,
pub tex_coords: ops::Range<usize>,
}

/// A `lyon::GeometryBuilder` around the `IntermediaryMesh` type.
#[derive(Debug)]
pub struct IntermediaryMeshBuilder<'a, S = geom::scalar::Default> {
pub(crate) mesh: &'a mut IntermediaryMesh<S>,
pub(crate) vertex_data_ranges: IntermediaryVertexDataRanges,
pub(crate) index_range: ops::Range<usize>,
}

impl<S> IntermediaryMesh<S> {
/// Produce a lyon-compatible `GeometryBuilder` for extending the `IntermediaryMesh`.
pub fn builder(&mut self) -> IntermediaryMeshBuilder<S> {
let vertex_data_ranges = Default::default();
let index_range = 0..0;
let mut builder = IntermediaryMeshBuilder {
mesh: self,
vertex_data_ranges,
index_range,
};
builder.update_ranges_start();
builder
}
}

impl<'a, S> IntermediaryMeshBuilder<'a, S> {
fn update_ranges_start(&mut self) {
self.vertex_data_ranges.points.start = self.mesh.vertex_data.points.len();
self.vertex_data_ranges.colors.start = self.mesh.vertex_data.colors.len();
self.vertex_data_ranges.tex_coords.start = self.mesh.vertex_data.tex_coords.len();
self.index_range.start = self.mesh.indices.len();
}

fn update_ranges_end(&mut self) {
self.vertex_data_ranges.points.end = self.mesh.vertex_data.points.len();
self.vertex_data_ranges.colors.end = self.mesh.vertex_data.colors.len();
self.vertex_data_ranges.tex_coords.end = self.mesh.vertex_data.tex_coords.len();
self.index_range.end = self.mesh.indices.len();
}

pub fn vertex_data_ranges(&self) -> IntermediaryVertexDataRanges {
self.vertex_data_ranges.clone()
}

pub fn index_range(&self) -> ops::Range<usize> {
self.index_range.clone()
}
}

impl<'a, S> GeometryBuilder<mesh::Vertex<S>> for IntermediaryMeshBuilder<'a, S> {
fn begin_geometry(&mut self) {
self.update_ranges_start();
self.vertex_data_ranges.points.end = self.vertex_data_ranges.points.start;
}

fn end_geometry(&mut self) -> geometry_builder::Count {
self.update_ranges_end();
let vertices = self.vertex_data_ranges.points.len() as u32;
let indices = self.index_range.len() as u32;
geometry_builder::Count { vertices, indices }
}

fn add_vertex(&mut self, v: mesh::Vertex<S>) -> Result<VertexId, GeometryBuilderError> {
let id = self.vertex_data_ranges.points.end as u32;
if id >= std::u32::MAX {
return Err(GeometryBuilderError::TooManyVertices);
}
let WithTexCoords {
tex_coords,
vertex: WithColor {
color,
vertex: point,
},
} = v;
self.mesh.vertex_data.points.push(point);
self.mesh.vertex_data.colors.push(color);
self.mesh.vertex_data.tex_coords.push(tex_coords);
self.vertex_data_ranges.points.end += 1;
Ok(VertexId(id))
}

fn add_triangle(&mut self, a: VertexId, b: VertexId, c: VertexId) {
self.mesh.indices.push(a.to_usize());
self.mesh.indices.push(b.to_usize());
self.mesh.indices.push(c.to_usize());
}

fn abort_geometry(&mut self) {
self.update_ranges_end();
}
}

impl<S> Default for IntermediaryVertexData<S> {
fn default() -> Self {
IntermediaryVertexData {
points: Default::default(),
colors: Default::default(),
tex_coords: Default::default(),
}
}
}

impl<S> Default for IntermediaryMesh<S> {
fn default() -> Self {
IntermediaryMesh {
vertex_data: Default::default(),
indices: Default::default(),
}
}
}

impl Default for IntermediaryVertexDataRanges {
fn default() -> Self {
IntermediaryVertexDataRanges {
points: 0..0,
colors: 0..0,
tex_coords: 0..0,
}
}
}
1 change: 1 addition & 0 deletions src/draw/mesh/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::math::{BaseFloat, BaseNum};
use crate::mesh::{self, MeshPoints, WithColors, WithIndices, WithTexCoords};
use std::ops::{Deref, DerefMut};

pub mod intermediary;
pub mod vertex;

pub use self::vertex::Vertex;
Expand Down
3 changes: 2 additions & 1 deletion src/draw/mesh/vertex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ pub type Normal<S> = Vector3<S>;
pub type ColoredPoint<S> = WithColor<Point<S>, Color>;

/// The vertex type produced by the **draw::Mesh**'s inner **MeshType**.
pub type Vertex<S> = WithTexCoords<WithColor<Point<S>, Color>, TexCoords<S>>;
pub type Vertex<S = geom::scalar::Default> =
WithTexCoords<WithColor<Point<S>, Color>, TexCoords<S>>;

/// Types that can be converted directly into a **draw::mesh::Vertex**.
pub trait IntoVertex<S> {
Expand Down
60 changes: 3 additions & 57 deletions src/draw/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ use std::ops;

pub use self::background::Background;
pub use self::drawing::Drawing;
pub use self::mesh::intermediary::{
IntermediaryMesh, IntermediaryMeshBuilder, IntermediaryVertexData, IntermediaryVertexDataRanges,
};
pub use self::mesh::Mesh;
use self::properties::spatial::orientation::{self, Orientation};
use self::properties::spatial::position::{self, Position};
Expand Down Expand Up @@ -90,63 +93,6 @@ where
background_color: Option<properties::LinSrgba>,
}

/// A set of intermediary buffers for collecting geometry point data for geometry types that may
/// produce a dynamic number of vertices that may or not also contain colour or texture data.
#[derive(Clone, Debug)]
pub struct IntermediaryVertexData<S> {
pub(crate) points: Vec<mesh::vertex::Point<S>>,
pub(crate) colors: Vec<mesh::vertex::Color>,
pub(crate) tex_coords: Vec<mesh::vertex::TexCoords<S>>,
}

/// An intermediary mesh to which drawings-in-progress may store vertex data and indices until they
/// are submitted to the **Draw**'s inner mesh.
#[derive(Clone, Debug)]
pub struct IntermediaryMesh<S> {
pub(crate) vertex_data: IntermediaryVertexData<S>,
pub(crate) indices: Vec<usize>,
}

/// A set of ranges into the **IntermediaryVertexData**.
///
/// This allows polygons, polylines, etc to track which slices of data are associated with their
/// own instance.
#[derive(Clone, Debug)]
pub struct IntermediaryVertexDataRanges {
pub points: ops::Range<usize>,
pub colors: ops::Range<usize>,
pub tex_coords: ops::Range<usize>,
}

impl<S> Default for IntermediaryVertexData<S> {
fn default() -> Self {
IntermediaryVertexData {
points: Default::default(),
colors: Default::default(),
tex_coords: Default::default(),
}
}
}

impl<S> Default for IntermediaryMesh<S> {
fn default() -> Self {
IntermediaryMesh {
vertex_data: Default::default(),
indices: Default::default(),
}
}
}

impl Default for IntermediaryVertexDataRanges {
fn default() -> Self {
IntermediaryVertexDataRanges {
points: 0..0,
colors: 0..0,
tex_coords: 0..0,
}
}
}

/// The vertex and index ranges into a mesh for a particular node.
#[derive(Clone, Debug)]
struct Ranges {
Expand Down
4 changes: 2 additions & 2 deletions src/draw/properties/primitive/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl Vertexless {
/// Describe the mesh with a sequence of triangles.
///
/// Each triangle may be composed of any vertex type that may be converted directly into the
/// `draw;;mesh::vertex` type.
/// `draw::mesh::vertex` type.
pub fn tris<S, I, V>(self, mesh: &mut draw::IntermediaryMesh<S>, tris: I) -> Mesh<S>
where
S: BaseFloat,
Expand Down Expand Up @@ -75,7 +75,7 @@ impl Vertexless {
///
/// Each trio of `indices` describes a single triangle of `vertices`.
///
/// Each vertex may be any type that may be converted directly into the `draw;;mesh::vertex`
/// Each vertex may be any type that may be converted directly into the `draw::mesh::vertex`
/// type.
pub fn indexed<S, V, I>(
self,
Expand Down
Loading

0 comments on commit 2e87b30

Please sign in to comment.