/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Copyright 2012-2015 Danny Robson */ #ifdef __UTIL_NOISE_BASIS_WORLEY_IPP #error #endif #define __UTIL_NOISE_BASIS_WORLEY_IPP #include "../../debug.hpp" namespace util { namespace noise { namespace basis { /////////////////////////////////////////////////////////////////////////// template worley::worley (seed_t _seed): m_seed (_seed) { ; } //------------------------------------------------------------------------- template util::range worley::bounds (void) const { return { 0.0, 1.5 }; } //------------------------------------------------------------------------- template seed_t worley::seed (void) const { return m_seed; } //------------------------------------------------------------------------- template seed_t worley::seed (seed_t _seed) { return m_seed = _seed; } //------------------------------------------------------------------------- template T worley::operator() (point p) const noexcept { // extract integer and fractional parts. be careful to always round down auto p_int = floor (p).template cast (); auto p_rem = (p - p_int).template as (); // setup an array of distances constexpr size_t COUNT = type::distance::OFFSET_SIZE; T distances[COUNT]; std::transform (std::begin (this->OFFSETS), std::end (this->OFFSETS), distances, [p_int,p_rem,this] (auto i) { auto q = this->generate (p_int + i); return distance2 (q + i, p_rem); }); // find the f'th lowest value static_assert (F < COUNT, "worley order must be less than search radius"); std::partial_sort (distances, distances + F, distances + COUNT); CHECK_GE (distances[F], 0); return distances[F]; } ////////////////////////////////////////////////////////////////////////// template point worley::generate (point p) const { return rand::coord (m_seed, p); } } } }