1use glam::{Vec2, Vec3};
6
7use std::sync::Arc;
8
9use super::SdfNode;
10
11impl SdfNode {
12 #[must_use]
16 #[inline]
17 pub const fn sphere(radius: f32) -> Self {
18 Self::Sphere { radius }
19 }
20
21 #[must_use]
36 #[inline]
37 pub fn box3d(width: f32, height: f32, depth: f32) -> Self {
38 Self::Box3d {
39 half_extents: Vec3::new(width * 0.5, height * 0.5, depth * 0.5),
40 }
41 }
42
43 #[must_use]
55 #[inline]
56 pub const fn box3d_half_extents(hx: f32, hy: f32, hz: f32) -> Self {
57 Self::Box3d {
58 half_extents: Vec3::new(hx, hy, hz),
59 }
60 }
61
62 #[must_use]
64 #[inline]
65 pub fn cylinder(radius: f32, height: f32) -> Self {
66 Self::Cylinder {
67 radius,
68 half_height: height * 0.5,
69 }
70 }
71
72 #[must_use]
74 #[inline]
75 pub const fn torus(major_radius: f32, minor_radius: f32) -> Self {
76 Self::Torus {
77 major_radius,
78 minor_radius,
79 }
80 }
81
82 #[must_use]
84 #[inline]
85 pub fn plane(normal: Vec3, distance: f32) -> Self {
86 Self::Plane {
87 normal: normal.normalize(),
88 distance,
89 }
90 }
91
92 #[must_use]
94 #[inline]
95 pub const fn capsule(a: Vec3, b: Vec3, radius: f32) -> Self {
96 Self::Capsule {
97 point_a: a,
98 point_b: b,
99 radius,
100 }
101 }
102
103 #[must_use]
105 #[inline]
106 pub fn cone(radius: f32, height: f32) -> Self {
107 Self::Cone {
108 radius,
109 half_height: height * 0.5,
110 }
111 }
112
113 #[must_use]
115 #[inline]
116 pub const fn ellipsoid(rx: f32, ry: f32, rz: f32) -> Self {
117 Self::Ellipsoid {
118 radii: Vec3::new(rx, ry, rz),
119 }
120 }
121
122 #[must_use]
124 #[inline]
125 pub fn rounded_cone(r1: f32, r2: f32, height: f32) -> Self {
126 Self::RoundedCone {
127 r1,
128 r2,
129 half_height: height * 0.5,
130 }
131 }
132
133 #[must_use]
135 #[inline]
136 pub fn pyramid(height: f32) -> Self {
137 Self::Pyramid {
138 half_height: height * 0.5,
139 }
140 }
141
142 #[must_use]
144 #[inline]
145 pub const fn octahedron(size: f32) -> Self {
146 Self::Octahedron { size }
147 }
148
149 #[must_use]
151 #[inline]
152 pub fn hex_prism(hex_radius: f32, height: f32) -> Self {
153 Self::HexPrism {
154 hex_radius,
155 half_height: height * 0.5,
156 }
157 }
158
159 #[must_use]
161 #[inline]
162 pub fn link(length: f32, r1: f32, r2: f32) -> Self {
163 Self::Link {
164 half_length: length * 0.5,
165 r1,
166 r2,
167 }
168 }
169
170 #[must_use]
172 #[inline]
173 pub const fn triangle(a: Vec3, b: Vec3, c: Vec3) -> Self {
174 Self::Triangle {
175 point_a: a,
176 point_b: b,
177 point_c: c,
178 }
179 }
180
181 #[must_use]
183 #[inline]
184 pub const fn bezier(a: Vec3, b: Vec3, c: Vec3, radius: f32) -> Self {
185 Self::Bezier {
186 point_a: a,
187 point_b: b,
188 point_c: c,
189 radius,
190 }
191 }
192
193 #[must_use]
200 #[inline]
201 pub const fn rounded_box(hx: f32, hy: f32, hz: f32, round_radius: f32) -> Self {
202 Self::RoundedBox {
203 half_extents: Vec3::new(hx, hy, hz),
204 round_radius,
205 }
206 }
207
208 #[must_use]
210 #[inline]
211 pub fn capped_cone(height: f32, r1: f32, r2: f32) -> Self {
212 Self::CappedCone {
213 half_height: height * 0.5,
214 r1,
215 r2,
216 }
217 }
218
219 #[must_use]
221 #[inline]
222 pub const fn capped_torus(major_radius: f32, minor_radius: f32, cap_angle: f32) -> Self {
223 Self::CappedTorus {
224 major_radius,
225 minor_radius,
226 cap_angle,
227 }
228 }
229
230 #[must_use]
232 #[inline]
233 pub fn rounded_cylinder(radius: f32, round_radius: f32, height: f32) -> Self {
234 Self::RoundedCylinder {
235 radius,
236 round_radius,
237 half_height: height * 0.5,
238 }
239 }
240
241 #[must_use]
243 #[inline]
244 pub fn triangular_prism(width: f32, depth: f32) -> Self {
245 Self::TriangularPrism {
246 width,
247 half_depth: depth * 0.5,
248 }
249 }
250
251 #[must_use]
253 #[inline]
254 pub const fn cut_sphere(radius: f32, cut_height: f32) -> Self {
255 Self::CutSphere { radius, cut_height }
256 }
257
258 #[must_use]
260 #[inline]
261 pub const fn cut_hollow_sphere(radius: f32, cut_height: f32, thickness: f32) -> Self {
262 Self::CutHollowSphere {
263 radius,
264 cut_height,
265 thickness,
266 }
267 }
268
269 #[must_use]
271 #[inline]
272 pub const fn death_star(ra: f32, rb: f32, d: f32) -> Self {
273 Self::DeathStar { ra, rb, d }
274 }
275
276 #[must_use]
278 #[inline]
279 pub const fn solid_angle(angle: f32, radius: f32) -> Self {
280 Self::SolidAngle { angle, radius }
281 }
282
283 #[must_use]
285 #[inline]
286 pub fn rhombus(la: f32, lb: f32, height: f32, round_radius: f32) -> Self {
287 Self::Rhombus {
288 la,
289 lb,
290 half_height: height * 0.5,
291 round_radius,
292 }
293 }
294
295 #[must_use]
297 #[inline]
298 pub fn horseshoe(angle: f32, radius: f32, length: f32, width: f32, thickness: f32) -> Self {
299 Self::Horseshoe {
300 angle,
301 radius,
302 half_length: length * 0.5,
303 width,
304 thickness,
305 }
306 }
307
308 #[must_use]
310 #[inline]
311 pub fn vesica(radius: f32, dist: f32) -> Self {
312 Self::Vesica {
313 radius,
314 half_dist: dist * 0.5,
315 }
316 }
317
318 #[must_use]
320 #[inline]
321 pub const fn infinite_cylinder(radius: f32) -> Self {
322 Self::InfiniteCylinder { radius }
323 }
324
325 #[must_use]
327 #[inline]
328 pub const fn infinite_cone(angle: f32) -> Self {
329 Self::InfiniteCone { angle }
330 }
331
332 #[must_use]
334 #[inline]
335 pub const fn gyroid(scale: f32, thickness: f32) -> Self {
336 Self::Gyroid { scale, thickness }
337 }
338
339 #[must_use]
347 #[inline]
348 pub const fn metric_ball(radius: f32, weights: alice_det_math::metric::MetricWeights) -> Self {
349 let (w_l1, w_l2, w_linf) = weights.weights();
350 Self::MetricBall {
351 radius,
352 w_l1,
353 w_l2,
354 w_linf,
355 }
356 }
357
358 #[must_use]
364 #[inline]
365 pub fn metric_blend(inner: Self, outer: Self, center: Vec3, radius: f32, skin: f32) -> Self {
366 Self::MetricBlend {
367 inner: Arc::new(inner),
368 outer: Arc::new(outer),
369 center,
370 radius,
371 skin,
372 }
373 }
374
375 #[must_use]
377 #[inline]
378 pub const fn heart(size: f32) -> Self {
379 Self::Heart { size }
380 }
381
382 #[must_use]
384 #[inline]
385 pub fn tube(outer_radius: f32, thickness: f32, height: f32) -> Self {
386 Self::Tube {
387 outer_radius,
388 thickness,
389 half_height: height * 0.5,
390 }
391 }
392
393 #[must_use]
395 #[inline]
396 pub fn barrel(radius: f32, height: f32, bulge: f32) -> Self {
397 Self::Barrel {
398 radius,
399 half_height: height * 0.5,
400 bulge,
401 }
402 }
403
404 #[must_use]
406 #[inline]
407 pub fn diamond(radius: f32, height: f32) -> Self {
408 Self::Diamond {
409 radius,
410 half_height: height * 0.5,
411 }
412 }
413
414 #[must_use]
416 #[inline]
417 pub fn chamfered_cube(width: f32, height: f32, depth: f32, chamfer: f32) -> Self {
418 Self::ChamferedCube {
419 half_extents: Vec3::new(width * 0.5, height * 0.5, depth * 0.5),
420 chamfer,
421 }
422 }
423
424 #[must_use]
426 #[inline]
427 pub const fn schwarz_p(scale: f32, thickness: f32) -> Self {
428 Self::SchwarzP { scale, thickness }
429 }
430
431 #[must_use]
433 #[inline]
434 pub fn superellipsoid(width: f32, height: f32, depth: f32, e1: f32, e2: f32) -> Self {
435 Self::Superellipsoid {
436 half_extents: Vec3::new(width * 0.5, height * 0.5, depth * 0.5),
437 e1,
438 e2,
439 }
440 }
441
442 #[must_use]
444 #[inline]
445 pub fn rounded_x(width: f32, round_radius: f32, height: f32) -> Self {
446 Self::RoundedX {
447 width,
448 round_radius,
449 half_height: height * 0.5,
450 }
451 }
452
453 #[must_use]
455 #[inline]
456 pub fn pie(angle: f32, radius: f32, height: f32) -> Self {
457 Self::Pie {
458 angle,
459 radius,
460 half_height: height * 0.5,
461 }
462 }
463
464 #[must_use]
466 #[inline]
467 pub fn trapezoid(r1: f32, r2: f32, trap_height: f32, depth: f32) -> Self {
468 Self::Trapezoid {
469 r1,
470 r2,
471 trap_height: trap_height * 0.5,
472 half_depth: depth * 0.5,
473 }
474 }
475
476 #[must_use]
478 #[inline]
479 pub fn parallelogram(width: f32, para_height: f32, skew: f32, depth: f32) -> Self {
480 Self::Parallelogram {
481 width,
482 para_height: para_height * 0.5,
483 skew,
484 half_depth: depth * 0.5,
485 }
486 }
487
488 #[must_use]
490 #[inline]
491 pub fn tunnel(width: f32, height_2d: f32, depth: f32) -> Self {
492 Self::Tunnel {
493 width,
494 height_2d,
495 half_depth: depth * 0.5,
496 }
497 }
498
499 #[must_use]
501 #[inline]
502 pub fn uneven_capsule(r1: f32, r2: f32, cap_height: f32, depth: f32) -> Self {
503 Self::UnevenCapsule {
504 r1,
505 r2,
506 cap_height: cap_height * 0.5,
507 half_depth: depth * 0.5,
508 }
509 }
510
511 #[must_use]
513 #[inline]
514 pub const fn egg(ra: f32, rb: f32) -> Self {
515 Self::Egg { ra, rb }
516 }
517
518 #[must_use]
520 pub fn arc_shape(aperture: f32, radius: f32, thickness: f32, height: f32) -> Self {
521 Self::ArcShape {
522 aperture,
523 radius,
524 thickness,
525 half_height: height * 0.5,
526 }
527 }
528
529 #[must_use]
531 pub fn moon(d: f32, ra: f32, rb: f32, height: f32) -> Self {
532 Self::Moon {
533 d,
534 ra,
535 rb,
536 half_height: height * 0.5,
537 }
538 }
539
540 #[must_use]
542 pub fn cross_shape(length: f32, thickness: f32, round_radius: f32, height: f32) -> Self {
543 Self::CrossShape {
544 length,
545 thickness,
546 round_radius,
547 half_height: height * 0.5,
548 }
549 }
550
551 #[must_use]
553 pub fn blobby_cross(size: f32, height: f32) -> Self {
554 Self::BlobbyCross {
555 size,
556 half_height: height * 0.5,
557 }
558 }
559
560 #[must_use]
562 pub fn parabola_segment(width: f32, para_height: f32, depth: f32) -> Self {
563 Self::ParabolaSegment {
564 width,
565 para_height,
566 half_depth: depth * 0.5,
567 }
568 }
569
570 #[must_use]
572 pub fn regular_polygon(radius: f32, n_sides: u32, height: f32) -> Self {
573 Self::RegularPolygon {
574 radius,
575 n_sides: n_sides as f32,
576 half_height: height * 0.5,
577 }
578 }
579
580 #[must_use]
582 pub fn star_polygon(radius: f32, n_points: u32, m: f32, height: f32) -> Self {
583 Self::StarPolygon {
584 radius,
585 n_points: n_points as f32,
586 m,
587 half_height: height * 0.5,
588 }
589 }
590
591 #[must_use]
593 pub fn stairs(step_width: f32, step_height: f32, n_steps: u32, depth: f32) -> Self {
594 Self::Stairs {
595 step_width,
596 step_height,
597 n_steps: n_steps as f32,
598 half_depth: depth * 0.5,
599 }
600 }
601
602 #[must_use]
604 pub fn helix(major_r: f32, minor_r: f32, pitch: f32, height: f32) -> Self {
605 Self::Helix {
606 major_r,
607 minor_r,
608 pitch,
609 half_height: height * 0.5,
610 }
611 }
612
613 #[must_use]
615 #[inline]
616 pub const fn tetrahedron(size: f32) -> Self {
617 Self::Tetrahedron { size }
618 }
619
620 #[must_use]
622 #[inline]
623 pub const fn dodecahedron(radius: f32) -> Self {
624 Self::Dodecahedron { radius }
625 }
626
627 #[must_use]
629 #[inline]
630 pub const fn icosahedron(radius: f32) -> Self {
631 Self::Icosahedron { radius }
632 }
633
634 #[must_use]
636 #[inline]
637 pub const fn truncated_octahedron(radius: f32) -> Self {
638 Self::TruncatedOctahedron { radius }
639 }
640
641 #[must_use]
643 #[inline]
644 pub const fn truncated_icosahedron(radius: f32) -> Self {
645 Self::TruncatedIcosahedron { radius }
646 }
647
648 #[must_use]
650 #[inline]
651 pub const fn box_frame(half_extents: Vec3, edge: f32) -> Self {
652 Self::BoxFrame { half_extents, edge }
653 }
654
655 #[must_use]
657 #[inline]
658 pub const fn diamond_surface(scale: f32, thickness: f32) -> Self {
659 Self::DiamondSurface { scale, thickness }
660 }
661
662 #[must_use]
664 #[inline]
665 pub const fn neovius(scale: f32, thickness: f32) -> Self {
666 Self::Neovius { scale, thickness }
667 }
668
669 #[must_use]
671 #[inline]
672 pub const fn lidinoid(scale: f32, thickness: f32) -> Self {
673 Self::Lidinoid { scale, thickness }
674 }
675
676 #[must_use]
678 #[inline]
679 pub const fn iwp(scale: f32, thickness: f32) -> Self {
680 Self::IWP { scale, thickness }
681 }
682
683 #[must_use]
685 #[inline]
686 pub const fn frd(scale: f32, thickness: f32) -> Self {
687 Self::FRD { scale, thickness }
688 }
689
690 #[must_use]
692 #[inline]
693 pub const fn fischer_koch_s(scale: f32, thickness: f32) -> Self {
694 Self::FischerKochS { scale, thickness }
695 }
696
697 #[must_use]
699 #[inline]
700 pub const fn pmy(scale: f32, thickness: f32) -> Self {
701 Self::PMY { scale, thickness }
702 }
703
704 #[must_use]
708 #[inline]
709 pub const fn circle_2d(radius: f32, half_height: f32) -> Self {
710 Self::Circle2D {
711 radius,
712 half_height,
713 }
714 }
715
716 #[must_use]
718 #[inline]
719 pub const fn rect_2d(half_w: f32, half_h: f32, half_height: f32) -> Self {
720 Self::Rect2D {
721 half_extents: Vec2::new(half_w, half_h),
722 half_height,
723 }
724 }
725
726 #[must_use]
728 #[inline]
729 pub const fn segment_2d(
730 ax: f32,
731 ay: f32,
732 bx: f32,
733 by: f32,
734 thickness: f32,
735 half_height: f32,
736 ) -> Self {
737 Self::Segment2D {
738 a: Vec2::new(ax, ay),
739 b: Vec2::new(bx, by),
740 thickness,
741 half_height,
742 }
743 }
744
745 #[must_use]
747 #[inline]
748 pub const fn polygon_2d(vertices: Vec<Vec2>, half_height: f32) -> Self {
749 Self::Polygon2D {
750 vertices,
751 half_height,
752 }
753 }
754
755 #[must_use]
757 #[inline]
758 pub const fn rounded_rect_2d(
759 half_w: f32,
760 half_h: f32,
761 round_radius: f32,
762 half_height: f32,
763 ) -> Self {
764 Self::RoundedRect2D {
765 half_extents: Vec2::new(half_w, half_h),
766 round_radius,
767 half_height,
768 }
769 }
770
771 #[must_use]
773 #[inline]
774 pub const fn annular_2d(outer_radius: f32, thickness: f32, half_height: f32) -> Self {
775 Self::Annular2D {
776 outer_radius,
777 thickness,
778 half_height,
779 }
780 }
781}