|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#pragma once |
|
|
|
struct vec3f |
|
{ |
|
float x, y, z; |
|
|
|
#ifdef __CUDACC__ |
|
__device__ vec3f() { } |
|
__device__ vec3f(float v) { x = v; y = v; z = v; } |
|
__device__ vec3f(float _x, float _y, float _z) { x = _x; y = _y; z = _z; } |
|
__device__ vec3f(float3 v) { x = v.x; y = v.y; z = v.z; } |
|
|
|
__device__ inline vec3f& operator+=(const vec3f& b) { x += b.x; y += b.y; z += b.z; return *this; } |
|
__device__ inline vec3f& operator-=(const vec3f& b) { x -= b.x; y -= b.y; z -= b.z; return *this; } |
|
__device__ inline vec3f& operator*=(const vec3f& b) { x *= b.x; y *= b.y; z *= b.z; return *this; } |
|
__device__ inline vec3f& operator/=(const vec3f& b) { x /= b.x; y /= b.y; z /= b.z; return *this; } |
|
#endif |
|
}; |
|
|
|
#ifdef __CUDACC__ |
|
__device__ static inline vec3f operator+(const vec3f& a, const vec3f& b) { return vec3f(a.x + b.x, a.y + b.y, a.z + b.z); } |
|
__device__ static inline vec3f operator-(const vec3f& a, const vec3f& b) { return vec3f(a.x - b.x, a.y - b.y, a.z - b.z); } |
|
__device__ static inline vec3f operator*(const vec3f& a, const vec3f& b) { return vec3f(a.x * b.x, a.y * b.y, a.z * b.z); } |
|
__device__ static inline vec3f operator/(const vec3f& a, const vec3f& b) { return vec3f(a.x / b.x, a.y / b.y, a.z / b.z); } |
|
__device__ static inline vec3f operator-(const vec3f& a) { return vec3f(-a.x, -a.y, -a.z); } |
|
|
|
__device__ static inline float sum(vec3f a) |
|
{ |
|
return a.x + a.y + a.z; |
|
} |
|
|
|
__device__ static inline vec3f cross(vec3f a, vec3f b) |
|
{ |
|
vec3f out; |
|
out.x = a.y * b.z - a.z * b.y; |
|
out.y = a.z * b.x - a.x * b.z; |
|
out.z = a.x * b.y - a.y * b.x; |
|
return out; |
|
} |
|
|
|
__device__ static inline void bwdCross(vec3f a, vec3f b, vec3f &d_a, vec3f &d_b, vec3f d_out) |
|
{ |
|
d_a.x += d_out.z * b.y - d_out.y * b.z; |
|
d_a.y += d_out.x * b.z - d_out.z * b.x; |
|
d_a.z += d_out.y * b.x - d_out.x * b.y; |
|
|
|
d_b.x += d_out.y * a.z - d_out.z * a.y; |
|
d_b.y += d_out.z * a.x - d_out.x * a.z; |
|
d_b.z += d_out.x * a.y - d_out.y * a.x; |
|
} |
|
|
|
__device__ static inline float dot(vec3f a, vec3f b) |
|
{ |
|
return a.x * b.x + a.y * b.y + a.z * b.z; |
|
} |
|
|
|
__device__ static inline void bwdDot(vec3f a, vec3f b, vec3f& d_a, vec3f& d_b, float d_out) |
|
{ |
|
d_a.x += d_out * b.x; d_a.y += d_out * b.y; d_a.z += d_out * b.z; |
|
d_b.x += d_out * a.x; d_b.y += d_out * a.y; d_b.z += d_out * a.z; |
|
} |
|
|
|
__device__ static inline vec3f reflect(vec3f x, vec3f n) |
|
{ |
|
return n * 2.0f * dot(n, x) - x; |
|
} |
|
|
|
__device__ static inline void bwdReflect(vec3f x, vec3f n, vec3f& d_x, vec3f& d_n, const vec3f d_out) |
|
{ |
|
d_x.x += d_out.x * (2 * n.x * n.x - 1) + d_out.y * (2 * n.x * n.y) + d_out.z * (2 * n.x * n.z); |
|
d_x.y += d_out.x * (2 * n.x * n.y) + d_out.y * (2 * n.y * n.y - 1) + d_out.z * (2 * n.y * n.z); |
|
d_x.z += d_out.x * (2 * n.x * n.z) + d_out.y * (2 * n.y * n.z) + d_out.z * (2 * n.z * n.z - 1); |
|
|
|
d_n.x += d_out.x * (2 * (2 * n.x * x.x + n.y * x.y + n.z * x.z)) + d_out.y * (2 * n.y * x.x) + d_out.z * (2 * n.z * x.x); |
|
d_n.y += d_out.x * (2 * n.x * x.y) + d_out.y * (2 * (n.x * x.x + 2 * n.y * x.y + n.z * x.z)) + d_out.z * (2 * n.z * x.y); |
|
d_n.z += d_out.x * (2 * n.x * x.z) + d_out.y * (2 * n.y * x.z) + d_out.z * (2 * (n.x * x.x + n.y * x.y + 2 * n.z * x.z)); |
|
} |
|
|
|
__device__ static inline vec3f safeNormalize(vec3f v) |
|
{ |
|
float l = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); |
|
return l > 0.0f ? (v / l) : vec3f(0.0f); |
|
} |
|
|
|
__device__ static inline void bwdSafeNormalize(const vec3f v, vec3f& d_v, const vec3f d_out) |
|
{ |
|
|
|
float l = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); |
|
if (l > 0.0f) |
|
{ |
|
float fac = 1.0 / powf(v.x * v.x + v.y * v.y + v.z * v.z, 1.5f); |
|
d_v.x += (d_out.x * (v.y * v.y + v.z * v.z) - d_out.y * (v.x * v.y) - d_out.z * (v.x * v.z)) * fac; |
|
d_v.y += (d_out.y * (v.x * v.x + v.z * v.z) - d_out.x * (v.y * v.x) - d_out.z * (v.y * v.z)) * fac; |
|
d_v.z += (d_out.z * (v.x * v.x + v.y * v.y) - d_out.x * (v.z * v.x) - d_out.y * (v.z * v.y)) * fac; |
|
} |
|
} |
|
|
|
#endif |