1#[allow(unused_imports)]
6use super::functions::*;
7
8#[derive(Debug, Clone)]
10pub struct SdfSmoothIntersection<A, B> {
11 pub a: A,
13 pub b: B,
15 pub k: f64,
17}
18#[allow(dead_code)]
19impl<A: Sdf, B: Sdf> SdfSmoothIntersection<A, B> {
20 pub fn new(a: A, b: B, k: f64) -> Self {
22 Self { a, b, k }
23 }
24}
25#[derive(Debug, Clone)]
29pub struct SdfSmoothUnion<A, B> {
30 pub a: A,
32 pub b: B,
34 pub k: f64,
36}
37#[allow(dead_code)]
38impl<A: Sdf, B: Sdf> SdfSmoothUnion<A, B> {
39 pub fn new(a: A, b: B, k: f64) -> Self {
41 Self { a, b, k }
42 }
43}
44#[derive(Debug, Clone, Copy)]
48pub struct SdfHexagonalPrism {
49 pub radius: f64,
51 pub half_height: f64,
53}
54#[allow(dead_code)]
55impl SdfHexagonalPrism {
56 pub fn new(radius: f64, half_height: f64) -> Self {
58 Self {
59 radius,
60 half_height,
61 }
62 }
63}
64#[derive(Debug, Clone, Copy, PartialEq, Eq)]
66pub enum BoolOp {
67 Union,
69 Intersection,
71 Difference,
73 SmoothUnion,
75 SmoothIntersection,
77 SmoothDifference,
79}
80#[derive(Debug, Clone, Copy)]
82pub struct ContactPoint {
83 pub position: [f64; 3],
85 pub normal: [f64; 3],
87 pub depth: f64,
89}
90#[derive(Debug, Clone)]
92pub struct SdfTranslate<S> {
93 pub inner: S,
95 pub offset: [f64; 3],
97}
98#[allow(dead_code)]
99impl<S: Sdf> SdfTranslate<S> {
100 pub fn new(inner: S, offset: [f64; 3]) -> Self {
102 Self { inner, offset }
103 }
104}
105#[derive(Debug, Clone)]
107pub struct SdfRepeat<S> {
108 pub inner: S,
110 pub period_x: f64,
112 pub period_y: f64,
114 pub period_z: f64,
116}
117#[allow(dead_code)]
118impl<S: Sdf> SdfRepeat<S> {
119 pub fn new(inner: S, period_x: f64, period_y: f64, period_z: f64) -> Self {
121 Self {
122 inner,
123 period_x,
124 period_y,
125 period_z,
126 }
127 }
128}
129#[derive(Debug, Clone)]
131pub struct SdfScale<S> {
132 pub inner: S,
134 pub factor: f64,
136}
137#[allow(dead_code)]
138impl<S: Sdf> SdfScale<S> {
139 pub fn new(inner: S, factor: f64) -> Self {
141 Self { inner, factor }
142 }
143}
144#[derive(Debug, Clone, Copy)]
146pub struct SdfTorus {
147 pub major: f64,
149 pub minor: f64,
151}
152#[allow(dead_code)]
153impl SdfTorus {
154 pub fn new(major: f64, minor: f64) -> Self {
156 Self { major, minor }
157 }
158}
159#[derive(Debug, Clone, Copy)]
163pub struct SdfPlane {
164 pub normal: [f64; 3],
166 pub offset: f64,
168}
169#[allow(dead_code)]
170impl SdfPlane {
171 pub fn new(normal: [f64; 3], offset: f64) -> Self {
173 Self {
174 normal: norm(normal),
175 offset,
176 }
177 }
178}
179#[derive(Debug, Clone)]
181pub struct SdfSmoothDifference<A, B> {
182 pub a: A,
184 pub b: B,
186 pub k: f64,
188}
189#[allow(dead_code)]
190impl<A: Sdf, B: Sdf> SdfSmoothDifference<A, B> {
191 pub fn new(a: A, b: B, k: f64) -> Self {
193 Self { a, b, k }
194 }
195}
196#[derive(Debug, Clone)]
200pub struct SdfTwist<S> {
201 pub inner: S,
203 pub strength: f64,
205}
206#[allow(dead_code)]
207impl<S: Sdf> SdfTwist<S> {
208 pub fn new(inner: S, strength: f64) -> Self {
210 Self { inner, strength }
211 }
212}
213#[derive(Debug, Clone)]
215pub struct SdfGrid {
216 pub nx: usize,
218 pub ny: usize,
220 pub nz: usize,
222 pub origin: [f64; 3],
224 pub spacing: f64,
226 pub data: Vec<f64>,
228}
229#[allow(dead_code)]
230impl SdfGrid {
231 pub fn new(nx: usize, ny: usize, nz: usize, origin: [f64; 3], spacing: f64) -> Self {
233 Self {
234 nx,
235 ny,
236 nz,
237 origin,
238 spacing,
239 data: vec![f64::INFINITY; nx * ny * nz],
240 }
241 }
242 pub fn from_sdf<S: Sdf>(
244 sdf: &S,
245 nx: usize,
246 ny: usize,
247 nz: usize,
248 origin: [f64; 3],
249 spacing: f64,
250 ) -> Self {
251 let mut grid = Self::new(nx, ny, nz, origin, spacing);
252 for iz in 0..nz {
253 for iy in 0..ny {
254 for ix in 0..nx {
255 let p = grid.cell_center(ix, iy, iz);
256 grid.data[iz * ny * nx + iy * nx + ix] = sdf.dist(p);
257 }
258 }
259 }
260 grid
261 }
262 pub fn cell_center(&self, ix: usize, iy: usize, iz: usize) -> [f64; 3] {
264 [
265 self.origin[0] + ix as f64 * self.spacing,
266 self.origin[1] + iy as f64 * self.spacing,
267 self.origin[2] + iz as f64 * self.spacing,
268 ]
269 }
270 pub fn get(&self, ix: usize, iy: usize, iz: usize) -> f64 {
272 self.data[iz * self.ny * self.nx + iy * self.nx + ix]
273 }
274 pub fn set(&mut self, ix: usize, iy: usize, iz: usize, v: f64) {
276 self.data[iz * self.ny * self.nx + iy * self.nx + ix] = v;
277 }
278 pub fn interpolate(&self, p: [f64; 3]) -> f64 {
280 let fx = (p[0] - self.origin[0]) / self.spacing;
281 let fy = (p[1] - self.origin[1]) / self.spacing;
282 let fz = (p[2] - self.origin[2]) / self.spacing;
283 let ix = (fx as usize).min(self.nx.saturating_sub(2));
284 let iy = (fy as usize).min(self.ny.saturating_sub(2));
285 let iz = (fz as usize).min(self.nz.saturating_sub(2));
286 let tx = (fx - ix as f64).clamp(0.0, 1.0);
287 let ty = (fy - iy as f64).clamp(0.0, 1.0);
288 let tz = (fz - iz as f64).clamp(0.0, 1.0);
289 let v000 = self.get(ix, iy, iz);
290 let v100 = self.get(ix + 1, iy, iz);
291 let v010 = self.get(ix, iy + 1, iz);
292 let v110 = self.get(ix + 1, iy + 1, iz);
293 let v001 = self.get(ix, iy, iz + 1);
294 let v101 = self.get(ix + 1, iy, iz + 1);
295 let v011 = self.get(ix, iy + 1, iz + 1);
296 let v111 = self.get(ix + 1, iy + 1, iz + 1);
297 let c00 = v000 * (1.0 - tx) + v100 * tx;
298 let c10 = v010 * (1.0 - tx) + v110 * tx;
299 let c01 = v001 * (1.0 - tx) + v101 * tx;
300 let c11 = v011 * (1.0 - tx) + v111 * tx;
301 let c0 = c00 * (1.0 - ty) + c10 * ty;
302 let c1 = c01 * (1.0 - ty) + c11 * ty;
303 c0 * (1.0 - tz) + c1 * tz
304 }
305 pub fn dilate(&mut self, delta: f64) {
307 for v in self.data.iter_mut() {
308 *v -= delta;
309 }
310 }
311 pub fn erode(&mut self, delta: f64) {
313 for v in self.data.iter_mut() {
314 *v += delta;
315 }
316 }
317}
318#[derive(Debug, Clone, Copy)]
323pub struct SdfRoundedCylinder {
324 pub radius: f64,
326 pub half_height: f64,
328 pub rounding: f64,
330}
331#[allow(dead_code)]
332impl SdfRoundedCylinder {
333 pub fn new(radius: f64, half_height: f64, rounding: f64) -> Self {
335 Self {
336 radius,
337 half_height,
338 rounding,
339 }
340 }
341}
342#[derive(Debug, Clone)]
344pub struct SdfIntersection<A, B> {
345 pub a: A,
347 pub b: B,
349}
350#[allow(dead_code)]
351impl<A: Sdf, B: Sdf> SdfIntersection<A, B> {
352 pub fn new(a: A, b: B) -> Self {
354 Self { a, b }
355 }
356}
357pub struct SdfExtrude<F> {
361 pub profile: F,
363 pub half_height: f64,
365}
366#[allow(dead_code)]
367impl<F: Fn([f64; 2]) -> f64 + Send + Sync> SdfExtrude<F> {
368 pub fn new(profile: F, half_height: f64) -> Self {
370 Self {
371 profile,
372 half_height,
373 }
374 }
375}
376pub struct SdfRevolution<F> {
381 pub profile: F,
383}
384#[allow(dead_code)]
385impl<F: Fn(f64, f64) -> f64 + Send + Sync> SdfRevolution<F> {
386 pub fn new(profile: F) -> Self {
388 Self { profile }
389 }
390}
391#[derive(Debug, Clone)]
393pub struct SdfUnion<A, B> {
394 pub a: A,
396 pub b: B,
398}
399#[allow(dead_code)]
400impl<A: Sdf, B: Sdf> SdfUnion<A, B> {
401 pub fn new(a: A, b: B) -> Self {
403 Self { a, b }
404 }
405}
406#[derive(Debug, Clone, Copy)]
410pub struct SdfCone {
411 pub half_angle: f64,
413 pub height: f64,
415}
416#[allow(dead_code)]
417impl SdfCone {
418 pub fn new(half_angle: f64, height: f64) -> Self {
420 Self { half_angle, height }
421 }
422}
423#[derive(Debug, Clone)]
427pub struct SdfOffset<S> {
428 pub inner: S,
430 pub offset: f64,
432}
433#[allow(dead_code)]
434impl<S: Sdf> SdfOffset<S> {
435 pub fn new(inner: S, offset: f64) -> Self {
437 Self { inner, offset }
438 }
439}
440#[derive(Debug, Clone, Default)]
442pub struct IsoMeshResult {
443 pub triangles: Vec<Triangle>,
445 pub vertex_count: usize,
447}
448#[derive(Debug, Clone, Copy)]
452pub struct SdfPyramid {
453 pub half_base: f64,
455 pub height: f64,
457}
458#[allow(dead_code)]
459impl SdfPyramid {
460 pub fn new(half_base: f64, height: f64) -> Self {
462 Self { half_base, height }
463 }
464}
465#[derive(Debug, Clone)]
467pub struct SdfDifference<A, B> {
468 pub a: A,
470 pub b: B,
472}
473#[allow(dead_code)]
474impl<A: Sdf, B: Sdf> SdfDifference<A, B> {
475 pub fn new(a: A, b: B) -> Self {
477 Self { a, b }
478 }
479}
480#[derive(Debug, Clone)]
485pub struct SdfNoiseDisplace<S> {
486 pub inner: S,
488 pub noise_scale: f64,
490 pub amplitude: f64,
492 pub octaves: u32,
494}
495#[allow(dead_code)]
496impl<S: Sdf> SdfNoiseDisplace<S> {
497 pub fn new(inner: S, noise_scale: f64, amplitude: f64, octaves: u32) -> Self {
499 Self {
500 inner,
501 noise_scale,
502 amplitude,
503 octaves,
504 }
505 }
506}
507#[derive(Debug, Clone, Copy)]
511pub struct SdfEllipsoid {
512 pub radii: [f64; 3],
514}
515#[allow(dead_code)]
516impl SdfEllipsoid {
517 pub fn new(rx: f64, ry: f64, rz: f64) -> Self {
519 Self {
520 radii: [rx, ry, rz],
521 }
522 }
523}
524#[derive(Debug, Clone, Copy)]
526pub struct Triangle {
527 pub v0: [f64; 3],
529 pub v1: [f64; 3],
531 pub v2: [f64; 3],
533}
534impl Triangle {
535 pub fn normal(&self) -> [f64; 3] {
537 cross(sub(self.v1, self.v0), sub(self.v2, self.v0))
538 }
539}
540pub enum SdfNode {
544 Leaf(Box<dyn Sdf>),
546 Binary {
548 op: BoolOp,
550 left: Box<SdfNode>,
552 right: Box<SdfNode>,
554 k: f64,
556 },
557}
558#[allow(dead_code)]
559impl SdfNode {
560 pub fn leaf<S: Sdf + 'static>(s: S) -> Self {
562 Self::Leaf(Box::new(s))
563 }
564 pub fn combine(op: BoolOp, left: Self, right: Self, k: f64) -> Self {
566 Self::Binary {
567 op,
568 left: Box::new(left),
569 right: Box::new(right),
570 k,
571 }
572 }
573 pub fn eval(&self, p: [f64; 3]) -> f64 {
575 match self {
576 Self::Leaf(s) => s.dist(p),
577 Self::Binary { op, left, right, k } => {
578 let a = left.eval(p);
579 let b = right.eval(p);
580 match op {
581 BoolOp::Union => a.min(b),
582 BoolOp::Intersection => a.max(b),
583 BoolOp::Difference => a.max(-b),
584 BoolOp::SmoothUnion => sdf_smooth_union(a, b, *k),
585 BoolOp::SmoothIntersection => sdf_smooth_intersection(a, b, *k),
586 BoolOp::SmoothDifference => sdf_smooth_difference(a, b, *k),
587 }
588 }
589 }
590 }
591}
592#[derive(Debug, Clone, Copy)]
596pub struct SdfTriangularPrism {
597 pub side: f64,
599 pub half_height: f64,
601}
602#[allow(dead_code)]
603impl SdfTriangularPrism {
604 pub fn new(side: f64, half_height: f64) -> Self {
606 Self { side, half_height }
607 }
608}
609#[derive(Debug, Clone, Copy)]
614pub struct SdfGyroid {
615 pub scale: f64,
617 pub thickness: f64,
619}
620#[allow(dead_code)]
621impl SdfGyroid {
622 pub fn new(scale: f64, thickness: f64) -> Self {
624 Self { scale, thickness }
625 }
626}
627#[derive(Debug, Clone)]
631pub struct SdfShell<S> {
632 pub inner: S,
634 pub thickness: f64,
636}
637#[allow(dead_code)]
638impl<S: Sdf> SdfShell<S> {
639 pub fn new(inner: S, thickness: f64) -> Self {
641 Self { inner, thickness }
642 }
643}
644#[derive(Debug, Clone)]
648pub struct SdfBend<S> {
649 pub inner: S,
651 pub strength: f64,
653}
654#[allow(dead_code)]
655impl<S: Sdf> SdfBend<S> {
656 pub fn new(inner: S, strength: f64) -> Self {
658 Self { inner, strength }
659 }
660}
661#[derive(Debug, Clone, Copy)]
665pub struct SdfLineSegment {
666 pub a: [f64; 3],
668 pub b: [f64; 3],
670 pub radius: f64,
672}
673#[allow(dead_code)]
674impl SdfLineSegment {
675 pub fn new(a: [f64; 3], b: [f64; 3], radius: f64) -> Self {
677 Self { a, b, radius }
678 }
679}
680#[derive(Debug, Clone, Copy)]
682pub struct RayMarchResult {
683 pub hit: bool,
685 pub t: f64,
687 pub point: [f64; 3],
689 pub steps: u32,
691}
692#[derive(Debug, Clone)]
696pub struct SdfBoundedProxy<S> {
697 pub inner: S,
699 pub bsphere_center: [f64; 3],
701 pub bsphere_radius: f64,
703}
704#[allow(dead_code)]
705impl<S: Sdf> SdfBoundedProxy<S> {
706 pub fn new(inner: S, bsphere_center: [f64; 3], bsphere_radius: f64) -> Self {
708 Self {
709 inner,
710 bsphere_center,
711 bsphere_radius,
712 }
713 }
714 pub fn outside_bounds(&self, p: [f64; 3]) -> bool {
716 len(sub(p, self.bsphere_center)) > self.bsphere_radius
717 }
718}
719#[derive(Debug, Clone, Copy)]
723pub struct SdfBox {
724 pub half_extents: [f64; 3],
726}
727#[allow(dead_code)]
728impl SdfBox {
729 pub fn new(hx: f64, hy: f64, hz: f64) -> Self {
731 Self {
732 half_extents: [hx, hy, hz],
733 }
734 }
735}
736#[derive(Debug, Clone, Copy)]
738pub struct SdfCollisionResult {
739 pub depth: f64,
741 pub normal: [f64; 3],
743 pub contact_point: [f64; 3],
745}
746#[derive(Debug, Clone, Copy)]
748pub struct SdfSphere {
749 pub radius: f64,
751}
752#[allow(dead_code)]
753impl SdfSphere {
754 pub fn new(radius: f64) -> Self {
756 Self { radius }
757 }
758}