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 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 t * (b - self) + *self
93 }
94
95 #[inline]
96 fn is_distance_finite(&self) -> bool {
97 self.is_finite()
98 }
99}
100
101#[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}