|
|
@@ -43,40 +43,41 @@ public: |
|
|
|
vec_t<float, N> simplex_position = m_base_inverse * position; |
|
|
|
|
|
|
|
// 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 |
|
|
|
//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<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; |
|
|
|
|
|
|
|
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) |
|
|
|
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<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; |
|
|
|
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<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 |
|
|
|
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<float, N>)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() |
|
|
|