1use crate::{
2 expr::{ErasedExpr, Expr},
3 fun::ErasedFunHandle,
4 types::{V2, V3, V4},
5};
6
7pub 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 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);