noise_expr/
expr.rs

1use {
2    noise::{
3        core::worley::{
4            self,
5            distance_functions::{chebyshev, euclidean, euclidean_squared, manhattan},
6        },
7        Abs, Add, BasicMulti, Billow, Blend, Checkerboard, Clamp, Constant, Curve, Cylinders,
8        Displace, Exponent, Fbm, HybridMulti, Max, Min, MultiFractal, Multiply, Negate, NoiseFn,
9        OpenSimplex, Perlin, PerlinSurflet, Power, RidgedMulti, RotatePoint, ScaleBias, ScalePoint,
10        Seedable, Select, Simplex, SuperSimplex, Terrace, TranslatePoint, Turbulence, Value,
11        Worley,
12    },
13    ordered_float::OrderedFloat,
14    serde::{Deserialize, Serialize},
15    std::cell::RefCell,
16};
17
18pub const MAX_FRACTAL_OCTAVES: u32 = BasicMulti::<Perlin>::MAX_OCTAVES as _;
19
20#[derive(Clone, Debug, Deserialize, Serialize)]
21pub struct BlendExpr {
22    pub sources: [Box<Expr>; 2],
23    pub control: Box<Expr>,
24}
25
26impl BlendExpr {
27    fn set_f64(&mut self, name: &str, value: f64) {
28        self.sources.iter_mut().for_each(|expr| {
29            expr.set_f64(name, value);
30        });
31        self.control.set_f64(name, value);
32    }
33
34    fn set_u32(&mut self, name: &str, value: u32) {
35        self.sources.iter_mut().for_each(|expr| {
36            expr.set_u32(name, value);
37        });
38        self.control.set_u32(name, value);
39    }
40}
41
42#[derive(Clone, Debug, Deserialize, Serialize)]
43pub struct ClampExpr {
44    pub source: Box<Expr>,
45
46    pub lower_bound: Variable<f64>,
47    pub upper_bound: Variable<f64>,
48}
49
50impl ClampExpr {
51    fn set_f64(&mut self, name: &str, value: f64) {
52        self.source.set_f64(name, value);
53        self.lower_bound.set_if_named(name, value);
54        self.lower_bound.set_if_named(name, value);
55    }
56
57    fn set_u32(&mut self, name: &str, value: u32) {
58        self.source.set_u32(name, value);
59    }
60}
61
62#[derive(Clone, Debug, Deserialize, Serialize)]
63pub struct ControlPointExpr {
64    pub input_value: Variable<f64>,
65    pub output_value: Variable<f64>,
66}
67
68impl ControlPointExpr {
69    fn set_f64(&mut self, name: &str, value: f64) {
70        self.input_value.set_if_named(name, value);
71        self.output_value.set_if_named(name, value);
72    }
73}
74
75#[derive(Clone, Debug, Deserialize, Serialize)]
76pub struct CurveExpr {
77    pub source: Box<Expr>,
78
79    pub control_points: Vec<ControlPointExpr>,
80}
81
82impl CurveExpr {
83    fn set_f64(&mut self, name: &str, value: f64) {
84        self.source.set_f64(name, value);
85        self.control_points
86            .iter_mut()
87            .for_each(|expr| expr.set_f64(name, value));
88    }
89
90    fn set_u32(&mut self, name: &str, value: u32) {
91        self.source.set_u32(name, value);
92    }
93}
94
95#[derive(Clone, Debug, Deserialize, Serialize)]
96pub struct DisplaceExpr {
97    pub source: Box<Expr>,
98
99    pub axes: [Box<Expr>; 4],
100}
101
102impl DisplaceExpr {
103    fn set_f64(&mut self, name: &str, value: f64) {
104        self.source.set_f64(name, value);
105        self.axes.iter_mut().for_each(|expr| {
106            expr.set_f64(name, value);
107        });
108    }
109
110    fn set_u32(&mut self, name: &str, value: u32) {
111        self.source.set_u32(name, value);
112        self.axes.iter_mut().for_each(|expr| {
113            expr.set_u32(name, value);
114        });
115    }
116}
117
118#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
119pub enum DistanceFunction {
120    Chebyshev,
121    Euclidean,
122    EuclideanSquared,
123    Manhattan,
124}
125
126#[derive(Clone, Debug, Deserialize, Serialize)]
127pub struct ExponentExpr {
128    pub source: Box<Expr>,
129
130    pub exponent: Variable<f64>,
131}
132
133impl ExponentExpr {
134    fn set_f64(&mut self, name: &str, value: f64) {
135        self.source.set_f64(name, value);
136        self.exponent.set_if_named(name, value);
137    }
138
139    fn set_u32(&mut self, name: &str, value: u32) {
140        self.source.set_u32(name, value);
141    }
142}
143
144#[derive(Clone, Debug, Deserialize, Serialize)]
145pub struct FractalExpr {
146    pub source_ty: SourceType,
147    pub seed: Variable<u32>,
148    pub octaves: Variable<u32>,
149    pub frequency: Variable<f64>,
150    pub lacunarity: Variable<f64>,
151    pub persistence: Variable<f64>,
152}
153
154impl FractalExpr {
155    fn set_f64(&mut self, name: &str, value: f64) {
156        self.frequency.set_if_named(name, value);
157        self.lacunarity.set_if_named(name, value);
158        self.persistence.set_if_named(name, value);
159    }
160
161    fn set_u32(&mut self, name: &str, value: u32) {
162        self.seed.set_if_named(name, value);
163        self.octaves.set_if_named(name, value);
164    }
165}
166
167#[derive(Clone, Debug, Deserialize, Serialize)]
168pub enum Expr {
169    Abs(Box<Expr>),
170    Add([Box<Expr>; 2]),
171    BasicMulti(FractalExpr),
172    Billow(FractalExpr),
173    Blend(BlendExpr),
174    Checkerboard(Variable<u32>),
175    Clamp(ClampExpr),
176    Constant(Variable<f64>),
177    ConstantU32(Variable<u32>),
178    Curve(CurveExpr),
179    Cylinders(Variable<f64>),
180    Displace(DisplaceExpr),
181    Exponent(ExponentExpr),
182    Fbm(FractalExpr),
183    HybridMulti(FractalExpr),
184    Max([Box<Expr>; 2]),
185    Min([Box<Expr>; 2]),
186    Multiply([Box<Expr>; 2]),
187    Negate(Box<Expr>),
188    OpenSimplex(Variable<u32>),
189    Perlin(Variable<u32>),
190    PerlinSurflet(Variable<u32>),
191    Power([Box<Expr>; 2]),
192    RidgedMulti(RigidFractalExpr),
193    RotatePoint(TransformExpr),
194    ScaleBias(ScaleBiasExpr),
195    ScalePoint(TransformExpr),
196    Select(SelectExpr),
197    Simplex(Variable<u32>),
198    SuperSimplex(Variable<u32>),
199    Terrace(TerraceExpr),
200    TranslatePoint(TransformExpr),
201    Turbulence(TurbulenceExpr),
202    Value(Variable<u32>),
203    Worley(WorleyExpr),
204}
205
206impl Expr {
207    fn basic_multi<T>(expr: &FractalExpr) -> Box<BasicMulti<T>>
208    where
209        T: Default + Seedable,
210    {
211        Box::new(
212            BasicMulti::<T>::new(expr.seed.value())
213                .set_octaves(expr.octaves.value().clamp(1, MAX_FRACTAL_OCTAVES) as _)
214                .set_frequency(expr.frequency.value())
215                .set_lacunarity(expr.lacunarity.value())
216                .set_persistence(expr.persistence.value()),
217        )
218    }
219
220    fn billow<T>(expr: &FractalExpr) -> Box<Billow<T>>
221    where
222        T: Default + Seedable,
223    {
224        Box::new(
225            Billow::<T>::new(expr.seed.value())
226                .set_octaves(expr.octaves.value().clamp(1, MAX_FRACTAL_OCTAVES) as _)
227                .set_frequency(expr.frequency.value())
228                .set_lacunarity(expr.lacunarity.value())
229                .set_persistence(expr.persistence.value()),
230        )
231    }
232
233    fn curve(expr: &CurveExpr) -> Box<dyn NoiseFn<f64, 3>> {
234        fn invalid_inputs(control_points: &[ControlPointExpr]) -> bool {
235            debug_assert!(control_points.len() >= 4);
236
237            type Inputs = Vec<OrderedFloat<f64>>;
238
239            thread_local! {
240                static INPUTS: RefCell<Option<Inputs>> = RefCell::new(Some(Vec::with_capacity(3)));
241            }
242
243            let mut inputs = INPUTS.take().unwrap();
244
245            for ControlPointExpr { input_value, .. } in control_points {
246                let input_value = OrderedFloat(input_value.value());
247                if let Err(idx) = inputs.binary_search(&input_value) {
248                    if inputs.len() == 3 {
249                        inputs.clear();
250                        INPUTS.set(Some(inputs));
251
252                        return false;
253                    }
254
255                    inputs.insert(idx, input_value);
256                }
257            }
258
259            inputs.clear();
260            INPUTS.set(Some(inputs));
261
262            true
263        }
264
265        // Make sure the control points are valid (noise-rs panics!)
266        if expr.control_points.len() < 4 || invalid_inputs(&expr.control_points) {
267            return Box::new(Constant::new(0.0));
268        }
269
270        let mut res = Curve::new(expr.source.noise());
271
272        for control_point in &expr.control_points {
273            res = res.add_control_point(
274                control_point.input_value.value(),
275                control_point.output_value.value(),
276            );
277        }
278
279        Box::new(res)
280    }
281
282    fn fbm<T>(expr: &FractalExpr) -> Box<Fbm<T>>
283    where
284        T: Default + Seedable,
285    {
286        Box::new(
287            Fbm::<T>::new(expr.seed.value())
288                .set_octaves(expr.octaves.value().clamp(1, MAX_FRACTAL_OCTAVES) as _)
289                .set_frequency(expr.frequency.value())
290                .set_lacunarity(expr.lacunarity.value())
291                .set_persistence(expr.persistence.value()),
292        )
293    }
294
295    fn hybrid_multi<T>(expr: &FractalExpr) -> Box<HybridMulti<T>>
296    where
297        T: Default + Seedable,
298    {
299        Box::new(
300            HybridMulti::<T>::new(expr.seed.value())
301                .set_octaves(expr.octaves.value().clamp(1, MAX_FRACTAL_OCTAVES) as _)
302                .set_frequency(expr.frequency.value())
303                .set_lacunarity(expr.lacunarity.value())
304                .set_persistence(expr.persistence.value()),
305        )
306    }
307
308    pub fn noise(&self) -> Box<dyn NoiseFn<f64, 3>> {
309        match self {
310            Self::Abs(expr) => Box::new(Abs::new(expr.noise())),
311            Self::Add([source1, source2]) => Box::new(Add::new(source1.noise(), source2.noise())),
312            Self::BasicMulti(expr) => match expr.source_ty {
313                SourceType::OpenSimplex => Self::basic_multi::<OpenSimplex>(expr),
314                SourceType::Perlin => Self::basic_multi::<Perlin>(expr),
315                SourceType::PerlinSurflet => Self::basic_multi::<PerlinSurflet>(expr),
316                SourceType::Simplex => Self::basic_multi::<Simplex>(expr),
317                SourceType::SuperSimplex => Self::basic_multi::<OpenSimplex>(expr),
318                SourceType::Value => Self::basic_multi::<Value>(expr),
319                SourceType::Worley => Self::basic_multi::<Worley>(expr),
320            },
321            Self::Billow(expr) => match expr.source_ty {
322                SourceType::OpenSimplex => Self::billow::<OpenSimplex>(expr),
323                SourceType::Perlin => Self::billow::<Perlin>(expr),
324                SourceType::PerlinSurflet => Self::billow::<PerlinSurflet>(expr),
325                SourceType::Simplex => Self::billow::<Simplex>(expr),
326                SourceType::SuperSimplex => Self::billow::<OpenSimplex>(expr),
327                SourceType::Value => Self::billow::<Value>(expr),
328                SourceType::Worley => Self::billow::<Worley>(expr),
329            },
330            Self::Blend(expr) => Box::new(Blend::new(
331                expr.sources[0].noise(),
332                expr.sources[1].noise(),
333                expr.control.noise(),
334            )),
335            Self::Checkerboard(size) => Box::new(Checkerboard::new(size.value() as _)),
336            Self::Clamp(expr) => Box::new(
337                Clamp::new(expr.source.noise())
338                    .set_lower_bound(expr.lower_bound.value().min(expr.upper_bound.value()))
339                    .set_upper_bound(expr.lower_bound.value().max(expr.upper_bound.value())),
340            ),
341            Self::Constant(value) => Box::new(Constant::new(value.value())),
342            Self::ConstantU32(_) => unreachable!(),
343            Self::Curve(expr) => Self::curve(expr),
344            Self::Cylinders(frequency) => {
345                Box::new(Cylinders::new().set_frequency(frequency.value()))
346            }
347            Self::Displace(expr) => Box::new(Displace::new(
348                expr.source.noise(),
349                expr.axes[0].noise(),
350                expr.axes[1].noise(),
351                expr.axes[2].noise(),
352                expr.axes[3].noise(),
353            )),
354            Self::Exponent(expr) => {
355                Box::new(Exponent::new(expr.source.noise()).set_exponent(expr.exponent.value()))
356            }
357            Self::Fbm(expr) => match expr.source_ty {
358                SourceType::OpenSimplex => Self::fbm::<OpenSimplex>(expr),
359                SourceType::Perlin => Self::fbm::<Perlin>(expr),
360                SourceType::PerlinSurflet => Self::fbm::<PerlinSurflet>(expr),
361                SourceType::Simplex => Self::fbm::<Simplex>(expr),
362                SourceType::SuperSimplex => Self::fbm::<OpenSimplex>(expr),
363                SourceType::Value => Self::fbm::<Value>(expr),
364                SourceType::Worley => Self::fbm::<Worley>(expr),
365            },
366            Self::HybridMulti(expr) => match expr.source_ty {
367                SourceType::OpenSimplex => Self::hybrid_multi::<OpenSimplex>(expr),
368                SourceType::Perlin => Self::hybrid_multi::<Perlin>(expr),
369                SourceType::PerlinSurflet => Self::hybrid_multi::<PerlinSurflet>(expr),
370                SourceType::Simplex => Self::hybrid_multi::<Simplex>(expr),
371                SourceType::SuperSimplex => Self::hybrid_multi::<OpenSimplex>(expr),
372                SourceType::Value => Self::hybrid_multi::<Value>(expr),
373                SourceType::Worley => Self::hybrid_multi::<Worley>(expr),
374            },
375            Self::Max([source1, source2]) => Box::new(Max::new(source1.noise(), source2.noise())),
376            Self::Min([source1, source2]) => Box::new(Min::new(source1.noise(), source2.noise())),
377            Self::Multiply([source1, source2]) => {
378                Box::new(Multiply::new(source1.noise(), source2.noise()))
379            }
380            Self::Negate(expr) => Box::new(Negate::new(expr.noise())),
381            Self::OpenSimplex(seed) => Box::new(OpenSimplex::new(seed.value())),
382            Self::Perlin(seed) => Box::new(Perlin::new(seed.value())),
383            Self::PerlinSurflet(seed) => Box::new(PerlinSurflet::new(seed.value())),
384            Self::Power([source1, source2]) => {
385                Box::new(Power::new(source1.noise(), source2.noise()))
386            }
387            Self::RidgedMulti(expr) => match expr.source_ty {
388                SourceType::OpenSimplex => Self::rigid_multi::<OpenSimplex>(expr),
389                SourceType::Perlin => Self::rigid_multi::<Perlin>(expr),
390                SourceType::PerlinSurflet => Self::rigid_multi::<PerlinSurflet>(expr),
391                SourceType::Simplex => Self::rigid_multi::<Simplex>(expr),
392                SourceType::SuperSimplex => Self::rigid_multi::<OpenSimplex>(expr),
393                SourceType::Value => Self::rigid_multi::<Value>(expr),
394                SourceType::Worley => Self::rigid_multi::<Worley>(expr),
395            },
396            Self::RotatePoint(expr) => Box::new(RotatePoint::new(expr.source.noise()).set_angles(
397                expr.axes[0].value(),
398                expr.axes[1].value(),
399                expr.axes[2].value(),
400                expr.axes[3].value(),
401            )),
402            Self::ScaleBias(expr) => Box::new(
403                ScaleBias::new(expr.source.noise())
404                    .set_bias(expr.bias.value())
405                    .set_scale(expr.scale.value()),
406            ),
407            Self::ScalePoint(expr) => {
408                Box::new(ScalePoint::new(expr.source.noise()).set_all_scales(
409                    expr.axes[0].value(),
410                    expr.axes[1].value(),
411                    expr.axes[2].value(),
412                    expr.axes[3].value(),
413                ))
414            }
415            Self::Select(expr) => Box::new(
416                Select::new(
417                    expr.sources[0].noise(),
418                    expr.sources[1].noise(),
419                    expr.control.noise(),
420                )
421                .set_bounds(expr.lower_bound.value(), expr.upper_bound.value())
422                .set_falloff(expr.falloff.value()),
423            ),
424            Self::Simplex(seed) => Box::new(Simplex::new(seed.value())),
425            Self::SuperSimplex(seed) => Box::new(SuperSimplex::new(seed.value())),
426            Self::Terrace(expr) => Self::terrace(expr),
427            Self::TranslatePoint(expr) => Box::new(
428                TranslatePoint::new(expr.source.noise()).set_all_translations(
429                    expr.axes[0].value(),
430                    expr.axes[1].value(),
431                    expr.axes[2].value(),
432                    expr.axes[3].value(),
433                ),
434            ),
435            Self::Turbulence(expr) => match expr.source_ty {
436                SourceType::OpenSimplex => Self::turbulence::<OpenSimplex>(expr),
437                SourceType::Perlin => Self::turbulence::<Perlin>(expr),
438                SourceType::PerlinSurflet => Self::turbulence::<PerlinSurflet>(expr),
439                SourceType::Simplex => Self::turbulence::<Simplex>(expr),
440                SourceType::SuperSimplex => Self::turbulence::<OpenSimplex>(expr),
441                SourceType::Value => Self::turbulence::<Value>(expr),
442                SourceType::Worley => Self::turbulence::<Worley>(expr),
443            },
444            Self::Value(seed) => Box::new(Value::new(seed.value())),
445            Self::Worley(expr) => Box::new(
446                Worley::new(expr.seed.value())
447                    .set_frequency(expr.frequency.value())
448                    .set_distance_function(match expr.distance_fn {
449                        DistanceFunction::Chebyshev => chebyshev,
450                        DistanceFunction::Euclidean => euclidean,
451                        DistanceFunction::EuclideanSquared => euclidean_squared,
452                        DistanceFunction::Manhattan => manhattan,
453                    })
454                    .set_return_type(match expr.return_ty {
455                        ReturnType::Distance => worley::ReturnType::Distance,
456                        ReturnType::Value => worley::ReturnType::Value,
457                    }),
458            ),
459        }
460    }
461
462    fn rigid_multi<T>(expr: &RigidFractalExpr) -> Box<RidgedMulti<T>>
463    where
464        T: Default + Seedable,
465    {
466        Box::new(
467            RidgedMulti::<T>::new(expr.seed.value())
468                .set_octaves(expr.octaves.value().clamp(1, MAX_FRACTAL_OCTAVES) as _)
469                .set_frequency(expr.frequency.value())
470                .set_lacunarity(expr.lacunarity.value())
471                .set_persistence(expr.persistence.value())
472                .set_attenuation(expr.attenuation.value()),
473        )
474    }
475
476    #[allow(unused)]
477    pub fn set_f64(&mut self, name: &str, value: f64) -> &mut Self {
478        match self {
479            Self::Abs(expr) | Self::Negate(expr) => {
480                expr.set_f64(name, value);
481            }
482            Self::Add(exprs)
483            | Self::Max(exprs)
484            | Self::Min(exprs)
485            | Self::Multiply(exprs)
486            | Self::Power(exprs) => exprs.iter_mut().for_each(|expr| {
487                expr.set_f64(name, value);
488            }),
489            Self::BasicMulti(expr)
490            | Self::Billow(expr)
491            | Self::Fbm(expr)
492            | Self::HybridMulti(expr) => expr.set_f64(name, value),
493            Self::Blend(expr) => expr.set_f64(name, value),
494            Self::Clamp(expr) => expr.set_f64(name, value),
495            Self::Constant(expr) | Self::Cylinders(expr) => expr.set_if_named(name, value),
496            Self::Curve(expr) => expr.set_f64(name, value),
497            Self::Displace(expr) => expr.set_f64(name, value),
498            Self::Exponent(expr) => expr.set_f64(name, value),
499            Self::RidgedMulti(expr) => expr.set_f64(name, value),
500            Self::RotatePoint(expr) | Self::ScalePoint(expr) | Self::TranslatePoint(expr) => {
501                expr.set_f64(name, value)
502            }
503            Self::ScaleBias(expr) => expr.set_f64(name, value),
504            Self::Select(expr) => expr.set_f64(name, value),
505            Self::Terrace(expr) => expr.set_f64(name, value),
506            Self::Turbulence(expr) => expr.set_f64(name, value),
507            Self::Worley(expr) => expr.set_f64(name, value),
508            Self::Checkerboard(_)
509            | Self::ConstantU32(_)
510            | Self::OpenSimplex(_)
511            | Self::Perlin(_)
512            | Self::PerlinSurflet(_)
513            | Self::Simplex(_)
514            | Self::SuperSimplex(_)
515            | Self::Value(_) => (),
516        }
517
518        self
519    }
520
521    #[allow(unused)]
522    pub fn set_u32(&mut self, name: &str, value: u32) -> &mut Self {
523        match self {
524            Self::Abs(expr) | Self::Negate(expr) => {
525                expr.set_u32(name, value);
526            }
527            Self::Add(exprs)
528            | Self::Max(exprs)
529            | Self::Min(exprs)
530            | Self::Multiply(exprs)
531            | Self::Power(exprs) => exprs.iter_mut().for_each(|expr| {
532                expr.set_u32(name, value);
533            }),
534            Self::BasicMulti(expr)
535            | Self::Billow(expr)
536            | Self::Fbm(expr)
537            | Self::HybridMulti(expr) => expr.set_u32(name, value),
538            Self::Blend(expr) => expr.set_u32(name, value),
539            Self::Checkerboard(expr)
540            | Self::ConstantU32(expr)
541            | Self::OpenSimplex(expr)
542            | Self::Perlin(expr)
543            | Self::PerlinSurflet(expr)
544            | Self::Simplex(expr)
545            | Self::SuperSimplex(expr)
546            | Self::Value(expr) => expr.set_if_named(name, value),
547            Self::Clamp(expr) => expr.set_u32(name, value),
548            Self::Curve(expr) => expr.set_u32(name, value),
549            Self::Displace(expr) => expr.set_u32(name, value),
550            Self::Exponent(expr) => expr.set_u32(name, value),
551            Self::RidgedMulti(expr) => expr.set_u32(name, value),
552            Self::RotatePoint(expr) | Self::ScalePoint(expr) | Self::TranslatePoint(expr) => {
553                expr.set_u32(name, value)
554            }
555            Self::Select(expr) => expr.set_u32(name, value),
556            Self::ScaleBias(expr) => expr.set_u32(name, value),
557            Self::Terrace(expr) => expr.set_u32(name, value),
558            Self::Turbulence(expr) => expr.set_u32(name, value),
559            Self::Worley(expr) => expr.set_u32(name, value),
560            Self::Constant(_) | Self::Cylinders(_) => (),
561        }
562
563        self
564    }
565
566    fn turbulence<T>(expr: &TurbulenceExpr) -> Box<Turbulence<Box<dyn NoiseFn<f64, 3>>, T>>
567    where
568        T: Default + Seedable,
569    {
570        Box::new(
571            Turbulence::<Box<dyn NoiseFn<f64, 3>>, T>::new(expr.source.noise())
572                .set_seed(expr.seed.value())
573                .set_frequency(expr.frequency.value())
574                .set_power(expr.power.value())
575                .set_roughness(expr.roughness.value() as _),
576        )
577    }
578
579    fn terrace(expr: &TerraceExpr) -> Box<dyn NoiseFn<f64, 3>> {
580        fn invalid_inputs(control_points: &[Variable<f64>]) -> bool {
581            debug_assert!(control_points.len() >= 2);
582
583            let first_input = OrderedFloat(control_points[0].value());
584
585            for input_value in &control_points[1..] {
586                let input_value = OrderedFloat(input_value.value());
587                if input_value != first_input {
588                    return false;
589                }
590            }
591
592            true
593        }
594
595        // Make sure the control points are valid (noise-rs panics!)
596        if expr.control_points.len() < 2 || invalid_inputs(&expr.control_points) {
597            return Box::new(Constant::new(0.0));
598        }
599
600        let mut res = Terrace::new(expr.source.noise()).invert_terraces(expr.inverted);
601
602        for control_point in expr.control_points.iter() {
603            res = res.add_control_point(control_point.value());
604        }
605
606        Box::new(res)
607    }
608}
609
610#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
611pub enum OpType {
612    Add,
613    Divide,
614    Multiply,
615    Subtract,
616}
617
618#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
619pub enum ReturnType {
620    Distance,
621    Value,
622}
623
624#[derive(Clone, Debug, Deserialize, Serialize)]
625pub struct RigidFractalExpr {
626    pub source_ty: SourceType,
627    pub seed: Variable<u32>,
628    pub octaves: Variable<u32>,
629    pub frequency: Variable<f64>,
630    pub lacunarity: Variable<f64>,
631    pub persistence: Variable<f64>,
632    pub attenuation: Variable<f64>,
633}
634
635impl RigidFractalExpr {
636    fn set_f64(&mut self, name: &str, value: f64) {
637        self.frequency.set_if_named(name, value);
638        self.lacunarity.set_if_named(name, value);
639        self.persistence.set_if_named(name, value);
640        self.attenuation.set_if_named(name, value);
641    }
642
643    fn set_u32(&mut self, name: &str, value: u32) {
644        self.seed.set_if_named(name, value);
645        self.octaves.set_if_named(name, value);
646    }
647}
648
649#[derive(Clone, Debug, Deserialize, Serialize)]
650pub struct ScaleBiasExpr {
651    pub source: Box<Expr>,
652
653    pub scale: Variable<f64>,
654    pub bias: Variable<f64>,
655}
656
657impl ScaleBiasExpr {
658    fn set_f64(&mut self, name: &str, value: f64) {
659        self.source.set_f64(name, value);
660        self.scale.set_if_named(name, value);
661        self.bias.set_if_named(name, value);
662    }
663
664    fn set_u32(&mut self, name: &str, value: u32) {
665        self.source.set_u32(name, value);
666    }
667}
668
669#[derive(Clone, Debug, Deserialize, Serialize)]
670pub struct SelectExpr {
671    pub sources: [Box<Expr>; 2],
672    pub control: Box<Expr>,
673
674    pub lower_bound: Variable<f64>,
675    pub upper_bound: Variable<f64>,
676    pub falloff: Variable<f64>,
677}
678
679impl SelectExpr {
680    fn set_f64(&mut self, name: &str, value: f64) {
681        self.sources.iter_mut().for_each(|expr| {
682            expr.set_f64(name, value);
683        });
684        self.control.set_f64(name, value);
685        self.lower_bound.set_if_named(name, value);
686        self.upper_bound.set_if_named(name, value);
687        self.falloff.set_if_named(name, value);
688    }
689
690    fn set_u32(&mut self, name: &str, value: u32) {
691        self.sources.iter_mut().for_each(|expr| {
692            expr.set_u32(name, value);
693        });
694        self.control.set_u32(name, value);
695    }
696}
697
698#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, Default)]
699pub enum SourceType {
700    OpenSimplex,
701    #[default]
702    Perlin,
703    PerlinSurflet,
704    Simplex,
705    SuperSimplex,
706    Value,
707    Worley,
708}
709
710#[derive(Clone, Debug, Deserialize, Serialize)]
711pub struct TerraceExpr {
712    pub source: Box<Expr>,
713
714    pub inverted: bool,
715    pub control_points: Vec<Variable<f64>>,
716}
717
718impl TerraceExpr {
719    fn set_f64(&mut self, name: &str, value: f64) {
720        self.source.set_f64(name, value);
721        self.control_points
722            .iter_mut()
723            .for_each(|control_point| control_point.set_if_named(name, value));
724    }
725
726    fn set_u32(&mut self, name: &str, value: u32) {
727        self.source.set_u32(name, value);
728    }
729}
730
731#[derive(Clone, Debug, Deserialize, Serialize)]
732pub struct TransformExpr {
733    pub source: Box<Expr>,
734
735    pub axes: [Variable<f64>; 4],
736}
737
738impl TransformExpr {
739    fn set_f64(&mut self, name: &str, value: f64) {
740        self.source.set_f64(name, value);
741        self.axes
742            .iter_mut()
743            .for_each(|axis| axis.set_if_named(name, value));
744    }
745
746    fn set_u32(&mut self, name: &str, value: u32) {
747        self.source.set_u32(name, value);
748    }
749}
750
751#[derive(Clone, Debug, Deserialize, Serialize)]
752pub struct TurbulenceExpr {
753    pub source: Box<Expr>,
754
755    pub source_ty: SourceType,
756    pub seed: Variable<u32>,
757    pub frequency: Variable<f64>,
758    pub power: Variable<f64>,
759    pub roughness: Variable<u32>,
760}
761
762impl TurbulenceExpr {
763    fn set_f64(&mut self, name: &str, value: f64) {
764        self.source.set_f64(name, value);
765        self.frequency.set_if_named(name, value);
766        self.power.set_if_named(name, value);
767    }
768
769    fn set_u32(&mut self, name: &str, value: u32) {
770        self.source.set_u32(name, value);
771        self.seed.set_if_named(name, value);
772        self.roughness.set_if_named(name, value);
773    }
774}
775
776#[derive(Clone, Debug, Deserialize, Serialize)]
777pub enum Variable<T> {
778    #[serde(rename = "Value")]
779    Anonymous(T),
780
781    #[serde(rename = "Variable")]
782    Named(String, T),
783
784    Operation([Box<Self>; 2], OpType),
785}
786
787impl<T> Variable<T> {
788    fn set_if_named(&mut self, name: &str, value: T)
789    where
790        T: Copy,
791    {
792        match self {
793            Self::Anonymous(_) => (),
794            Self::Named(named, valued) => {
795                if named == name {
796                    *valued = value;
797                }
798            }
799            Self::Operation(vars, _) => {
800                vars.iter_mut()
801                    .for_each(|var| var.set_if_named(name, value));
802            }
803        }
804    }
805}
806
807impl Variable<f64> {
808    fn value(&self) -> f64 {
809        match self {
810            Self::Anonymous(value) | Self::Named(_, value) => *value,
811            Self::Operation(vars, op) => {
812                let (lhs, rhs) = (vars[0].value(), vars[1].value());
813                match op {
814                    OpType::Add => lhs + rhs,
815                    OpType::Divide => {
816                        if rhs != 0.0 {
817                            lhs / rhs
818                        } else {
819                            0.0
820                        }
821                    }
822                    OpType::Multiply => lhs * rhs,
823                    OpType::Subtract => lhs - rhs,
824                }
825            }
826        }
827    }
828}
829
830impl Variable<u32> {
831    fn value(&self) -> u32 {
832        match self {
833            Self::Anonymous(value) | Self::Named(_, value) => *value,
834            Self::Operation(vars, op) => {
835                let (lhs, rhs) = (vars[0].value(), vars[1].value());
836                match op {
837                    OpType::Add => lhs.checked_add(rhs),
838                    OpType::Divide => lhs.checked_div(rhs),
839                    OpType::Multiply => lhs.checked_mul(rhs),
840                    OpType::Subtract => lhs.checked_sub(rhs),
841                }
842                .unwrap_or_default()
843            }
844        }
845    }
846}
847
848#[derive(Clone, Debug, Deserialize, Serialize)]
849pub struct WorleyExpr {
850    pub seed: Variable<u32>,
851    pub frequency: Variable<f64>,
852    pub distance_fn: DistanceFunction,
853    pub return_ty: ReturnType,
854}
855
856impl WorleyExpr {
857    fn set_f64(&mut self, name: &str, value: f64) {
858        self.frequency.set_if_named(name, value);
859    }
860
861    fn set_u32(&mut self, name: &str, value: u32) {
862        self.seed.set_if_named(name, value);
863    }
864}