URI:
       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