anput_physics/density_fields/
mod.rs1pub mod aabb;
2pub mod addition;
3pub mod multiplication;
4pub mod sphere;
5pub mod subtraction;
6
7use crate::{Scalar, components::BodyAccessInfo};
8use std::{
9 any::Any,
10 ops::{Add, AddAssign, Deref, DerefMut, Div, DivAssign, Mul, MulAssign, Sub, SubAssign},
11};
12use vek::{Aabb, Vec3};
13
14pub struct DensityFieldBox(Box<dyn DensityField>);
15
16impl DensityFieldBox {
17 pub fn new(field: impl DensityField + 'static) -> Self {
18 Self(Box::new(field))
19 }
20
21 pub fn as_any(&self) -> &dyn Any {
22 &*self.0
23 }
24
25 pub fn as_any_mut(&mut self) -> &mut dyn Any {
26 &mut *self.0
27 }
28}
29
30impl Deref for DensityFieldBox {
31 type Target = dyn DensityField;
32
33 fn deref(&self) -> &Self::Target {
34 &*self.0
35 }
36}
37
38impl DerefMut for DensityFieldBox {
39 fn deref_mut(&mut self) -> &mut Self::Target {
40 &mut *self.0
41 }
42}
43
44pub trait DensityField: Send + Sync + Any {
45 #[allow(unused_variables)]
47 fn aabb(&self, info: &BodyAccessInfo) -> Aabb<Scalar>;
48
49 fn density_at_point(&self, point: Vec3<Scalar>, info: &BodyAccessInfo) -> Scalar;
62
63 fn density_at_region(&self, region: Aabb<Scalar>, info: &BodyAccessInfo) -> DensityRange {
76 let center = region.center();
77 let size = region.size().into_array().map(|size| size * 0.5);
78 std::iter::once(center)
79 .chain(
80 size.into_iter()
81 .enumerate()
82 .filter(|(_, size)| *size > Scalar::EPSILON)
83 .flat_map(|(index, size)| {
84 let mut offset = Vec3::zero();
85 offset[index] = size;
86 [center - offset, center + offset]
87 }),
88 )
89 .map(|point| DensityRange::converged(self.density_at_point(point, info)))
90 .reduce(|accum, range| accum.min_max(&range))
91 .unwrap()
92 }
93
94 #[allow(unused_variables)]
104 fn normal_at_point(
105 &self,
106 point: Vec3<Scalar>,
107 resolution: Vec3<Scalar>,
108 info: &BodyAccessInfo,
109 ) -> Vec3<Scalar> {
110 Default::default()
111 }
112}
113
114#[derive(Debug, Default, Clone, Copy, PartialEq)]
115pub struct DensityRange {
116 pub min: Scalar,
117 pub max: Scalar,
118}
119
120impl DensityRange {
121 pub fn converged(density: Scalar) -> Self {
122 Self {
123 min: density,
124 max: density,
125 }
126 }
127
128 pub fn separation(&self) -> Scalar {
129 (self.max - self.min).abs()
130 }
131
132 pub fn has_converged(&self) -> bool {
133 self.separation() < Scalar::EPSILON
134 }
135
136 pub fn has_separation(&self) -> bool {
137 !self.has_converged()
138 }
139
140 pub fn average(&self) -> Scalar {
141 (self.min + self.max) * 0.5
142 }
143
144 pub fn min_max(&self, other: &Self) -> Self {
145 Self {
146 min: self.min.min(other.min),
147 max: self.max.max(other.max),
148 }
149 }
150
151 pub fn clamp(&self) -> Self {
152 Self {
153 min: self.min.clamp(0.0, 1.0),
154 max: self.max.clamp(0.0, 1.0),
155 }
156 }
157}
158
159impl Add for DensityRange {
160 type Output = Self;
161
162 fn add(self, other: Self) -> Self::Output {
163 Self {
164 min: self.min + other.min,
165 max: self.max + other.max,
166 }
167 }
168}
169
170impl AddAssign for DensityRange {
171 fn add_assign(&mut self, other: Self) {
172 self.min += other.min;
173 self.max += other.max;
174 }
175}
176
177impl Sub for DensityRange {
178 type Output = Self;
179
180 fn sub(self, other: Self) -> Self::Output {
181 Self {
182 min: self.min - other.min,
183 max: self.max - other.max,
184 }
185 }
186}
187
188impl SubAssign for DensityRange {
189 fn sub_assign(&mut self, other: Self) {
190 self.min -= other.min;
191 self.max -= other.max;
192 }
193}
194
195impl Mul for DensityRange {
196 type Output = Self;
197
198 fn mul(self, other: Self) -> Self::Output {
199 Self {
200 min: self.min * other.min,
201 max: self.max * other.max,
202 }
203 }
204}
205
206impl MulAssign for DensityRange {
207 fn mul_assign(&mut self, other: Self) {
208 self.min *= other.min;
209 self.max *= other.max;
210 }
211}
212
213impl Mul<Scalar> for DensityRange {
214 type Output = Self;
215
216 fn mul(self, scalar: Scalar) -> Self::Output {
217 Self {
218 min: self.min * scalar,
219 max: self.max * scalar,
220 }
221 }
222}
223
224impl MulAssign<Scalar> for DensityRange {
225 fn mul_assign(&mut self, scalar: Scalar) {
226 self.min *= scalar;
227 self.max *= scalar;
228 }
229}
230
231impl Div for DensityRange {
232 type Output = Self;
233
234 fn div(self, other: Self) -> Self::Output {
235 Self {
236 min: self.min / other.min,
237 max: self.max / other.max,
238 }
239 }
240}
241
242impl DivAssign for DensityRange {
243 fn div_assign(&mut self, other: Self) {
244 self.min /= other.min;
245 self.max /= other.max;
246 }
247}
248
249impl Div<Scalar> for DensityRange {
250 type Output = Self;
251
252 fn div(self, scalar: Scalar) -> Self::Output {
253 Self {
254 min: self.min / scalar,
255 max: self.max / scalar,
256 }
257 }
258}
259
260impl DivAssign<Scalar> for DensityRange {
261 fn div_assign(&mut self, scalar: Scalar) {
262 self.min /= scalar;
263 self.max /= scalar;
264 }
265}