tvector_arithmetic.h - sphere - GPU-based 3D discrete element method algorithm with optional fluid coupling
HTML git clone git://src.adamsgaard.dk/sphere
DIR Log
DIR Files
DIR Refs
DIR LICENSE
---
tvector_arithmetic.h (12726B)
---
1 #ifndef VECTOR_ARITHMETIC_H_
2 #define VECTOR_ARITHMETIC_H_
3
4 #include "cuda_runtime.h"
5 #include "datatypes.h"
6
7 typedef unsigned int uint;
8 typedef unsigned short ushort;
9
10 #ifndef __CUDACC__
11 #include <math.h>
12
13 ////////////////////////////////////////////////////////////////////////////////
14 // host implementations of CUDA functions
15 ////////////////////////////////////////////////////////////////////////////////
16
17 inline Float fminf(Float a, Float b)
18 {
19 return a < b ? a : b;
20 }
21
22 inline Float fmaxf(Float a, Float b)
23 {
24 return a > b ? a : b;
25 }
26
27 inline Float rsqrtf(Float x)
28 {
29 return 1.0f / sqrtf(x);
30 }
31 #endif
32
33 ////////////////////////////////////////////////////////////////////////////////
34 // negate
35 ////////////////////////////////////////////////////////////////////////////////
36 inline __host__ __device__ Float3 operator-(Float3 &a)
37 {
38 return MAKE_FLOAT3(-a.x, -a.y, -a.z);
39 }
40 inline __host__ __device__ Float4 operator-(Float4 &a)
41 {
42 return MAKE_FLOAT4(-a.x, -a.y, -a.z, -a.w);
43 }
44
45 ////////////////////////////////////////////////////////////////////////////////
46 // addition
47 ////////////////////////////////////////////////////////////////////////////////
48
49 inline __host__ __device__ void operator+=(Float2 &a, Float2 b)
50 {
51 a.x += b.x; a.y += b.y;
52 }
53 inline __host__ __device__ Float3 operator+(Float3 a, Float3 b)
54 {
55 return MAKE_FLOAT3(a.x + b.x, a.y + b.y, a.z + b.z);
56 }
57 inline __host__ __device__ void operator+=(Float3 &a, Float3 b)
58 {
59 a.x += b.x; a.y += b.y; a.z += b.z;
60 }
61 inline __host__ __device__ Float3 operator+(Float3 a, Float b)
62 {
63 return MAKE_FLOAT3(a.x + b, a.y + b, a.z + b);
64 }
65 inline __host__ __device__ void operator+=(Float3 &a, Float b)
66 {
67 a.x += b; a.y += b; a.z += b;
68 }
69
70 inline __host__ __device__ Float3 operator+(Float b, Float3 a)
71 {
72 return MAKE_FLOAT3(a.x + b, a.y + b, a.z + b);
73 }
74
75 inline __host__ __device__ Float4 operator+(Float4 a, Float4 b)
76 {
77 return MAKE_FLOAT4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
78 }
79 inline __host__ __device__ void operator+=(Float4 &a, Float4 b)
80 {
81 a.x += b.x; a.y += b.y; a.z += b.z; a.w += b.w;
82 }
83 inline __host__ __device__ Float4 operator+(Float4 a, Float b)
84 {
85 return MAKE_FLOAT4(a.x + b, a.y + b, a.z + b, a.w + b);
86 }
87 inline __host__ __device__ Float4 operator+(Float b, Float4 a)
88 {
89 return MAKE_FLOAT4(a.x + b, a.y + b, a.z + b, a.w + b);
90 }
91 inline __host__ __device__ void operator+=(Float4 &a, Float b)
92 {
93 a.x += b; a.y += b; a.z += b; a.w += b;
94 }
95
96 ////////////////////////////////////////////////////////////////////////////////
97 // subtract
98 ////////////////////////////////////////////////////////////////////////////////
99
100 inline __host__ __device__ Float3 operator-(Float3 a, Float3 b)
101 {
102 return MAKE_FLOAT3(a.x - b.x, a.y - b.y, a.z - b.z);
103 }
104 inline __host__ __device__ void operator-=(Float3 &a, Float3 b)
105 {
106 a.x -= b.x; a.y -= b.y; a.z -= b.z;
107 }
108 inline __host__ __device__ Float3 operator-(Float3 a, Float b)
109 {
110 return MAKE_FLOAT3(a.x - b, a.y - b, a.z - b);
111 }
112 inline __host__ __device__ Float3 operator-(Float b, Float3 a)
113 {
114 return MAKE_FLOAT3(b - a.x, b - a.y, b - a.z);
115 }
116 inline __host__ __device__ void operator-=(Float3 &a, Float b)
117 {
118 a.x -= b; a.y -= b; a.z -= b;
119 }
120
121 inline __host__ __device__ Float4 operator-(Float4 a, Float4 b)
122 {
123 return MAKE_FLOAT4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
124 }
125 inline __host__ __device__ void operator-=(Float4 &a, Float4 b)
126 {
127 a.x -= b.x; a.y -= b.y; a.z -= b.z; a.w -= b.w;
128 }
129 inline __host__ __device__ Float4 operator-(Float4 a, Float b)
130 {
131 return MAKE_FLOAT4(a.x - b, a.y - b, a.z - b, a.w - b);
132 }
133 inline __host__ __device__ void operator-=(Float4 &a, Float b)
134 {
135 a.x -= b; a.y -= b; a.z -= b; a.w -= b;
136 }
137
138 ////////////////////////////////////////////////////////////////////////////////
139 // multiply
140 ////////////////////////////////////////////////////////////////////////////////
141
142 inline __host__ __device__ Float3 operator*(Float3 a, Float3 b)
143 {
144 return MAKE_FLOAT3(a.x * b.x, a.y * b.y, a.z * b.z);
145 }
146 inline __host__ __device__ void operator*=(Float3 &a, Float3 b)
147 {
148 a.x *= b.x; a.y *= b.y; a.z *= b.z;
149 }
150 inline __host__ __device__ Float3 operator*(Float3 a, Float b)
151 {
152 return MAKE_FLOAT3(a.x * b, a.y * b, a.z * b);
153 }
154 inline __host__ __device__ Float3 operator*(Float b, Float3 a)
155 {
156 return MAKE_FLOAT3(b * a.x, b * a.y, b * a.z);
157 }
158 inline __host__ __device__ void operator*=(Float3 &a, Float b)
159 {
160 a.x *= b; a.y *= b; a.z *= b;
161 }
162
163 inline __host__ __device__ Float4 operator*(Float4 a, Float4 b)
164 {
165 return MAKE_FLOAT4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
166 }
167 inline __host__ __device__ void operator*=(Float4 &a, Float4 b)
168 {
169 a.x *= b.x; a.y *= b.y; a.z *= b.z; a.w *= b.w;
170 }
171 inline __host__ __device__ Float4 operator*(Float4 a, Float b)
172 {
173 return MAKE_FLOAT4(a.x * b, a.y * b, a.z * b, a.w * b);
174 }
175 inline __host__ __device__ Float4 operator*(Float b, Float4 a)
176 {
177 return MAKE_FLOAT4(b * a.x, b * a.y, b * a.z, b * a.w);
178 }
179 inline __host__ __device__ void operator*=(Float4 &a, Float b)
180 {
181 a.x *= b; a.y *= b; a.z *= b; a.w *= b;
182 }
183
184 ////////////////////////////////////////////////////////////////////////////////
185 // divide
186 ////////////////////////////////////////////////////////////////////////////////
187
188 inline __host__ __device__ Float3 operator/(Float3 a, Float3 b)
189 {
190 return MAKE_FLOAT3(a.x / b.x, a.y / b.y, a.z / b.z);
191 }
192 inline __host__ __device__ void operator/=(Float3 &a, Float3 b)
193 {
194 a.x /= b.x; a.y /= b.y; a.z /= b.z;
195 }
196 inline __host__ __device__ Float3 operator/(Float3 a, Float b)
197 {
198 return MAKE_FLOAT3(a.x / b, a.y / b, a.z / b);
199 }
200 inline __host__ __device__ void operator/=(Float3 &a, Float b)
201 {
202 a.x /= b; a.y /= b; a.z /= b;
203 }
204 inline __host__ __device__ Float3 operator/(Float b, Float3 a)
205 {
206 return MAKE_FLOAT3(b / a.x, b / a.y, b / a.z);
207 }
208
209 inline __host__ __device__ Float4 operator/(Float4 a, Float4 b)
210 {
211 return MAKE_FLOAT4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w);
212 }
213 inline __host__ __device__ void operator/=(Float4 &a, Float4 b)
214 {
215 a.x /= b.x; a.y /= b.y; a.z /= b.z; a.w /= b.w;
216 }
217 inline __host__ __device__ Float4 operator/(Float4 a, Float b)
218 {
219 return MAKE_FLOAT4(a.x / b, a.y / b, a.z / b, a.w / b);
220 }
221 inline __host__ __device__ void operator/=(Float4 &a, Float b)
222 {
223 a.x /= b; a.y /= b; a.z /= b; a.w /= b;
224 }
225 inline __host__ __device__ Float4 operator/(Float b, Float4 a){
226 return MAKE_FLOAT4(b / a.x, b / a.y, b / a.z, b / a.w);
227 }
228
229 ////////////////////////////////////////////////////////////////////////////////
230 // min
231 ////////////////////////////////////////////////////////////////////////////////
232
233 inline __host__ __device__ Float3 fminf(Float3 a, Float3 b)
234 {
235 return MAKE_FLOAT3(fminf(a.x,b.x), fminf(a.y,b.y), fminf(a.z,b.z));
236 }
237 inline __host__ __device__ Float4 fminf(Float4 a, Float4 b)
238 {
239 return MAKE_FLOAT4(fminf(a.x,b.x), fminf(a.y,b.y), fminf(a.z,b.z), fminf(a.w,b.w));
240 }
241
242 ////////////////////////////////////////////////////////////////////////////////
243 // max
244 ////////////////////////////////////////////////////////////////////////////////
245
246 inline __host__ __device__ Float3 fmaxf(Float3 a, Float3 b)
247 {
248 return MAKE_FLOAT3(fmaxf(a.x,b.x), fmaxf(a.y,b.y), fmaxf(a.z,b.z));
249 }
250 inline __host__ __device__ Float4 fmaxf(Float4 a, Float4 b)
251 {
252 return MAKE_FLOAT4(fmaxf(a.x,b.x), fmaxf(a.y,b.y), fmaxf(a.z,b.z), fmaxf(a.w,b.w));
253 }
254
255 ////////////////////////////////////////////////////////////////////////////////
256 // lerp
257 // - linear interpolation between a and b, based on value t in [0, 1] range
258 ////////////////////////////////////////////////////////////////////////////////
259
260 inline __device__ __host__ Float lerp(Float a, Float b, Float t)
261 {
262 return a + t*(b-a);
263 }
264 inline __device__ __host__ Float3 lerp(Float3 a, Float3 b, Float t)
265 {
266 return a + t*(b-a);
267 }
268 inline __device__ __host__ Float4 lerp(Float4 a, Float4 b, Float t)
269 {
270 return a + t*(b-a);
271 }
272
273 ////////////////////////////////////////////////////////////////////////////////
274 // clamp
275 // - clamp the value v to be in the range [a, b]
276 ////////////////////////////////////////////////////////////////////////////////
277
278 inline __device__ __host__ Float clamp(Float f, Float a, Float b)
279 {
280 return fmaxf(a, fminf(f, b));
281 }
282
283 inline __device__ __host__ Float3 clamp(Float3 v, Float a, Float b)
284 {
285 return MAKE_FLOAT3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b));
286 }
287 inline __device__ __host__ Float3 clamp(Float3 v, Float3 a, Float3 b)
288 {
289 return MAKE_FLOAT3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z));
290 }
291 inline __device__ __host__ Float4 clamp(Float4 v, Float a, Float b)
292 {
293 return MAKE_FLOAT4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b));
294 }
295 inline __device__ __host__ Float4 clamp(Float4 v, Float4 a, Float4 b)
296 {
297 return MAKE_FLOAT4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w));
298 }
299
300 ////////////////////////////////////////////////////////////////////////////////
301 // dot product
302 ////////////////////////////////////////////////////////////////////////////////
303
304 inline __host__ __device__ Float dot(Float3 a, Float3 b)
305 {
306 return a.x * b.x + a.y * b.y + a.z * b.z;
307 }
308 inline __host__ __device__ Float dot(Float4 a, Float4 b)
309 {
310 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
311 }
312
313 ////////////////////////////////////////////////////////////////////////////////
314 // length
315 ////////////////////////////////////////////////////////////////////////////////
316
317 inline __host__ __device__ Float length(Float3 v)
318 {
319 return sqrtf(dot(v, v));
320 }
321 inline __host__ __device__ Float length(Float4 v)
322 {
323 return sqrtf(dot(v, v));
324 }
325
326 ////////////////////////////////////////////////////////////////////////////////
327 // normalize
328 ////////////////////////////////////////////////////////////////////////////////
329
330 inline __host__ __device__ Float3 normalize(Float3 v)
331 {
332 Float invLen = rsqrtf(dot(v, v));
333 return v * invLen;
334 }
335 inline __host__ __device__ Float4 normalize(Float4 v)
336 {
337 Float invLen = rsqrtf(dot(v, v));
338 return v * invLen;
339 }
340
341 ////////////////////////////////////////////////////////////////////////////////
342 // floor
343 ////////////////////////////////////////////////////////////////////////////////
344
345 inline __host__ __device__ Float3 floorf(Float3 v)
346 {
347 return MAKE_FLOAT3(floorf(v.x), floorf(v.y), floorf(v.z));
348 }
349 inline __host__ __device__ Float4 floorf(Float4 v)
350 {
351 return MAKE_FLOAT4(floorf(v.x), floorf(v.y), floorf(v.z), floorf(v.w));
352 }
353
354 ////////////////////////////////////////////////////////////////////////////////
355 // frac - returns the fractional portion of a scalar or each vector component
356 ////////////////////////////////////////////////////////////////////////////////
357
358 inline __host__ __device__ Float fracf(Float v)
359 {
360 return v - floorf(v);
361 }
362 inline __host__ __device__ Float3 fracf(Float3 v)
363 {
364 return MAKE_FLOAT3(fracf(v.x), fracf(v.y), fracf(v.z));
365 }
366 inline __host__ __device__ Float4 fracf(Float4 v)
367 {
368 return MAKE_FLOAT4(fracf(v.x), fracf(v.y), fracf(v.z), fracf(v.w));
369 }
370
371 ////////////////////////////////////////////////////////////////////////////////
372 // fmod
373 ////////////////////////////////////////////////////////////////////////////////
374
375 inline __host__ __device__ Float3 fmodf(Float3 a, Float3 b)
376 {
377 return MAKE_FLOAT3(fmodf(a.x, b.x), fmodf(a.y, b.y), fmodf(a.z, b.z));
378 }
379 inline __host__ __device__ Float4 fmodf(Float4 a, Float4 b)
380 {
381 return MAKE_FLOAT4(fmodf(a.x, b.x), fmodf(a.y, b.y), fmodf(a.z, b.z), fmodf(a.w, b.w));
382 }
383
384 ////////////////////////////////////////////////////////////////////////////////
385 // absolute value
386 ////////////////////////////////////////////////////////////////////////////////
387
388 inline __host__ __device__ Float3 fabs(Float3 v)
389 {
390 return MAKE_FLOAT3(fabs(v.x), fabs(v.y), fabs(v.z));
391 }
392 inline __host__ __device__ Float4 fabs(Float4 v)
393 {
394 return MAKE_FLOAT4(fabs(v.x), fabs(v.y), fabs(v.z), fabs(v.w));
395 }
396
397 ////////////////////////////////////////////////////////////////////////////////
398 // reflect
399 // - returns reflection of incident ray I around surface normal N
400 // - N should be normalized, reflected vector's length is equal to length of I
401 ////////////////////////////////////////////////////////////////////////////////
402
403 inline __host__ __device__ Float3 reflect(Float3 i, Float3 n)
404 {
405 return i - 2.0f * n * dot(n,i);
406 }
407
408 ////////////////////////////////////////////////////////////////////////////////
409 // cross product
410 ////////////////////////////////////////////////////////////////////////////////
411
412 inline __host__ __device__ Float3 cross(Float3 a, Float3 b)
413 {
414 return MAKE_FLOAT3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x);
415 }
416
417 #endif
418 // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4