1#[derive(Clone, Copy, Debug, PartialEq, Eq)]
2pub struct ShapeSourceHandle {
3 pub id: u32,
4 pub generation: u32,
5}
6
7#[derive(Clone, Copy, Debug, PartialEq)]
8pub enum Shape {
9 Sphere { radius: f32 },
10 Cuboid { half_extents: [f32; 3] },
11 Capsule { radius: f32, half_height: f32 },
12 Cylinder { radius: f32, half_height: f32 },
13 Hull(ShapeSourceHandle),
14 Mesh(ShapeSourceHandle),
15 HeightField(ShapeSourceHandle),
16 Plane,
17}
18
19impl Shape {
20 pub fn sphere(radius: f32) -> Self {
21 assert!(radius > 0.0, "shape radius must be strictly positive");
22 Self::Sphere { radius }
23 }
24
25 pub fn cuboid(half_extents: [f32; 3]) -> Self {
26 assert!(
27 half_extents.iter().all(|extent| *extent > 0.0),
28 "cuboid half extents must be strictly positive"
29 );
30 Self::Cuboid { half_extents }
31 }
32
33 pub fn capsule(radius: f32, half_height: f32) -> Self {
34 assert!(radius > 0.0, "capsule radius must be strictly positive");
35 assert!(
36 half_height >= 0.0,
37 "capsule half height must be non-negative"
38 );
39 Self::Capsule {
40 radius,
41 half_height,
42 }
43 }
44
45 pub fn cylinder(radius: f32, half_height: f32) -> Self {
46 assert!(radius > 0.0, "cylinder radius must be strictly positive");
47 assert!(
48 half_height >= 0.0,
49 "cylinder half height must be non-negative"
50 );
51 Self::Cylinder {
52 radius,
53 half_height,
54 }
55 }
56
57 pub fn hull(source: ShapeSourceHandle) -> Self {
58 Self::Hull(source)
59 }
60
61 pub fn mesh(source: ShapeSourceHandle) -> Self {
62 Self::Mesh(source)
63 }
64
65 pub fn height_field(source: ShapeSourceHandle) -> Self {
66 Self::HeightField(source)
67 }
68
69 pub fn plane() -> Self {
70 Self::Plane
71 }
72
73 pub fn is_world_geometry(&self) -> bool {
74 matches!(self, Self::Mesh(_) | Self::HeightField(_) | Self::Plane)
75 }
76
77 pub fn is_convex(&self) -> bool {
78 !matches!(self, Self::Mesh(_) | Self::HeightField(_) | Self::Plane)
79 }
80}