Skip to content

Commit e53c8e0

Browse files
BD103IQuick143
andauthoredJan 14, 2025··
Create missing constructors for 2D primitive mesh builders (bevyengine#17291)
# Objective - While all [`MeshBuilder`](https://dev-docs.bevyengine.org/bevy/prelude/trait.MeshBuilder.html)s can be created by first creating the primitive `bevy_math` type and using [`Meshable`](https://dev-docs.bevyengine.org/bevy/prelude/trait.Meshable.html), most builders have their own `const` constructors that can be used instead. Some builders are missing constructors, however, making them unavailable in `const` contexts. ## Solution - Add a `const` constructor for `RegularPolygonMeshBuilder`, `RhombusMeshBuilder`, `Triangle2dMeshBuilder`, and `RectangleMeshBuilder`. - Add a note on the requirements of `ConvexPolygonMeshBuilder`, and recommend using `ConvexPolygon::new().mesh()` instead. - A constructor cannot easily be created for this type, since it requires duplicating all of `ConvexPolygon::new()`'s verification code. I may be able to work around this, but it requires touching a bit more code surface. Opinions? ## Testing Not much beyond CI! The changes are trivial enough that only a cursory glance for typos and switched variables should be necessary. ## Note for Reviewers Hi! I haven't directly used the types I modify in this PR beyond some benchmarking work I did this morning. If you're familiar with these types, please let me know if any of the constructors need additional validation (or if the constructors shouldn't be there at all). Thanks! --------- Co-authored-by: IQuick 143 <[email protected]>
1 parent 031bb09 commit e53c8e0

File tree

1 file changed

+74
-0
lines changed
  • crates/bevy_mesh/src/primitives

1 file changed

+74
-0
lines changed
 

‎crates/bevy_mesh/src/primitives/dim2.rs

+74
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,9 @@ impl From<CircularSegment> for Mesh {
399399
}
400400

401401
/// A builder used for creating a [`Mesh`] with a [`ConvexPolygon`] shape.
402+
///
403+
/// You must verify that the `vertices` are not concave when constructing this type. You can
404+
/// guarantee this by creating a [`ConvexPolygon`] first, then calling [`ConvexPolygon::mesh()`].
402405
pub struct ConvexPolygonMeshBuilder<const N: usize> {
403406
pub vertices: [Vec2; N],
404407
}
@@ -452,6 +455,28 @@ pub struct RegularPolygonMeshBuilder {
452455
circumradius: f32,
453456
sides: u32,
454457
}
458+
459+
impl RegularPolygonMeshBuilder {
460+
/// Creates a new [`RegularPolygonMeshBuilder`] from the radius of a circumcircle and a number
461+
/// of sides.
462+
///
463+
/// # Panics
464+
///
465+
/// Panics in debug mode if `circumradius` is negative, or if `sides` is less than 3.
466+
pub const fn new(circumradius: f32, sides: u32) -> Self {
467+
debug_assert!(
468+
circumradius.is_sign_positive(),
469+
"polygon has a negative radius"
470+
);
471+
debug_assert!(sides > 2, "polygon has less than 3 sides");
472+
473+
Self {
474+
circumradius,
475+
sides,
476+
}
477+
}
478+
}
479+
455480
impl Meshable for RegularPolygon {
456481
type Output = RegularPolygonMeshBuilder;
457482

@@ -726,6 +751,28 @@ pub struct RhombusMeshBuilder {
726751
half_diagonals: Vec2,
727752
}
728753

754+
impl RhombusMeshBuilder {
755+
/// Creates a new [`RhombusMeshBuilder`] from a horizontal and vertical diagonal size.
756+
///
757+
/// # Panics
758+
///
759+
/// Panics in debug mode if `horizontal_diagonal` or `vertical_diagonal` is negative.
760+
pub const fn new(horizontal_diagonal: f32, vertical_diagonal: f32) -> Self {
761+
debug_assert!(
762+
horizontal_diagonal >= 0.0,
763+
"rhombus has a negative horizontal size",
764+
);
765+
debug_assert!(
766+
vertical_diagonal >= 0.0,
767+
"rhombus has a negative vertical size"
768+
);
769+
770+
Self {
771+
half_diagonals: Vec2::new(horizontal_diagonal / 2.0, vertical_diagonal / 2.0),
772+
}
773+
}
774+
}
775+
729776
impl MeshBuilder for RhombusMeshBuilder {
730777
fn build(&self) -> Mesh {
731778
let [hhd, vhd] = [self.half_diagonals.x, self.half_diagonals.y];
@@ -778,13 +825,24 @@ impl From<Rhombus> for Mesh {
778825
pub struct Triangle2dMeshBuilder {
779826
triangle: Triangle2d,
780827
}
828+
829+
impl Triangle2dMeshBuilder {
830+
/// Creates a new [`Triangle2dMeshBuilder`] from the points `a`, `b`, and `c`.
831+
pub const fn new(a: Vec2, b: Vec2, c: Vec2) -> Self {
832+
Self {
833+
triangle: Triangle2d::new(a, b, c),
834+
}
835+
}
836+
}
837+
781838
impl Meshable for Triangle2d {
782839
type Output = Triangle2dMeshBuilder;
783840

784841
fn mesh(&self) -> Self::Output {
785842
Self::Output { triangle: *self }
786843
}
787844
}
845+
788846
impl MeshBuilder for Triangle2dMeshBuilder {
789847
fn build(&self) -> Mesh {
790848
let vertices_3d = self.triangle.vertices.map(|v| v.extend(0.));
@@ -843,6 +901,22 @@ pub struct RectangleMeshBuilder {
843901
half_size: Vec2,
844902
}
845903

904+
impl RectangleMeshBuilder {
905+
/// Creates a new [`RectangleMeshBuilder`] from a full width and height.
906+
///
907+
/// # Panics
908+
///
909+
/// Panics in debug mode if `width` or `height` is negative.
910+
pub const fn new(width: f32, height: f32) -> Self {
911+
debug_assert!(width >= 0.0, "rectangle has a negative width");
912+
debug_assert!(height >= 0.0, "rectangle has a negative height");
913+
914+
Self {
915+
half_size: Vec2::new(width / 2.0, height / 2.0),
916+
}
917+
}
918+
}
919+
846920
impl MeshBuilder for RectangleMeshBuilder {
847921
fn build(&self) -> Mesh {
848922
let [hw, hh] = [self.half_size.x, self.half_size.y];

0 commit comments

Comments
 (0)
Please sign in to comment.