1use bevy::prelude::*;
2
3use space_shared::ext::bevy_inspector_egui;
4use space_shared::ext::bevy_inspector_egui::prelude::*;
5
6#[derive(Component, Reflect, Clone)]
8#[reflect(Default, Component)]
9pub enum MeshPrimitivePrefab {
10 Cube(f32),
11 Box(BoxPrefab),
12 Sphere(SpherePrefab),
13 Quad(QuadPrefab),
14 Capsule(CapsulePrefab),
15 Circle(CirclePrefab),
16 Cylinder(CylinderPrefab),
17 Icosphere(IcospherePrefab),
18 Plane(PlanePrefab),
19 RegularPolygon(RegularPolygonPrefab),
20 Torus(TorusPrefab),
21}
22
23impl Default for MeshPrimitivePrefab {
24 fn default() -> Self {
25 Self::Box(BoxPrefab {
26 w: 1.0,
27 h: 1.0,
28 d: 1.0,
29 })
30 }
31}
32
33impl MeshPrimitivePrefab {
34 pub fn to_mesh(&self) -> Mesh {
36 match self {
37 Self::Cube(s) => Mesh::from(shape::Cube::new(*s)),
38 Self::Box(b) => b.to_mesh(),
39 Self::Sphere(s) => s.to_mesh(),
40 Self::Quad(q) => q.to_mesh(),
41 Self::Capsule(c) => c.to_mesh(),
42 Self::Circle(c) => c.to_mesh(),
43 Self::Cylinder(c) => c.to_mesh(),
44 Self::Icosphere(c) => c.to_mesh(),
45 Self::Plane(c) => c.to_mesh(),
46 Self::RegularPolygon(c) => c.to_mesh(),
47 Self::Torus(c) => c.to_mesh(),
48 }
49 }
50}
51
52#[derive(Reflect, Clone)]
54#[reflect(Default)]
55pub struct BoxPrefab {
56 pub w: f32,
57 pub h: f32,
58 pub d: f32,
59}
60
61impl Default for BoxPrefab {
62 fn default() -> Self {
63 Self {
64 w: 1.0,
65 h: 1.0,
66 d: 1.0,
67 }
68 }
69}
70
71impl BoxPrefab {
72 pub fn to_mesh(&self) -> Mesh {
73 Mesh::from(shape::Box::new(self.w, self.h, self.d))
74 }
75}
76
77#[derive(Reflect, Clone)]
79#[reflect(Default)]
80pub struct SpherePrefab {
81 pub r: f32,
82}
83
84impl Default for SpherePrefab {
85 fn default() -> Self {
86 Self { r: 1.0 }
87 }
88}
89
90impl SpherePrefab {
91 pub fn to_mesh(&self) -> Mesh {
92 let data = shape::UVSphere {
93 radius: self.r,
94 ..Default::default()
95 };
96 Mesh::from(data)
97 }
98}
99
100#[derive(Reflect, Clone)]
102#[reflect(Default)]
103pub struct QuadPrefab {
104 pub size: Vec2,
106 pub flip: bool,
108}
109
110impl Default for QuadPrefab {
111 fn default() -> Self {
112 Self {
113 size: Vec2::ONE,
114 flip: false,
115 }
116 }
117}
118
119impl QuadPrefab {
120 pub fn to_mesh(&self) -> Mesh {
121 let data = shape::Quad {
122 size: self.size,
123 flip: self.flip,
124 };
125 Mesh::from(data)
126 }
127}
128
129#[derive(Reflect, Clone)]
131#[reflect(Default)]
132pub struct CapsulePrefab {
133 pub r: f32,
134 pub rings: usize,
135}
136
137impl Default for CapsulePrefab {
138 fn default() -> Self {
139 let def = shape::Capsule::default();
140 Self {
141 r: def.radius,
142 rings: def.rings,
143 }
144 }
145}
146
147impl CapsulePrefab {
148 pub fn to_mesh(&self) -> Mesh {
149 let data = shape::Capsule {
150 radius: self.r,
151 rings: self.rings,
152 ..Default::default()
153 };
154 Mesh::from(data)
155 }
156}
157
158#[derive(Reflect, Clone, InspectorOptions)]
160#[reflect(Default, InspectorOptions)]
161pub struct CirclePrefab {
162 pub r: f32,
163 #[inspector(min = 3)]
164 pub vertices: usize,
165}
166
167impl Default for CirclePrefab {
168 fn default() -> Self {
169 let def = shape::Circle::default();
170 Self {
171 r: def.radius,
172 vertices: def.vertices,
173 }
174 }
175}
176
177impl CirclePrefab {
178 pub fn to_mesh(&self) -> Mesh {
179 let data = shape::Circle {
180 radius: self.r,
181 vertices: self.vertices,
182 };
183 Mesh::from(data)
184 }
185}
186
187#[derive(Reflect, Clone)]
189#[reflect(Default)]
190pub struct CylinderPrefab {
191 pub r: f32,
192 pub resolution: u32,
193 pub segments: u32,
194}
195
196impl Default for CylinderPrefab {
197 fn default() -> Self {
198 let def = shape::Cylinder::default();
199 Self {
200 r: def.radius,
201 resolution: def.resolution,
202 segments: def.segments,
203 }
204 }
205}
206
207impl CylinderPrefab {
208 pub fn to_mesh(&self) -> Mesh {
209 let data = shape::Cylinder {
210 radius: self.r,
211 resolution: self.resolution,
212 segments: self.segments,
213 ..Default::default()
214 };
215 Mesh::from(data)
216 }
217}
218
219#[derive(Reflect, Clone)]
221#[reflect(Default)]
222pub struct IcospherePrefab {
223 pub r: f32,
224 pub subdivisions: usize,
225}
226
227impl Default for IcospherePrefab {
228 fn default() -> Self {
229 let def = shape::Icosphere::default();
230 Self {
231 r: def.radius,
232 subdivisions: def.subdivisions,
233 }
234 }
235}
236
237impl IcospherePrefab {
238 pub fn to_mesh(&self) -> Mesh {
239 let data = shape::Icosphere {
240 radius: self.r,
241 subdivisions: self.subdivisions,
242 };
243 Mesh::try_from(data).map_or_else(
244 |_| Mesh::try_from(shape::Icosphere::default()).unwrap(),
245 |mesh| mesh,
246 )
247 }
248}
249
250#[derive(Reflect, Clone)]
252#[reflect(Default)]
253pub struct PlanePrefab {
254 pub size: f32,
255 pub subdivisions: u32,
256}
257
258impl Default for PlanePrefab {
259 fn default() -> Self {
260 let def = shape::Plane::default();
261 Self {
262 size: def.size,
263 subdivisions: def.subdivisions,
264 }
265 }
266}
267
268impl PlanePrefab {
269 pub fn to_mesh(&self) -> Mesh {
270 let data = shape::Plane {
271 size: self.size,
272 subdivisions: self.subdivisions,
273 };
274 Mesh::from(data)
275 }
276}
277
278#[derive(Reflect, Clone, InspectorOptions)]
280#[reflect(Default, InspectorOptions)]
281pub struct RegularPolygonPrefab {
282 pub radius: f32,
283 #[inspector(min = 3)]
284 pub sides: usize,
285}
286
287impl Default for RegularPolygonPrefab {
288 fn default() -> Self {
289 let def = shape::RegularPolygon::default();
290 Self {
291 radius: def.radius,
292 sides: def.sides,
293 }
294 }
295}
296
297impl RegularPolygonPrefab {
298 pub fn to_mesh(&self) -> Mesh {
299 let data = shape::RegularPolygon {
300 radius: self.radius,
301 sides: self.sides,
302 };
303 Mesh::from(data)
304 }
305}
306
307#[derive(Reflect, Clone)]
309#[reflect(Default)]
310pub struct TorusPrefab {
311 pub radius: f32,
312 pub ring_radius: f32,
313 pub subdivisions_sides: usize,
314 pub subdivisions_segments: usize,
315}
316
317impl Default for TorusPrefab {
318 fn default() -> Self {
319 let def = shape::Torus::default();
320 Self {
321 radius: def.radius,
322 ring_radius: def.ring_radius,
323 subdivisions_sides: def.subdivisions_sides,
324 subdivisions_segments: def.subdivisions_segments,
325 }
326 }
327}
328
329impl TorusPrefab {
330 pub fn to_mesh(&self) -> Mesh {
331 let data = shape::Torus {
332 radius: self.radius,
333 ring_radius: self.ring_radius,
334 subdivisions_sides: self.subdivisions_sides,
335 subdivisions_segments: self.subdivisions_segments,
336 };
337 Mesh::from(data)
338 }
339}