Skip to main content

dynamis_model/
shape.rs

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