Split out B-vertex positions and info so that they're easier to pack into textures
This commit is contained in:
parent
fa1b2390c7
commit
57ebbf8281
|
@ -14,11 +14,13 @@ class PathfinderMeshes {
|
|||
if (!('Ok' in response))
|
||||
throw new Error("Failed to partition the font!");
|
||||
const meshes = response.Ok;
|
||||
this.bQuads = base64js.toByteArray(meshes.bQuads);
|
||||
this.bQuadPositions = base64js.toByteArray(meshes.bQuadPositions);
|
||||
this.bQuadInfo = base64js.toByteArray(meshes.bQuadInfo);
|
||||
this.bVertices = base64js.toByteArray(meshes.bVertices);
|
||||
}
|
||||
|
||||
bQuads: ArrayBuffer;
|
||||
bQuadPositions: ArrayBuffer;
|
||||
bQuadInfo: ArrayBuffer;
|
||||
bVertices: ArrayBuffer;
|
||||
}
|
||||
|
||||
|
|
|
@ -121,8 +121,10 @@ struct PartitionFontResponse {
|
|||
glyphInfo: Vec<PartitionGlyphInfo>,
|
||||
// Base64-encoded `bincode`-encoded `BQuad`s.
|
||||
bQuads: String,
|
||||
// Base64-encoded `bincode`-encoded `BVertex`es.
|
||||
bVertices: String,
|
||||
// Base64-encoded `bincode`-encoded `Point2D<f32>`s.
|
||||
bVertexPositions: String,
|
||||
// Base64-encoded `bincode`-encoded `BVertexInfo`s.
|
||||
bVertexInfo: String,
|
||||
coverInteriorIndices: Vec<u32>,
|
||||
coverCurveIndices: Vec<u32>,
|
||||
// Base64-encoded `bincode`-encoded `LineIndices` instances.
|
||||
|
@ -195,7 +197,7 @@ fn partition_font(request: Json<PartitionFontRequest>)
|
|||
|
||||
// Partition the decoded glyph outlines.
|
||||
let mut partitioner = Partitioner::new();
|
||||
let (mut b_quads, mut b_vertices) = (vec![], vec![]);
|
||||
let (mut b_quads, mut b_vertex_positions, mut b_vertex_info) = (vec![], vec![], vec![]);
|
||||
let (mut cover_interior_indices, mut cover_curve_indices) = (vec![], vec![]);
|
||||
let (mut edge_upper_line_indices, mut edge_upper_curve_indices) = (vec![], vec![]);
|
||||
let (mut edge_lower_line_indices, mut edge_lower_curve_indices) = (vec![], vec![]);
|
||||
|
@ -228,18 +230,23 @@ fn partition_font(request: Json<PartitionFontRequest>)
|
|||
decoded_outline_indices.subpath_indices.start as u32,
|
||||
decoded_outline_indices.subpath_indices.end as u32);
|
||||
|
||||
let (path_b_quads, path_b_vertices) = (partitioner.b_quads(), partitioner.b_vertices());
|
||||
let path_b_quads = partitioner.b_quads();
|
||||
let path_b_vertex_positions = partitioner.b_vertex_positions();
|
||||
let path_b_vertex_info = partitioner.b_vertex_info();
|
||||
let cover_indices = partitioner.cover_indices();
|
||||
let edge_indices = partitioner.edge_indices();
|
||||
|
||||
IndexRange::from_vector_append_and_serialization(&mut b_vertex_positions,
|
||||
path_b_vertex_positions).unwrap();
|
||||
|
||||
glyph_info.push(PartitionGlyphInfo {
|
||||
id: glyph_id,
|
||||
dimensions: dimensions,
|
||||
bQuadIndices: IndexRange::from_vector_append_and_serialization(&mut b_quads,
|
||||
path_b_quads).unwrap(),
|
||||
bVertexIndices:
|
||||
IndexRange::from_vector_append_and_serialization(&mut b_vertices,
|
||||
path_b_vertices).unwrap(),
|
||||
IndexRange::from_vector_append_and_serialization(&mut b_vertex_info,
|
||||
path_b_vertex_info).unwrap(),
|
||||
coverInteriorIndices:
|
||||
IndexRange::from_vector_append_operation(&mut cover_interior_indices,
|
||||
cover_indices.interior_indices),
|
||||
|
@ -265,7 +272,8 @@ fn partition_font(request: Json<PartitionFontRequest>)
|
|||
Json(Ok(PartitionFontResponse {
|
||||
glyphInfo: glyph_info,
|
||||
bQuads: base64::encode(&b_quads),
|
||||
bVertices: base64::encode(&b_vertices),
|
||||
bVertexPositions: base64::encode(&b_vertex_positions),
|
||||
bVertexInfo: base64::encode(&b_vertex_info),
|
||||
coverInteriorIndices: cover_interior_indices,
|
||||
coverCurveIndices: cover_curve_indices,
|
||||
edgeUpperLineIndices: base64::encode(&edge_upper_line_indices),
|
||||
|
|
|
@ -6,7 +6,7 @@ use legalizer::Legalizer;
|
|||
use partitioner::Partitioner;
|
||||
use std::mem;
|
||||
use std::slice;
|
||||
use {BQuad, BVertex, CurveIndices, Endpoint, LineIndices, Subpath};
|
||||
use {BQuad, BVertexInfo, CurveIndices, Endpoint, LineIndices, Subpath};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
|
@ -184,15 +184,25 @@ pub unsafe extern fn pf_partitioner_b_quads<'a>(partitioner: *const Partitioner<
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn pf_partitioner_b_vertices<'a>(partitioner: *const Partitioner<'a>,
|
||||
out_b_vertex_count: *mut u32)
|
||||
-> *const BVertex {
|
||||
// FIXME(pcwalton): This is unsafe! `Point2D<f32>` and `Point2DF32` may have different layouts!
|
||||
let b_vertices = (*partitioner).b_vertices();
|
||||
pub unsafe extern fn pf_partitioner_b_vertex_positions<'a>(partitioner: *const Partitioner<'a>,
|
||||
out_b_vertex_count: *mut u32)
|
||||
-> *const Point2D<f32> {
|
||||
let b_vertex_positions = (*partitioner).b_vertex_positions();
|
||||
if !out_b_vertex_count.is_null() {
|
||||
*out_b_vertex_count = b_vertices.len() as u32
|
||||
*out_b_vertex_count = b_vertex_positions.len() as u32
|
||||
}
|
||||
b_vertices.as_ptr() as *const BVertex
|
||||
b_vertex_positions.as_ptr() as *const Point2D<f32>
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn pf_partitioner_b_vertex_info<'a>(partitioner: *const Partitioner<'a>,
|
||||
out_b_vertex_count: *mut u32)
|
||||
-> *const BVertexInfo {
|
||||
let b_vertex_info = (*partitioner).b_vertex_info();
|
||||
if !out_b_vertex_count.is_null() {
|
||||
*out_b_vertex_count = b_vertex_info.len() as u32
|
||||
}
|
||||
b_vertex_info.as_ptr() as *const BVertexInfo
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
|
|
@ -91,24 +91,22 @@ pub enum BVertexKind {
|
|||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||
#[repr(C)]
|
||||
pub struct BVertex {
|
||||
pub position: Point2D<f32>,
|
||||
pub struct BVertexInfo {
|
||||
pub path_id: u32,
|
||||
pub tex_coord: [u8; 2],
|
||||
pub kind: BVertexKind,
|
||||
pad: u8,
|
||||
}
|
||||
|
||||
impl BVertex {
|
||||
impl BVertexInfo {
|
||||
#[inline]
|
||||
pub fn new(position: &Point2D<f32>, kind: BVertexKind, path_id: u32) -> BVertex {
|
||||
pub fn new(kind: BVertexKind, path_id: u32) -> BVertexInfo {
|
||||
let tex_coord = match kind {
|
||||
BVertexKind::Endpoint0 => [0, 0],
|
||||
BVertexKind::Endpoint1 => [2, 2],
|
||||
BVertexKind::ConcaveControlPoint | BVertexKind::ConvexControlPoint => [1, 0],
|
||||
};
|
||||
BVertex {
|
||||
position: *position,
|
||||
BVertexInfo {
|
||||
path_id: path_id,
|
||||
tex_coord: tex_coord,
|
||||
kind: kind,
|
||||
|
@ -121,7 +119,7 @@ impl BVertex {
|
|||
right_endpoint_position: &Point2D<f32>,
|
||||
path_id: u32,
|
||||
bottom: bool)
|
||||
-> BVertex {
|
||||
-> BVertexInfo {
|
||||
let control_point_vector = *control_point_position - *left_endpoint_position;
|
||||
let right_vector = *right_endpoint_position - *left_endpoint_position;
|
||||
let determinant = right_vector.cross(control_point_vector);
|
||||
|
@ -130,7 +128,7 @@ impl BVertex {
|
|||
} else {
|
||||
BVertexKind::ConcaveControlPoint
|
||||
};
|
||||
BVertex::new(control_point_position, endpoint_kind, path_id)
|
||||
BVertexInfo::new(endpoint_kind, path_id)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,15 +37,14 @@ struct pf_matrix2d_f32 {
|
|||
|
||||
typedef struct pf_matrix2d_f32 pf_matrix2d_f32_t;
|
||||
|
||||
struct pf_b_vertex {
|
||||
pf_point2d_f32_t position;
|
||||
struct pf_b_vertex_info {
|
||||
uint32_t path_id;
|
||||
uint8_t tex_coord[2];
|
||||
pf_b_vertex_kind_t kind;
|
||||
uint8_t pad;
|
||||
};
|
||||
|
||||
typedef struct pf_b_vertex pf_b_vertex_t;
|
||||
typedef struct pf_b_vertex_info pf_b_vertex_info_t;
|
||||
|
||||
struct pf_cover_indices {
|
||||
const uint32_t *interior_indices;
|
||||
|
@ -169,8 +168,11 @@ void pf_partitioner_partition(pf_partitioner_t *partitioner,
|
|||
const pf_b_quad_t *pf_partitioner_b_quads(const pf_partitioner_t *partitioner,
|
||||
uint32_t *out_b_quad_count);
|
||||
|
||||
const pf_b_vertex_t *pf_partitioner_b_vertices(const pf_partitioner_t *partitioner,
|
||||
uint32_t *out_b_vertex_count);
|
||||
const pf_point2d_f32_t *pf_partitioner_b_vertex_positions(const pf_partitioner_t *partitioner,
|
||||
uint32_t *out_b_vertex_count);
|
||||
|
||||
const pf_b_vertex_info_t *pf_partitioner_b_vertex_info(const pf_partitioner_t *partitioner,
|
||||
uint32_t *out_b_vertex_count);
|
||||
|
||||
const void pf_partitioner_cover_indices(const pf_partitioner_t *partitioner,
|
||||
pf_cover_indices_t *out_cover_indices);
|
||||
|
|
|
@ -8,7 +8,7 @@ use std::collections::BinaryHeap;
|
|||
use std::cmp::Ordering;
|
||||
use std::f32;
|
||||
use std::u32;
|
||||
use {BQuad, BVertex, BVertexKind, CurveIndices, Endpoint, LineIndices, Subpath};
|
||||
use {BQuad, BVertexInfo, BVertexKind, CurveIndices, Endpoint, LineIndices, Subpath};
|
||||
|
||||
pub struct Partitioner<'a> {
|
||||
endpoints: &'a [Endpoint],
|
||||
|
@ -16,7 +16,8 @@ pub struct Partitioner<'a> {
|
|||
subpaths: &'a [Subpath],
|
||||
|
||||
b_quads: Vec<BQuad>,
|
||||
b_vertices: Vec<BVertex>,
|
||||
b_vertex_positions: Vec<Point2D<f32>>,
|
||||
b_vertex_info: Vec<BVertexInfo>,
|
||||
cover_indices: CoverIndicesBuffer,
|
||||
edge_indices: EdgeIndicesBuffer,
|
||||
|
||||
|
@ -35,7 +36,8 @@ impl<'a> Partitioner<'a> {
|
|||
subpaths: &[],
|
||||
|
||||
b_quads: vec![],
|
||||
b_vertices: vec![],
|
||||
b_vertex_positions: vec![],
|
||||
b_vertex_info: vec![],
|
||||
cover_indices: CoverIndicesBuffer::new(),
|
||||
edge_indices: EdgeIndicesBuffer::new(),
|
||||
|
||||
|
@ -61,7 +63,8 @@ impl<'a> Partitioner<'a> {
|
|||
|
||||
pub fn partition(&mut self, path_id: u32, first_subpath_index: u32, last_subpath_index: u32) {
|
||||
self.b_quads.clear();
|
||||
self.b_vertices.clear();
|
||||
self.b_vertex_info.clear();
|
||||
self.b_vertex_positions.clear();
|
||||
self.cover_indices.clear();
|
||||
self.edge_indices.clear();
|
||||
self.heap.clear();
|
||||
|
@ -80,8 +83,13 @@ impl<'a> Partitioner<'a> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn b_vertices(&self) -> &[BVertex] {
|
||||
&self.b_vertices
|
||||
pub fn b_vertex_positions(&self) -> &[Point2D<f32>] {
|
||||
&self.b_vertex_positions
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn b_vertex_info(&self) -> &[BVertexInfo] {
|
||||
&self.b_vertex_info
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -172,13 +180,13 @@ impl<'a> Partitioner<'a> {
|
|||
|
||||
{
|
||||
let active_edge = &mut self.active_edges[active_edge_index as usize];
|
||||
active_edge.left_vertex_index = self.b_vertices.len() as u32;
|
||||
active_edge.left_vertex_index = self.b_vertex_info.len() as u32;
|
||||
active_edge.control_point_vertex_index = active_edge.left_vertex_index + 1;
|
||||
|
||||
let endpoint_position = self.endpoints[active_edge.right_endpoint_index as usize]
|
||||
.position;
|
||||
self.b_vertices
|
||||
.push(BVertex::new(&endpoint_position, active_edge.endpoint_kind(), self.path_id));
|
||||
self.b_vertex_positions.push(endpoint_position);
|
||||
self.b_vertex_info.push(BVertexInfo::new(active_edge.endpoint_kind(), self.path_id));
|
||||
|
||||
active_edge.toggle_parity();
|
||||
|
||||
|
@ -206,18 +214,19 @@ impl<'a> Partitioner<'a> {
|
|||
}
|
||||
control_point_index => {
|
||||
self.active_edges[active_edge_index as usize].control_point_vertex_index =
|
||||
self.b_vertices.len() as u32;
|
||||
self.b_vertex_info.len() as u32;
|
||||
|
||||
let left_vertex_index = self.active_edges[active_edge_index as usize]
|
||||
.left_vertex_index;
|
||||
let control_point_position = &self.control_points[control_point_index as usize];
|
||||
let control_point_b_vertex =
|
||||
BVertex::control_point(&self.b_vertices[left_vertex_index as usize].position,
|
||||
&control_point_position,
|
||||
&new_point.position,
|
||||
self.path_id,
|
||||
bottom);
|
||||
self.b_vertices.push(control_point_b_vertex)
|
||||
let control_point_b_vertex_info = BVertexInfo::control_point(
|
||||
&self.b_vertex_positions[left_vertex_index as usize],
|
||||
&control_point_position,
|
||||
&new_point.position,
|
||||
self.path_id,
|
||||
bottom);
|
||||
self.b_vertex_positions.push(*control_point_position);
|
||||
self.b_vertex_info.push(control_point_b_vertex_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -271,12 +280,13 @@ impl<'a> Partitioner<'a> {
|
|||
let new_active_edges = &mut self.active_edges[next_active_edge_index as usize..
|
||||
next_active_edge_index as usize + 2];
|
||||
|
||||
let left_vertex_index = self.b_vertices.len() as u32;
|
||||
let left_vertex_index = self.b_vertex_info.len() as u32;
|
||||
new_active_edges[0].left_vertex_index = left_vertex_index;
|
||||
new_active_edges[1].left_vertex_index = left_vertex_index;
|
||||
|
||||
let position = self.endpoints[endpoint_index as usize].position;
|
||||
self.b_vertices.push(BVertex::new(&position, BVertexKind::Endpoint0, self.path_id));
|
||||
self.b_vertex_positions.push(position);
|
||||
self.b_vertex_info.push(BVertexInfo::new(BVertexKind::Endpoint0, self.path_id));
|
||||
|
||||
new_active_edges[0].toggle_parity();
|
||||
new_active_edges[1].toggle_parity();
|
||||
|
@ -312,36 +322,40 @@ impl<'a> Partitioner<'a> {
|
|||
match upper_control_point_index {
|
||||
u32::MAX => new_active_edges[0].control_point_vertex_index = u32::MAX,
|
||||
upper_control_point_index => {
|
||||
new_active_edges[0].control_point_vertex_index = self.b_vertices.len() as u32;
|
||||
new_active_edges[0].control_point_vertex_index = self.b_vertex_info.len() as u32;
|
||||
|
||||
let control_point_position =
|
||||
self.control_points[upper_control_point_index as usize];
|
||||
let right_vertex_position =
|
||||
self.endpoints[new_active_edges[0].right_endpoint_index as usize].position;
|
||||
let control_point_b_vertex = BVertex::control_point(&position,
|
||||
&control_point_position,
|
||||
&right_vertex_position,
|
||||
self.path_id,
|
||||
false);
|
||||
self.b_vertices.push(control_point_b_vertex)
|
||||
let control_point_b_vertex_info =
|
||||
BVertexInfo::control_point(&position,
|
||||
&control_point_position,
|
||||
&right_vertex_position,
|
||||
self.path_id,
|
||||
false);
|
||||
self.b_vertex_positions.push(control_point_position);
|
||||
self.b_vertex_info.push(control_point_b_vertex_info);
|
||||
}
|
||||
}
|
||||
|
||||
match lower_control_point_index {
|
||||
u32::MAX => new_active_edges[1].control_point_vertex_index = u32::MAX,
|
||||
lower_control_point_index => {
|
||||
new_active_edges[1].control_point_vertex_index = self.b_vertices.len() as u32;
|
||||
new_active_edges[1].control_point_vertex_index = self.b_vertex_info.len() as u32;
|
||||
|
||||
let control_point_position =
|
||||
self.control_points[lower_control_point_index as usize];
|
||||
let right_vertex_position =
|
||||
self.endpoints[new_active_edges[1].right_endpoint_index as usize].position;
|
||||
let control_point_b_vertex = BVertex::control_point(&position,
|
||||
&control_point_position,
|
||||
&right_vertex_position,
|
||||
self.path_id,
|
||||
true);
|
||||
self.b_vertices.push(control_point_b_vertex)
|
||||
let control_point_b_vertex_info =
|
||||
BVertexInfo::control_point(&position,
|
||||
&control_point_position,
|
||||
&right_vertex_position,
|
||||
self.path_id,
|
||||
true);
|
||||
self.b_vertex_positions.push(control_point_position);
|
||||
self.b_vertex_info.push(control_point_b_vertex_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -419,8 +433,8 @@ impl<'a> Partitioner<'a> {
|
|||
|
||||
// NB: Order is important here—we depend on the provoking vertex!
|
||||
|
||||
let upper_shape = upper_curve.shape(&self.b_vertices);
|
||||
let lower_shape = lower_curve.shape(&self.b_vertices);
|
||||
let upper_shape = upper_curve.shape(&self.b_vertex_info);
|
||||
let lower_shape = lower_curve.shape(&self.b_vertex_info);
|
||||
|
||||
match upper_shape {
|
||||
Shape::Flat => {
|
||||
|
@ -627,8 +641,8 @@ impl<'a> Partitioner<'a> {
|
|||
}
|
||||
|
||||
fn solve_active_edge_t_for_x(&self, x: f32, active_edge: &ActiveEdge) -> f32 {
|
||||
let left_vertex_position = &self.b_vertices[active_edge.left_vertex_index as usize]
|
||||
.position;
|
||||
let left_vertex_position = &self.b_vertex_positions[active_edge.left_vertex_index as
|
||||
usize];
|
||||
let right_endpoint_position = &self.endpoints[active_edge.right_endpoint_index as usize]
|
||||
.position;
|
||||
match active_edge.control_point_vertex_index {
|
||||
|
@ -636,7 +650,7 @@ impl<'a> Partitioner<'a> {
|
|||
geometry::solve_line_t_for_x(x, left_vertex_position, right_endpoint_position)
|
||||
}
|
||||
control_point_vertex_index => {
|
||||
let control_point = &self.b_vertices[control_point_vertex_index as usize].position;
|
||||
let control_point = &self.b_vertex_positions[control_point_vertex_index as usize];
|
||||
geometry::solve_quadratic_bezier_t_for_x(x,
|
||||
left_vertex_position,
|
||||
control_point,
|
||||
|
@ -650,8 +664,8 @@ impl<'a> Partitioner<'a> {
|
|||
}
|
||||
|
||||
fn sample_active_edge(&self, t: f32, active_edge: &ActiveEdge) -> Point2D<f32> {
|
||||
let left_vertex_position = &self.b_vertices[active_edge.left_vertex_index as usize]
|
||||
.position;
|
||||
let left_vertex_position = &self.b_vertex_positions[active_edge.left_vertex_index as
|
||||
usize];
|
||||
let right_endpoint_position = &self.endpoints[active_edge.right_endpoint_index as usize]
|
||||
.position;
|
||||
match active_edge.control_point_vertex_index {
|
||||
|
@ -661,7 +675,7 @@ impl<'a> Partitioner<'a> {
|
|||
.to_point()
|
||||
}
|
||||
control_point_vertex_index => {
|
||||
let control_point = &self.b_vertices[control_point_vertex_index as usize].position;
|
||||
let control_point = &self.b_vertex_positions[control_point_vertex_index as usize];
|
||||
geometry::sample_quadratic_bezier(t,
|
||||
left_vertex_position,
|
||||
control_point,
|
||||
|
@ -682,11 +696,11 @@ impl<'a> Partitioner<'a> {
|
|||
}
|
||||
|
||||
let upper_left_vertex_position =
|
||||
&self.b_vertices[upper_active_edge.left_vertex_index as usize].position;
|
||||
&self.b_vertex_positions[upper_active_edge.left_vertex_index as usize];
|
||||
let upper_right_endpoint_position =
|
||||
&self.endpoints[upper_active_edge.right_endpoint_index as usize].position;
|
||||
let lower_left_vertex_position =
|
||||
&self.b_vertices[lower_active_edge.left_vertex_index as usize].position;
|
||||
&self.b_vertex_positions[lower_active_edge.left_vertex_index as usize];
|
||||
let lower_right_endpoint_position =
|
||||
&self.endpoints[lower_active_edge.right_endpoint_index as usize].position;
|
||||
|
||||
|
@ -700,7 +714,7 @@ impl<'a> Partitioner<'a> {
|
|||
}
|
||||
(upper_control_point_vertex_index, u32::MAX) => {
|
||||
let upper_control_point =
|
||||
&self.b_vertices[upper_control_point_vertex_index as usize].position;
|
||||
&self.b_vertex_positions[upper_control_point_vertex_index as usize];
|
||||
geometry::line_quadratic_bezier_crossing_point(lower_left_vertex_position,
|
||||
lower_right_endpoint_position,
|
||||
upper_left_vertex_position,
|
||||
|
@ -709,7 +723,7 @@ impl<'a> Partitioner<'a> {
|
|||
}
|
||||
(u32::MAX, lower_control_point_vertex_index) => {
|
||||
let lower_control_point =
|
||||
&self.b_vertices[lower_control_point_vertex_index as usize].position;
|
||||
&self.b_vertex_positions[lower_control_point_vertex_index as usize];
|
||||
geometry::line_quadratic_bezier_crossing_point(upper_left_vertex_position,
|
||||
upper_right_endpoint_position,
|
||||
lower_left_vertex_position,
|
||||
|
@ -718,9 +732,9 @@ impl<'a> Partitioner<'a> {
|
|||
}
|
||||
(upper_control_point_vertex_index, lower_control_point_vertex_index) => {
|
||||
let upper_control_point =
|
||||
&self.b_vertices[upper_control_point_vertex_index as usize].position;
|
||||
&self.b_vertex_positions[upper_control_point_vertex_index as usize];
|
||||
let lower_control_point =
|
||||
&self.b_vertices[lower_control_point_vertex_index as usize].position;
|
||||
&self.b_vertex_positions[lower_control_point_vertex_index as usize];
|
||||
geometry::quadratic_bezier_quadratic_bezier_crossing_point(
|
||||
upper_left_vertex_position,
|
||||
upper_control_point,
|
||||
|
@ -743,57 +757,53 @@ impl<'a> Partitioner<'a> {
|
|||
let left_curve_control_point_vertex_index;
|
||||
match active_edge.control_point_vertex_index {
|
||||
u32::MAX => {
|
||||
let left_point = self.b_vertices[left_curve_left as usize];
|
||||
let path_id = self.b_vertex_info[left_curve_left as usize].path_id;
|
||||
let left_point_position = self.b_vertex_positions[left_curve_left as usize];
|
||||
let right_point = self.endpoints[active_edge.right_endpoint_index as usize]
|
||||
.position;
|
||||
let middle_point = left_point.position.to_vector().lerp(right_point.to_vector(), t);
|
||||
let middle_point = left_point_position.to_vector().lerp(right_point.to_vector(), t);
|
||||
|
||||
active_edge.left_vertex_index = self.b_vertices.len() as u32;
|
||||
self.b_vertices.push(BVertex::new(&middle_point.to_point(),
|
||||
active_edge.endpoint_kind(),
|
||||
left_point.path_id));
|
||||
active_edge.left_vertex_index = self.b_vertex_info.len() as u32;
|
||||
self.b_vertex_positions.push(middle_point.to_point());
|
||||
self.b_vertex_info.push(BVertexInfo::new(active_edge.endpoint_kind(), path_id));
|
||||
|
||||
active_edge.toggle_parity();
|
||||
|
||||
left_curve_control_point_vertex_index = u32::MAX;
|
||||
}
|
||||
_ => {
|
||||
let left_endpoint_position = self.b_vertices[active_edge.left_vertex_index as usize]
|
||||
.position;
|
||||
let left_endpoint_position =
|
||||
self.b_vertex_positions[active_edge.left_vertex_index as usize];
|
||||
let right_endpoint_position =
|
||||
self.endpoints[active_edge.right_endpoint_index as usize].position;
|
||||
let subdivided_quadratic_bezier = SubdividedQuadraticBezier::new(
|
||||
t,
|
||||
&left_endpoint_position,
|
||||
&self.b_vertices[active_edge.control_point_vertex_index as usize].position,
|
||||
&self.b_vertex_positions[active_edge.control_point_vertex_index as usize],
|
||||
&right_endpoint_position);
|
||||
|
||||
let control_point_b_vertex_a =
|
||||
BVertex::control_point(&left_endpoint_position,
|
||||
&subdivided_quadratic_bezier.ap1,
|
||||
&subdivided_quadratic_bezier.ap2bp0,
|
||||
self.path_id,
|
||||
bottom);
|
||||
|
||||
left_curve_control_point_vertex_index = self.b_vertices.len() as u32;
|
||||
left_curve_control_point_vertex_index = self.b_vertex_info.len() as u32;
|
||||
active_edge.left_vertex_index = left_curve_control_point_vertex_index + 1;
|
||||
active_edge.control_point_vertex_index = left_curve_control_point_vertex_index + 2;
|
||||
|
||||
self.b_vertices.extend([
|
||||
control_point_b_vertex_a,
|
||||
BVertex::new(&subdivided_quadratic_bezier.ap2bp0,
|
||||
active_edge.endpoint_kind(),
|
||||
self.path_id)
|
||||
self.b_vertex_positions.extend([
|
||||
subdivided_quadratic_bezier.ap1,
|
||||
subdivided_quadratic_bezier.ap2bp0,
|
||||
subdivided_quadratic_bezier.bp1,
|
||||
].into_iter());
|
||||
self.b_vertex_info.extend([
|
||||
BVertexInfo::control_point(&left_endpoint_position,
|
||||
&subdivided_quadratic_bezier.ap1,
|
||||
&subdivided_quadratic_bezier.ap2bp0,
|
||||
self.path_id,
|
||||
bottom),
|
||||
BVertexInfo::new(active_edge.endpoint_kind(), self.path_id),
|
||||
BVertexInfo::control_point(&subdivided_quadratic_bezier.ap2bp0,
|
||||
&subdivided_quadratic_bezier.bp1,
|
||||
&right_endpoint_position,
|
||||
self.path_id,
|
||||
bottom),
|
||||
].into_iter());
|
||||
|
||||
let control_point_b_vertex_b =
|
||||
BVertex::control_point(&subdivided_quadratic_bezier.ap2bp0,
|
||||
&subdivided_quadratic_bezier.bp1,
|
||||
&right_endpoint_position,
|
||||
self.path_id,
|
||||
bottom);
|
||||
|
||||
active_edge.control_point_vertex_index = self.b_vertices.len() as u32;
|
||||
self.b_vertices.push(control_point_b_vertex_b);
|
||||
|
||||
active_edge.toggle_parity();
|
||||
}
|
||||
|
@ -1005,11 +1015,11 @@ struct SubdividedActiveEdge {
|
|||
}
|
||||
|
||||
impl SubdividedActiveEdge {
|
||||
fn shape(&self, b_vertices: &[BVertex]) -> Shape {
|
||||
fn shape(&self, b_vertex_info: &[BVertexInfo]) -> Shape {
|
||||
if self.left_curve_control_point == u32::MAX {
|
||||
return Shape::Flat
|
||||
}
|
||||
match b_vertices[self.left_curve_control_point as usize].kind {
|
||||
match b_vertex_info[self.left_curve_control_point as usize].kind {
|
||||
BVertexKind::ConvexControlPoint => Shape::Convex,
|
||||
_ => Shape::Concave,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue