saft_sdf/
structs.rs

1use macaw::Vec3;
2use macaw::Vec4;
3
4#[derive(Copy, Clone)]
5#[cfg_attr(feature = "with_serde", derive(serde::Serialize, serde::Deserialize))]
6#[cfg_attr(feature = "with_speedy", derive(speedy::Writable, speedy::Readable))]
7#[cfg_attr(not(target_arch = "spirv"), derive(Debug))]
8pub struct Material {
9    /// [0-1] linear space
10    rgb: Vec3,
11}
12
13impl Default for Material {
14    fn default() -> Self {
15        Self::new(Vec3::ONE)
16    }
17}
18
19impl From<Vec3> for Material {
20    fn from(rgb: Vec3) -> Self {
21        Self { rgb }
22    }
23}
24
25impl Material {
26    pub fn new(rgb: Vec3) -> Self {
27        Self { rgb }
28    }
29
30    pub fn rgb(&self) -> Vec3 {
31        self.rgb
32    }
33}
34
35pub trait SignedDistance: Copy {
36    #[must_use]
37    fn infinity() -> Self;
38
39    fn distance(&self) -> f32;
40
41    #[must_use]
42    fn copy_with_distance(&self, distance: f32) -> Self;
43
44    #[must_use]
45    fn multiply_distance_by(&self, factor: f32) -> Self;
46
47    fn material(&self) -> Material;
48
49    #[must_use]
50    fn lerp(&self, b: &Self, t: f32) -> Self;
51
52    #[must_use]
53    fn new_with_distance(material: Material, distance: f32) -> Self;
54
55    fn is_distance_finite(&self) -> bool;
56}
57
58impl SignedDistance for f32 {
59    #[inline]
60    fn infinity() -> Self {
61        Self::INFINITY
62    }
63
64    #[inline]
65    fn distance(&self) -> f32 {
66        *self
67    }
68
69    #[inline]
70    fn material(&self) -> Material {
71        Material::new(Vec3::ONE)
72    }
73
74    #[inline]
75    fn copy_with_distance(&self, distance: f32) -> Self {
76        distance
77    }
78
79    #[inline]
80    fn multiply_distance_by(&self, factor: f32) -> Self {
81        self * factor
82    }
83
84    #[inline]
85    fn new_with_distance(_material: Material, distance: f32) -> Self {
86        distance
87    }
88
89    #[inline]
90    fn lerp(&self, b: &Self, t: f32) -> Self {
91        //Self(self + (b.0 - self) * t)
92        t * (b - self) + *self
93    }
94
95    #[inline]
96    fn is_distance_finite(&self) -> bool {
97        self.is_finite()
98    }
99}
100
101/// r, g, b, distance
102#[derive(Default, Copy, Clone, PartialEq)]
103#[cfg_attr(not(target_arch = "spirv"), derive(Debug))]
104pub struct RgbWithDistance(pub Vec4);
105
106impl SignedDistance for RgbWithDistance {
107    #[inline]
108    fn infinity() -> Self {
109        Self(Vec4::new(1.0, 1.0, 1.0, core::f32::INFINITY))
110    }
111
112    #[inline]
113    fn distance(&self) -> f32 {
114        self.0.w
115    }
116
117    #[inline]
118    fn material(&self) -> Material {
119        Material::new(self.0.truncate())
120    }
121
122    #[inline]
123    fn copy_with_distance(&self, distance: f32) -> Self {
124        let mut n = *self;
125        n.0.w = distance;
126        n
127    }
128
129    #[inline]
130    fn multiply_distance_by(&self, factor: f32) -> Self {
131        Self(self.0.truncate().extend(self.0.w * factor))
132    }
133
134    #[inline]
135    fn new_with_distance(material: Material, distance: f32) -> Self {
136        Self(material.rgb().extend(distance))
137    }
138
139    #[inline]
140    fn lerp(&self, b: &Self, t: f32) -> Self {
141        Self(self.0.lerp(b.0, t))
142    }
143
144    #[inline]
145    fn is_distance_finite(&self) -> bool {
146        self.0.is_finite()
147    }
148}