diff --git a/src/lol/math/simplex_interpolator.h b/src/lol/math/simplex_interpolator.h index aacae7fe..c0fbac7b 100644 --- a/src/lol/math/simplex_interpolator.h +++ b/src/lol/math/simplex_interpolator.h @@ -43,40 +43,41 @@ public: vec_t simplex_position = m_base_inverse * position; // Retrieving the closest floor point and decimals - vec_t floor_point; - vec_t decimal_point; + vec_t origin; + vec_t pos; - this->ExtractFloorDecimal(simplex_position, floor_point, decimal_point); + this->ExtractFloorDecimal(simplex_position, origin, pos); - vec_t index_order = this->GetIndexOrder(decimal_point); + vec_t index_order = this->GetIndexOrder(pos); // Resetting decimal point in regular orthonormal coordinates - //decimal_point = m_base * decimal_point; + // pos = m_base * pos; - return this->LastInterp(floor_point, decimal_point, index_order); + return this->LastInterp(origin, pos, index_order); } protected: - inline float LastInterp(vec_t & floor_point, - vec_t const & decimal_point, - vec_t index_order) const + inline float LastInterp(vec_t & origin, + vec_t const & pos, + vec_t index_order) const { - vec_t point_of_interest(0); + // “corner” will traverse the simplex along its edges + vec_t corner(0); float result = 0; - for (int i = 0 ; i < N+1 ; ++i) + for (int i = 0; i < N + 1; ++i) { - float dist = 0.5 - 0.75f * sqlength(this->m_base * (decimal_point - point_of_interest)); - vec_t gradient = this->m_gradients[floor_point]; + float dist = 0.5f - 0.75f * sqlength(this->m_base * (pos - corner)); + vec_t const &gradient = this->m_gradients[origin]; if (dist > 0) - result += dist * dist * dist * dist * dot(gradient, this->m_base * (decimal_point - point_of_interest)); + result += dist * dist * dist * dist * dot(gradient, this->m_base * (pos - corner)); if (i < N) { - point_of_interest[index_order[i]] += 1; - floor_point[index_order[i]] = this->Mod(floor_point[index_order[i]] + 1, index_order[i]); + corner[index_order[i]] += 1; + origin[index_order[i]] = this->Mod(origin[index_order[i]] + 1, index_order[i]); } } @@ -85,25 +86,19 @@ protected: return result * 100; } - inline vec_t GetIndexOrder(vec_t const & decimal_point) const + /* For a given position [0…1]^n inside a square/cube/hypercube etc., + * find the simplex which contains that position, and return the path + * from (0,0,…,0) to (1,1,…,1) that describes that simplex. */ + inline vec_t GetIndexOrder(vec_t const & pos) const { vec_t result; - for (int i = 0 ; i < N ; ++i) + for (int i = 0; i < N; ++i) result[i] = i; - for (int i = 0 ; i < N ; ++i) - { - for (int j = i + 1 ; j < N ; ++j) - { - if (decimal_point[result[i]] < decimal_point[result[j]]) - { - // just swapping… - result[i] ^= result[j]; - result[j] ^= result[i]; - result[i] ^= result[j]; - } - } - } + for (int i = 0; i < N; ++i) + for (int j = i + 1; j < N; ++j) + if (pos[result[i]] < pos[result[j]]) + std::swap(result[i], result[j]); return result; } @@ -115,19 +110,22 @@ protected: return ret >= 0 ? ret : ret + dim; } - inline void ExtractFloorDecimal(vec_t const & simplex_position, vec_t & floor_point, vec_t & decimal_point) const + /* For a given world position, extract grid coordinates (origin) and + * the corresponding delta position (pos). */ + inline void ExtractFloorDecimal(vec_t const & simplex_position, + vec_t & origin, + vec_t & pos) const { // Finding floor point index - for (int i = 0 ; i < N ; ++i) - floor_point[i] = ((int) simplex_position[i]) - (simplex_position[i] < 0 ? 1 : 0); + for (int i = 0; i < N; ++i) + origin[i] = ((int) simplex_position[i]) - (simplex_position[i] < 0 ? 1 : 0); // Extracting decimal part from simplex sample - for (int i = 0 ; i < N ; ++i) - decimal_point[i] = simplex_position[i] - floor_point[i]; + pos = simplex_position - (vec_t)origin; // Never exceed the size of the gradients and loop on it - for (int i = 0 ; i < N ; ++i) - floor_point[i] = this->Mod(floor_point[i], i); + for (int i = 0; i < N; ++i) + origin[i] = this->Mod(origin[i], i); } inline void InitBase()