Skip to content
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

Add and impl Primitives #10580

Merged
merged 22 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
3c439a1
Add new primitives
Aztro-dev Nov 15, 2023
4c79096
Impl new functions for primitive shapes
Aztro-dev Nov 16, 2023
5e12cc9
Update crates/bevy_math/src/primitives/dim2.rs
Aztro-dev Nov 16, 2023
e976114
Implement requested changes and change up constructors a bit
Aztro-dev Nov 16, 2023
5200e06
Update crates/bevy_math/src/primitives/dim3.rs
Aztro-dev Nov 16, 2023
926c2df
Implement requested changes
Aztro-dev Nov 16, 2023
235b473
Remove more trivial constructors
Aztro-dev Nov 16, 2023
2efd563
Update crates/bevy_math/src/primitives/dim3.rs
Aztro-dev Nov 16, 2023
9d5cbc3
Should be the last of the trivial constructors
Aztro-dev Nov 16, 2023
ca5f977
Implicit return
Aztro-dev Nov 16, 2023
5bf8491
Added index enumeration
Aztro-dev Nov 16, 2023
5e93e79
Minor capsule documentation fix
Aztro-dev Nov 16, 2023
9422276
Iterator fix
Aztro-dev Nov 17, 2023
c543697
Fix CI error
Aztro-dev Nov 17, 2023
05d488f
take() instead of checking for iterator size
Aztro-dev Nov 17, 2023
da80164
take() implemented into iterator
Aztro-dev Nov 17, 2023
5340e96
Implement from_iter() for structs and check for non-positive circumci…
Aztro-dev Nov 17, 2023
cf2b44e
Polygon iterator constructor and Triangle2d a,b,c constructor
Aztro-dev Nov 17, 2023
0550f30
Update crates/bevy_math/src/primitives/dim2.rs
Aztro-dev Nov 17, 2023
5b7e525
Update FromIterator constructors to have more general documentation w…
Aztro-dev Nov 17, 2023
fce6f02
Update dim3.rs
Aztro-dev Nov 17, 2023
2bc9c0c
Update dim3.rs docs
Aztro-dev Nov 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 79 additions & 2 deletions crates/bevy_math/src/primitives/dim2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,30 @@ pub struct Circle {
}
impl Primitive2d for Circle {}

impl Circle {
/// Create a `Circle` from a radius
pub fn new(radius: f32) -> Self {
Aztro-dev marked this conversation as resolved.
Show resolved Hide resolved
Self { radius }
}
}

/// An ellipse primitive
#[derive(Clone, Copy, Debug)]
pub struct Ellipse {
/// The "width" of the ellipse
pub width: f32,
/// The "height" of the ellipse
pub height: f32,
Aztro-dev marked this conversation as resolved.
Show resolved Hide resolved
}
impl Primitive2d for Ellipse {}

impl Ellipse {
/// Create a new `Ellipse` from a "width" and a "height"
pub fn new(width: f32, height: f32) -> Self {
Self { width, height }
}
}

/// An unbounded plane in 2D space. It forms a separating surface through the origin,
/// stretching infinitely far
#[derive(Clone, Copy, Debug)]
Expand All @@ -43,6 +67,13 @@ pub struct Plane2d {
}
impl Primitive2d for Plane2d {}

impl Plane2d {
/// Create a new `Plane2d` from the normal of the plane
pub fn new(normal: Direction2d) -> Self {
Aztro-dev marked this conversation as resolved.
Show resolved Hide resolved
Self { normal }
}
}

/// An infinite line along a direction in 2D space.
///
/// For a finite line: [`Segment2d`]
Expand Down Expand Up @@ -108,6 +139,13 @@ pub struct Polyline2d<const N: usize> {
}
impl<const N: usize> Primitive2d for Polyline2d<N> {}

impl<const N: usize> Polyline2d<N> {
/// Create a new `Polyline2d` from an array of vertices
Aztro-dev marked this conversation as resolved.
Show resolved Hide resolved
pub fn new(vertices: [Vec2; N]) -> Self {
Aztro-dev marked this conversation as resolved.
Show resolved Hide resolved
Self { vertices }
}
}

/// A series of connected line segments in 2D space, allocated on the heap
/// in a `Box<[Vec2]>`.
///
Expand All @@ -119,6 +157,13 @@ pub struct BoxedPolyline2d {
}
impl Primitive2d for BoxedPolyline2d {}

impl BoxedPolyline2d {
/// Create a new `Polyline2d` from an array of vertices
pub fn new(vertices: Box<[Vec2]>) -> Self {
alice-i-cecile marked this conversation as resolved.
Show resolved Hide resolved
Self { vertices }
}
}

/// A triangle in 2D space
#[derive(Clone, Debug)]
pub struct Triangle2d {
Expand All @@ -127,6 +172,13 @@ pub struct Triangle2d {
}
impl Primitive2d for Triangle2d {}

impl Triangle2d {
/// Create a new `Triangle2d` from a list of Vertices
Aztro-dev marked this conversation as resolved.
Show resolved Hide resolved
pub fn new(vertices: [Vec2; 3]) -> Self {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be nice to have a method that takes points a, b and c instead. Taking an array doesn't feel quite as intuitive in my opinion, although it's almost the same.

Not sure which one of them should be new, but the other method could be either from_points or from_array based on what is chosen.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer this to be the new, and not include from_array at all.

Self { vertices }
}
}

/// A rectangle primitive
#[doc(alias = "Quad")]
#[derive(Clone, Copy, Debug)]
Expand Down Expand Up @@ -158,22 +210,36 @@ impl Rectangle {
/// For a version without generics: [`BoxedPolygon`]
#[derive(Clone, Debug)]
pub struct Polygon<const N: usize> {
/// The vertices of the polygon
/// The vertices of the `Polygon`
pub vertices: [Vec2; N],
}
impl<const N: usize> Primitive2d for Polygon<N> {}

impl<const N: usize> Polygon<N> {
/// Create a new `Polygon` from an array of vertices
pub fn new(vertices: [Vec2; N]) -> Self {
alice-i-cecile marked this conversation as resolved.
Show resolved Hide resolved
Self { vertices }
}
}

/// A polygon with a variable number of vertices, allocated on the heap
/// in a `Box<[Vec2]>`.
///
/// For a version without alloc: [`Polygon`]
#[derive(Clone, Debug)]
pub struct BoxedPolygon {
/// The vertices of the polygon
/// The vertices of the `BoxedPolygon`
pub vertices: Box<[Vec2]>,
}
impl Primitive2d for BoxedPolygon {}

impl BoxedPolygon {
/// Create a new `BoxedPolygon` from an array of vertices
pub fn new(vertices: Box<[Vec2]>) -> Self {
alice-i-cecile marked this conversation as resolved.
Show resolved Hide resolved
Self { vertices }
}
}

/// A polygon where all vertices lie on a circle, equally far apart
#[derive(Clone, Copy, Debug)]
pub struct RegularPolygon {
Expand All @@ -183,3 +249,14 @@ pub struct RegularPolygon {
pub sides: usize,
}
impl Primitive2d for RegularPolygon {}

impl RegularPolygon {
/// Create a new `RegularPolygon`
/// from a circumcircle and number of sides
pub fn new(circumcircle: Circle, sides: usize) -> Self {
Aztro-dev marked this conversation as resolved.
Show resolved Hide resolved
Self {
circumcircle,
sides,
}
}
}
108 changes: 108 additions & 0 deletions crates/bevy_math/src/primitives/dim3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ pub struct Sphere {
}
impl Primitive3d for Sphere {}

impl Sphere {
/// Create a new `Sphere` from a radius
pub fn new(radius: f32) -> Self {
Self { radius }
}
}

/// An unbounded plane in 3D space. It forms a separating surface through the origin,
/// stretching infinitely far
#[derive(Clone, Copy, Debug)]
Expand All @@ -43,6 +50,13 @@ pub struct Plane3d {
}
impl Primitive3d for Plane3d {}

impl Plane3d {
/// Create a new `Plane3d` from the normal of the plane
pub fn new(normal: Direction3d) -> Self {
Self { normal }
}
}

/// An infinite line along a direction in 3D space.
///
/// For a finite line: [`Segment3d`]
Expand All @@ -53,6 +67,13 @@ pub struct Line3d {
}
impl Primitive3d for Line3d {}

impl Line3d {
/// Create a new `Line3d` from the direction of the line
pub fn new(direction: Direction3d) -> Self {
Self { direction }
}
}

/// A segment of a line along a direction in 3D space.
#[doc(alias = "LineSegment3d")]
#[derive(Clone, Debug)]
Expand Down Expand Up @@ -107,6 +128,13 @@ pub struct Polyline3d<const N: usize> {
}
impl<const N: usize> Primitive3d for Polyline3d<N> {}

impl<const N: usize> Polyline3d<N> {
/// Create a new `Polyline3d` from a list of vertices
pub fn new(vertices: [Vec3; N]) -> Self {
Aztro-dev marked this conversation as resolved.
Show resolved Hide resolved
Self { vertices }
}
}

/// A series of connected line segments in 3D space, allocated on the heap
/// in a `Box<[Vec3]>`.
///
Expand All @@ -118,6 +146,13 @@ pub struct BoxedPolyline3d {
}
impl Primitive3d for BoxedPolyline3d {}

impl BoxedPolyline3d {
/// Create a new `BoxedPolyline3d` from a list of vertices
pub fn new(vertices: Box<[Vec3]>) -> Self {
Self { vertices }
}
}

/// A cuboid primitive, more commonly known as a box.
#[derive(Clone, Copy, Debug)]
pub struct Cuboid {
Expand Down Expand Up @@ -171,3 +206,76 @@ pub struct Capsule {
}
impl super::Primitive2d for Capsule {}
impl Primitive3d for Capsule {}

impl Capsule {
/// Create a new `Capsule` from a radius and half-length
Aztro-dev marked this conversation as resolved.
Show resolved Hide resolved
pub fn new(radius: f32, half_length: f32) -> Self {
Self {
radius,
half_length,
}
}
Aztro-dev marked this conversation as resolved.
Show resolved Hide resolved
}

/// A cone primitive.
Copy link
Contributor

@Jondolf Jondolf Nov 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @NiseVoid suggested (#10580 (comment)), maybe we should mention where the origin of the cone should be so that different integrations have consistent representations?

If the options are the base and apex (tip), the base is more intuitive for me personally. I view cones like Wikipedia's description:

a three-dimensional geometric shape that tapers smoothly from a flat base (frequently, though not necessarily, circular) to a point called the apex or vertex.

#[derive(Clone, Copy, Debug)]
pub struct Cone {
/// radius of the base
pub radius: f32,
/// height of the cone
pub height: f32,
Aztro-dev marked this conversation as resolved.
Show resolved Hide resolved
Aztro-dev marked this conversation as resolved.
Show resolved Hide resolved
}
impl Primitive3d for Cone {}

impl Cone {
/// Create a new `Cone` from a radius and height
pub fn new(radius: f32, height: f32) -> Self {
Aztro-dev marked this conversation as resolved.
Show resolved Hide resolved
Self { radius, height }
}
}

/// A conical frustum primitive.
/// A conical frustum can be created
/// by slicing off a section of a cone.
#[derive(Clone, Copy, Debug)]
pub struct ConicalFrustum {
Copy link
Contributor

@Jondolf Jondolf Nov 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also nice to have, but if we also want primitives to be used for rendering, a viewing frustum would be more useful. For rendering, it would be defined by an aspect-ratio, fov and the near and far planes, but maybe that's a bit too rendering-specific for primitives? More opinions on this would be useful.

If we add a viewing frustum though, it should probably be done in a separate PR since it'd touch on rendering code too and be a bit more controversial.

If we want to support different types of frusta, then perhaps a polygonal frustum with a regular polygon as a base could also be useful?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@superdump also briefly touched on this here: #10466 (comment)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, we should split rendering frustra into a different PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rendering frustum most likely belongs in the bounding PR. Might be good to create some helper later to create a primitive shape you can render from the 6 plane representation (which is not exactly most convinient way to render them)

/// Radius of the top of the frustum
pub radius_top: f32,
/// Radius of the base of the frustum
pub radius_bottom: f32,
/// Height of the frustum
pub height: f32,
Aztro-dev marked this conversation as resolved.
Show resolved Hide resolved
Aztro-dev marked this conversation as resolved.
Show resolved Hide resolved
}
impl Primitive3d for ConicalFrustum {}

impl ConicalFrustum {
/// Create a new `ConicalFrustum` from a top
/// radius, bottom radius, and height
pub fn new(radius_top: f32, radius_bottom: f32, height: f32) -> Self {
Aztro-dev marked this conversation as resolved.
Show resolved Hide resolved
Self {
radius_top,
radius_bottom,
height,
}
}
}

/// A torus (AKA donut) primitive.
#[derive(Clone, Copy, Debug)]
pub struct Torus {
/// The radius of the overall shape
pub radius: f32,
/// The radius of the ring
Aztro-dev marked this conversation as resolved.
Show resolved Hide resolved
pub ring_radius: f32,
}
impl Primitive3d for Torus {}

impl Torus {
/// Create a new `Torus` from a radius and ring radius
pub fn new(radius: f32, ring_radius: f32) -> Self {
Aztro-dev marked this conversation as resolved.
Show resolved Hide resolved
Self {
radius,
ring_radius,
}
}
}