| @@ -43,40 +43,41 @@ public: | |||||
| vec_t<float, N> simplex_position = m_base_inverse * position; | vec_t<float, N> simplex_position = m_base_inverse * position; | ||||
| // Retrieving the closest floor point and decimals | // Retrieving the closest floor point and decimals | ||||
| vec_t<int, N> floor_point; | |||||
| vec_t<float, N> decimal_point; | |||||
| vec_t<int, N> origin; | |||||
| vec_t<float, N> pos; | |||||
| this->ExtractFloorDecimal(simplex_position, floor_point, decimal_point); | |||||
| this->ExtractFloorDecimal(simplex_position, origin, pos); | |||||
| vec_t<int, N> index_order = this->GetIndexOrder(decimal_point); | |||||
| vec_t<int, N> index_order = this->GetIndexOrder(pos); | |||||
| // Resetting decimal point in regular orthonormal coordinates | // 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: | protected: | ||||
| inline float LastInterp(vec_t<int, N> & floor_point, | |||||
| vec_t<float, N> const & decimal_point, | |||||
| vec_t<int, N> index_order) const | |||||
| inline float LastInterp(vec_t<int, N> & origin, | |||||
| vec_t<float, N> const & pos, | |||||
| vec_t<int, N> index_order) const | |||||
| { | { | ||||
| vec_t<float, N> point_of_interest(0); | |||||
| // “corner” will traverse the simplex along its edges | |||||
| vec_t<float, N> corner(0); | |||||
| float result = 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<float, N> gradient = this->m_gradients[floor_point]; | |||||
| float dist = 0.5f - 0.75f * sqlength(this->m_base * (pos - corner)); | |||||
| vec_t<float, N> const &gradient = this->m_gradients[origin]; | |||||
| if (dist > 0) | 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) | 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; | return result * 100; | ||||
| } | } | ||||
| inline vec_t<int, N> GetIndexOrder(vec_t<float, N> 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<int, N> GetIndexOrder(vec_t<float, N> const & pos) const | |||||
| { | { | ||||
| vec_t<int, N> result; | vec_t<int, N> result; | ||||
| for (int i = 0 ; i < N ; ++i) | |||||
| for (int i = 0; i < N; ++i) | |||||
| result[i] = 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; | return result; | ||||
| } | } | ||||
| @@ -115,19 +110,22 @@ protected: | |||||
| return ret >= 0 ? ret : ret + dim; | return ret >= 0 ? ret : ret + dim; | ||||
| } | } | ||||
| inline void ExtractFloorDecimal(vec_t<float, N> const & simplex_position, vec_t<int, N> & floor_point, vec_t<float, N> & decimal_point) const | |||||
| /* For a given world position, extract grid coordinates (origin) and | |||||
| * the corresponding delta position (pos). */ | |||||
| inline void ExtractFloorDecimal(vec_t<float, N> const & simplex_position, | |||||
| vec_t<int, N> & origin, | |||||
| vec_t<float, N> & pos) const | |||||
| { | { | ||||
| // Finding floor point index | // 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 | // 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<float, N>)origin; | |||||
| // Never exceed the size of the gradients and loop on it | // 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() | inline void InitBase() | ||||