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