shades/
stdlib.rs

1use crate::{
2  expr::{ErasedExpr, Expr},
3  fun::ErasedFunHandle,
4  types::{V2, V3, V4},
5};
6
7// standard library
8pub trait Trigonometry {
9  fn radians(&self) -> Self;
10
11  fn degrees(&self) -> Self;
12
13  fn sin(&self) -> Self;
14
15  fn cos(&self) -> Self;
16
17  fn tan(&self) -> Self;
18
19  fn asin(&self) -> Self;
20
21  fn acos(&self) -> Self;
22
23  fn atan(&self) -> Self;
24
25  fn sinh(&self) -> Self;
26
27  fn cosh(&self) -> Self;
28
29  fn tanh(&self) -> Self;
30
31  fn asinh(&self) -> Self;
32
33  fn acosh(&self) -> Self;
34
35  fn atanh(&self) -> Self;
36}
37
38macro_rules! impl_Trigonometry {
39  ($t:ty) => {
40    impl Trigonometry for Expr<$t> {
41      fn radians(&self) -> Self {
42        Expr::new(ErasedExpr::FunCall(
43          ErasedFunHandle::Radians,
44          vec![self.erased.clone()],
45        ))
46      }
47
48      fn degrees(&self) -> Self {
49        Expr::new(ErasedExpr::FunCall(
50          ErasedFunHandle::Degrees,
51          vec![self.erased.clone()],
52        ))
53      }
54
55      fn sin(&self) -> Self {
56        Expr::new(ErasedExpr::FunCall(
57          ErasedFunHandle::Sin,
58          vec![self.erased.clone()],
59        ))
60      }
61
62      fn cos(&self) -> Self {
63        Expr::new(ErasedExpr::FunCall(
64          ErasedFunHandle::Cos,
65          vec![self.erased.clone()],
66        ))
67      }
68
69      fn tan(&self) -> Self {
70        Expr::new(ErasedExpr::FunCall(
71          ErasedFunHandle::Tan,
72          vec![self.erased.clone()],
73        ))
74      }
75
76      fn asin(&self) -> Self {
77        Expr::new(ErasedExpr::FunCall(
78          ErasedFunHandle::ASin,
79          vec![self.erased.clone()],
80        ))
81      }
82
83      fn acos(&self) -> Self {
84        Expr::new(ErasedExpr::FunCall(
85          ErasedFunHandle::ACos,
86          vec![self.erased.clone()],
87        ))
88      }
89
90      fn atan(&self) -> Self {
91        Expr::new(ErasedExpr::FunCall(
92          ErasedFunHandle::ATan,
93          vec![self.erased.clone()],
94        ))
95      }
96
97      fn sinh(&self) -> Self {
98        Expr::new(ErasedExpr::FunCall(
99          ErasedFunHandle::SinH,
100          vec![self.erased.clone()],
101        ))
102      }
103
104      fn cosh(&self) -> Self {
105        Expr::new(ErasedExpr::FunCall(
106          ErasedFunHandle::CosH,
107          vec![self.erased.clone()],
108        ))
109      }
110
111      fn tanh(&self) -> Self {
112        Expr::new(ErasedExpr::FunCall(
113          ErasedFunHandle::TanH,
114          vec![self.erased.clone()],
115        ))
116      }
117
118      fn asinh(&self) -> Self {
119        Expr::new(ErasedExpr::FunCall(
120          ErasedFunHandle::ASinH,
121          vec![self.erased.clone()],
122        ))
123      }
124
125      fn acosh(&self) -> Self {
126        Expr::new(ErasedExpr::FunCall(
127          ErasedFunHandle::ACosH,
128          vec![self.erased.clone()],
129        ))
130      }
131
132      fn atanh(&self) -> Self {
133        Expr::new(ErasedExpr::FunCall(
134          ErasedFunHandle::ATanH,
135          vec![self.erased.clone()],
136        ))
137      }
138    }
139  };
140}
141
142impl_Trigonometry!(f32);
143impl_Trigonometry!(V2<f32>);
144impl_Trigonometry!(V3<f32>);
145impl_Trigonometry!(V4<f32>);
146
147pub trait Exponential: Sized {
148  fn pow(&self, p: impl Into<Self>) -> Self;
149
150  fn exp(&self) -> Self;
151
152  fn exp2(&self) -> Self;
153
154  fn log(&self) -> Self;
155
156  fn log2(&self) -> Self;
157
158  fn sqrt(&self) -> Self;
159
160  fn isqrt(&self) -> Self;
161}
162
163macro_rules! impl_Exponential {
164  ($t:ty) => {
165    impl Exponential for Expr<$t> {
166      fn pow(&self, p: impl Into<Self>) -> Self {
167        Expr::new(ErasedExpr::FunCall(
168          ErasedFunHandle::Pow,
169          vec![self.erased.clone(), p.into().erased],
170        ))
171      }
172
173      fn exp(&self) -> Self {
174        Expr::new(ErasedExpr::FunCall(
175          ErasedFunHandle::Exp,
176          vec![self.erased.clone()],
177        ))
178      }
179
180      fn exp2(&self) -> Self {
181        Expr::new(ErasedExpr::FunCall(
182          ErasedFunHandle::Exp2,
183          vec![self.erased.clone()],
184        ))
185      }
186
187      fn log(&self) -> Self {
188        Expr::new(ErasedExpr::FunCall(
189          ErasedFunHandle::Log,
190          vec![self.erased.clone()],
191        ))
192      }
193
194      fn log2(&self) -> Self {
195        Expr::new(ErasedExpr::FunCall(
196          ErasedFunHandle::Log2,
197          vec![self.erased.clone()],
198        ))
199      }
200
201      fn sqrt(&self) -> Self {
202        Expr::new(ErasedExpr::FunCall(
203          ErasedFunHandle::Sqrt,
204          vec![self.erased.clone()],
205        ))
206      }
207
208      fn isqrt(&self) -> Self {
209        Expr::new(ErasedExpr::FunCall(
210          ErasedFunHandle::InverseSqrt,
211          vec![self.erased.clone()],
212        ))
213      }
214    }
215  };
216}
217
218impl_Exponential!(f32);
219impl_Exponential!(V2<f32>);
220impl_Exponential!(V3<f32>);
221impl_Exponential!(V4<f32>);
222
223pub trait Relative {
224  fn abs(&self) -> Self;
225
226  fn sign(&self) -> Self;
227}
228
229macro_rules! impl_Relative {
230  ($t:ty) => {
231    impl Relative for Expr<$t> {
232      fn abs(&self) -> Self {
233        Expr::new(ErasedExpr::FunCall(
234          ErasedFunHandle::Abs,
235          vec![self.erased.clone()],
236        ))
237      }
238
239      fn sign(&self) -> Self {
240        Expr::new(ErasedExpr::FunCall(
241          ErasedFunHandle::Sign,
242          vec![self.erased.clone()],
243        ))
244      }
245    }
246  };
247}
248
249impl_Relative!(i32);
250impl_Relative!(V2<i32>);
251impl_Relative!(V3<i32>);
252impl_Relative!(V4<i32>);
253impl_Relative!(f32);
254impl_Relative!(V2<f32>);
255impl_Relative!(V3<f32>);
256impl_Relative!(V4<f32>);
257
258pub trait Floating {
259  fn floor(&self) -> Self;
260
261  fn trunc(&self) -> Self;
262
263  fn round(&self) -> Self;
264
265  fn ceil(&self) -> Self;
266
267  fn fract(&self) -> Self;
268}
269
270macro_rules! impl_Floating {
271  ($t:ty) => {
272    impl Floating for Expr<$t> {
273      fn floor(&self) -> Self {
274        Expr::new(ErasedExpr::FunCall(
275          ErasedFunHandle::Floor,
276          vec![self.erased.clone()],
277        ))
278      }
279
280      fn trunc(&self) -> Self {
281        Expr::new(ErasedExpr::FunCall(
282          ErasedFunHandle::Trunc,
283          vec![self.erased.clone()],
284        ))
285      }
286
287      fn round(&self) -> Self {
288        Expr::new(ErasedExpr::FunCall(
289          ErasedFunHandle::Round,
290          vec![self.erased.clone()],
291        ))
292      }
293
294      fn ceil(&self) -> Self {
295        Expr::new(ErasedExpr::FunCall(
296          ErasedFunHandle::Ceil,
297          vec![self.erased.clone()],
298        ))
299      }
300
301      fn fract(&self) -> Self {
302        Expr::new(ErasedExpr::FunCall(
303          ErasedFunHandle::Fract,
304          vec![self.erased.clone()],
305        ))
306      }
307    }
308  };
309}
310
311impl_Floating!(f32);
312impl_Floating!(V2<f32>);
313impl_Floating!(V3<f32>);
314impl_Floating!(V4<f32>);
315
316pub trait Bounded: Sized {
317  fn min(self, rhs: Self) -> Self;
318
319  fn max(self, rhs: Self) -> Self;
320
321  fn clamp(self, min_value: Self, max_value: Self) -> Self;
322}
323
324macro_rules! impl_Bounded {
325  ($t:ty) => {
326    impl Bounded for Expr<$t> {
327      fn min(self, rhs: Self) -> Self {
328        Expr::new(ErasedExpr::FunCall(
329          ErasedFunHandle::Min,
330          vec![self.erased, rhs.erased],
331        ))
332      }
333
334      fn max(self, rhs: Self) -> Self {
335        Expr::new(ErasedExpr::FunCall(
336          ErasedFunHandle::Max,
337          vec![self.erased, rhs.erased],
338        ))
339      }
340
341      fn clamp(self, min_value: Self, max_value: Self) -> Self {
342        Expr::new(ErasedExpr::FunCall(
343          ErasedFunHandle::Clamp,
344          vec![self.erased, min_value.erased, max_value.erased],
345        ))
346      }
347    }
348  };
349}
350
351impl_Bounded!(i32);
352impl_Bounded!(V2<i32>);
353impl_Bounded!(V3<i32>);
354impl_Bounded!(V4<i32>);
355
356impl_Bounded!(u32);
357impl_Bounded!(V2<u32>);
358impl_Bounded!(V3<u32>);
359impl_Bounded!(V4<u32>);
360
361impl_Bounded!(f32);
362impl_Bounded!(V2<f32>);
363impl_Bounded!(V3<f32>);
364impl_Bounded!(V4<f32>);
365
366impl_Bounded!(bool);
367impl_Bounded!(V2<bool>);
368impl_Bounded!(V3<bool>);
369impl_Bounded!(V4<bool>);
370
371pub trait Mix<RHS>: Sized {
372  fn mix(self, y: Self, a: RHS) -> Self;
373
374  fn step(self, edge: RHS) -> Self;
375
376  fn smooth_step(self, edge_a: RHS, edge_b: RHS) -> Self;
377}
378
379macro_rules! impl_Mix {
380  ($t:ty, $q:ty) => {
381    impl Mix<Expr<$q>> for Expr<$t> {
382      fn mix(self, y: Self, a: Expr<$q>) -> Self {
383        Expr::new(ErasedExpr::FunCall(
384          ErasedFunHandle::Mix,
385          vec![self.erased, y.erased, a.erased],
386        ))
387      }
388
389      fn step(self, edge: Expr<$q>) -> Self {
390        Expr::new(ErasedExpr::FunCall(
391          ErasedFunHandle::Step,
392          vec![self.erased, edge.erased],
393        ))
394      }
395
396      fn smooth_step(self, edge_a: Expr<$q>, edge_b: Expr<$q>) -> Self {
397        Expr::new(ErasedExpr::FunCall(
398          ErasedFunHandle::SmoothStep,
399          vec![self.erased, edge_a.erased, edge_b.erased],
400        ))
401      }
402    }
403  };
404}
405
406impl_Mix!(f32, f32);
407impl_Mix!(V2<f32>, f32);
408impl_Mix!(V2<f32>, V2<f32>);
409
410impl_Mix!(V3<f32>, f32);
411impl_Mix!(V3<f32>, V3<f32>);
412
413impl_Mix!(V4<f32>, f32);
414impl_Mix!(V4<f32>, V4<f32>);
415
416pub trait FloatingExt {
417  type BoolExpr;
418
419  fn is_nan(self) -> Self::BoolExpr;
420
421  fn is_inf(self) -> Self::BoolExpr;
422}
423
424macro_rules! impl_FloatingExt {
425  ($t:ty, $bool_expr:ty) => {
426    impl FloatingExt for Expr<$t> {
427      type BoolExpr = Expr<$bool_expr>;
428
429      fn is_nan(self) -> Self::BoolExpr {
430        Expr::new(ErasedExpr::FunCall(
431          ErasedFunHandle::IsNan,
432          vec![self.erased],
433        ))
434      }
435
436      fn is_inf(self) -> Self::BoolExpr {
437        Expr::new(ErasedExpr::FunCall(
438          ErasedFunHandle::IsInf,
439          vec![self.erased],
440        ))
441      }
442    }
443  };
444}
445
446impl_FloatingExt!(f32, bool);
447impl_FloatingExt!(V2<f32>, V2<bool>);
448impl_FloatingExt!(V3<f32>, V3<bool>);
449impl_FloatingExt!(V4<f32>, V4<bool>);
450
451pub trait Geometry: Sized {
452  type LengthExpr;
453
454  fn length(self) -> Self::LengthExpr;
455
456  fn distance(self, other: Self) -> Self::LengthExpr;
457
458  fn dot(self, other: Self) -> Self::LengthExpr;
459
460  fn cross(self, other: Self) -> Self;
461
462  fn normalize(self) -> Self;
463
464  fn face_forward(self, normal: Self, reference: Self) -> Self;
465
466  fn reflect(self, normal: Self) -> Self;
467
468  fn refract(self, normal: Self, eta: Expr<f32>) -> Self;
469}
470
471macro_rules! impl_Geometry {
472  ($t:ty, $l:ty) => {
473    impl Geometry for Expr<$t> {
474      type LengthExpr = Expr<$l>;
475
476      fn length(self) -> Self::LengthExpr {
477        Expr::new(ErasedExpr::FunCall(
478          ErasedFunHandle::Length,
479          vec![self.erased],
480        ))
481      }
482
483      fn distance(self, other: Self) -> Self::LengthExpr {
484        Expr::new(ErasedExpr::FunCall(
485          ErasedFunHandle::Distance,
486          vec![self.erased, other.erased],
487        ))
488      }
489
490      fn dot(self, other: Self) -> Self::LengthExpr {
491        Expr::new(ErasedExpr::FunCall(
492          ErasedFunHandle::Dot,
493          vec![self.erased, other.erased],
494        ))
495      }
496
497      fn cross(self, other: Self) -> Self {
498        Expr::new(ErasedExpr::FunCall(
499          ErasedFunHandle::Cross,
500          vec![self.erased, other.erased],
501        ))
502      }
503
504      fn normalize(self) -> Self {
505        Expr::new(ErasedExpr::FunCall(
506          ErasedFunHandle::Normalize,
507          vec![self.erased],
508        ))
509      }
510
511      fn face_forward(self, normal: Self, reference: Self) -> Self {
512        // note: this function call is super weird as the normal and incident (i.e. self) arguments are swapped
513        Expr::new(ErasedExpr::FunCall(
514          ErasedFunHandle::FaceForward,
515          vec![normal.erased, self.erased, reference.erased],
516        ))
517      }
518
519      fn reflect(self, normal: Self) -> Self {
520        Expr::new(ErasedExpr::FunCall(
521          ErasedFunHandle::Reflect,
522          vec![self.erased, normal.erased],
523        ))
524      }
525
526      fn refract(self, normal: Self, eta: Expr<f32>) -> Self {
527        Expr::new(ErasedExpr::FunCall(
528          ErasedFunHandle::Refract,
529          vec![self.erased, normal.erased, eta.erased],
530        ))
531      }
532    }
533  };
534}
535
536impl_Geometry!(V2<f32>, f32);
537impl_Geometry!(V3<f32>, f32);
538impl_Geometry!(V4<f32>, f32);