Add Meshable trait and implement meshing for 2D primitives#11431
Add Meshable trait and implement meshing for 2D primitives#11431alice-i-cecile merged 25 commits intobevyengine:mainfrom
Meshable trait and implement meshing for 2D primitives#11431Conversation
|
I think we should also consider re-exporting the primitives so that you don't need I'll probably make a separate PR for this now |
|
The generated |
|
@ManevilleF has done similar things in |
Co-authored-by: Alice Cecile <[email protected]>
# Objective Currently, the `primitives` module is inside of the prelude for `bevy_math`, but the actual primitives are not. This requires either importing the shapes everywhere that uses them, or adding the `primitives::` prefix: ```rust let rectangle = meshes.add(primitives::Rectangle::new(5.0, 2.5)); ``` (Note: meshing isn't actually implemented yet, but it's in #11431) The primitives are meant to be used for a variety of tasks across several crates, like for meshing, bounding volumes, gizmos, colliders, and so on, so I think having them in the prelude is justified. It would make several common tasks a lot more ergonomic. ```rust let rectangle = meshes.add(Rectangle::new(5.0, 2.5)); ``` ## Solution Add `primitives::*` to `bevy_math::prelude`. --------- Co-authored-by: Alice Cecile <[email protected]>
|
I don't know if an extra struct is needed, I have one in |
|
I think it would actually make sense to just remove the stuff related to Moving |
|
Yep, let's split that out! |
|
Alright, I've made some changes:
One extra thing to note is that Bevy's "old" |
# Objective Currently, the `Capsule` primitive is technically dimension-agnostic in that it implements both `Primitive2d` and `Primitive3d`. This seems good on paper, but it can often be useful to have separate 2D and 3D versions of primitives. For example, one might want a two-dimensional capsule mesh. We can't really implement both 2D and 3D meshing for the same type using the upcoming `Meshable` trait (see #11431). We also currently don't implement `Bounded2d` for `Capsule`, see #11336 (comment). Having 2D and 3D separate at a type level is more explicit, and also more consistent with the existing primitives, as there are no other types that implement both `Primitive2d` and `Primitive3d` at the same time. ## Solution Rename `Capsule` to `Capsule3d` and add `Capsule2d`. `Capsule2d` implements `Bounded2d`. For now, I went for `Capsule2d` for the sake of consistency and clarity. Mathematically the more accurate term would be `Stadium` or `Pill` (see [Wikipedia](https://en.wikipedia.org/wiki/Stadium_(geometry))), but those might be less obvious to game devs. For reference, Godot has [`CapsuleShape2D`](https://docs.godotengine.org/en/stable/classes/class_capsuleshape2d.html). I can rename it if others think the geometrically correct name is better though. --- ## Changelog - Renamed `Capsule` to `Capsule3d` - Added `Capsule2d` with `Bounded2d` implemented --------- Co-authored-by: Alice Cecile <[email protected]>
…ine#11431) # Objective The first part of bevyengine#10569, split up from bevyengine#11007. The goal is to implement meshing support for Bevy's new geometric primitives, starting with 2D primitives. 3D meshing will be added in a follow-up, and we can consider removing the old mesh shapes completely. ## Solution Add a `Meshable` trait that primitives need to implement to support meshing, as suggested by the [RFC](https://github.com/bevyengine/rfcs/blob/main/rfcs/12-primitive-shapes.md#meshing). ```rust /// A trait for shapes that can be turned into a [`Mesh`]. pub trait Meshable { /// The output of [`Self::mesh`]. This can either be a [`Mesh`] /// or a builder used for creating a [`Mesh`]. type Output; /// Creates a [`Mesh`] for a shape. fn mesh(&self) -> Self::Output; } ``` This PR implements it for the following primitives: - `Circle` - `Ellipse` - `Rectangle` - `RegularPolygon` - `Triangle2d` The `mesh` method typically returns a builder-like struct such as `CircleMeshBuilder`. This is needed to support shape-specific configuration for things like mesh resolution or UV configuration: ```rust meshes.add(Circle { radius: 0.5 }.mesh().resolution(64)); ``` Note that if no configuration is needed, you can even skip calling `mesh` because `From<MyPrimitive>` is implemented for `Mesh`: ```rust meshes.add(Circle { radius: 0.5 }); ``` I also updated the `2d_shapes` example to use primitives, and tweaked the colors to have better contrast against the dark background. Before:  After:  Here you can see the UVs and different facing directions: (taken from bevyengine#11007, so excuse the 3D primitives at the bottom left)  --- ## Changelog - Added `bevy_render::mesh::primitives` module - Added `Meshable` trait and implemented it for: - `Circle` - `Ellipse` - `Rectangle` - `RegularPolygon` - `Triangle2d` - Implemented `Default` and `Copy` for several 2D primitives - Updated `2d_shapes` example to use primitives - Tweaked colors in `2d_shapes` example to have better contrast against the (new-ish) dark background --------- Co-authored-by: Alice Cecile <[email protected]>
# Objective Currently, the `Capsule` primitive is technically dimension-agnostic in that it implements both `Primitive2d` and `Primitive3d`. This seems good on paper, but it can often be useful to have separate 2D and 3D versions of primitives. For example, one might want a two-dimensional capsule mesh. We can't really implement both 2D and 3D meshing for the same type using the upcoming `Meshable` trait (see bevyengine#11431). We also currently don't implement `Bounded2d` for `Capsule`, see bevyengine#11336 (comment). Having 2D and 3D separate at a type level is more explicit, and also more consistent with the existing primitives, as there are no other types that implement both `Primitive2d` and `Primitive3d` at the same time. ## Solution Rename `Capsule` to `Capsule3d` and add `Capsule2d`. `Capsule2d` implements `Bounded2d`. For now, I went for `Capsule2d` for the sake of consistency and clarity. Mathematically the more accurate term would be `Stadium` or `Pill` (see [Wikipedia](https://en.wikipedia.org/wiki/Stadium_(geometry))), but those might be less obvious to game devs. For reference, Godot has [`CapsuleShape2D`](https://docs.godotengine.org/en/stable/classes/class_capsuleshape2d.html). I can rename it if others think the geometrically correct name is better though. --- ## Changelog - Renamed `Capsule` to `Capsule3d` - Added `Capsule2d` with `Bounded2d` implemented --------- Co-authored-by: Alice Cecile <[email protected]>
# Objective #11431 and #11688 implemented meshing support for Bevy's new geometric primitives. The next step is to deprecate the shapes in `bevy_render::mesh::shape` and to later remove them completely for 0.14. ## Solution Deprecate the shapes and reduce code duplication by utilizing the primitive meshing API for the old shapes where possible. Note that some shapes have behavior that can't be exactly reproduced with the new primitives yet: - `Box` is more of an AABB with min/max extents - `Plane` supports a subdivision count - `Quad` has a `flipped` property These types have not been changed to utilize the new primitives yet. --- ## Changelog - Deprecated all shapes in `bevy_render::mesh::shape` - Changed all examples to use new primitives for meshing ## Migration Guide Bevy has previously used rendering-specific types like `UVSphere` and `Quad` for primitive mesh shapes. These have now been deprecated to use the geometric primitives newly introduced in version 0.13. Some examples: ```rust let before = meshes.add(shape::Box::new(5.0, 0.15, 5.0)); let after = meshes.add(Cuboid::new(5.0, 0.15, 5.0)); let before = meshes.add(shape::Quad::default()); let after = meshes.add(Rectangle::default()); let before = meshes.add(shape::Plane::from_size(5.0)); // The surface normal can now also be specified when using `new` let after = meshes.add(Plane3d::default().mesh().size(5.0, 5.0)); let before = meshes.add( Mesh::try_from(shape::Icosphere { radius: 0.5, subdivisions: 5, }) .unwrap(), ); let after = meshes.add(Sphere::new(0.5).mesh().ico(5).unwrap()); ```
Objective
The first part of #10569, split up from #11007.
The goal is to implement meshing support for Bevy's new geometric primitives, starting with 2D primitives. 3D meshing will be added in a follow-up, and we can consider removing the old mesh shapes completely.
Solution
Add a
Meshabletrait that primitives need to implement to support meshing, as suggested by the RFC.This PR implements it for the following primitives:
CircleEllipseRectangleRegularPolygonTriangle2dThe
meshmethod typically returns a builder-like struct such asCircleMeshBuilder. This is needed to support shape-specific configuration for things like mesh resolution or UV configuration:Note that if no configuration is needed, you can even skip calling
meshbecauseFrom<MyPrimitive>is implemented forMesh:I also updated the
2d_shapesexample to use primitives, and tweaked the colors to have better contrast against the dark background.Before:
After:
Here you can see the UVs and different facing directions: (taken from #11007, so excuse the 3D primitives at the bottom left)
Changelog
bevy_render::mesh::primitivesmoduleMeshabletrait and implemented it for:CircleEllipseRectangleRegularPolygonTriangle2dDefaultandCopyfor several 2D primitives2d_shapesexample to use primitives2d_shapesexample to have better contrast against the (new-ish) dark background