-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor primitive meshing #12793
base: main
Are you sure you want to change the base?
Refactor primitive meshing #12793
Changes from all commits
d430554
c421e29
90963cd
86e6de4
512084e
da14a71
19017ba
6e356cd
5a31d31
1bd3e48
d08fae3
dd0725e
8049680
8f8c980
c5d4341
9ba2b9e
cfbb22a
8e7ca84
2b8f50b
025591d
188d654
57176e8
f4bafb9
fcbb23b
de58e4f
5792f15
980cbdc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
use criterion::{black_box, criterion_group, criterion_main, Criterion}; | ||
|
||
use bevy_render::mesh::Capsule3dMeshBuilder; | ||
|
||
criterion_group!(benches, capsule_low_res, capsule_default, capsule_high_res); | ||
fn capsule_low_res(c: &mut Criterion) { | ||
c.bench_function("build_capsule_low_res", |b| { | ||
b.iter(|| { | ||
black_box( | ||
Capsule3dMeshBuilder::new( | ||
black_box(0.5), | ||
black_box(1.0), | ||
black_box(16), | ||
black_box(4), | ||
) | ||
.build(), | ||
) | ||
}); | ||
}); | ||
} | ||
fn capsule_default(c: &mut Criterion) { | ||
c.bench_function("build_capsule_default", |b| { | ||
b.iter(|| { | ||
black_box( | ||
Capsule3dMeshBuilder::new( | ||
black_box(0.5), | ||
black_box(1.0), | ||
black_box(32), | ||
black_box(8), | ||
) | ||
.build(), | ||
) | ||
}); | ||
}); | ||
} | ||
|
||
fn capsule_high_res(c: &mut Criterion) { | ||
c.bench_function("build_capsule_high_res", |b| { | ||
b.iter(|| { | ||
black_box( | ||
Capsule3dMeshBuilder::new( | ||
black_box(0.5), | ||
black_box(1.0), | ||
black_box(64), | ||
black_box(16), | ||
) | ||
.build(), | ||
) | ||
}); | ||
}); | ||
} | ||
criterion_main!(benches); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,14 +2,38 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; | |
|
||
use bevy_render::mesh::TorusMeshBuilder; | ||
|
||
fn torus(c: &mut Criterion) { | ||
c.bench_function("build_torus", |b| { | ||
b.iter(|| black_box(TorusMeshBuilder::new(black_box(0.5),black_box(1.0)))); | ||
criterion_group!(benches, torus_low_res, torus_default, torus_high_res,); | ||
|
||
fn torus_low_res(c: &mut Criterion) { | ||
c.bench_function("build_torus_low_res", |b| { | ||
b.iter(|| { | ||
black_box( | ||
TorusMeshBuilder::new(black_box(0.5), black_box(1.0)) | ||
.minor_resolution(black_box(12)) | ||
.major_resolution(black_box(16)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Its interesting that torus needs the builder-style api to set the resolution while Capsule (and Sphere?) have them set from |
||
.build(), | ||
) | ||
}); | ||
}); | ||
} | ||
|
||
fn torus_default(c: &mut Criterion) { | ||
c.bench_function("build_torus_default", |b| { | ||
b.iter(|| black_box(TorusMeshBuilder::new(black_box(0.5), black_box(1.0)).build())); | ||
}); | ||
} | ||
|
||
fn torus_high_res(c: &mut Criterion) { | ||
c.bench_function("build_torus_high_res", |b| { | ||
b.iter(|| { | ||
black_box( | ||
TorusMeshBuilder::new(black_box(0.5), black_box(1.0)) | ||
.minor_resolution(black_box(48)) | ||
.major_resolution(black_box(64)) | ||
.build(), | ||
) | ||
}); | ||
}); | ||
} | ||
|
||
criterion_group!( | ||
benches, | ||
torus, | ||
); | ||
criterion_main!(benches); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
use bevy_math::DMat2; | ||
use bevy_math::DVec2; | ||
use bevy_math::Vec2; | ||
use std::f64::consts::TAU; | ||
|
||
//iterator for generating a set of points around a unit circle, beginning at 0 radians | ||
#[derive(Debug, Clone)] | ||
pub(crate) struct CircleIterator { | ||
count: usize, | ||
rot: DMat2, | ||
pos: DVec2, | ||
} | ||
|
||
impl CircleIterator { | ||
//produces an iterator over (count) equidistant points that starts at (1.0, 0.0) on the unit circle | ||
pub(crate) fn new(count: usize) -> CircleIterator { | ||
Self { | ||
count, | ||
rot: DMat2::from_angle(TAU / (count as f64)), | ||
pos: DVec2::new(1.0, 0.0), | ||
} | ||
} | ||
|
||
//produces an iterator over (count) equidistant points that starts at (1.0, 0.0) on the unit circle, with an additional end point of (1.0, 0.0) | ||
pub(crate) fn wrapping(count: usize) -> impl Iterator<Item = Vec2> { | ||
Self::new(count).chain(std::iter::once(Vec2::new(1.0, 0.0))) | ||
} | ||
|
||
//semicircle with points ranging from 0 radians to pi radians, with (count) regions between points. | ||
pub(crate) fn semicircle(count: usize) -> impl Iterator<Item = Vec2> { | ||
Self::new(count * 2) | ||
.take(count) | ||
.chain(std::iter::once(Vec2::new(-1.0, 0.0))) | ||
} | ||
|
||
//quarter circle with points ranging from 0 radians to pi/2 radians, with (count) regions between points. | ||
pub(crate) fn quarter_circle(count: usize) -> impl Iterator<Item = Vec2> { | ||
Self::new(count * 4) | ||
.take(count) | ||
.chain(std::iter::once(Vec2::new(0.0, 1.0))) | ||
} | ||
} | ||
impl Iterator for CircleIterator { | ||
type Item = Vec2; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just opening a discussion here: Thoughts on using Maybe There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If this method does not yield favorable results, I agree that something else should be used (and if it does, it would still make sense to have it return something with labels that are more intuitive than |
||
fn next(&mut self) -> Option<Self::Item> { | ||
if self.count != 0 { | ||
let prev = self.pos.as_vec2(); | ||
self.pos = self.rot * self.pos; | ||
self.count -= 1; | ||
Some(prev) | ||
} else { | ||
None | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
gibletfeets marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
use super::CircleIterator; | ||
use bevy_math::Vec2; | ||
#[test] | ||
fn circle_iterator_has_correct_length() { | ||
let vertices: Vec<Vec2> = CircleIterator::new(6).collect(); | ||
assert_eq!(vertices.len(), 6); | ||
} | ||
|
||
#[test] | ||
fn circle_iterator_vertices_are_equidistant() { | ||
let epsilon = 0.00001; | ||
let vertices: Vec<Vec2> = CircleIterator::new(6).collect(); | ||
let center = Vec2::new(0.0, 0.0); | ||
let distances_center: Vec<f32> = vertices.iter().map(|x| center.distance(*x)).collect(); | ||
assert!(distances_center | ||
.windows(2) | ||
.all(|w| (w[0] - w[1]).abs() < epsilon)); | ||
let distances_neighbors: Vec<f32> = | ||
vertices.windows(2).map(|w| w[0].distance(w[1])).collect(); | ||
assert!(distances_neighbors | ||
.windows(2) | ||
.all(|w| (w[0] - w[1]).abs() < epsilon)); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Torus and capsule could probably live together in primitives.rs