#pragma once #include #include //---------------------- Vector Types ---------------------- // TODO: make generic, as per glm struct vec2 { float x, y; }; void ?{}( vec2 & v, float x, float y) { v.[x, y] = [x, y]; } forall( dtype ostype | ostream( ostype ) ) { ostype & ?|?( ostype & os, const vec2& v) with (v) { if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) ); fmt( os, "<%g,%g>", x, y); return os; } void ?|?( ostype & os, const vec2& v ) { (ostype &)(os | v); ends( os ); } } void ?{}(vec2& vec, zero_t) with (vec) { x = y = 0; } void ?{}(vec2& vec, vec2& other) with (vec) { [x,y] = other.[x,y]; } vec2 ?-?(const vec2& u, const vec2& v) { return [u.x - v.x, u.y - v.y]; } vec2 ?*?(const vec2& v, float scalar) with (v) { return [x * scalar, y * scalar]; } vec2 ?*?(float scalar, const vec2& v) { return v * scalar; } vec2 ?/?(const vec2& v, float scalar) with (v) { return [x / scalar, y / scalar]; } vec2 -?(const vec2& v) with (v) { return [-x, -y]; } /* //---------------------- Geometric Functions ---------------------- */ /* // These functions implement the Geometric Functions section of GLSL */ static inline float dot(const vec2& u, const vec2& v) { return u.x * v.x + u.y * v.y; } static inline float length(const vec2& v) { return sqrt(dot(v, v)); } // Returns the distance betwwen v1 and v2, i.e., length(p0 - p1). static inline float distance(const vec2& v1, const vec2& v2) { return length(v1 - v2); } static inline vec2 normalize(const vec2& v) { // TODO(dkobets) -- show them inversesqrt // https://github.com/g-truc/glm/blob/269ae641283426f7f84116f2fe333472b9c914c9/glm/detail/func_exponential.inl /* return v * inversesqrt(dot(v, v)); */ return v / sqrt(dot(v, v)); } // project vector u onto vector v static inline vec2 project(const vec2& u, const vec2& v) { vec2 v_norm = normalize(v); return v_norm * dot(u, v_norm); } /* returns the reflection direction : v - 2.0 * project(v, n) * for incident vector v and surface normal n */ static inline vec2 reflect(const vec2& v, const vec2& n) { return v - 2 * project(v, n); } // incident vector v, surface normal n // eta = ratio of indices of refraction between starting material and // entering material (i.e., from air to water, eta = 1/1.33) static inline vec2 refract(const vec2& v, const vec2& n, float eta) { float dotValue = dot(n, v); float k = 1 - eta * eta * (1 - dotValue * dotValue); if (k < 0) { return 0; } return eta * v - (eta * dotValue + sqrt(k)) * n; } // TODO: I don't quite understand the use-case for faceforward