noise: reduce repetition in template params

This commit is contained in:
Danny Robson 2015-10-07 00:14:13 +11:00
parent b464f089a5
commit 8b458ad452
30 changed files with 519 additions and 503 deletions

View File

@ -17,6 +17,7 @@
#ifndef __UTIL_NOISE_BASIS_CONSTANT_HPP #ifndef __UTIL_NOISE_BASIS_CONSTANT_HPP
#define __UTIL_NOISE_BASIS_CONSTANT_HPP #define __UTIL_NOISE_BASIS_CONSTANT_HPP
#include "../rand.hpp"
#include "../../point.hpp" #include "../../point.hpp"
#include <cstdint> #include <cstdint>
@ -24,11 +25,12 @@
namespace util { namespace noise { namespace basis { namespace util { namespace noise { namespace basis {
template <size_t S, typename T> template <size_t S, typename T>
struct constant { struct constant {
using seed_t = uint64_t; using value_t = T;
using point_t = point<S,T>;
constant (seed_t); constant (seed_t);
T operator() (point<S,T>) const; T operator() (point_t) const;
seed_t seed; seed_t seed;
T value; T value;

View File

@ -22,7 +22,7 @@
namespace util { namespace noise { namespace basis { namespace util { namespace noise { namespace basis {
template <size_t S, typename T> template <size_t S, typename T>
T T
constant<S,T>::operator() (point<S,T>) const constant<S,T>::operator() (point_t) const
{ {
return value; return value;
} }

View File

@ -33,10 +33,9 @@
namespace util { namespace noise { namespace basis { namespace util { namespace noise { namespace basis {
template < template <
size_t S, // probe point dimensionality size_t S, // probe point dimensionality
typename T, // probe point value_type typename T // probe point value_type
lerp_t<T> L // axis interpolation function
> >
struct expgrad : public gradient<S,T,L> { struct expgrad : public gradient<S,T> {
explicit expgrad (seed_t seed, explicit expgrad (seed_t seed,
T base = (T)1.02, T base = (T)1.02,
T exponent = T{256}); T exponent = T{256});

View File

@ -24,22 +24,21 @@
namespace util { namespace noise { namespace basis { namespace util { namespace noise { namespace basis {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template <size_t S, typename T, util::noise::lerp_t<T> L template <size_t S, typename T>
> expgrad<S,T>::expgrad (seed_t _seed, T _base, T _exponent):
expgrad<S,T,L>::expgrad (seed_t _seed, T _base, T _exponent): gradient<S,T> (_seed),
gradient<S,T,L> (_seed),
m_base (_base), m_base (_base),
m_exponent (_exponent) m_exponent (_exponent)
{ ; } { ; }
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template <size_t S, typename T, util::noise::lerp_t<T> L> template <size_t S, typename T>
vector<S,T> vector<S,T>
expgrad<S,T,L>::generate (pointi<S> p) const expgrad<S,T>::generate (pointi<S> p) const
{ {
auto t = rand::scalar<float> (this->seed (), p); auto t = rand::scalar<float> (this->seed (), p);
auto factor = std::pow (m_base, -t * m_exponent); auto factor = std::pow (m_base, -t * m_exponent);
return factor * gradient<S,T,L>::generate (p); return factor * gradient<S,T>::generate (p);
} }
} } } } } }

View File

@ -26,8 +26,7 @@ namespace util { namespace noise { namespace basis {
/// Perlin: interpolated value across each grid space /// Perlin: interpolated value across each grid space
template < template <
size_t S, // probe point dimensionality size_t S, // probe point dimensionality
typename T, // probe point value_type typename T // probe point value_type
lerp_t<T> L // axis interpolation function
> >
struct gradient { struct gradient {
gradient (seed_t); gradient (seed_t);

View File

@ -23,34 +23,34 @@
namespace util { namespace noise { namespace basis { namespace util { namespace noise { namespace basis {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template <size_t S, typename T, util::noise::lerp_t<T> L> template <size_t S, typename T>
gradient<S,T,L>::gradient (seed_t _seed): gradient<S,T>::gradient (seed_t _seed):
m_seed (_seed) m_seed (_seed)
{ ; } { ; }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, lerp_t<T> L> template <size_t S, typename T>
seed_t seed_t
gradient<S,T,L>::seed (void) const gradient<S,T>::seed (void) const
{ {
return m_seed; return m_seed;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, lerp_t<T> L> template <size_t S, typename T>
seed_t seed_t
gradient<S,T,L>::seed (seed_t _seed) gradient<S,T>::seed (seed_t _seed)
{ {
return m_seed = _seed; return m_seed = _seed;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, util::noise::lerp_t<T> L> template <size_t S, typename T>
vector<S,T> vector<S,T>
gradient<S,T,L>::generate (pointi<S> p) const gradient<S,T>::generate (pointi<S> p) const
{ {
return rand::coord<vector,T> (m_seed, p) * 2 - 1; return rand::coord<vector,T> (m_seed, p) * 2 - 1;
} }

View File

@ -30,19 +30,23 @@ namespace util { namespace noise { namespace basis {
template < template <
size_t S, // point point dimensionality size_t S, // point point dimensionality
typename T, // arithmetic and result value_type, must be floating point typename T, // arithmetic and result value_type, must be floating point
lerp_t<T> L, // gradient interpolation function template < // gradient interpolation function
typename
> class L,
template < // gradient provider class, must provide generate(point_t) template < // gradient provider class, must provide generate(point_t)
size_t, size_t,
typename, typename
lerp_t<T>
> class G = gradient > class G = gradient
> >
struct perlin : public G<S,T,L>, public type::gradient<S> { struct perlin : public G<S,T>, public type::gradient<S> {
using value_t = T;
using point_t = point<S,T>;
perlin (seed_t); perlin (seed_t);
range<T> bounds (void) const; range<T> bounds (void) const;
T operator() (point<S,T>) const; T operator() (point_t) const;
}; };
} } } } } }

View File

@ -24,14 +24,14 @@
namespace util { namespace noise { namespace basis { namespace util { namespace noise { namespace basis {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template <size_t S, typename T, util::noise::lerp_t<T> L, template <size_t,typename,lerp_t<T>> class G> template <size_t S, typename T, template <typename> class L, template <size_t,typename> class G>
perlin<S,T,L,G>::perlin (seed_t _seed): perlin<S,T,L,G>::perlin (seed_t _seed):
G<S,T,L> (_seed) G<S,T> (_seed)
{ ; } { ; }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, util::noise::lerp_t<T> L, template <size_t,typename,lerp_t<T>> class G> template <size_t S, typename T, template <typename> class L, template <size_t,typename> class G>
util::range<T> util::range<T>
perlin<S,T,L,G>::bounds (void) const perlin<S,T,L,G>::bounds (void) const
{ {
@ -43,9 +43,9 @@ namespace util { namespace noise { namespace basis {
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, util::noise::lerp_t<T> L, template <size_t,typename,lerp_t<T>> class G> template <size_t S, typename T, template <typename> class L, template <size_t,typename> class G>
T T
perlin<S,T,L,G>::operator() (util::point<S,T> p) const perlin<S,T,L,G>::operator() (point_t p) const
{ {
// extract integer and fractional parts. be careful to always round down // extract integer and fractional parts. be careful to always round down
auto p_int = floor (p).template cast<intmax_t> (); auto p_int = floor (p).template cast<intmax_t> ();
@ -74,7 +74,7 @@ namespace util { namespace noise { namespace basis {
for (size_t i = S; i; --i) for (size_t i = S; i; --i)
for (size_t j = 0; j < std::pow(2,i); j += 2) for (size_t j = 0; j < std::pow(2,i); j += 2)
l_[j / 2] = L (l_[j], l_[j+1], p_rem[S-i]); l_[j / 2] = L<T>() (l_[j], l_[j+1], p_rem[S-i]);
return l_[0]; return l_[0];
} }
} } } } } }

View File

@ -28,6 +28,9 @@ namespace util { namespace noise { namespace basis {
template <size_t S, typename T> template <size_t S, typename T>
struct runtime { struct runtime {
public: public:
using value_t = T;
using point_t = point<S,T>;
runtime (seed_t) {} runtime (seed_t) {}
runtime (runtime&&) = default; runtime (runtime&&) = default;
runtime (const runtime&) = delete; runtime (const runtime&) = delete;

View File

@ -26,13 +26,22 @@
namespace util { namespace noise { namespace basis { namespace util { namespace noise { namespace basis {
/// Single value per grid space /// Single value per grid space
template <size_t S, typename T, lerp_t<T>> template <
size_t S,
typename T,
template <
typename
> class L
>
struct value : public type::gradient<S> { struct value : public type::gradient<S> {
using value_t = T;
using point_t = point<S,T>;
value (seed_t); value (seed_t);
range<T> bounds (void) const; range<T> bounds (void) const;
T operator() (util::point<S,T>) const; value_t operator() (point_t) const;
seed_t seed (void) const; seed_t seed (void) const;
seed_t seed (seed_t); seed_t seed (seed_t);

View File

@ -25,14 +25,14 @@
namespace util { namespace noise { namespace basis { namespace util { namespace noise { namespace basis {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template <size_t S, typename T, util::noise::lerp_t<T> L> template <size_t S, typename T, template <typename> class L>
value<S,T,L>::value (seed_t _seed): value<S,T,L>::value (seed_t _seed):
m_seed (_seed) m_seed (_seed)
{ ; } { ; }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, util::noise::lerp_t<T> L> template <size_t S, typename T, template <typename> class L>
util::range<T> util::range<T>
value<S,T,L>::bounds (void) const value<S,T,L>::bounds (void) const
{ {
@ -41,7 +41,7 @@ namespace util { namespace noise { namespace basis {
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, lerp_t<T> L> template <size_t S, typename T, template <typename> class L>
seed_t seed_t
value<S,T,L>::seed (void) const value<S,T,L>::seed (void) const
{ {
@ -50,7 +50,7 @@ namespace util { namespace noise { namespace basis {
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, lerp_t<T> L> template <size_t S, typename T, template <typename> class L>
seed_t seed_t
value<S,T,L>::seed (seed_t _seed) value<S,T,L>::seed (seed_t _seed)
{ {
@ -59,7 +59,7 @@ namespace util { namespace noise { namespace basis {
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, util::noise::lerp_t<T> L> template <size_t S, typename T, template <typename> class L>
T T
value<S,T,L>::operator() (util::point<S,T> p) const value<S,T,L>::operator() (util::point<S,T> p) const
{ {
@ -77,7 +77,7 @@ namespace util { namespace noise { namespace basis {
std::array<T,pow(2,S)> g_; std::array<T,pow(2,S)> g_;
std::transform (std::begin (p_), std::end (p_), std::transform (std::begin (p_), std::end (p_),
std::begin (g_), std::begin (g_),
[this] (auto i) { return rand::scalar<float> (m_seed, i) * 2 - 1; }); [this] (auto i) { return rand::scalar<value_t> (m_seed, i) * 2 - 1; });
// Interpolate on one dimension, then the other. // Interpolate on one dimension, then the other.
T l_[pow(2,S)]; T l_[pow(2,S)];
@ -85,7 +85,7 @@ namespace util { namespace noise { namespace basis {
for (size_t i = S; i; --i) for (size_t i = S; i; --i)
for (size_t j = 0; j < std::pow(2,i); j += 2) for (size_t j = 0; j < std::pow(2,i); j += 2)
l_[j / 2] = L (l_[j], l_[j+1], p_rem[S-i]); l_[j / 2] = L<T>() (l_[j], l_[j+1], p_rem[S-i]);
return l_[0]; return l_[0];
} }
} } } } } }

View File

@ -27,11 +27,14 @@
namespace util { namespace noise { namespace basis { namespace util { namespace noise { namespace basis {
template <size_t S, typename T, size_t F = 0> template <size_t S, typename T, size_t F = 0>
struct worley : public type::distance<S,1> { struct worley : public type::distance<S,1> {
using value_t = T;
using point_t = point<S,T>;
worley (seed_t); worley (seed_t);
range<T> bounds (void) const; range<T> bounds (void) const;
T operator() (util::point<S,T>) const; value_t operator() (point_t) const;
seed_t seed (void) const; seed_t seed (void) const;
seed_t seed (seed_t); seed_t seed (seed_t);

View File

@ -7,7 +7,7 @@
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUvalue_t WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
@ -20,6 +20,7 @@
#include <cstdint> #include <cstdint>
#include "../../point.hpp" #include "../../point.hpp"
#include "../rand.hpp"
namespace util { namespace noise { namespace fractal { namespace util { namespace noise { namespace fractal {
/// Fractal Brownian Motion summation. /// Fractal Brownian Motion summation.
@ -32,41 +33,38 @@ namespace util { namespace noise { namespace fractal {
/// lacunarity: per octave frequency scaling factor /// lacunarity: per octave frequency scaling factor
/// amplitude: maximum absolute value of the noise /// amplitude: maximum absolute value of the noise
/// gain: per octave amplitude scaling factor. typically 1/f. /// gain: per octave amplitude scaling factor. typically 1/f.
template < template <class B>
size_t S, // probe point dimensionality
typename T, // probe point value_type
typename B // noise basis function
>
struct base { struct base {
using seed_t = uint64_t; using value_t = typename B::value_t;
using point_t = typename B::point_t;
// constructors // constructors
base (seed_t, base (seed_t,
unsigned octaves, unsigned octaves,
T H, value_t H,
T frequency, value_t frequency,
T lacunarity, value_t lacunarity,
T amplitude, value_t amplitude,
T gain); value_t gain);
// accessors // accessors
constexpr unsigned octaves (void) const; constexpr unsigned octaves (void) const;
unsigned octaves (unsigned); unsigned octaves (unsigned);
constexpr T H (void) const; constexpr value_t H (void) const;
T H (T); value_t H (value_t);
constexpr T frequency (void) const; constexpr value_t frequency (void) const;
T frequency (T); value_t frequency (value_t);
constexpr T lacunarity (void) const; constexpr value_t lacunarity (void) const;
T lacunarity (T); value_t lacunarity (value_t);
constexpr T amplitude (void) const; constexpr value_t amplitude (void) const;
T amplitude (T); value_t amplitude (value_t);
constexpr T gain (void) const; constexpr value_t gain (void) const;
T gain (T); value_t gain (value_t);
seed_t seed (void) const; seed_t seed (void) const;
seed_t seed (seed_t); seed_t seed (seed_t);
@ -76,18 +74,18 @@ namespace util { namespace noise { namespace fractal {
protected: protected:
unsigned m_octaves; unsigned m_octaves;
T m_H; value_t m_H;
T m_frequency; value_t m_frequency;
T m_lacunarity; value_t m_lacunarity;
T m_amplitude; value_t m_amplitude;
T m_gain; value_t m_gain;
B m_basis; B m_basis;
T m_invAH; value_t m_invAH;
T m_invGH; value_t m_invGH;
}; };
} } } } } }

View File

@ -7,7 +7,7 @@
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUvalue_t WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
@ -23,14 +23,14 @@
namespace util { namespace noise { namespace fractal { namespace util { namespace noise { namespace fractal {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template <size_t S, typename T, typename B> template <class B>
base<S,T,B>::base (seed_t _seed, base<B>::base (seed_t _seed,
unsigned _octaves, unsigned _octaves,
T _H, value_t _H,
T _frequency, value_t _frequency,
T _lacunarity, value_t _lacunarity,
T _amplitude, value_t _amplitude,
T _gain): value_t _gain):
// literals // literals
m_octaves (_octaves), m_octaves (_octaves),
m_H (_H), m_H (_H),
@ -51,27 +51,27 @@ namespace util { namespace noise { namespace fractal {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template <size_t S, typename T, typename B> template <class B>
unsigned unsigned
base<S,T,B>::octaves (unsigned _octaves) base<B>::octaves (unsigned _octaves)
{ {
return m_octaves = _octaves; return m_octaves = _octaves;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
constexpr unsigned constexpr unsigned
base<S,T,B>::octaves (void) const base<B>::octaves (void) const
{ {
return m_octaves; return m_octaves;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
T typename base<B>::value_t
base<S,T,B>::H (T _h) base<B>::H (value_t _h)
{ {
m_H = _h; m_H = _h;
m_invAH = std::pow (m_amplitude, -m_H); m_invAH = std::pow (m_amplitude, -m_H);
@ -81,63 +81,63 @@ namespace util { namespace noise { namespace fractal {
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
constexpr T constexpr typename base<B>::value_t
base<S,T,B>::H (void) const base<B>::H (void) const
{ {
return m_H; return m_H;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
T typename base<B>::value_t
base<S,T,B>::frequency (T _frequency) base<B>::frequency (value_t _frequency)
{ {
return m_frequency = _frequency; return m_frequency = _frequency;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
constexpr T constexpr typename base<B>::value_t
base<S,T,B>::frequency (void) const base<B>::frequency (void) const
{ {
return m_frequency; return m_frequency;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
T typename base<B>::value_t
base<S,T,B>::lacunarity (T _lacunarity) base<B>::lacunarity (value_t _lacunarity)
{ {
return m_lacunarity = _lacunarity; return m_lacunarity = _lacunarity;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
constexpr T constexpr typename base<B>::value_t
base<S,T,B>::lacunarity (void) const base<B>::lacunarity (void) const
{ {
return m_lacunarity; return m_lacunarity;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
constexpr T constexpr typename base<B>::value_t
base<S,T,B>::amplitude (void) const base<B>::amplitude (void) const
{ {
return m_amplitude; return m_amplitude;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
T typename base<B>::value_t
base<S,T,B>::amplitude (T _amplitude) base<B>::amplitude (value_t _amplitude)
{ {
m_amplitude = _amplitude; m_amplitude = _amplitude;
m_invAH = std::pow (m_amplitude, -m_H); m_invAH = std::pow (m_amplitude, -m_H);
@ -146,18 +146,18 @@ namespace util { namespace noise { namespace fractal {
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
constexpr T constexpr typename base<B>::value_t
base<S,T,B>::gain (void) const base<B>::gain (void) const
{ {
return m_gain; return m_gain;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
T typename base<B>::value_t
base<S,T,B>::gain (T _gain) base<B>::gain (value_t _gain)
{ {
m_gain = _gain; m_gain = _gain;
m_invGH = std::pow (_gain, m_H); m_invGH = std::pow (_gain, m_H);
@ -166,36 +166,36 @@ namespace util { namespace noise { namespace fractal {
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
typename base<S,T,B>::seed_t seed_t
base<S,T,B>::seed (seed_t _seed) base<B>::seed (seed_t _seed)
{ {
return m_basis.seed (_seed); return m_basis.seed (_seed);
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
typename base<S,T,B>::seed_t seed_t
base<S,T,B>::seed (void) const base<B>::seed (void) const
{ {
return m_basis.seed (); return m_basis.seed ();
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
const B& const B&
base<S,T,B>::basis (void) const base<B>::basis (void) const
{ {
return m_basis; return m_basis;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
B& B&
base<S,T,B>::basis (void) base<B>::basis (void)
{ {
return m_basis; return m_basis;
} }

View File

@ -7,7 +7,7 @@
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUvalue_t WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
@ -33,31 +33,28 @@ namespace util { namespace noise { namespace fractal {
/// lacunarity: per octave frequency scaling factor /// lacunarity: per octave frequency scaling factor
/// amplitude: maximum absolute value of the noise /// amplitude: maximum absolute value of the noise
/// gain: per octave amplitude scaling factor. typically 1/f. /// gain: per octave amplitude scaling factor. typically 1/f.
template < template <class B>
size_t S, // probe point dimensionality struct fbm : public base<B> {
typename T, // probe point value_type using value_t = typename base<B>::value_t;
typename B // generating basis function using point_t = typename base<B>::point_t;
>
struct fbm : public base<S,T,B> {
using seed_t = typename base<S,T,B>::seed_t;
static constexpr unsigned DEFAULT_OCTAVES = 8; static constexpr unsigned DEFAULT_OCTAVES = 8;
static constexpr T DEFAULT_H = 1; static constexpr value_t DEFAULT_H = 1;
static constexpr T DEFAULT_FREQUENCY = T(0.1); static constexpr value_t DEFAULT_FREQUENCY = value_t(0.1);
static constexpr T DEFAULT_LACUNARITY = 2; static constexpr value_t DEFAULT_LACUNARITY = 2;
static constexpr T DEFAULT_AMPLITUDE = 1; static constexpr value_t DEFAULT_AMPLITUDE = 1;
static constexpr T DEFAULT_GAIN = 1 / DEFAULT_LACUNARITY; static constexpr value_t DEFAULT_GAIN = 1 / DEFAULT_LACUNARITY;
fbm (seed_t seed, fbm (seed_t seed,
unsigned octaves, unsigned octaves,
T H, value_t H,
T frequency, value_t frequency,
T lacunarity, value_t lacunarity,
T amplitude, value_t amplitude,
T gain); value_t gain);
fbm (seed_t); fbm (seed_t);
T operator() (point<S,T>) const; value_t operator() (point_t) const;
}; };
} } } } } }

View File

@ -7,7 +7,7 @@
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUvalue_t WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
@ -23,15 +23,15 @@
namespace util { namespace noise { namespace fractal { namespace util { namespace noise { namespace fractal {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template <size_t S, typename T, typename B> template <class B>
fbm<S,T,B>::fbm (seed_t _seed, fbm<B>::fbm (seed_t _seed,
unsigned _octaves, unsigned _octaves,
T _H, value_t _H,
T _frequency, value_t _frequency,
T _lacunarity, value_t _lacunarity,
T _amplitude, value_t _amplitude,
T _gain): value_t _gain):
base<S,T,B> (_seed, base<B> (_seed,
_octaves, _octaves,
_H, _H,
_frequency, _frequency,
@ -42,9 +42,9 @@ namespace util { namespace noise { namespace fractal {
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
fbm<S,T,B>::fbm (seed_t _seed): fbm<B>::fbm (seed_t _seed):
fbm<S,T,B> (_seed, fbm<B> (_seed,
DEFAULT_OCTAVES, DEFAULT_OCTAVES,
DEFAULT_H, DEFAULT_H,
DEFAULT_FREQUENCY, DEFAULT_FREQUENCY,
@ -55,19 +55,19 @@ namespace util { namespace noise { namespace fractal {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template <size_t S, typename T, typename B> template <class B>
T typename fbm<B>::value_t
fbm<S,T,B>::operator() (point<S,T> p) const fbm<B>::operator() (point_t p) const
{ {
T total = 0; value_t total = 0;
T scale = this->m_invAH; value_t scale = this->m_invAH;
p *= this->m_frequency; p *= this->m_frequency;
for (size_t i = 0; i < this->m_octaves; ++i) { for (size_t i = 0; i < this->m_octaves; ++i) {
total += this->m_basis (p) * scale; total += this->m_basis (p) * scale;
p += PI<float>; p += PI<value_t>;
p *= this->m_lacunarity; p *= this->m_lacunarity;
scale *= this->m_invGH; scale *= this->m_invGH;
} }

View File

@ -7,7 +7,7 @@
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUvalue_t WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
@ -25,48 +25,45 @@
namespace util { namespace noise { namespace fractal { namespace util { namespace noise { namespace fractal {
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
/// Heterogeneous procedural terrain fucntion: stats by altitude method /// Heterogeneous procedural terrain fucntion: stats by altitude method
template < template <class B>
size_t S, // probe point dimensionality struct hetero : public base<B> {
typename T, // probe point value_type using value_t = typename base<B>::value_t;
typename B // generating basis function using point_t = typename base<B>::point_t;
>
struct hetero : public base<S,T,B> {
using seed_t = typename base<S,T,B>::seed_t;
static constexpr unsigned DEFAULT_OCTAVES = 6; static constexpr unsigned DEFAULT_OCTAVES = 6;
static constexpr T DEFAULT_H = T(0.75); static constexpr value_t DEFAULT_H = value_t(0.75);
static constexpr T DEFAULT_FREQUENCY = T(0.1); static constexpr value_t DEFAULT_FREQUENCY = value_t(0.1);
static constexpr T DEFAULT_LACUNARITY = 2; static constexpr value_t DEFAULT_LACUNARITY = 2;
static constexpr T DEFAULT_AMPLITUDE = 1; static constexpr value_t DEFAULT_AMPLITUDE = 1;
static constexpr T DEFAULT_GAIN = 1 / DEFAULT_LACUNARITY; static constexpr value_t DEFAULT_GAIN = 1 / DEFAULT_LACUNARITY;
static constexpr T DEFAULT_OFFSET = T(0.7); static constexpr value_t DEFAULT_OFFSET = value_t(0.7);
hetero (seed_t, hetero (seed_t,
unsigned octaves, unsigned octaves,
T H, value_t H,
T frequency, value_t frequency,
T lacunarity, value_t lacunarity,
T amplitude, value_t amplitude,
T gain); value_t gain);
hetero (seed_t, hetero (seed_t,
unsigned octaves, unsigned octaves,
T H, value_t H,
T frequency, value_t frequency,
T lacunarity, value_t lacunarity,
T amplitude, value_t amplitude,
T gain, value_t gain,
T offset); value_t offset);
hetero (seed_t); hetero (seed_t);
constexpr T offset (void) const; constexpr value_t offset (void) const;
T offset (T); value_t offset (value_t);
T operator() (point<S,T>) const; value_t operator() (point_t) const;
private: private:
T m_offset; value_t m_offset;
}; };
} } } } } }

View File

@ -7,7 +7,7 @@
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUvalue_t WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
@ -21,36 +21,36 @@
namespace util { namespace noise { namespace fractal { namespace util { namespace noise { namespace fractal {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template <size_t S, typename T, typename B> template <class B>
hetero<S,T,B>::hetero(seed_t _seed, hetero<B>::hetero(seed_t _seed,
unsigned _octaves, unsigned _octaves,
T _H, value_t _H,
T _frequency, value_t _frequency,
T _lacunarity, value_t _lacunarity,
T _amplitude, value_t _amplitude,
T _gain): value_t _gain):
hetero<S,T,B> (_seed, hetero<B> (_seed,
_octaves, _octaves,
_H, _H,
_frequency, _frequency,
_lacunarity, _lacunarity,
_amplitude, _amplitude,
_gain, _gain,
-this->basis ().bounds ().min + this->basis ().bounds ().magnitude () / T{2}) -this->basis ().bounds ().min + this->basis ().bounds ().magnitude () / value_t{2})
{ ; } { ; }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
hetero<S,T,B>::hetero(seed_t _seed, hetero<B>::hetero(seed_t _seed,
unsigned _octaves, unsigned _octaves,
T _H, value_t _H,
T _frequency, value_t _frequency,
T _lacunarity, value_t _lacunarity,
T _amplitude, value_t _amplitude,
T _gain, value_t _gain,
T _offset): value_t _offset):
base<S,T,B> (_seed, base<B> (_seed,
_octaves, _octaves,
_H, _H,
_frequency, _frequency,
@ -62,9 +62,9 @@ namespace util { namespace noise { namespace fractal {
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
hetero<S,T,B>::hetero (seed_t _seed): hetero<B>::hetero (seed_t _seed):
hetero<S,T,B> (_seed, hetero<B> (_seed,
DEFAULT_OCTAVES, DEFAULT_OCTAVES,
DEFAULT_H, DEFAULT_H,
DEFAULT_FREQUENCY, DEFAULT_FREQUENCY,
@ -76,35 +76,35 @@ namespace util { namespace noise { namespace fractal {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template <size_t S, typename T, typename B> template <class B>
constexpr T constexpr typename hetero<B>::value_t
hetero<S,T,B>::offset (void) const hetero<B>::offset (void) const
{ {
return m_offset; return m_offset;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
T typename hetero<B>::value_t
hetero<S,T,B>::offset (T _offset) hetero<B>::offset (value_t _offset)
{ {
return m_offset = _offset; return m_offset = _offset;
} }
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template <size_t S, typename T, typename B> template <class B>
T typename hetero<B>::value_t
hetero<S,T,B>::operator() (point<S,T> p) const hetero<B>::operator() (point_t p) const
{ {
T scale = this->m_invAH; value_t scale = this->m_invAH;
p *= this->m_frequency; p *= this->m_frequency;
T result = (this->m_basis (p) + m_offset) * scale; value_t result = (this->m_basis (p) + m_offset) * scale;
p *= this->m_lacunarity; p *= this->m_lacunarity;
T increment = 0; value_t increment = 0;
for (size_t i = 1; i < this->m_octaves; ++i) { for (size_t i = 1; i < this->m_octaves; ++i) {
scale *= this->m_invGH; scale *= this->m_invGH;
@ -115,7 +115,7 @@ namespace util { namespace noise { namespace fractal {
result += increment; result += increment;
p += PI<T>; p += PI<value_t>;
p *= this->m_lacunarity; p *= this->m_lacunarity;
} }

View File

@ -24,38 +24,35 @@
namespace util { namespace noise { namespace fractal { namespace util { namespace noise { namespace fractal {
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
/// Musgrave's "Hybrid MultiFractal" /// Musgrave's "Hybrid MultiFractal"
template < template <class B>
size_t S, // probe point dimensionality struct hmf : public base<B> {
typename T, // probe point value_type using value_t = typename base<B>::value_t;
typename B // generating basis function using point_t = typename base<B>::point_t;
>
struct hmf : public base<S,T,B> {
using seed_t = typename base<S,T,B>::seed_t;
// H should be fairly low due to the decreasing weight parameter in eval // H should be fairly low due to the decreasing weight parameter in eval
static constexpr unsigned DEFAULT_OCTAVES = 6; static constexpr unsigned DEFAULT_OCTAVES = 6;
static constexpr T DEFAULT_H = T(0.25); static constexpr value_t DEFAULT_H = value_t(0.25);
static constexpr T DEFAULT_FREQUENCY = T(0.1); static constexpr value_t DEFAULT_FREQUENCY = value_t(0.1);
static constexpr T DEFAULT_LACUNARITY = 2; static constexpr value_t DEFAULT_LACUNARITY = 2;
static constexpr T DEFAULT_AMPLITUDE = 1; static constexpr value_t DEFAULT_AMPLITUDE = 1;
static constexpr T DEFAULT_GAIN = 1 / DEFAULT_LACUNARITY; static constexpr value_t DEFAULT_GAIN = 1 / DEFAULT_LACUNARITY;
static constexpr T DEFAULT_OFFSET = T(0.7); static constexpr value_t DEFAULT_OFFSET = value_t(0.7);
hmf (seed_t, hmf (seed_t,
unsigned octaves, unsigned octaves,
T H, value_t H,
T frequency, value_t frequency,
T lacunarity, value_t lacunarity,
T amplitude, value_t amplitude,
T gain, value_t gain,
T offset); value_t offset);
hmf (seed_t); hmf (seed_t);
T operator() (point<S,T>) const; value_t operator() (point_t) const;
private: private:
T m_offset; value_t m_offset;
}; };
} } } } } }

View File

@ -22,16 +22,16 @@
namespace util { namespace noise { namespace fractal { namespace util { namespace noise { namespace fractal {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template <size_t S, typename T, typename B> template <class B>
hmf<S,T,B>::hmf (seed_t _seed, hmf<B>::hmf (seed_t _seed,
unsigned _octaves, unsigned _octaves,
T _H, value_t _H,
T _frequency, value_t _frequency,
T _lacunarity, value_t _lacunarity,
T _amplitude, value_t _amplitude,
T _gain, value_t _gain,
T _offset): value_t _offset):
base<S,T,B> (_seed, base<B> (_seed,
_octaves, _octaves,
_H, _H,
_frequency, _frequency,
@ -43,9 +43,9 @@ namespace util { namespace noise { namespace fractal {
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
hmf<S,T,B>::hmf (seed_t _seed): hmf<B>::hmf (seed_t _seed):
hmf<S,T,B> (_seed, hmf<B> (_seed,
DEFAULT_OCTAVES, DEFAULT_OCTAVES,
DEFAULT_H, DEFAULT_H,
DEFAULT_FREQUENCY, DEFAULT_FREQUENCY,
@ -57,15 +57,15 @@ namespace util { namespace noise { namespace fractal {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template <size_t S, typename T, typename B> template <class B>
T typename hmf<B>::value_t
hmf<S,T,B>::operator() (point<S,T> p) const hmf<B>::operator() (point_t p) const
{ {
T scale = this->m_invAH; value_t scale = this->m_invAH;
T result = 0; value_t result = 0;
T signal = 0; value_t signal = 0;
T weight = 1; value_t weight = 1;
p *= this->m_frequency; p *= this->m_frequency;
@ -74,10 +74,10 @@ namespace util { namespace noise { namespace fractal {
result += signal * weight; result += signal * weight;
weight *= signal; weight *= signal;
weight = min (weight, T{1}); weight = min (weight, value_t{1});
scale *= this->m_invGH; scale *= this->m_invGH;
p += PI<T>; p += PI<value_t>;
p *= this->m_lacunarity; p *= this->m_lacunarity;
} }

View File

@ -32,40 +32,37 @@ namespace util { namespace noise { namespace fractal {
/// lacunarity: incremental octave frequency scaling factor /// lacunarity: incremental octave frequency scaling factor
/// amplitude: value scaling factor for the base octave /// amplitude: value scaling factor for the base octave
/// gain: incremental octave value scaling factor /// gain: incremental octave value scaling factor
template < template <class B>
size_t S, // probe point dimensionality struct rmf : public base<B> {
typename T, // probe point value_type using value_t = typename base<B>::value_t;
typename B // generating basis function using point_t = typename base<B>::point_t;
>
struct rmf : public base<S,T,B> {
using seed_t = typename base<S,T,B>::seed_t;
static constexpr unsigned DEFAULT_OCTAVES = 5; static constexpr unsigned DEFAULT_OCTAVES = 5;
static constexpr T DEFAULT_H = 1; static constexpr value_t DEFAULT_H = 1;
static constexpr T DEFAULT_OFFSET = 1; static constexpr value_t DEFAULT_OFFSET = 1;
static constexpr T DEFAULT_FREQUENCY = 1; static constexpr value_t DEFAULT_FREQUENCY = 1;
static constexpr T DEFAULT_LACUNARITY = 2; static constexpr value_t DEFAULT_LACUNARITY = 2;
static constexpr T DEFAULT_AMPLITUDE = 2; static constexpr value_t DEFAULT_AMPLITUDE = 2;
static constexpr T DEFAULT_GAIN = 1 / DEFAULT_LACUNARITY; static constexpr value_t DEFAULT_GAIN = 1 / DEFAULT_LACUNARITY;
rmf (seed_t, rmf (seed_t,
unsigned octaves, unsigned octaves,
T H, value_t H,
T frequency, value_t frequency,
T lacunarity, value_t lacunarity,
T amplitude, value_t amplitude,
T gain, value_t gain,
T offset); value_t offset);
rmf (seed_t); rmf (seed_t);
T operator() (point<S,T>) const; value_t operator() (point_t) const;
T offset (void) const; value_t offset (void) const;
T offset (T); value_t offset (value_t);
private: private:
T m_offset; value_t m_offset;
}; };
} } } } } }

View File

@ -22,16 +22,16 @@
namespace util { namespace noise { namespace fractal { namespace util { namespace noise { namespace fractal {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template <size_t S, typename T, typename B> template <class B>
rmf<S,T,B>::rmf (seed_t _seed, rmf<B>::rmf (seed_t _seed,
unsigned _octaves, unsigned _octaves,
T _H, value_t _H,
T _offset, value_t _offset,
T _frequency, value_t _frequency,
T _lacunarity, value_t _lacunarity,
T _amplitude, value_t _amplitude,
T _gain): value_t _gain):
base<S,T,B> (_seed, base<B> (_seed,
_octaves, _octaves,
_H, _H,
_frequency, _frequency,
@ -43,9 +43,9 @@ namespace util { namespace noise { namespace fractal {
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
rmf<S,T,B>::rmf (seed_t _seed): rmf<B>::rmf (seed_t _seed):
rmf<S,T,B> (_seed, rmf<B> (_seed,
DEFAULT_OCTAVES, DEFAULT_OCTAVES,
DEFAULT_H, DEFAULT_H,
DEFAULT_FREQUENCY, DEFAULT_FREQUENCY,
@ -59,15 +59,15 @@ namespace util { namespace noise { namespace fractal {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// we use the name 'amplitude' instead of musgrave's 'gain'. // we use the name 'amplitude' instead of musgrave's 'gain'.
// assumes basis distribution [-1,1] and offset ~= 1 // assumes basis distribution [-1,1] and offset ~= 1
template <size_t S, typename T, typename B> template <class B>
T typename rmf<B>::value_t
rmf<S,T,B>::operator() (point<S,T> p) const rmf<B>::operator() (point_t p) const
{ {
T scale = this->m_invAH; value_t scale = this->m_invAH;
T signal = 0; value_t signal = 0;
T result = 0; value_t result = 0;
T weight = 1; value_t weight = 1;
p *= this->m_frequency; p *= this->m_frequency;
@ -92,7 +92,7 @@ namespace util { namespace noise { namespace fractal {
scale *= this->m_invGH; scale *= this->m_invGH;
p += PI<T>; p += PI<value_t>;
p *= this->m_lacunarity; p *= this->m_lacunarity;
} }
@ -101,18 +101,18 @@ namespace util { namespace noise { namespace fractal {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template <size_t S, typename T, typename B> template <class B>
T typename rmf<B>::value_t
rmf<S,T,B>::offset (void) const rmf<B>::offset (void) const
{ {
return m_offset; return m_offset;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename B> template <class B>
T typename rmf<B>::value_t
rmf<S,T,B>::offset (T _offset) rmf<B>::offset (value_t _offset)
{ {
return m_offset = _offset; return m_offset = _offset;
} }

View File

@ -18,6 +18,5 @@
#include "../basis/runtime.hpp" #include "../basis/runtime.hpp"
template struct util::noise::fractal::runtime< template struct util::noise::fractal::runtime<
2,float,
util::noise::basis::runtime<2,float> util::noise::basis::runtime<2,float>
>; >;

View File

@ -19,20 +19,15 @@
#define __UTIL_NOISE_FRACTAL_RUNTIME_HPP #define __UTIL_NOISE_FRACTAL_RUNTIME_HPP
#include "base.hpp" #include "base.hpp"
#include "../../point.hpp"
#include "../../range.hpp"
#include <memory> #include <memory>
namespace util { namespace noise { namespace fractal { namespace util { namespace noise { namespace fractal {
template < template <class B>
size_t S, // probe point dimensionality
typename T, // probe point value_type
typename B // generating basis function
>
struct runtime { struct runtime {
public: public:
using seed_t = uint64_t; using value_t = typename B::value_t;
using point_t = typename B::point_t;
runtime (seed_t) { } runtime (seed_t) { }
runtime () = default; runtime () = default;
@ -41,25 +36,25 @@ namespace util { namespace noise { namespace fractal {
runtime& operator= (const runtime&) = delete; runtime& operator= (const runtime&) = delete;
// basis functions // basis functions
T operator () (point<S,T> p) const { return (*m_child) (p); } value_t operator () (point_t p) const { return (*m_child) (p); }
unsigned octaves (void) const { return m_child->octaves (); } unsigned octaves (void) const { return m_child->octaves (); }
unsigned octaves (unsigned _octaves) { return m_child->octaves (_octaves); } unsigned octaves (unsigned _octaves) { return m_child->octaves (_octaves); }
T H (void) const { return m_child->H (); } value_t H (void) const { return m_child->H (); }
T H (T _H) { return m_child->H (_H); } value_t H (value_t _H) { return m_child->H (_H); }
T frequency (void) const { return m_child->frequency (); } value_t frequency (void) const { return m_child->frequency (); }
T frequency (T _frequency) { return m_child->frequency (_frequency); } value_t frequency (value_t _frequency) { return m_child->frequency (_frequency); }
T lacunarity (void) const { return m_child->lacunarity (); } value_t lacunarity (void) const { return m_child->lacunarity (); }
T lacunarity (T _lacunarity) { return m_child->lacunarity (_lacunarity); } value_t lacunarity (value_t _lacunarity) { return m_child->lacunarity (_lacunarity); }
T amplitude (void) const { return m_child->amplitude (); } value_t amplitude (void) const { return m_child->amplitude (); }
T amplitude (T _amplitude) { return m_child->amplitude (_amplitude); } value_t amplitude (value_t _amplitude) { return m_child->amplitude (_amplitude); }
T gain (void) const { return m_child->gain (); } value_t gain (void) const { return m_child->gain (); }
T gain (T _gain) { return m_child->gain (_gain); } value_t gain (value_t _gain) { return m_child->gain (_gain); }
B& basis (void) { return m_child->basis (); } B& basis (void) { return m_child->basis (); }
const B& basis (void) const { return m_child->basis (); } const B& basis (void) const { return m_child->basis (); }
@ -71,25 +66,25 @@ namespace util { namespace noise { namespace fractal {
struct base { struct base {
virtual ~base () = default; virtual ~base () = default;
virtual T operator() (util::point<S,T>) = 0; virtual value_t operator() (point_t) = 0;
virtual unsigned octaves (void) const = 0; virtual unsigned octaves (void) const = 0;
virtual unsigned octaves (unsigned) = 0; virtual unsigned octaves (unsigned) = 0;
virtual T H (void) const = 0; virtual value_t H (void) const = 0;
virtual T H (T) = 0; virtual value_t H (value_t) = 0;
virtual T frequency (void) const = 0; virtual value_t frequency (void) const = 0;
virtual T frequency (T) = 0; virtual value_t frequency (value_t) = 0;
virtual T lacunarity (void) const = 0; virtual value_t lacunarity (void) const = 0;
virtual T lacunarity (T) = 0; virtual value_t lacunarity (value_t) = 0;
virtual T amplitude (void) const = 0; virtual value_t amplitude (void) const = 0;
virtual T amplitude (T) = 0; virtual value_t amplitude (value_t) = 0;
virtual T gain (void) const = 0; virtual value_t gain (void) const = 0;
virtual T gain (T) = 0; virtual value_t gain (value_t) = 0;
virtual B& basis (void) = 0; virtual B& basis (void) = 0;
virtual const B& basis (void) const = 0; virtual const B& basis (void) const = 0;
@ -106,11 +101,11 @@ namespace util { namespace noise { namespace fractal {
child (seed_t _seed, child (seed_t _seed,
unsigned _octaves, unsigned _octaves,
T _H, value_t _H,
T _frequency, value_t _frequency,
T _lacunarity, value_t _lacunarity,
T _amplitude, value_t _amplitude,
T _gain): value_t _gain):
data (_seed, data (_seed,
_octaves, _octaves,
_H, _H,
@ -120,25 +115,25 @@ namespace util { namespace noise { namespace fractal {
_gain) _gain)
{ ; } { ; }
T operator() (util::point<S,T> p) override { return data (p); } value_t operator() (point_t p) override { return data (p); }
unsigned octaves (void) const override { return data.octaves (); } unsigned octaves (void) const override { return data.octaves (); }
unsigned octaves (unsigned _octaves) override { return data.octaves (_octaves); } unsigned octaves (unsigned _octaves) override { return data.octaves (_octaves); }
T H (void) const override { return data.H (); } value_t H (void) const override { return data.H (); }
T H (T _H) override { return data.H (_H); } value_t H (value_t _H) override { return data.H (_H); }
T frequency (void) const override { return data.frequency (); } value_t frequency (void) const override { return data.frequency (); }
T frequency (T _frequency) override { return data.frequency (_frequency); } value_t frequency (value_t _frequency) override { return data.frequency (_frequency); }
T lacunarity (void) const override { return data.lacunarity (); } value_t lacunarity (void) const override { return data.lacunarity (); }
T lacunarity (T _lacunarity) override { return data.lacunarity (_lacunarity); } value_t lacunarity (value_t _lacunarity) override { return data.lacunarity (_lacunarity); }
T amplitude (void) const override { return data.amplitude (); } value_t amplitude (void) const override { return data.amplitude (); }
T amplitude (T _amplitude) override { return data.amplitude (_amplitude); } value_t amplitude (value_t _amplitude) override { return data.amplitude (_amplitude); }
T gain (void) const override { return data.gain (); } value_t gain (void) const override { return data.gain (); }
T gain (T _gain) override { return data.gain (_gain); } value_t gain (value_t _gain) override { return data.gain (_gain); }
B& basis (void) override { return data.basis (); } B& basis (void) override { return data.basis (); }
const B& basis (void) const override { return data.basis (); } const B& basis (void) const override { return data.basis (); }

View File

@ -11,7 +11,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
* Copyright 2011 Danny Robson <danny@nerdcruft.net> * Copyright 2011-2015 Danny Robson <danny@nerdcruft.net>
*/ */
#include "lerp.hpp" #include "lerp.hpp"
@ -21,25 +21,17 @@
#include <cmath> #include <cmath>
using util::lerp::linear;
//----------------------------------------------------------------------------- using util::lerp::cosine;
template <typename T> using util::lerp::cubic;
T using util::lerp::quintic;
util::lerp::sigmoid (T val) using util::lerp::truncate;
{
static_assert (std::is_floating_point<T>::value,
"lerp is only defined for floating types");
return -1 + 2 / (1 + std::exp (-2 * val));
}
template float util::lerp::sigmoid (float);
template double util::lerp::sigmoid (double);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <typename T>
T T
util::lerp::trunc (T a, T, T weight) truncate<T>::operator() (T a, T, T weight)
{ {
static_assert (std::is_floating_point<T>::value, static_assert (std::is_floating_point<T>::value,
"lerp is only defined for floating types"); "lerp is only defined for floating types");
@ -50,14 +42,14 @@ util::lerp::trunc (T a, T, T weight)
return a; return a;
} }
template float util::lerp::trunc (float, float, float); template struct util::lerp::truncate<float>;
template double util::lerp::trunc (double, double, double); template struct util::lerp::truncate<double>;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <typename T>
T T
util::lerp::linear (T a, T b, T weight) linear<T>::operator() (T a, T b, T weight)
{ {
static_assert (std::is_floating_point<T>::value, static_assert (std::is_floating_point<T>::value,
"lerp is only defined for floating types"); "lerp is only defined for floating types");
@ -66,14 +58,14 @@ util::lerp::linear (T a, T b, T weight)
return a * (1 - weight) + b * weight; return a * (1 - weight) + b * weight;
} }
template float util::lerp::linear (float, float, float); template struct util::lerp::linear<float>;
template double util::lerp::linear (double, double, double); template struct util::lerp::linear<double>;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <typename T>
T T
util::lerp::cosine (T a, T b, T weight) cosine<T>::operator() (T a, T b, T weight)
{ {
static_assert (std::is_floating_point<T>::value, static_assert (std::is_floating_point<T>::value,
"lerp is only defined for floating types"); "lerp is only defined for floating types");
@ -83,14 +75,14 @@ util::lerp::cosine (T a, T b, T weight)
return a * (1 - t) + b * t; return a * (1 - t) + b * t;
} }
template float util::lerp::cosine (float, float, float); template struct util::lerp::cosine<float>;
template double util::lerp::cosine (double, double, double); template struct util::lerp::cosine<double>;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <typename T>
T T
util::lerp::cubic (T a, T b, T weight) cubic<T>::operator() (T a, T b, T weight)
{ {
static_assert (std::is_floating_point<T>::value, static_assert (std::is_floating_point<T>::value,
"lerp is only defined for floating types"); "lerp is only defined for floating types");
@ -101,14 +93,14 @@ util::lerp::cubic (T a, T b, T weight)
return a * (1 - t) + b * t; return a * (1 - t) + b * t;
} }
template float util::lerp::cubic (float, float, float); template struct util::lerp::cubic<float>;
template double util::lerp::cubic (double, double, double); template struct util::lerp::cubic<double>;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <typename T>
T T
util::lerp::quintic (T a, T b, T weight) quintic<T>::operator() (T a, T b, T weight)
{ {
static_assert (std::is_floating_point<T>::value, static_assert (std::is_floating_point<T>::value,
"lerp is only defined for floating types"); "lerp is only defined for floating types");
@ -119,6 +111,5 @@ util::lerp::quintic (T a, T b, T weight)
return a * (1 - t) + b * t; return a * (1 - t) + b * t;
} }
template struct util::lerp::quintic<float>;
template float util::lerp::quintic (float, float, float); template struct util::lerp::quintic<double>;
template double util::lerp::quintic (double, double, double);

View File

@ -11,20 +11,18 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
* Copyright 2011 Danny Robson <danny@nerdcruft.net> * Copyright 2011-2015 Danny Robson <danny@nerdcruft.net>
*/ */
#ifndef __UTIL_NOISE_LERP_HPP #ifndef __UTIL_NOISE_LERP_HPP
#define __UTIL_NOISE_LERP_HPP #define __UTIL_NOISE_LERP_HPP
namespace util { namespace lerp { namespace util { namespace lerp {
template <typename T> T sigmoid (T val); template <typename T> struct linear { T operator() (T, T, T weight); };
template <typename T> struct cosine { T operator() (T, T, T weight); };
template <typename T> T linear (T a, T b, T weight); template <typename T> struct cubic { T operator() (T, T, T weight); };
template <typename T> T cosine (T a, T b, T weight); template <typename T> struct quintic { T operator() (T, T, T weight); };
template <typename T> T cubic (T a, T b, T weight); template <typename T> struct truncate { T operator() (T, T, T weight); };
template <typename T> T quintic (T a, T b, T weight);
template <typename T> T trunc (T a, T b, T weight);
} } } }
#endif #endif

View File

@ -20,6 +20,12 @@
#include "./rand/permute.hpp" #include "./rand/permute.hpp"
#include "./rand/hash.hpp" #include "./rand/hash.hpp"
#include <cstdint>
namespace util { namespace noise {
using seed_t = uint64_t;
} }
namespace util { namespace noise { namespace rand { namespace util { namespace noise { namespace rand {
/// generate a uniform random floating point in the range [0, 1] from a seed and vector /// generate a uniform random floating point in the range [0, 1] from a seed and vector
template < template <

View File

@ -30,23 +30,27 @@ namespace util { namespace noise {
/// nothing will explode if it isn't, but you'll see strong directional /// nothing will explode if it isn't, but you'll see strong directional
/// artefacts with higher scaling factors. /// artefacts with higher scaling factors.
template < template <
size_t S, // dimension
typename T, // value_type
typename D, // data fractal typename D, // data fractal
typename P // pertubation fractal typename P // pertubation fractal
> >
struct turbulence { struct turbulence {
static constexpr auto dimension = S; using value_t = typename D::value_t;
using value_type = T; using point_t = typename D::point_t;
using scale_t = vector<point_t::dimension,value_t>;
using seed_t = uint64_t; static constexpr size_t S = D::point_t::dimension;
turbulence (seed_t, vector<S,T> scale); static_assert (std::is_same<typename D::value_t, typename P::value_t>::value,
"data and perturbation value types must match");
static_assert (std::is_same<typename D::point_t, typename P::point_t>::value,
"data and perturbation point types must match");
turbulence (seed_t, scale_t);
seed_t seed (seed_t); seed_t seed (seed_t);
seed_t seed (void) const; seed_t seed (void) const;
constexpr T operator() (point<S,T>) const; constexpr value_t operator() (point_t) const;
D data; D data;
@ -58,7 +62,7 @@ namespace util { namespace noise {
P perturb[S]; P perturb[S];
}; };
vector<S,T> scale; scale_t scale;
}; };
} } } }

View File

@ -24,9 +24,9 @@
namespace util { namespace noise { namespace util { namespace noise {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template <size_t S, typename T, typename D, typename P> template <typename D, typename P>
turbulence<S,T,D,P>::turbulence (seed_t _seed, turbulence<D,P>::turbulence (seed_t _seed,
vector<S,T> _scale): scale_t _scale):
data (_seed), data (_seed),
scale (_scale) scale (_scale)
{ {
@ -35,18 +35,18 @@ namespace util { namespace noise {
} }
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
template <size_t S, typename T, typename D, typename P> template <typename D, typename P>
typename turbulence<S,T,D,P>::seed_t seed_t
turbulence<S,T,D,P>::seed (void) const turbulence<D,P>::seed (void) const
{ {
return data.seed (); return data.seed ();
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <size_t S, typename T, typename D, typename P> template <typename D, typename P>
typename turbulence<S,T,D,P>::seed_t seed_t
turbulence<S,T,D,P>::seed (seed_t _seed) turbulence<D,P>::seed (seed_t _seed)
{ {
auto ret = _seed; auto ret = _seed;
data.seed (_seed); data.seed (_seed);
@ -59,11 +59,11 @@ namespace util { namespace noise {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template <size_t S, typename T, typename D, typename P> template <typename D, typename P>
constexpr T constexpr typename turbulence<D,P>::value_t
turbulence<S,T,D,P>::operator() (point<S,T> p) const turbulence<D,P>::operator() (point_t p) const
{ {
vector<S,T> n; scale_t n;
for (size_t i = 0; i < S; ++i) for (size_t i = 0; i < S; ++i)
n[i] = perturb[i] (p); n[i] = perturb[i] (p);

View File

@ -28,10 +28,27 @@
constexpr size_t S = 2; constexpr size_t S = 2;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
template struct util::noise::fractal::fbm<S,float, util::noise::basis::perlin<S,float,util::lerp::cubic>>; template struct util::noise::fractal::rmf<util::noise::basis::constant<S,float>>;
template struct util::noise::fractal::hmf<S,float, util::noise::basis::value<S,float,util::lerp::cubic>>;
template struct util::noise::fractal::rmf<S,float, util::noise::basis::constant<S,float>>; template struct util::noise::fractal::fbm<
template struct util::noise::fractal::hetero<S,float, util::noise::basis::worley<S,float,S>>; util::noise::basis::perlin<
S,float,util::lerp::cubic,util::noise::basis::gradient
>
>;
template struct util::noise::fractal::fbm<
util::noise::basis::perlin<
S,float,util::lerp::quintic,util::noise::basis::expgrad
>
>;
template struct util::noise::fractal::hmf<
util::noise::basis::value<
S,float,util::lerp::cubic
>
>;
template struct util::noise::fractal::hetero<util::noise::basis::worley<S,float>>;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -223,13 +240,10 @@ main (int argc, char **argv)
#endif #endif
util::noise::turbulence< util::noise::turbulence<
S,float,
util::noise::fractal::runtime< util::noise::fractal::runtime<
S,float,
util::noise::basis::runtime<S,float> util::noise::basis::runtime<S,float>
>, >,
util::noise::fractal::fbm< util::noise::fractal::fbm<
S,float,
util::noise::basis::perlin< util::noise::basis::perlin<
S,float, S,float,
util::lerp::cubic util::lerp::cubic
@ -242,11 +256,11 @@ main (int argc, char **argv)
switch (fractal) { switch (fractal) {
using namespace util::noise; using namespace util::noise;
case FBM: f.reset<fractal::fbm<S,float,basis::runtime<S,float>>> (seed); break; case FBM: f.reset<fractal::fbm<basis::runtime<S,float>>> (seed); break;
case HMF: f.reset<fractal::hmf<S,float,basis::runtime<S,float>>> (seed); break; case HMF: f.reset<fractal::hmf<basis::runtime<S,float>>> (seed); break;
case RMF: f.reset<fractal::rmf<S,float,basis::runtime<S,float>>> (seed); break; case RMF: f.reset<fractal::rmf<basis::runtime<S,float>>> (seed); break;
case HETERO: { case HETERO: {
auto &child = f.reset<fractal::hetero<S,float,basis::runtime<S,float>>> (seed); auto &child = f.reset<fractal::hetero<basis::runtime<S,float>>> (seed);
if (!std::isnan (offset)) if (!std::isnan (offset))
child.offset (offset); child.offset (offset);
break; break;
@ -266,7 +280,7 @@ main (int argc, char **argv)
case CUBIC: b.reset<basis::perlin<S,float,util::lerp::cubic>> (seed); break; case CUBIC: b.reset<basis::perlin<S,float,util::lerp::cubic>> (seed); break;
case QUINTIC: b.reset<basis::perlin<S,float,util::lerp::quintic>> (seed); break; case QUINTIC: b.reset<basis::perlin<S,float,util::lerp::quintic>> (seed); break;
case COSINE: b.reset<basis::perlin<S,float,util::lerp::cosine>> (seed); break; case COSINE: b.reset<basis::perlin<S,float,util::lerp::cosine>> (seed); break;
case TRUNC: b.reset<basis::perlin<S,float,util::lerp::trunc>> (seed); break; case TRUNC: b.reset<basis::perlin<S,float,util::lerp::truncate>> (seed); break;
default: default:
unreachable (); unreachable ();
@ -276,11 +290,16 @@ main (int argc, char **argv)
case EXPDIST: { case EXPDIST: {
switch (lerp) { switch (lerp) {
case LINEAR: b.reset<basis::perlin<S,float,util::lerp::linear,basis::expgrad>> (seed); break; case LINEAR: b.reset<
basis::perlin<
S,float,util::lerp::linear,basis::expgrad
>
> (seed); break;
case CUBIC: b.reset<basis::perlin<S,float,util::lerp::cubic,basis::expgrad>> (seed); break; case CUBIC: b.reset<basis::perlin<S,float,util::lerp::cubic,basis::expgrad>> (seed); break;
case QUINTIC: b.reset<basis::perlin<S,float,util::lerp::quintic,basis::expgrad>> (seed); break; case QUINTIC: b.reset<basis::perlin<S,float,util::lerp::quintic,basis::expgrad>> (seed); break;
case COSINE: b.reset<basis::perlin<S,float,util::lerp::cosine,basis::expgrad>> (seed); break; case COSINE: b.reset<basis::perlin<S,float,util::lerp::cosine,basis::expgrad>> (seed); break;
case TRUNC: b.reset<basis::perlin<S,float,util::lerp::trunc,basis::expgrad>> (seed); break; case TRUNC: b.reset<basis::perlin<S,float,util::lerp::truncate,basis::expgrad>> (seed); break;
default: default:
unreachable (); unreachable ();
@ -294,7 +313,7 @@ main (int argc, char **argv)
case CUBIC: b.reset<basis::value<S,float,util::lerp::cubic>> (seed); break; case CUBIC: b.reset<basis::value<S,float,util::lerp::cubic>> (seed); break;
case QUINTIC: b.reset<basis::value<S,float,util::lerp::quintic>> (seed); break; case QUINTIC: b.reset<basis::value<S,float,util::lerp::quintic>> (seed); break;
case COSINE: b.reset<basis::value<S,float,util::lerp::cosine>> (seed); break; case COSINE: b.reset<basis::value<S,float,util::lerp::cosine>> (seed); break;
case TRUNC: b.reset<basis::value<S,float,util::lerp::trunc>> (seed); break; case TRUNC: b.reset<basis::value<S,float,util::lerp::truncate>> (seed); break;
default: default:
unreachable (); unreachable ();