OWL
Loading...
Searching...
No Matches
functors.h
1// ======================================================================== //
2// Copyright 2018-2019 Ingo Wald //
3// //
4// Licensed under the Apache License, Version 2.0 (the "License"); //
5// you may not use this file except in compliance with the License. //
6// You may obtain a copy of the License at //
7// //
8// http://www.apache.org/licenses/LICENSE-2.0 //
9// //
10// Unless required by applicable law or agreed to in writing, software //
11// distributed under the License is distributed on an "AS IS" BASIS, //
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
13// See the License for the specific language governing permissions and //
14// limitations under the License. //
15// ======================================================================== //
16
17#pragma once
18
19#include <type_traits>
20
21namespace owl {
22 namespace common {
23
24 // =======================================================
25 // vector specializations of those scalar functors
26 // =======================================================
27
28 template<typename T, int N> inline __both__
29 bool any_less_than(const vec_t<T,N> &a, const vec_t<T,N> &b);
30
31 template<typename T, int N> inline __both__
32 bool all_less_than(const vec_t<T,N> &a, const vec_t<T,N> &b);
33
34 template<typename T, int N> inline __both__
35 bool any_greater_or_equal(const vec_t<T,N> &a, const vec_t<T,N> &b);
36
37 template<typename T, int N> inline __both__
38 bool any_less_than(const vec_t<T,N> &a, const vec_t<T,N> &b);
39
40 // ----------- specialization for 2 -----------
41 template<typename T> inline __both__
42 bool any_less_than(const vec_t<T,2> &a, const vec_t<T,2> &b)
43 { return (a.x < b.x) | (a.y < b.y); }
44
45 template<typename T> inline __both__
46 bool all_less_than(const vec_t<T,2> &a, const vec_t<T,2> &b)
47 { return (a.x < b.x) & (a.y < b.y); }
48
49 template<typename T> inline __both__
50 bool any_greater_than(const vec_t<T,2> &a, const vec_t<T,2> &b)
51 { return (a.x > b.x) | (a.y > b.y); }
52
53 template<typename T> inline __both__
54 bool any_greater_or_equal(const vec_t<T,2> &a, const vec_t<T,2> &b)
55 { return (a.x >= b.x) | (a.y >= b.y); }
56
57 // ----------- specialization for 3 -----------
58 template<typename T> inline __both__
59 bool any_less_than(const vec_t<T,3> &a, const vec_t<T,3> &b)
60 { return (a.x < b.x) | (a.y < b.y) | (a.z < b.z); }
61
62 template<typename T> inline __both__
63 bool all_less_than(const vec_t<T,3> &a, const vec_t<T,3> &b)
64 { return (a.x < b.x) & (a.y < b.y) & (a.z < b.z); }
65
66 template<typename T> inline __both__
67 bool any_greater_than(const vec_t<T,3> &a, const vec_t<T,3> &b)
68 { return (a.x > b.x) | (a.y > b.y) | (a.z > b.z); }
69
70 template<typename T> inline __both__
71 bool any_greater_or_equal(const vec_t<T,3> &a, const vec_t<T,3> &b)
72 { return (a.x >= b.x) | (a.y >= b.y) | (a.z >= b.z); }
73
74 // ----------- specialization for 4 -----------
75 template<typename T> inline __both__
76 bool any_less_than(const vec_t<T,4> &a, const vec_t<T,4> &b)
77 { return (a.x < b.x) | (a.y < b.y) | (a.z < b.z) | (a.w < b.w); }
78
79 template<typename T> inline __both__
80 bool all_less_than(const vec_t<T,4> &a, const vec_t<T,4> &b)
81 { return (a.x < b.x) & (a.y < b.y) & (a.z < b.z) & (a.w < b.w); }
82
83 template<typename T> inline __both__
84 bool any_greater_than(const vec_t<T,4> &a, const vec_t<T,4> &b)
85 { return (a.x > b.x) | (a.y > b.y) | (a.z > b.z) | (a.w > b.w); }
86
87 template<typename T> inline __both__
88 bool any_greater_or_equal(const vec_t<T,4> &a, const vec_t<T,4> &b)
89 { return (a.x >= b.x) | (a.y >= b.y) | (a.z >= b.z) | (a.w >= b.w); }
90
91 // -------------------------------------------------------
92 // unary functors
93 // -------------------------------------------------------
94
95 template<typename T>
96 inline __both__ T clamp(const T &val, const T &lo, const T &hi)
97 { return min(hi,max(lo,val)); }
98
99 template<typename T>
100 inline __both__ T clamp(const T &val, const T &hi)
101 { return clamp(val,(T)0,hi); }
102
103#define _define_float_functor(func) \
104 template<typename T> inline __both__ vec_t<T,2> func(const vec_t<T,2> &v) \
105 { return vec_t<T,2>(owl::common::func(v.x),owl::common::func(v.y)); } \
106 \
107 template<typename T> inline __both__ vec_t<T,3> func(const vec_t<T,3> &v) \
108 { return vec_t<T,3>(owl::common::func(v.x),owl::common::func(v.y),owl::common::func(v.z)); } \
109 \
110 template<typename T> inline __both__ vec_t<T,4> func(const vec_t<T,4> &v) \
111 { return vec_t<T,4>(owl::common::func(v.x),owl::common::func(v.y),owl::common::func(v.z),owl::common::func(v.w)); } \
112
113 _define_float_functor(rcp)
114 _define_float_functor(sin)
115 _define_float_functor(cos)
116 _define_float_functor(abs)
117 _define_float_functor(saturate)
118
119#undef _define_float_functor
120
121 // -------------------------------------------------------
122 // binary functors
123 // -------------------------------------------------------
124
125#define _define_binary_functor(fct) \
126 template<typename T> \
127 inline __both__ vec_t<T,1> fct(const vec_t<T,1> &a, const vec_t<T,1> &b) \
128 { \
129 return vec_t<T,1>(fct(a.x,b.x)); \
130 } \
131 \
132 template<typename T> \
133 inline __both__ vec_t<T,2> fct(const vec_t<T,2> &a, const vec_t<T,2> &b) \
134 { \
135 return vec_t<T,2>(fct(a.x,b.x), \
136 fct(a.y,b.y)); \
137 } \
138 \
139 template<typename T> \
140 inline __both__ vec_t<T,3> fct(const vec_t<T,3> &a, const vec_t<T,3> &b) \
141 { \
142 return vec_t<T,3>(fct(a.x,b.x), \
143 fct(a.y,b.y), \
144 fct(a.z,b.z)); \
145 } \
146 \
147 template<typename T1, typename T2> \
148 inline __both__ vec_t<typename BinaryOpResultType<T1,T2>::type,3> \
149 fct(const vec_t<T1,3> &a, const vec_t<T2,3> &b) \
150 { \
151 return vec_t<typename BinaryOpResultType<T1,T2>::type,3> \
152 (fct(a.x,b.x), \
153 fct(a.y,b.y), \
154 fct(a.z,b.z)); \
155 } \
156 \
157 template<typename T> \
158 inline __both__ vec_t<T,4> fct(const vec_t<T,4> &a, const vec_t<T,4> &b) \
159 { \
160 return vec_t<T,4>(fct(a.x,b.x), \
161 fct(a.y,b.y), \
162 fct(a.z,b.z), \
163 fct(a.w,b.w)); \
164 } \
165
166
167 _define_binary_functor(divRoundUp)
168 _define_binary_functor(min)
169 _define_binary_functor(max)
170#undef _define_binary_functor
171
172
173
174
175
176
177 // -------------------------------------------------------
178 // binary operators
179 // -------------------------------------------------------
180#define _define_operator(op) \
181 /* vec op vec */ \
182 template<typename T> \
183 inline __both__ vec_t<T,2> operator op(const vec_t<T,2> &a, \
184 const vec_t<T,2> &b) \
185 { return vec_t<T,2>(a.x op b.x, a.y op b.y); } \
186 \
187 template<typename T> \
188 inline __both__ vec_t<T,3> operator op(const vec_t<T,3> &a, \
189 const vec_t<T,3> &b) \
190 { return vec_t<T,3>(a.x op b.x, a.y op b.y, a.z op b.z); } \
191 \
192 template<typename T> \
193 inline __both__ vec_t<T,4> operator op(const vec_t<T,4> &a, \
194 const vec_t<T,4> &b) \
195 { return vec_t<T,4>(a.x op b.x,a.y op b.y,a.z op b.z,a.w op b.w); } \
196 \
197 /* vec op scalar */ \
198 template<typename T> \
199 inline __both__ vec_t<T,2> operator op(const vec_t<T,2> &a, \
200 const T &b) \
201 { return vec_t<T,2>(a.x op b, a.y op b); } \
202 \
203 template<typename T1, typename T2> \
204 inline __both__ vec_t<typename BinaryOpResultType<T1,T2>::type,3> \
205 operator op(const vec_t<T1,3> &a, const T2 &b) \
206 { return vec_t<typename BinaryOpResultType<T1,T2>::type,3> \
207 (a.x op b, a.y op b, a.z op b); \
208 } \
209 \
210 template<typename T> \
211 inline __both__ vec_t<T,4> operator op(const vec_t<T,4> &a, \
212 const T &b) \
213 { return vec_t<T,4>(a.x op b, a.y op b, a.z op b, a.w op b); } \
214 \
215 /* scalar op vec */ \
216 template<typename T> \
217 inline __both__ vec_t<T,2> operator op(const T &a, \
218 const vec_t<T,2> &b) \
219 { return vec_t<T,2>(a op b.x, a op b.y); } \
220 \
221 template<typename T> \
222 inline __both__ vec_t<T,3> operator op(const T &a, \
223 const vec_t<T,3> &b) \
224 { return vec_t<T,3>(a op b.x, a op b.y, a op b.z); } \
225 \
226 template<typename T> \
227 inline __both__ vec_t<T,4> operator op(const T &a, \
228 const vec_t<T,4> &b) \
229 { return vec_t<T,4>(a op b.x, a op b.y, a op b.z, a op b.w); } \
230 \
231 \
232
233 _define_operator(*);
234 _define_operator(/);
235 _define_operator(%);
236 _define_operator(+);
237 _define_operator(-);
238
239#undef _define_operator
240
241
242
243
244 // -------------------------------------------------------
245 // unary operators
246 // -------------------------------------------------------
247
248 template<typename T>
249 inline __both__ vec_t<T,2> operator-(const vec_t<T,2> &v)
250 { return vec_t<T,2>(-v.x, -v.y); }
251
252 template<typename T>
253 inline __both__ vec_t<T,2> operator+(const vec_t<T,2> &v)
254 { return vec_t<T,2>(v.x, v.y); }
255
256 template<typename T>
257 inline __both__ vec_t<T,3> operator-(const vec_t<T,3> &v)
258 { return vec_t<T,3>(-v.x, -v.y, -v.z); }
259
260 template<typename T>
261 inline __both__ vec_t<T,3> operator+(const vec_t<T,3> &v)
262 { return vec_t<T,3>(v.x, v.y, v.z); }
263
264
265
266 // -------------------------------------------------------
267 // binary op-assign operators
268 // -------------------------------------------------------
269#define _define_op_assign_operator(operator_op,op) \
270 /* vec op vec */ \
271 template<typename T, typename OT> \
272 inline __both__ vec_t<T,2> &operator_op(vec_t<T,2> &a, \
273 const vec_t<OT,2> &b) \
274 { \
275 a.x op (T)b.x; \
276 a.y op (T)b.y; \
277 return a; \
278 } \
279 \
280 template<typename T, typename OT> \
281 inline __both__ vec_t<T,3> &operator_op(vec_t<T,3> &a, \
282 const vec_t<OT,3> &b) \
283 { \
284 a.x op (T)b.x; \
285 a.y op (T)b.y; \
286 a.z op (T)b.z; \
287 return a; \
288 } \
289 \
290 template<typename T, typename OT> \
291 inline __both__ vec_t<T,4> &operator_op(vec_t<T,4> &a, \
292 const vec_t<OT,4> &b) \
293 { \
294 a.x op (T)b.x; \
295 a.y op (T)b.y; \
296 a.z op (T)b.z; \
297 a.w op (T)b.w; \
298 return a; \
299 } \
300 \
301 /* vec op scalar */ \
302 template<typename T, typename OT> \
303 inline __both__ vec_t<T,2> &operator_op(vec_t<T,2> &a, \
304 const OT &b) \
305 { a.x op (T)b; a.y op (T)b; return a; } \
306 \
307 template<typename T, typename OT> \
308 inline __both__ vec_t<T,3> &operator_op(vec_t<T,3> &a, \
309 const OT &b) \
310 { a.x op (T)b; a.y op (T)b; a.z op (T)b; return a; } \
311 \
312 template<typename T, typename OT> \
313 inline __both__ vec_t<T,4> &operator_op(vec_t<T,4> &a, \
314 const OT &b) \
315 { a.x op (T)b; a.y op (T)b; a.z op (T)b; a.w op (T)b; return a; } \
316
317 _define_op_assign_operator(operator*=,*=);
318 _define_op_assign_operator(operator/=,/=);
319 _define_op_assign_operator(operator+=,+=);
320 _define_op_assign_operator(operator-=,-=);
321
322#undef _define_op_assign_operator
323
324
325 template<typename T>
326 __both__ T reduce_min(const vec_t<T,1> &v) { return v.x; }
327 template<typename T>
328 __both__ T reduce_min(const vec_t<T,2> &v) { return min(v.x,v.y); }
329 template<typename T>
330 __both__ T reduce_min(const vec_t<T,3> &v) { return min(min(v.x,v.y),v.z); }
331 template<typename T>
332 __both__ T reduce_min(const vec_t<T,4> &v) { return min(min(v.x,v.y),min(v.z,v.w)); }
333 template<typename T>
334 __both__ T reduce_max(const vec_t<T,2> &v) { return max(v.x,v.y); }
335 template<typename T>
336 __both__ T reduce_max(const vec_t<T,3> &v) { return max(max(v.x,v.y),v.z); }
337 template<typename T>
338 __both__ T reduce_max(const vec_t<T,4> &v) { return max(max(v.x,v.y),max(v.z,v.w)); }
339
340
341 template<typename T, int N>
342 __both__ vec_t<T,3> madd(const vec_t<T,N> &a, const vec_t<T,N> &b, const vec_t<T,N> &c)
343 {
344 return a*b + c;
345 }
346
347
348 template<typename T, int N>
349 __both__ int arg_max(const vec_t<T,N> &v)
350 {
351 int biggestDim = 0;
352 for (int i=1;i<N;i++)
353 if ((v[i]) > (v[biggestDim])) biggestDim = i;
354 return biggestDim;
355 }
356
357 template<typename T, int N>
358 __both__ int arg_min(const vec_t<T,N> &v)
359 {
360 int biggestDim = 0;
361 for (int i=1;i<N;i++)
362 if ((v[i]) < (v[biggestDim])) biggestDim = i;
363 return biggestDim;
364 }
365
366
367 // less, for std::set, std::map, etc
368 template<typename T>
369 __both__ bool operator<(const vec_t<T,2> &a, const vec_t<T,2> &b)
370 {
371 if (a.x < b.x) return true;
372 if (a.x == b.x && a.y < b.y) return true;
373 return false;
374 }
375 template<typename T>
376 __both__ bool operator<(const vec_t<T,3> &a, const vec_t<T,3> &b)
377 {
378 if (a.x < b.x) return true;
379 if (a.x == b.x && a.y < b.y) return true;
380 if (a.x == b.x && a.y == b.y && a.z < b.z) return true;
381 return false;
382 }
383 template<typename T>
384 __both__ bool operator<(const vec_t<T,4> &a, const vec_t<T,4> &b)
385 {
386 if (a.x < b.x) return true;
387 if (a.x == b.x && a.y < b.y) return true;
388 if (a.x == b.x && a.y == b.y && a.z < b.z) return true;
389 if (a.x == b.x && a.y == b.y && a.z == b.z && a.w < b.w) return true;
390 return false;
391 }
392
394 inline __both__ vec3f randomColor(int i)
395 {
396 int r = unsigned(i)*13*17 + 0x234235;
397 int g = unsigned(i)*7*3*5 + 0x773477;
398 int b = unsigned(i)*11*19 + 0x223766;
399 return vec3f((r&255)/255.f,
400 (g&255)/255.f,
401 (b&255)/255.f);
402 }
403
405 inline __both__ vec3f randomColor(size_t idx)
406 {
407 unsigned int r = (unsigned int)(idx*13*17 + 0x234235);
408 unsigned int g = (unsigned int)(idx*7*3*5 + 0x773477);
409 unsigned int b = (unsigned int)(idx*11*19 + 0x223766);
410 return vec3f((r&255)/255.f,
411 (g&255)/255.f,
412 (b&255)/255.f);
413 }
414
416 template<typename T>
417 inline __both__ vec3f randomColor(const T *ptr)
418 {
419 return randomColor((size_t)ptr);
420 }
421
422 inline __both__ float sqrt(const float v) { return sqrtf(v); }
423 inline __both__ vec2f sqrt(const vec2f v) { return vec2f(sqrtf(v.x),sqrtf(v.y)); }
424 inline __both__ vec3f sqrt(const vec3f v) { return vec3f(sqrtf(v.x),sqrtf(v.y),sqrtf(v.z)); }
425 inline __both__ vec4f sqrt(const vec4f v) { return vec4f(sqrtf(v.x),sqrtf(v.y),sqrtf(v.z),sqrtf(v.w)); }
426
427 } // ::owl::common
428} // ::owl
429