anput_physics/density_fields/
subtraction.rs1use crate::{
2 Scalar,
3 components::BodyAccessInfo,
4 density_fields::{DensityField, DensityFieldBox, DensityRange},
5};
6use vek::{Aabb, Vec3};
7
8pub struct SubtractionDensityField {
9 pub fields: Vec<DensityFieldBox>,
10}
11
12impl DensityField for SubtractionDensityField {
13 fn aabb(&self, info: &BodyAccessInfo) -> Aabb<Scalar> {
14 self.fields
15 .iter()
16 .map(|field| field.aabb(info))
17 .reduce(|accum, aabb| accum.union(aabb))
18 .unwrap_or_default()
19 }
20
21 fn density_at_point(&self, point: Vec3<Scalar>, info: &BodyAccessInfo) -> Scalar {
22 self.fields
23 .iter()
24 .map(|field| field.density_at_point(point, info))
25 .reduce(|accum, normal| accum - normal)
26 .unwrap_or_default()
27 }
28
29 fn density_at_region(&self, region: Aabb<Scalar>, info: &BodyAccessInfo) -> DensityRange {
30 self.fields
31 .iter()
32 .map(|field| field.density_at_region(region, info))
33 .reduce(|accum, range| accum - range)
34 .unwrap_or_default()
35 }
36
37 fn normal_at_point(
38 &self,
39 point: Vec3<Scalar>,
40 resolution: Vec3<Scalar>,
41 info: &BodyAccessInfo,
42 ) -> Vec3<Scalar> {
43 self.fields
44 .iter()
45 .map(|field| field.normal_at_point(point, resolution, info))
46 .reduce(|accum, normal| accum - normal)
47 .and_then(|normal| normal.try_normalized())
48 .unwrap_or_default()
49 }
50}