Precompute rounded vertices (#1547)
Co-authored-by: Daniel Buch Hansen <boogiewasthere@gmail.com>
This commit is contained in:
parent
3a83a600bb
commit
8303523ccf
2 changed files with 345 additions and 22 deletions
|
@ -21,6 +21,7 @@ All notable changes to the epaint crate will be documented in this file.
|
||||||
* MSRV (Minimum Supported Rust Version) is now `1.60.0` ([#1467](https://github.com/emilk/egui/pull/1467)).
|
* MSRV (Minimum Supported Rust Version) is now `1.60.0` ([#1467](https://github.com/emilk/egui/pull/1467)).
|
||||||
* Renamed the feature `convert_bytemuck` to `bytemuck` ([#1467](https://github.com/emilk/egui/pull/1467)).
|
* Renamed the feature `convert_bytemuck` to `bytemuck` ([#1467](https://github.com/emilk/egui/pull/1467)).
|
||||||
* Renamed the feature `serialize` to `serde` ([#1467](https://github.com/emilk/egui/pull/1467)).
|
* Renamed the feature `serialize` to `serde` ([#1467](https://github.com/emilk/egui/pull/1467)).
|
||||||
|
* Optimize tessellation of circles and boxes with rounded corners ([#1547](https://github.com/emilk/egui/pull/1547)).
|
||||||
|
|
||||||
|
|
||||||
## 0.17.0 - 2022-02-22
|
## 0.17.0 - 2022-02-22
|
||||||
|
|
|
@ -7,7 +7,293 @@
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use emath::*;
|
use emath::*;
|
||||||
use std::f32::consts::TAU;
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#[allow(clippy::approx_constant)]
|
||||||
|
mod precomputed_vertices {
|
||||||
|
/*
|
||||||
|
fn main() {
|
||||||
|
let n = 64;
|
||||||
|
println!("pub const CIRCLE_{}: [Vec2; {}] = [", n, n+1);
|
||||||
|
for i in 0..=n {
|
||||||
|
let a = std::f64::consts::TAU * i as f64 / n as f64;
|
||||||
|
println!(" vec2({:.06}, {:.06}),", a.cos(), a.sin());
|
||||||
|
}
|
||||||
|
println!("];")
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
use emath::{vec2, Vec2};
|
||||||
|
|
||||||
|
pub const CIRCLE_8: [Vec2; 9] = [
|
||||||
|
vec2(1.000000, 0.000000),
|
||||||
|
vec2(0.707107, 0.707107),
|
||||||
|
vec2(0.000000, 1.000000),
|
||||||
|
vec2(-0.707107, 0.707107),
|
||||||
|
vec2(-1.000000, 0.000000),
|
||||||
|
vec2(-0.707107, -0.707107),
|
||||||
|
vec2(0.000000, -1.000000),
|
||||||
|
vec2(0.707107, -0.707107),
|
||||||
|
vec2(1.000000, 0.000000),
|
||||||
|
];
|
||||||
|
|
||||||
|
pub const CIRCLE_16: [Vec2; 17] = [
|
||||||
|
vec2(1.000000, 0.000000),
|
||||||
|
vec2(0.923880, 0.382683),
|
||||||
|
vec2(0.707107, 0.707107),
|
||||||
|
vec2(0.382683, 0.923880),
|
||||||
|
vec2(0.000000, 1.000000),
|
||||||
|
vec2(-0.382684, 0.923880),
|
||||||
|
vec2(-0.707107, 0.707107),
|
||||||
|
vec2(-0.923880, 0.382683),
|
||||||
|
vec2(-1.000000, 0.000000),
|
||||||
|
vec2(-0.923880, -0.382683),
|
||||||
|
vec2(-0.707107, -0.707107),
|
||||||
|
vec2(-0.382684, -0.923880),
|
||||||
|
vec2(0.000000, -1.000000),
|
||||||
|
vec2(0.382684, -0.923879),
|
||||||
|
vec2(0.707107, -0.707107),
|
||||||
|
vec2(0.923880, -0.382683),
|
||||||
|
vec2(1.000000, 0.000000),
|
||||||
|
];
|
||||||
|
|
||||||
|
pub const CIRCLE_32: [Vec2; 33] = [
|
||||||
|
vec2(1.000000, 0.000000),
|
||||||
|
vec2(0.980785, 0.195090),
|
||||||
|
vec2(0.923880, 0.382683),
|
||||||
|
vec2(0.831470, 0.555570),
|
||||||
|
vec2(0.707107, 0.707107),
|
||||||
|
vec2(0.555570, 0.831470),
|
||||||
|
vec2(0.382683, 0.923880),
|
||||||
|
vec2(0.195090, 0.980785),
|
||||||
|
vec2(0.000000, 1.000000),
|
||||||
|
vec2(-0.195090, 0.980785),
|
||||||
|
vec2(-0.382683, 0.923880),
|
||||||
|
vec2(-0.555570, 0.831470),
|
||||||
|
vec2(-0.707107, 0.707107),
|
||||||
|
vec2(-0.831470, 0.555570),
|
||||||
|
vec2(-0.923880, 0.382683),
|
||||||
|
vec2(-0.980785, 0.195090),
|
||||||
|
vec2(-1.000000, 0.000000),
|
||||||
|
vec2(-0.980785, -0.195090),
|
||||||
|
vec2(-0.923880, -0.382683),
|
||||||
|
vec2(-0.831470, -0.555570),
|
||||||
|
vec2(-0.707107, -0.707107),
|
||||||
|
vec2(-0.555570, -0.831470),
|
||||||
|
vec2(-0.382683, -0.923880),
|
||||||
|
vec2(-0.195090, -0.980785),
|
||||||
|
vec2(-0.000000, -1.000000),
|
||||||
|
vec2(0.195090, -0.980785),
|
||||||
|
vec2(0.382683, -0.923880),
|
||||||
|
vec2(0.555570, -0.831470),
|
||||||
|
vec2(0.707107, -0.707107),
|
||||||
|
vec2(0.831470, -0.555570),
|
||||||
|
vec2(0.923880, -0.382683),
|
||||||
|
vec2(0.980785, -0.195090),
|
||||||
|
vec2(1.000000, -0.000000),
|
||||||
|
];
|
||||||
|
|
||||||
|
pub const CIRCLE_64: [Vec2; 65] = [
|
||||||
|
vec2(1.000000, 0.000000),
|
||||||
|
vec2(0.995185, 0.098017),
|
||||||
|
vec2(0.980785, 0.195090),
|
||||||
|
vec2(0.956940, 0.290285),
|
||||||
|
vec2(0.923880, 0.382683),
|
||||||
|
vec2(0.881921, 0.471397),
|
||||||
|
vec2(0.831470, 0.555570),
|
||||||
|
vec2(0.773010, 0.634393),
|
||||||
|
vec2(0.707107, 0.707107),
|
||||||
|
vec2(0.634393, 0.773010),
|
||||||
|
vec2(0.555570, 0.831470),
|
||||||
|
vec2(0.471397, 0.881921),
|
||||||
|
vec2(0.382683, 0.923880),
|
||||||
|
vec2(0.290285, 0.956940),
|
||||||
|
vec2(0.195090, 0.980785),
|
||||||
|
vec2(0.098017, 0.995185),
|
||||||
|
vec2(0.000000, 1.000000),
|
||||||
|
vec2(-0.098017, 0.995185),
|
||||||
|
vec2(-0.195090, 0.980785),
|
||||||
|
vec2(-0.290285, 0.956940),
|
||||||
|
vec2(-0.382683, 0.923880),
|
||||||
|
vec2(-0.471397, 0.881921),
|
||||||
|
vec2(-0.555570, 0.831470),
|
||||||
|
vec2(-0.634393, 0.773010),
|
||||||
|
vec2(-0.707107, 0.707107),
|
||||||
|
vec2(-0.773010, 0.634393),
|
||||||
|
vec2(-0.831470, 0.555570),
|
||||||
|
vec2(-0.881921, 0.471397),
|
||||||
|
vec2(-0.923880, 0.382683),
|
||||||
|
vec2(-0.956940, 0.290285),
|
||||||
|
vec2(-0.980785, 0.195090),
|
||||||
|
vec2(-0.995185, 0.098017),
|
||||||
|
vec2(-1.000000, 0.000000),
|
||||||
|
vec2(-0.995185, -0.098017),
|
||||||
|
vec2(-0.980785, -0.195090),
|
||||||
|
vec2(-0.956940, -0.290285),
|
||||||
|
vec2(-0.923880, -0.382683),
|
||||||
|
vec2(-0.881921, -0.471397),
|
||||||
|
vec2(-0.831470, -0.555570),
|
||||||
|
vec2(-0.773010, -0.634393),
|
||||||
|
vec2(-0.707107, -0.707107),
|
||||||
|
vec2(-0.634393, -0.773010),
|
||||||
|
vec2(-0.555570, -0.831470),
|
||||||
|
vec2(-0.471397, -0.881921),
|
||||||
|
vec2(-0.382683, -0.923880),
|
||||||
|
vec2(-0.290285, -0.956940),
|
||||||
|
vec2(-0.195090, -0.980785),
|
||||||
|
vec2(-0.098017, -0.995185),
|
||||||
|
vec2(-0.000000, -1.000000),
|
||||||
|
vec2(0.098017, -0.995185),
|
||||||
|
vec2(0.195090, -0.980785),
|
||||||
|
vec2(0.290285, -0.956940),
|
||||||
|
vec2(0.382683, -0.923880),
|
||||||
|
vec2(0.471397, -0.881921),
|
||||||
|
vec2(0.555570, -0.831470),
|
||||||
|
vec2(0.634393, -0.773010),
|
||||||
|
vec2(0.707107, -0.707107),
|
||||||
|
vec2(0.773010, -0.634393),
|
||||||
|
vec2(0.831470, -0.555570),
|
||||||
|
vec2(0.881921, -0.471397),
|
||||||
|
vec2(0.923880, -0.382683),
|
||||||
|
vec2(0.956940, -0.290285),
|
||||||
|
vec2(0.980785, -0.195090),
|
||||||
|
vec2(0.995185, -0.098017),
|
||||||
|
vec2(1.000000, -0.000000),
|
||||||
|
];
|
||||||
|
|
||||||
|
pub const CIRCLE_128: [Vec2; 129] = [
|
||||||
|
vec2(1.000000, 0.000000),
|
||||||
|
vec2(0.998795, 0.049068),
|
||||||
|
vec2(0.995185, 0.098017),
|
||||||
|
vec2(0.989177, 0.146730),
|
||||||
|
vec2(0.980785, 0.195090),
|
||||||
|
vec2(0.970031, 0.242980),
|
||||||
|
vec2(0.956940, 0.290285),
|
||||||
|
vec2(0.941544, 0.336890),
|
||||||
|
vec2(0.923880, 0.382683),
|
||||||
|
vec2(0.903989, 0.427555),
|
||||||
|
vec2(0.881921, 0.471397),
|
||||||
|
vec2(0.857729, 0.514103),
|
||||||
|
vec2(0.831470, 0.555570),
|
||||||
|
vec2(0.803208, 0.595699),
|
||||||
|
vec2(0.773010, 0.634393),
|
||||||
|
vec2(0.740951, 0.671559),
|
||||||
|
vec2(0.707107, 0.707107),
|
||||||
|
vec2(0.671559, 0.740951),
|
||||||
|
vec2(0.634393, 0.773010),
|
||||||
|
vec2(0.595699, 0.803208),
|
||||||
|
vec2(0.555570, 0.831470),
|
||||||
|
vec2(0.514103, 0.857729),
|
||||||
|
vec2(0.471397, 0.881921),
|
||||||
|
vec2(0.427555, 0.903989),
|
||||||
|
vec2(0.382683, 0.923880),
|
||||||
|
vec2(0.336890, 0.941544),
|
||||||
|
vec2(0.290285, 0.956940),
|
||||||
|
vec2(0.242980, 0.970031),
|
||||||
|
vec2(0.195090, 0.980785),
|
||||||
|
vec2(0.146730, 0.989177),
|
||||||
|
vec2(0.098017, 0.995185),
|
||||||
|
vec2(0.049068, 0.998795),
|
||||||
|
vec2(0.000000, 1.000000),
|
||||||
|
vec2(-0.049068, 0.998795),
|
||||||
|
vec2(-0.098017, 0.995185),
|
||||||
|
vec2(-0.146730, 0.989177),
|
||||||
|
vec2(-0.195090, 0.980785),
|
||||||
|
vec2(-0.242980, 0.970031),
|
||||||
|
vec2(-0.290285, 0.956940),
|
||||||
|
vec2(-0.336890, 0.941544),
|
||||||
|
vec2(-0.382683, 0.923880),
|
||||||
|
vec2(-0.427555, 0.903989),
|
||||||
|
vec2(-0.471397, 0.881921),
|
||||||
|
vec2(-0.514103, 0.857729),
|
||||||
|
vec2(-0.555570, 0.831470),
|
||||||
|
vec2(-0.595699, 0.803208),
|
||||||
|
vec2(-0.634393, 0.773010),
|
||||||
|
vec2(-0.671559, 0.740951),
|
||||||
|
vec2(-0.707107, 0.707107),
|
||||||
|
vec2(-0.740951, 0.671559),
|
||||||
|
vec2(-0.773010, 0.634393),
|
||||||
|
vec2(-0.803208, 0.595699),
|
||||||
|
vec2(-0.831470, 0.555570),
|
||||||
|
vec2(-0.857729, 0.514103),
|
||||||
|
vec2(-0.881921, 0.471397),
|
||||||
|
vec2(-0.903989, 0.427555),
|
||||||
|
vec2(-0.923880, 0.382683),
|
||||||
|
vec2(-0.941544, 0.336890),
|
||||||
|
vec2(-0.956940, 0.290285),
|
||||||
|
vec2(-0.970031, 0.242980),
|
||||||
|
vec2(-0.980785, 0.195090),
|
||||||
|
vec2(-0.989177, 0.146730),
|
||||||
|
vec2(-0.995185, 0.098017),
|
||||||
|
vec2(-0.998795, 0.049068),
|
||||||
|
vec2(-1.000000, 0.000000),
|
||||||
|
vec2(-0.998795, -0.049068),
|
||||||
|
vec2(-0.995185, -0.098017),
|
||||||
|
vec2(-0.989177, -0.146730),
|
||||||
|
vec2(-0.980785, -0.195090),
|
||||||
|
vec2(-0.970031, -0.242980),
|
||||||
|
vec2(-0.956940, -0.290285),
|
||||||
|
vec2(-0.941544, -0.336890),
|
||||||
|
vec2(-0.923880, -0.382683),
|
||||||
|
vec2(-0.903989, -0.427555),
|
||||||
|
vec2(-0.881921, -0.471397),
|
||||||
|
vec2(-0.857729, -0.514103),
|
||||||
|
vec2(-0.831470, -0.555570),
|
||||||
|
vec2(-0.803208, -0.595699),
|
||||||
|
vec2(-0.773010, -0.634393),
|
||||||
|
vec2(-0.740951, -0.671559),
|
||||||
|
vec2(-0.707107, -0.707107),
|
||||||
|
vec2(-0.671559, -0.740951),
|
||||||
|
vec2(-0.634393, -0.773010),
|
||||||
|
vec2(-0.595699, -0.803208),
|
||||||
|
vec2(-0.555570, -0.831470),
|
||||||
|
vec2(-0.514103, -0.857729),
|
||||||
|
vec2(-0.471397, -0.881921),
|
||||||
|
vec2(-0.427555, -0.903989),
|
||||||
|
vec2(-0.382683, -0.923880),
|
||||||
|
vec2(-0.336890, -0.941544),
|
||||||
|
vec2(-0.290285, -0.956940),
|
||||||
|
vec2(-0.242980, -0.970031),
|
||||||
|
vec2(-0.195090, -0.980785),
|
||||||
|
vec2(-0.146730, -0.989177),
|
||||||
|
vec2(-0.098017, -0.995185),
|
||||||
|
vec2(-0.049068, -0.998795),
|
||||||
|
vec2(-0.000000, -1.000000),
|
||||||
|
vec2(0.049068, -0.998795),
|
||||||
|
vec2(0.098017, -0.995185),
|
||||||
|
vec2(0.146730, -0.989177),
|
||||||
|
vec2(0.195090, -0.980785),
|
||||||
|
vec2(0.242980, -0.970031),
|
||||||
|
vec2(0.290285, -0.956940),
|
||||||
|
vec2(0.336890, -0.941544),
|
||||||
|
vec2(0.382683, -0.923880),
|
||||||
|
vec2(0.427555, -0.903989),
|
||||||
|
vec2(0.471397, -0.881921),
|
||||||
|
vec2(0.514103, -0.857729),
|
||||||
|
vec2(0.555570, -0.831470),
|
||||||
|
vec2(0.595699, -0.803208),
|
||||||
|
vec2(0.634393, -0.773010),
|
||||||
|
vec2(0.671559, -0.740951),
|
||||||
|
vec2(0.707107, -0.707107),
|
||||||
|
vec2(0.740951, -0.671559),
|
||||||
|
vec2(0.773010, -0.634393),
|
||||||
|
vec2(0.803208, -0.595699),
|
||||||
|
vec2(0.831470, -0.555570),
|
||||||
|
vec2(0.857729, -0.514103),
|
||||||
|
vec2(0.881921, -0.471397),
|
||||||
|
vec2(0.903989, -0.427555),
|
||||||
|
vec2(0.923880, -0.382683),
|
||||||
|
vec2(0.941544, -0.336890),
|
||||||
|
vec2(0.956940, -0.290285),
|
||||||
|
vec2(0.970031, -0.242980),
|
||||||
|
vec2(0.980785, -0.195090),
|
||||||
|
vec2(0.989177, -0.146730),
|
||||||
|
vec2(0.995185, -0.098017),
|
||||||
|
vec2(0.998795, -0.049068),
|
||||||
|
vec2(1.000000, -0.000000),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -50,13 +336,36 @@ impl Path {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_circle(&mut self, center: Pos2, radius: f32) {
|
pub fn add_circle(&mut self, center: Pos2, radius: f32) {
|
||||||
let n = (radius * 4.0).round() as i32; // TODO: tweak a bit more
|
use precomputed_vertices::*;
|
||||||
let n = n.clamp(4, 64);
|
|
||||||
self.reserve(n as usize);
|
// These cutoffs are based on a high-dpi display. TODO: use pixels_per_point here?
|
||||||
for i in 0..n {
|
// same cutoffs as in add_circle_quadrant
|
||||||
let angle = remap(i as f32, 0.0..=n as f32, 0.0..=TAU);
|
|
||||||
let normal = vec2(angle.cos(), angle.sin());
|
if radius <= 2.0 {
|
||||||
self.add_point(center + radius * normal, normal);
|
self.0.extend(CIRCLE_8.iter().map(|&n| PathPoint {
|
||||||
|
pos: center + radius * n,
|
||||||
|
normal: n,
|
||||||
|
}));
|
||||||
|
} else if radius <= 5.0 {
|
||||||
|
self.0.extend(CIRCLE_16.iter().map(|&n| PathPoint {
|
||||||
|
pos: center + radius * n,
|
||||||
|
normal: n,
|
||||||
|
}));
|
||||||
|
} else if radius < 18.0 {
|
||||||
|
self.0.extend(CIRCLE_32.iter().map(|&n| PathPoint {
|
||||||
|
pos: center + radius * n,
|
||||||
|
normal: n,
|
||||||
|
}));
|
||||||
|
} else if radius < 50.0 {
|
||||||
|
self.0.extend(CIRCLE_64.iter().map(|&n| PathPoint {
|
||||||
|
pos: center + radius * n,
|
||||||
|
normal: n,
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
self.0.extend(CIRCLE_128.iter().map(|&n| PathPoint {
|
||||||
|
pos: center + radius * n,
|
||||||
|
normal: n,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,8 +498,7 @@ impl Path {
|
||||||
pub mod path {
|
pub mod path {
|
||||||
//! Helpers for constructing paths
|
//! Helpers for constructing paths
|
||||||
use crate::shape::Rounding;
|
use crate::shape::Rounding;
|
||||||
|
use emath::*;
|
||||||
use super::*;
|
|
||||||
|
|
||||||
/// overwrites existing points
|
/// overwrites existing points
|
||||||
pub fn rounded_rectangle(path: &mut Vec<Pos2>, rect: Rect, rounding: Rounding) {
|
pub fn rounded_rectangle(path: &mut Vec<Pos2>, rect: Rect, rounding: Rounding) {
|
||||||
|
@ -236,19 +544,33 @@ pub mod path {
|
||||||
// - quadrant 3: right top
|
// - quadrant 3: right top
|
||||||
// * angle 4 * TAU / 4 = right
|
// * angle 4 * TAU / 4 = right
|
||||||
pub fn add_circle_quadrant(path: &mut Vec<Pos2>, center: Pos2, radius: f32, quadrant: f32) {
|
pub fn add_circle_quadrant(path: &mut Vec<Pos2>, center: Pos2, radius: f32, quadrant: f32) {
|
||||||
// TODO: optimize with precalculated vertices for some radii ranges
|
use super::precomputed_vertices::*;
|
||||||
|
|
||||||
let n = (radius * 0.75).round() as i32; // TODO: tweak a bit more
|
// These cutoffs are based on a high-dpi display. TODO: use pixels_per_point here?
|
||||||
let n = n.clamp(2, 32);
|
// same cutoffs as in add_circle
|
||||||
const RIGHT_ANGLE: f32 = TAU / 4.0;
|
|
||||||
path.reserve(n as usize + 1);
|
if radius <= 0.0 {
|
||||||
for i in 0..=n {
|
path.push(center);
|
||||||
let angle = remap(
|
} else if radius <= 2.0 {
|
||||||
i as f32,
|
let offset = quadrant as usize * 2;
|
||||||
0.0..=n as f32,
|
let quadrant_vertices = &CIRCLE_8[offset..=offset + 2];
|
||||||
quadrant * RIGHT_ANGLE..=(quadrant + 1.0) * RIGHT_ANGLE,
|
path.extend(quadrant_vertices.iter().map(|&n| center + radius * n));
|
||||||
);
|
} else if radius <= 5.0 {
|
||||||
path.push(center + radius * Vec2::angled(angle));
|
let offset = quadrant as usize * 4;
|
||||||
|
let quadrant_vertices = &CIRCLE_16[offset..=offset + 4];
|
||||||
|
path.extend(quadrant_vertices.iter().map(|&n| center + radius * n));
|
||||||
|
} else if radius < 18.0 {
|
||||||
|
let offset = quadrant as usize * 8;
|
||||||
|
let quadrant_vertices = &CIRCLE_32[offset..=offset + 8];
|
||||||
|
path.extend(quadrant_vertices.iter().map(|&n| center + radius * n));
|
||||||
|
} else if radius < 50.0 {
|
||||||
|
let offset = quadrant as usize * 16;
|
||||||
|
let quadrant_vertices = &CIRCLE_64[offset..=offset + 16];
|
||||||
|
path.extend(quadrant_vertices.iter().map(|&n| center + radius * n));
|
||||||
|
} else {
|
||||||
|
let offset = quadrant as usize * 32;
|
||||||
|
let quadrant_vertices = &CIRCLE_128[offset..=offset + 32];
|
||||||
|
path.extend(quadrant_vertices.iter().map(|&n| center + radius * n));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue