Skip to content

Meshes from primitives #10569

@Jondolf

Description

@Jondolf

What problem does this solve or what need does it fill?

Meshes can currently be created from the shapes in bevy_render::mesh::shape. These are shapes that are specific to rendering and contain information about things like how a sphere should be subdivided.

Now that primitive shapes have been added in #10466, it should be possible to have a more unified shape API for meshes, gizmos, colliders and so on. It should be possible to create meshes from the primitive shapes in bevy_math::primitives.

What solution would you like?

Implement mesh generation for primitive shapes, and maybe remove duplicate shapes from bevy_render::mesh::shape.

For some shapes, it's as straightforward as this:

let cube = Mesh::from(Cuboid::new(1.0, 1.0, 1.0)); // or just call .mesh()?

However, for many other shapes it's not as straightforward. For example, the current Capsule shape used for rendering has properties such as rings, latitudes, longitudes and uv_profile. This would not work with a simple impl From<Capsule> for Mesh.

Some options include:

  1. Keep separate types for rendering specifics, and create meshes from them like Mesh::from(UvSphere::new(Sphere::new(1.0), longitudes, latitudes)).
    • Similar to what we have now, pretty explicit and also familiar
    • Quite verbose and repeats Sphere
    • Annoying to have separate rendering shapes when one of the main ideas of shape primitives is to unify things
    • Rendering configuration is stored in a separate struct (good or bad depending on the use case)
  2. Have methods like mesh that are different for each primitive, like Sphere::new(1.0).uv_mesh(longitudes, latitudes)
    • Can be nice and concise
    • Shape primitives can be used directly instead of intermediary types
    • No shared trait for all types of meshes because of different requirements
    • No information about the rendering configuration is stored (good or bad depending on the use case)
  3. Hard-code a global default configuration for mesh quality / subdivision count
    • Very easy API, just Mesh::from(Sphere::new(1.0))
    • Very inflexible; there would still need to be a way to specify it manually as needed
    • Shapes don't always have a single subdivision property, but can have multiple like longitudes/latitudes

We don't want 3 by itself, but I'm personally leaning on a combination of 2 and 3. We could have hard-coded default implementations for From and maybe a Meshable trait that has a mesh method with some default mesh configuration implemented, as suggested by the original RFC, but also give primitives custom mesh construction methods like .uv_mesh(...) where necessary. This would provide a nice API with good defaults, without having many different shape types for the same core shapes (like spheres), while still allowing full control for subdivisions and other configuration as needed.

Ideas and suggestions are welcome!

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-RenderingDrawing game state to the screenC-FeatureA new feature, making something new possible

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions