Skip to content

Commit 33cd59f

Browse files
Aztro-devJondolfalice-i-cecile
authored
Add and impl Primitives (#10580)
# Add and implement constructors for Primitives - Adds more Primitive types and adds a constructor for almost all of them - Works towards finishing #10572 ## Solution - Created new primitives - Torus - Conical Frustum - Cone - Ellipse - Implemented constructors (`Primitive::new`) for almost every single other primitive. --------- Co-authored-by: Joona Aalto <[email protected]> Co-authored-by: Alice Cecile <[email protected]>
1 parent 0c9f265 commit 33cd59f

File tree

2 files changed

+195
-2
lines changed

2 files changed

+195
-2
lines changed

crates/bevy_math/src/primitives/dim2.rs

Lines changed: 117 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,26 @@ pub struct Circle {
3434
}
3535
impl Primitive2d for Circle {}
3636

37+
/// An ellipse primitive
38+
#[derive(Clone, Copy, Debug)]
39+
pub struct Ellipse {
40+
/// The half "width" of the ellipse
41+
pub half_width: f32,
42+
/// The half "height" of the ellipse
43+
pub half_height: f32,
44+
}
45+
impl Primitive2d for Ellipse {}
46+
47+
impl Ellipse {
48+
/// Create a new `Ellipse` from a "width" and a "height"
49+
pub fn new(width: f32, height: f32) -> Self {
50+
Self {
51+
half_width: width / 2.0,
52+
half_height: height / 2.0,
53+
}
54+
}
55+
}
56+
3757
/// An unbounded plane in 2D space. It forms a separating surface through the origin,
3858
/// stretching infinitely far
3959
#[derive(Clone, Copy, Debug)]
@@ -108,6 +128,24 @@ pub struct Polyline2d<const N: usize> {
108128
}
109129
impl<const N: usize> Primitive2d for Polyline2d<N> {}
110130

131+
impl<const N: usize> FromIterator<Vec2> for Polyline2d<N> {
132+
fn from_iter<I: IntoIterator<Item = Vec2>>(iter: I) -> Self {
133+
let mut vertices: [Vec2; N] = [Vec2::ZERO; N];
134+
135+
for (index, i) in iter.into_iter().take(N).enumerate() {
136+
vertices[index] = i;
137+
}
138+
Self { vertices }
139+
}
140+
}
141+
142+
impl<const N: usize> Polyline2d<N> {
143+
/// Create a new `Polyline2d` from its vertices
144+
pub fn new(vertices: impl IntoIterator<Item = Vec2>) -> Self {
145+
Self::from_iter(vertices)
146+
}
147+
}
148+
111149
/// A series of connected line segments in 2D space, allocated on the heap
112150
/// in a `Box<[Vec2]>`.
113151
///
@@ -119,6 +157,22 @@ pub struct BoxedPolyline2d {
119157
}
120158
impl Primitive2d for BoxedPolyline2d {}
121159

160+
impl FromIterator<Vec2> for BoxedPolyline2d {
161+
fn from_iter<I: IntoIterator<Item = Vec2>>(iter: I) -> Self {
162+
let vertices: Vec<Vec2> = iter.into_iter().collect();
163+
Self {
164+
vertices: vertices.into_boxed_slice(),
165+
}
166+
}
167+
}
168+
169+
impl BoxedPolyline2d {
170+
/// Create a new `BoxedPolyline2d` from its vertices
171+
pub fn new(vertices: impl IntoIterator<Item = Vec2>) -> Self {
172+
Self::from_iter(vertices)
173+
}
174+
}
175+
122176
/// A triangle in 2D space
123177
#[derive(Clone, Debug)]
124178
pub struct Triangle2d {
@@ -127,6 +181,15 @@ pub struct Triangle2d {
127181
}
128182
impl Primitive2d for Triangle2d {}
129183

184+
impl Triangle2d {
185+
/// Create a new `Triangle2d` from `a`, `b`, and `c`,
186+
pub fn new(a: Vec2, b: Vec2, c: Vec2) -> Self {
187+
Self {
188+
vertices: [a, b, c],
189+
}
190+
}
191+
}
192+
130193
/// A rectangle primitive
131194
#[doc(alias = "Quad")]
132195
#[derive(Clone, Copy, Debug)]
@@ -158,22 +221,56 @@ impl Rectangle {
158221
/// For a version without generics: [`BoxedPolygon`]
159222
#[derive(Clone, Debug)]
160223
pub struct Polygon<const N: usize> {
161-
/// The vertices of the polygon
224+
/// The vertices of the `Polygon`
162225
pub vertices: [Vec2; N],
163226
}
164227
impl<const N: usize> Primitive2d for Polygon<N> {}
165228

229+
impl<const N: usize> FromIterator<Vec2> for Polygon<N> {
230+
fn from_iter<I: IntoIterator<Item = Vec2>>(iter: I) -> Self {
231+
let mut vertices: [Vec2; N] = [Vec2::ZERO; N];
232+
233+
for (index, i) in iter.into_iter().take(N).enumerate() {
234+
vertices[index] = i;
235+
}
236+
Self { vertices }
237+
}
238+
}
239+
240+
impl<const N: usize> Polygon<N> {
241+
/// Create a new `Polygon` from its vertices
242+
pub fn new(vertices: impl IntoIterator<Item = Vec2>) -> Self {
243+
Self::from_iter(vertices)
244+
}
245+
}
246+
166247
/// A polygon with a variable number of vertices, allocated on the heap
167248
/// in a `Box<[Vec2]>`.
168249
///
169250
/// For a version without alloc: [`Polygon`]
170251
#[derive(Clone, Debug)]
171252
pub struct BoxedPolygon {
172-
/// The vertices of the polygon
253+
/// The vertices of the `BoxedPolygon`
173254
pub vertices: Box<[Vec2]>,
174255
}
175256
impl Primitive2d for BoxedPolygon {}
176257

258+
impl FromIterator<Vec2> for BoxedPolygon {
259+
fn from_iter<I: IntoIterator<Item = Vec2>>(iter: I) -> Self {
260+
let vertices: Vec<Vec2> = iter.into_iter().collect();
261+
Self {
262+
vertices: vertices.into_boxed_slice(),
263+
}
264+
}
265+
}
266+
267+
impl BoxedPolygon {
268+
/// Create a new `BoxedPolygon` from its vertices
269+
pub fn new(vertices: impl IntoIterator<Item = Vec2>) -> Self {
270+
Self::from_iter(vertices)
271+
}
272+
}
273+
177274
/// A polygon where all vertices lie on a circle, equally far apart
178275
#[derive(Clone, Copy, Debug)]
179276
pub struct RegularPolygon {
@@ -183,3 +280,21 @@ pub struct RegularPolygon {
183280
pub sides: usize,
184281
}
185282
impl Primitive2d for RegularPolygon {}
283+
284+
impl RegularPolygon {
285+
/// Create a new `RegularPolygon`
286+
/// from the radius of the circumcircle and number of sides
287+
///
288+
/// # Panics
289+
///
290+
/// Panics if `circumcircle_radius` is non-positive
291+
pub fn new(circumcircle_radius: f32, sides: usize) -> Self {
292+
assert!(circumcircle_radius > 0.0);
293+
Self {
294+
circumcircle: Circle {
295+
radius: circumcircle_radius,
296+
},
297+
sides,
298+
}
299+
}
300+
}

crates/bevy_math/src/primitives/dim3.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,24 @@ pub struct Polyline3d<const N: usize> {
107107
}
108108
impl<const N: usize> Primitive3d for Polyline3d<N> {}
109109

110+
impl<const N: usize> FromIterator<Vec3> for Polyline3d<N> {
111+
fn from_iter<I: IntoIterator<Item = Vec3>>(iter: I) -> Self {
112+
let mut vertices: [Vec3; N] = [Vec3::ZERO; N];
113+
114+
for (index, i) in iter.into_iter().take(N).enumerate() {
115+
vertices[index] = i;
116+
}
117+
Self { vertices }
118+
}
119+
}
120+
121+
impl<const N: usize> Polyline3d<N> {
122+
/// Create a new `Polyline3d` from its vertices
123+
pub fn new(vertices: impl IntoIterator<Item = Vec3>) -> Self {
124+
Self::from_iter(vertices)
125+
}
126+
}
127+
110128
/// A series of connected line segments in 3D space, allocated on the heap
111129
/// in a `Box<[Vec3]>`.
112130
///
@@ -118,6 +136,22 @@ pub struct BoxedPolyline3d {
118136
}
119137
impl Primitive3d for BoxedPolyline3d {}
120138

139+
impl FromIterator<Vec3> for BoxedPolyline3d {
140+
fn from_iter<I: IntoIterator<Item = Vec3>>(iter: I) -> Self {
141+
let vertices: Vec<Vec3> = iter.into_iter().collect();
142+
Self {
143+
vertices: vertices.into_boxed_slice(),
144+
}
145+
}
146+
}
147+
148+
impl BoxedPolyline3d {
149+
/// Create a new `BoxedPolyline3d` from its vertices
150+
pub fn new(vertices: impl IntoIterator<Item = Vec3>) -> Self {
151+
Self::from_iter(vertices)
152+
}
153+
}
154+
121155
/// A cuboid primitive, more commonly known as a box.
122156
#[derive(Clone, Copy, Debug)]
123157
pub struct Cuboid {
@@ -171,3 +205,47 @@ pub struct Capsule {
171205
}
172206
impl super::Primitive2d for Capsule {}
173207
impl Primitive3d for Capsule {}
208+
209+
impl Capsule {
210+
/// Create a new `Capsule` from a radius and length
211+
pub fn new(radius: f32, length: f32) -> Self {
212+
Self {
213+
radius,
214+
half_length: length / 2.0,
215+
}
216+
}
217+
}
218+
219+
/// A cone primitive.
220+
#[derive(Clone, Copy, Debug)]
221+
pub struct Cone {
222+
/// The radius of the base
223+
pub radius: f32,
224+
/// The height of the cone
225+
pub height: f32,
226+
}
227+
impl Primitive3d for Cone {}
228+
229+
/// A conical frustum primitive.
230+
/// A conical frustum can be created
231+
/// by slicing off a section of a cone.
232+
#[derive(Clone, Copy, Debug)]
233+
pub struct ConicalFrustum {
234+
/// The radius of the top of the frustum
235+
pub radius_top: f32,
236+
/// The radius of the base of the frustum
237+
pub radius_bottom: f32,
238+
/// The height of the frustum
239+
pub height: f32,
240+
}
241+
impl Primitive3d for ConicalFrustum {}
242+
243+
/// A torus (AKA donut) primitive.
244+
#[derive(Clone, Copy, Debug)]
245+
pub struct Torus {
246+
/// The radius of the overall shape
247+
pub radius: f32,
248+
/// The radius of the internal ring
249+
pub ring_radius: f32,
250+
}
251+
impl Primitive3d for Torus {}

0 commit comments

Comments
 (0)