bevy icon indicating copy to clipboard operation
bevy copied to clipboard

New circular primitives: `Arc2d`, `CircularSector`, `CircularSegment`

Open spectria-limina opened this issue 2 years ago • 9 comments

Objective

There are no 2d primitives available for the common shapes of an arc or a circular sector (pie slice).

Solution

This PR introduces three new types to the existing math primitives:

  • Arc2d: a portion of a (hollow) circle
  • CircularSector: the area between an arc and the centre of the circle
  • CircularSegment: the convex hull of an arc

Run cargo run --example 2d_shapes to see examples of the CircularSector and CircularSegment type.

Design decisions

  1. What should the arc type be named?

    Answer: Arc2d, because Arc is already taken by the standard library.

  2. What should the origin point of these shapes be?

    • The origin point is the point around which the shape rotates, among other things.
    • For an arc and a circular sector, it's intuitive I think that the origin be the center of the corresponding circle.
    • But for a circular segment, I think the origin being the center of the chord is more intuitive, because it is easier to reason about rotation math that way.
    • On the other hand, consistency between the three shapes has value.

    Answer: This PR puts the origin of all three shapes in the center, prioritizing consistency,

  3. What should the UV-mapping of CircularSector and CircularSegment look like? There are two reasonable options:

    1. Treat the shapes as masks of the corresponding circle. Good for animating the texture, or cutting a single circular texture into pieces e.g. pizza slices.
    2. Map the shape's bounding box onto the texture. Good when the slice size is fixed and not going to change, to be maximally efficient with the texture space.

    Answer: This PR chooses option 1 as the default, but puts UV-mapping configuration in a CircularMeshUvMode enum, as futureproofing for later adding option 2.

  4. How should the angle of these shapes be expressed?

    1. Follow mathematical conventions of starting from the right and going counterclockwise.
    2. Start from the top and extend by half the angle on either side.

    Answer: This PR chooses option 2, because it leads to better defaults and better ergonomics when reasoning about how to rotate the shape.

TODO

  • [x] Add convenience methods on CircularSector and CircularSegment that avoid needing to explicitly access the arc field.
  • [x] Add examples that make use of textures, to verify that the UV mappings are correct.
  • [x] Add testing, particularly of the shape math. (I've already caught at least one bug and there are probably more.)

Future Work

For after this PR is merged:

  • Add support for these shapes to Gizmos as in #11072.
  • Add support for the alternative UV mode discussed above, as a configurable option on the MeshBuilder types.
  • Integrate these shapes into the new math/primitives example.

Changelog

  • Added Arc2d, CircularSector, and CircularSegment primitives to [bevy::math::primitives].

spectria-limina avatar Feb 06 '24 22:02 spectria-limina

Welcome, new contributor!

Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨

github-actions[bot] avatar Feb 06 '24 22:02 github-actions[bot]

Thanks for the review! I've made the changes plus a few more things. I'll update the first comment to reflect the current state of things.

spectria-limina avatar Feb 13 '24 05:02 spectria-limina

The generated examples/README.md is out of sync with the example metadata in Cargo.toml or the example readme template. Please run cargo run -p build-templated-pages -- update examples to update it, and commit the file change.

github-actions[bot] avatar Feb 14 '24 21:02 github-actions[bot]

You added a new example but didn't add metadata for it. Please update the root Cargo.toml file.

github-actions[bot] avatar Mar 09 '24 09:03 github-actions[bot]

I've now updated the PR and got it as close to working as I can, but #12729 is preventing all tests from passing and I can't figure out a fix locally.

spectria-limina avatar Mar 26 '24 08:03 spectria-limina

The generated examples/README.md is out of sync with the example metadata in Cargo.toml or the example readme template. Please run cargo run -p build-templated-pages -- update examples to update it, and commit the file change.

github-actions[bot] avatar Mar 26 '24 09:03 github-actions[bot]

There also seems to be a failing wasm build that isn't related to my PR.

spectria-limina avatar Mar 26 '24 09:03 spectria-limina

There also seems to be a failing wasm build that isn't related to my PR.

That has been fixed #12730

bugsweeper avatar Mar 26 '24 15:03 bugsweeper

@spectria-limina I'm happy to merge this as is: let me know if you're able to resolve merge conflicts?

alice-i-cecile avatar Apr 30 '24 00:04 alice-i-cecile