noise/basis: extract basis into seperate units
This commit is contained in:
parent
c9812f7c78
commit
78f61af84c
@ -133,8 +133,13 @@ UTIL_FILES = \
|
|||||||
net/types.cpp \
|
net/types.cpp \
|
||||||
net/types.hpp \
|
net/types.hpp \
|
||||||
nocopy.hpp \
|
nocopy.hpp \
|
||||||
noise/basis.cpp \
|
|
||||||
noise/basis.hpp \
|
noise/basis.hpp \
|
||||||
|
noise/basis/value.cpp \
|
||||||
|
noise/basis/value.hpp \
|
||||||
|
noise/basis/perlin.cpp \
|
||||||
|
noise/basis/perlin.hpp \
|
||||||
|
noise/basis/worley.cpp \
|
||||||
|
noise/basis/worley.hpp \
|
||||||
noise.cpp \
|
noise.cpp \
|
||||||
noise/fractal.cpp \
|
noise/fractal.cpp \
|
||||||
noise/fractal.hpp \
|
noise/fractal.hpp \
|
||||||
|
311
noise/basis.cpp
311
noise/basis.cpp
@ -1,311 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "noise/basis.hpp"
|
|
||||||
#include "noise/lut.hpp"
|
|
||||||
|
|
||||||
#include "../debug.hpp"
|
|
||||||
#include "../point.hpp"
|
|
||||||
#include "../random.hpp"
|
|
||||||
#include "../vector.hpp"
|
|
||||||
#include "../hash/murmur/murmur2.hpp"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
using util::noise::basis;
|
|
||||||
using util::noise::value;
|
|
||||||
using util::noise::gradient;
|
|
||||||
using util::noise::cellular;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Generate a type from [-UNIT..UNIT]
|
|
||||||
template <typename T>
|
|
||||||
T
|
|
||||||
gen_scalar (util::point<2,T> p, uint64_t seed)
|
|
||||||
{
|
|
||||||
using util::hash::murmur2::mix;
|
|
||||||
|
|
||||||
T v = mix (seed, mix (uint64_t (p.y), uint64_t (p.x))) & 0xffff;
|
|
||||||
v = v / T{0xffff} * 2 - 1;
|
|
||||||
|
|
||||||
CHECK_GE (v, T{0});
|
|
||||||
CHECK_LE (v, T{1});
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <typename T>
|
|
||||||
util::vector<2,T>
|
|
||||||
gen_vector (util::point<2,T> p, uint64_t seed)
|
|
||||||
{
|
|
||||||
using util::hash::murmur2::mix;
|
|
||||||
|
|
||||||
auto u = mix (seed, mix (uint64_t (p.x), uint64_t (p.y)));
|
|
||||||
auto v = mix (u, seed);
|
|
||||||
|
|
||||||
auto r = util::vector<2,T> {
|
|
||||||
(u & 0xffff) / T{0xffff},
|
|
||||||
(v & 0xffff) / T{0xffff}
|
|
||||||
} * 2 - 1;
|
|
||||||
|
|
||||||
CHECK_GE (r, T{-1});
|
|
||||||
CHECK_LE (r, T{ 1});
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T>
|
|
||||||
basis<T>::basis (seed_t _seed):
|
|
||||||
seed (_seed)
|
|
||||||
{ ; }
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <typename T>
|
|
||||||
basis<T>::basis ():
|
|
||||||
seed (util::random<seed_t> ())
|
|
||||||
{ ; }
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <typename T>
|
|
||||||
basis<T>::~basis ()
|
|
||||||
{ ; }
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <typename T>
|
|
||||||
T
|
|
||||||
basis<T>::operator() (util::point<2,T>) const
|
|
||||||
{
|
|
||||||
unreachable ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
namespace util { namespace noise {
|
|
||||||
template struct basis<float>;
|
|
||||||
template struct basis<double>;
|
|
||||||
} }
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T, util::noise::lerp_t<T> L>
|
|
||||||
value<T,L>::value (seed_t _seed):
|
|
||||||
basis<T> (_seed)
|
|
||||||
{ ; }
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <typename T, util::noise::lerp_t<T> L>
|
|
||||||
value<T,L>::value ()
|
|
||||||
{ ; }
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <typename T, util::noise::lerp_t<T> L>
|
|
||||||
util::range<T>
|
|
||||||
value<T,L>::bounds (void) const
|
|
||||||
{
|
|
||||||
return { -1, 1 };
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <typename T, util::noise::lerp_t<T> L>
|
|
||||||
T
|
|
||||||
value<T,L>::operator() (util::point<2,T> p) const
|
|
||||||
{
|
|
||||||
auto p_int = p.template cast<intmax_t> ();
|
|
||||||
auto p_rem = p - p_int;
|
|
||||||
|
|
||||||
// Shift the coordinate system down a little to ensure we get unit weights
|
|
||||||
// for the lerp. It's better to do this than abs the fractional portion so
|
|
||||||
// we don't get reflections along the origin.
|
|
||||||
if (p.x < 0) { p_rem.x = 1 + p_rem.x; p_int.x -= 1; }
|
|
||||||
if (p.y < 0) { p_rem.y = 1 + p_rem.y; p_int.y -= 1; }
|
|
||||||
|
|
||||||
// Generate the four corner values
|
|
||||||
T p0 = gen_scalar<T> (p_int + util::vector<2,T>{ 0, 0 }, this->seed);
|
|
||||||
T p1 = gen_scalar<T> (p_int + util::vector<2,T>{ 1, 0 }, this->seed);
|
|
||||||
T p2 = gen_scalar<T> (p_int + util::vector<2,T>{ 0, 0 }, this->seed);
|
|
||||||
T p3 = gen_scalar<T> (p_int + util::vector<2,T>{ 1, 1 }, this->seed);
|
|
||||||
|
|
||||||
// Interpolate on one dimension, then the other.
|
|
||||||
return L (L (p0, p1, p_rem.x),
|
|
||||||
L (p2, p3, p_rem.x),
|
|
||||||
p_rem.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
namespace util { namespace noise {
|
|
||||||
template struct value<float, lerp::trunc>;
|
|
||||||
template struct value<float, lerp::linear>;
|
|
||||||
template struct value<float, lerp::cubic>;
|
|
||||||
template struct value<float, lerp::quintic>;
|
|
||||||
|
|
||||||
template struct value<double, lerp::trunc>;
|
|
||||||
template struct value<double, lerp::linear>;
|
|
||||||
template struct value<double, lerp::cubic>;
|
|
||||||
template struct value<double, lerp::quintic>;
|
|
||||||
} }
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T, util::noise::lerp_t<T> L>
|
|
||||||
gradient<T,L>::gradient (seed_t _seed):
|
|
||||||
basis<T> (_seed)
|
|
||||||
{ ; }
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <typename T, util::noise::lerp_t<T> L>
|
|
||||||
gradient<T,L>::gradient ()
|
|
||||||
{ ; }
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <typename T, util::noise::lerp_t<T> L>
|
|
||||||
util::range<T>
|
|
||||||
gradient<T,L>::bounds (void) const
|
|
||||||
{ return { -std::sqrt(T{2}) / 2, std::sqrt (T{2}) / 2 }; }
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <typename T, util::noise::lerp_t<T> L>
|
|
||||||
T
|
|
||||||
gradient<T,L>::operator() (util::point<2,T> p) const
|
|
||||||
{
|
|
||||||
auto p_int = p.template cast<intmax_t> ();
|
|
||||||
auto p_rem = p - p_int;
|
|
||||||
|
|
||||||
// Shift the coordinate system down a little to ensure we get unit weights
|
|
||||||
// for the lerp. It's better to do this than abs the fractional portion so
|
|
||||||
// we don't get reflections along the origin.
|
|
||||||
if (p.x < 0) { p_rem.x = 1 + p_rem.x; p_int.x -= 1; }
|
|
||||||
if (p.y < 0) { p_rem.y = 1 + p_rem.y; p_int.y -= 1; }
|
|
||||||
|
|
||||||
// Generate the four corner values. It's not strictly necessary to
|
|
||||||
// normalise the values, but we get a more consistent and visually
|
|
||||||
// appealing range of outputs with normalised values.
|
|
||||||
auto p0 = gen_vector<T> (p_int + util::vector<2,T> { 0, 0 }, this->seed).normalise ();
|
|
||||||
auto p1 = gen_vector<T> (p_int + util::vector<2,T> { 1, 0 }, this->seed).normalise ();
|
|
||||||
auto p2 = gen_vector<T> (p_int + util::vector<2,T> { 0, 1 }, this->seed).normalise ();
|
|
||||||
auto p3 = gen_vector<T> (p_int + util::vector<2,T> { 1, 1 }, this->seed).normalise ();
|
|
||||||
|
|
||||||
T v0 = p0.x * p_rem.x + p0.y * p_rem.y;
|
|
||||||
T v1 = p1.x * (p_rem.x - 1) + p1.y * p_rem.y;
|
|
||||||
T v2 = p2.x * p_rem.x + p2.y * (p_rem.y - 1);
|
|
||||||
T v3 = p3.x * (p_rem.x - 1) + p3.y * (p_rem.y - 1);
|
|
||||||
|
|
||||||
auto L0 = L (v0, v1, p_rem.x);
|
|
||||||
auto L1 = L (v2, v3, p_rem.x);
|
|
||||||
auto L_ = L (L0, L1, p_rem.y);
|
|
||||||
return L_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
namespace util {
|
|
||||||
namespace noise {
|
|
||||||
template struct gradient<float, lerp::linear>;
|
|
||||||
template struct gradient<float, lerp::cubic>;
|
|
||||||
template struct gradient<float, lerp::quintic>;
|
|
||||||
|
|
||||||
template struct gradient<double, lerp::linear>;
|
|
||||||
template struct gradient<double, lerp::cubic>;
|
|
||||||
template struct gradient<double, lerp::quintic>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T>
|
|
||||||
cellular<T>::cellular (seed_t _seed):
|
|
||||||
basis<T> (_seed)
|
|
||||||
{ ; }
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <typename T>
|
|
||||||
cellular<T>::cellular ()
|
|
||||||
{ ; }
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <typename T>
|
|
||||||
util::range<T>
|
|
||||||
cellular<T>::bounds (void) const
|
|
||||||
{ return { 0.0, 1.5 }; }
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <typename T>
|
|
||||||
T
|
|
||||||
cellular<T>::operator() (util::point<2,T> p) const
|
|
||||||
{
|
|
||||||
auto p_int = p.template cast<intmax_t> ();
|
|
||||||
auto p_rem = p - p_int;
|
|
||||||
|
|
||||||
// Generate the four corner values. It's not strictly necessary to
|
|
||||||
// normalise the values, but we get a more consistent and visually
|
|
||||||
// appealing range of outputs with normalised values.
|
|
||||||
if (p.x < 0) { p_rem.x = 1 + p_rem.x; p_int.x -= 1; }
|
|
||||||
if (p.y < 0) { p_rem.y = 1 + p_rem.y; p_int.y -= 1; }
|
|
||||||
|
|
||||||
// +---+---+---+
|
|
||||||
// | 0 | 1 | 2 |
|
|
||||||
// +---+---+---+
|
|
||||||
// | 3 | 4 | 5 |
|
|
||||||
// +---+-------+
|
|
||||||
// | 6 | 7 | 8 |
|
|
||||||
// +---+---+---+
|
|
||||||
|
|
||||||
T distances[9] = { std::numeric_limits<T>::quiet_NaN () };
|
|
||||||
T *cursor = distances;
|
|
||||||
|
|
||||||
for (signed y_off = -1; y_off <= 1 ; ++y_off)
|
|
||||||
for (signed x_off = -1; x_off <= 1; ++x_off) {
|
|
||||||
auto pos = vector<2,T> (T (x_off), T (y_off));
|
|
||||||
auto off = gen_vector<T> (p_int + pos, this->seed);
|
|
||||||
off += T{1};
|
|
||||||
off /= T{2};
|
|
||||||
|
|
||||||
CHECK (off.x >= 0 && off.x <= 1);
|
|
||||||
CHECK (off.y >= 0 && off.y <= 1);
|
|
||||||
|
|
||||||
pos += off;
|
|
||||||
*cursor++ = pos.difference2 (p_rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::sort (std::begin (distances), std::end (distances));
|
|
||||||
CHECK_GE (distances[0], 0);
|
|
||||||
CHECK (bounds ().contains (distances[0]));
|
|
||||||
return distances[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
namespace util { namespace noise {
|
|
||||||
template struct cellular<float>;
|
|
||||||
template struct cellular<double>;
|
|
||||||
} }
|
|
@ -17,67 +17,11 @@
|
|||||||
#ifndef __UTIL_NOISE_BASIS_HPP
|
#ifndef __UTIL_NOISE_BASIS_HPP
|
||||||
#define __UTIL_NOISE_BASIS_HPP
|
#define __UTIL_NOISE_BASIS_HPP
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdint>
|
||||||
#include "lerp.hpp"
|
|
||||||
#include "../point.hpp"
|
|
||||||
#include "../range.hpp"
|
|
||||||
|
|
||||||
namespace util { namespace noise {
|
namespace util { namespace noise {
|
||||||
template <typename T> using lerp_t = T (*)(T,T,T);
|
template <typename T> using lerp_t = T (*)(T,T,T);
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct basis {
|
|
||||||
typedef uint64_t seed_t;
|
typedef uint64_t seed_t;
|
||||||
|
|
||||||
basis (seed_t);
|
|
||||||
basis ();
|
|
||||||
virtual ~basis ();
|
|
||||||
|
|
||||||
seed_t seed;
|
|
||||||
|
|
||||||
virtual range<T> bounds (void) const = 0;
|
|
||||||
virtual T operator() (util::point<2,T>) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/// Single value per grid space
|
|
||||||
template <typename T, lerp_t<T>>
|
|
||||||
struct value : public basis<T> {
|
|
||||||
using seed_t = typename basis<T>::seed_t;
|
|
||||||
|
|
||||||
value (seed_t);
|
|
||||||
value ();
|
|
||||||
|
|
||||||
virtual range<T> bounds (void) const final;
|
|
||||||
virtual T operator() (util::point<2,T>) const final;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/// Perlin: interpolated value across each grid space
|
|
||||||
template <typename T, lerp_t<T> L>
|
|
||||||
struct gradient : public basis<T> {
|
|
||||||
using seed_t = typename basis<T>::seed_t;
|
|
||||||
|
|
||||||
gradient (seed_t);
|
|
||||||
gradient ();
|
|
||||||
|
|
||||||
virtual range<T> bounds (void) const final;
|
|
||||||
virtual T operator() (util::point<2,T>) const final;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/// Cellular/Worley/Vornoi of order-1
|
|
||||||
template <typename T>
|
|
||||||
struct cellular : public basis<T> {
|
|
||||||
using seed_t = typename basis<T>::seed_t;
|
|
||||||
|
|
||||||
cellular (seed_t);
|
|
||||||
cellular ();
|
|
||||||
|
|
||||||
virtual range<T> bounds (void) const final;
|
|
||||||
virtual T operator() (util::point<2,T>) const final;
|
|
||||||
};
|
|
||||||
} }
|
} }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
118
noise/basis/perlin.cpp
Normal file
118
noise/basis/perlin.cpp
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* 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 <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "perlin.hpp"
|
||||||
|
|
||||||
|
#include "../../hash/murmur/murmur2.hpp"
|
||||||
|
|
||||||
|
using util::noise::basis::perlin;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
util::vector<2,T>
|
||||||
|
generate (util::point<2,T> p, uint64_t seed)
|
||||||
|
{
|
||||||
|
using util::hash::murmur2::mix;
|
||||||
|
|
||||||
|
auto u = mix (seed, mix (uint64_t (p.x), uint64_t (p.y)));
|
||||||
|
auto v = mix (u, seed);
|
||||||
|
|
||||||
|
auto r = util::vector<2,T> {
|
||||||
|
(u & 0xffff) / T{0xffff},
|
||||||
|
(v & 0xffff) / T{0xffff}
|
||||||
|
} * 2 - 1;
|
||||||
|
|
||||||
|
CHECK_GE (r, T{-1});
|
||||||
|
CHECK_LE (r, T{ 1});
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename T, util::noise::lerp_t<T> L>
|
||||||
|
perlin<T,L>::perlin (seed_t _seed):
|
||||||
|
seed (_seed)
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template <typename T, util::noise::lerp_t<T> L>
|
||||||
|
perlin<T,L>::perlin ():
|
||||||
|
seed (time (nullptr))
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template <typename T, util::noise::lerp_t<T> L>
|
||||||
|
util::range<T>
|
||||||
|
perlin<T,L>::bounds (void) const
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
-std::sqrt (T{2}) / 2,
|
||||||
|
std::sqrt (T{2}) / 2
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template <typename T, util::noise::lerp_t<T> L>
|
||||||
|
T
|
||||||
|
perlin<T,L>::operator() (util::point<2,T> p) const
|
||||||
|
{
|
||||||
|
auto p_int = p.template cast<intmax_t> ();
|
||||||
|
auto p_rem = p - p_int;
|
||||||
|
|
||||||
|
// Shift the coordinate system down a little to ensure we get unit weights
|
||||||
|
// for the lerp. It's better to do this than abs the fractional portion so
|
||||||
|
// we don't get reflections along the origin.
|
||||||
|
if (p.x < 0) { p_rem.x = 1 + p_rem.x; p_int.x -= 1; }
|
||||||
|
if (p.y < 0) { p_rem.y = 1 + p_rem.y; p_int.y -= 1; }
|
||||||
|
|
||||||
|
// Generate the four corner values. It's not strictly necessary to
|
||||||
|
// normalise the values, but we get a more consistent and visually
|
||||||
|
// appealing range of outputs with normalised values.
|
||||||
|
auto p0 = generate<T> (p_int + util::vector<2,T> { 0, 0 }, this->seed).normalise ();
|
||||||
|
auto p1 = generate<T> (p_int + util::vector<2,T> { 1, 0 }, this->seed).normalise ();
|
||||||
|
auto p2 = generate<T> (p_int + util::vector<2,T> { 0, 1 }, this->seed).normalise ();
|
||||||
|
auto p3 = generate<T> (p_int + util::vector<2,T> { 1, 1 }, this->seed).normalise ();
|
||||||
|
|
||||||
|
T v0 = p0.x * p_rem.x + p0.y * p_rem.y;
|
||||||
|
T v1 = p1.x * (p_rem.x - 1) + p1.y * p_rem.y;
|
||||||
|
T v2 = p2.x * p_rem.x + p2.y * (p_rem.y - 1);
|
||||||
|
T v3 = p3.x * (p_rem.x - 1) + p3.y * (p_rem.y - 1);
|
||||||
|
|
||||||
|
auto L0 = L (v0, v1, p_rem.x);
|
||||||
|
auto L1 = L (v2, v3, p_rem.x);
|
||||||
|
auto L_ = L (L0, L1, p_rem.y);
|
||||||
|
return L_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
#include "../lerp.hpp"
|
||||||
|
|
||||||
|
namespace util { namespace noise { namespace basis {
|
||||||
|
template struct perlin<float, lerp::linear>;
|
||||||
|
template struct perlin<float, lerp::cubic>;
|
||||||
|
template struct perlin<float, lerp::quintic>;
|
||||||
|
|
||||||
|
template struct perlin<double, lerp::linear>;
|
||||||
|
template struct perlin<double, lerp::cubic>;
|
||||||
|
template struct perlin<double, lerp::quintic>;
|
||||||
|
} } }
|
39
noise/basis/perlin.hpp
Normal file
39
noise/basis/perlin.hpp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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 <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __UTIL_NOISE_BASIS_PERLIN_HPP
|
||||||
|
#define __UTIL_NOISE_BASIS_PERLIN_HPP
|
||||||
|
|
||||||
|
#include "../basis.hpp"
|
||||||
|
#include "../../point.hpp"
|
||||||
|
#include "../../range.hpp"
|
||||||
|
|
||||||
|
namespace util { namespace noise { namespace basis {
|
||||||
|
/// Perlin: interpolated value across each grid space
|
||||||
|
template <typename T, lerp_t<T> L>
|
||||||
|
struct perlin {
|
||||||
|
perlin (seed_t);
|
||||||
|
perlin ();
|
||||||
|
|
||||||
|
range<T> bounds (void) const;
|
||||||
|
T operator() (util::point<2,T>) const;
|
||||||
|
|
||||||
|
seed_t seed;
|
||||||
|
};
|
||||||
|
} } }
|
||||||
|
|
||||||
|
#endif
|
105
noise/basis/value.cpp
Normal file
105
noise/basis/value.cpp
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* 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 <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "value.hpp"
|
||||||
|
|
||||||
|
#include "../../hash/murmur/murmur2.hpp"
|
||||||
|
|
||||||
|
using util::noise::basis::value;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Generate a type from [-UNIT..UNIT]
|
||||||
|
template <typename T>
|
||||||
|
T
|
||||||
|
generate (util::point<2,T> p, uint64_t seed)
|
||||||
|
{
|
||||||
|
using util::hash::murmur2::mix;
|
||||||
|
|
||||||
|
T v = mix (seed, mix (uint64_t (p.y), uint64_t (p.x))) & 0xffff;
|
||||||
|
v = v / T{0xffff} * 2 - 1;
|
||||||
|
|
||||||
|
CHECK_GE (v, T{0});
|
||||||
|
CHECK_LE (v, T{1});
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename T, util::noise::lerp_t<T> L>
|
||||||
|
value<T,L>::value (seed_t _seed):
|
||||||
|
seed (_seed)
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template <typename T, util::noise::lerp_t<T> L>
|
||||||
|
value<T,L>::value ():
|
||||||
|
seed (time (nullptr))
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template <typename T, util::noise::lerp_t<T> L>
|
||||||
|
util::range<T>
|
||||||
|
value<T,L>::bounds (void) const
|
||||||
|
{
|
||||||
|
return { -1, 1 };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template <typename T, util::noise::lerp_t<T> L>
|
||||||
|
T
|
||||||
|
value<T,L>::operator() (util::point<2,T> p) const
|
||||||
|
{
|
||||||
|
auto p_int = p.template cast<intmax_t> ();
|
||||||
|
auto p_rem = p - p_int;
|
||||||
|
|
||||||
|
// Shift the coordinate system down a little to ensure we get unit weights
|
||||||
|
// for the lerp. It's better to do this than abs the fractional portion so
|
||||||
|
// we don't get reflections along the origin.
|
||||||
|
if (p.x < 0) { p_rem.x = 1 + p_rem.x; p_int.x -= 1; }
|
||||||
|
if (p.y < 0) { p_rem.y = 1 + p_rem.y; p_int.y -= 1; }
|
||||||
|
|
||||||
|
// Generate the four corner values
|
||||||
|
T p0 = generate<T> (p_int + util::vector<2,T>{ 0, 0 }, this->seed);
|
||||||
|
T p1 = generate<T> (p_int + util::vector<2,T>{ 1, 0 }, this->seed);
|
||||||
|
T p2 = generate<T> (p_int + util::vector<2,T>{ 0, 0 }, this->seed);
|
||||||
|
T p3 = generate<T> (p_int + util::vector<2,T>{ 1, 1 }, this->seed);
|
||||||
|
|
||||||
|
// Interpolate on one dimension, then the other.
|
||||||
|
return L (L (p0, p1, p_rem.x),
|
||||||
|
L (p2, p3, p_rem.x),
|
||||||
|
p_rem.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
#include "../lerp.hpp"
|
||||||
|
|
||||||
|
namespace util { namespace noise { namespace basis {
|
||||||
|
template struct value<float, lerp::trunc>;
|
||||||
|
template struct value<float, lerp::linear>;
|
||||||
|
template struct value<float, lerp::cubic>;
|
||||||
|
template struct value<float, lerp::quintic>;
|
||||||
|
|
||||||
|
template struct value<double, lerp::trunc>;
|
||||||
|
template struct value<double, lerp::linear>;
|
||||||
|
template struct value<double, lerp::cubic>;
|
||||||
|
template struct value<double, lerp::quintic>;
|
||||||
|
} } }
|
39
noise/basis/value.hpp
Normal file
39
noise/basis/value.hpp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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 <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __UTIL_NOISE_BASIS_VALUE_HPP
|
||||||
|
#define __UTIL_NOISE_BASIS_VALUE_HPP
|
||||||
|
|
||||||
|
#include "../basis.hpp"
|
||||||
|
#include "../../range.hpp"
|
||||||
|
#include "../../point.hpp"
|
||||||
|
|
||||||
|
namespace util { namespace noise { namespace basis {
|
||||||
|
/// Single value per grid space
|
||||||
|
template <typename T, lerp_t<T>>
|
||||||
|
struct value {
|
||||||
|
value (seed_t);
|
||||||
|
value ();
|
||||||
|
|
||||||
|
range<T> bounds (void) const;
|
||||||
|
T operator() (util::point<2,T>) const;
|
||||||
|
|
||||||
|
seed_t seed;
|
||||||
|
};
|
||||||
|
} } }
|
||||||
|
|
||||||
|
#endif
|
121
noise/basis/worley.cpp
Normal file
121
noise/basis/worley.cpp
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* 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 <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "worley.hpp"
|
||||||
|
|
||||||
|
#include "../../hash/murmur/murmur2.hpp"
|
||||||
|
|
||||||
|
using util::noise::basis::worley;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
util::vector<2,T>
|
||||||
|
generate (util::point<2,T> p, uint64_t seed)
|
||||||
|
{
|
||||||
|
using util::hash::murmur2::mix;
|
||||||
|
|
||||||
|
auto u = mix (seed, mix (uint64_t (p.x), uint64_t (p.y)));
|
||||||
|
auto v = mix (u, seed);
|
||||||
|
|
||||||
|
auto r = util::vector<2,T> {
|
||||||
|
(u & 0xffff) / T{0xffff},
|
||||||
|
(v & 0xffff) / T{0xffff}
|
||||||
|
} * 2 - 1;
|
||||||
|
|
||||||
|
CHECK_GE (r, T{-1});
|
||||||
|
CHECK_LE (r, T{ 1});
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
worley<T>::worley (seed_t _seed):
|
||||||
|
seed (_seed)
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template <typename T>
|
||||||
|
worley<T>::worley ():
|
||||||
|
seed (time (nullptr))
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template <typename T>
|
||||||
|
util::range<T>
|
||||||
|
worley<T>::bounds (void) const
|
||||||
|
{
|
||||||
|
return { 0.0, 1.5 };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
template <typename T>
|
||||||
|
T
|
||||||
|
worley<T>::operator() (util::point<2,T> p) const
|
||||||
|
{
|
||||||
|
auto p_int = p.template cast<intmax_t> ();
|
||||||
|
auto p_rem = p - p_int;
|
||||||
|
|
||||||
|
// Generate the four corner values. It's not strictly necessary to
|
||||||
|
// normalise the values, but we get a more consistent and visually
|
||||||
|
// appealing range of outputs with normalised values.
|
||||||
|
if (p.x < 0) { p_rem.x = 1 + p_rem.x; p_int.x -= 1; }
|
||||||
|
if (p.y < 0) { p_rem.y = 1 + p_rem.y; p_int.y -= 1; }
|
||||||
|
|
||||||
|
// +---+---+---+
|
||||||
|
// | 0 | 1 | 2 |
|
||||||
|
// +---+---+---+
|
||||||
|
// | 3 | 4 | 5 |
|
||||||
|
// +---+-------+
|
||||||
|
// | 6 | 7 | 8 |
|
||||||
|
// +---+---+---+
|
||||||
|
|
||||||
|
T distances[9] = { std::numeric_limits<T>::quiet_NaN () };
|
||||||
|
T *cursor = distances;
|
||||||
|
|
||||||
|
for (signed y_off = -1; y_off <= 1 ; ++y_off)
|
||||||
|
for (signed x_off = -1; x_off <= 1; ++x_off) {
|
||||||
|
auto pos = vector<2,T> (T (x_off), T (y_off));
|
||||||
|
auto off = generate<T> (p_int + pos, this->seed);
|
||||||
|
off += T{1};
|
||||||
|
off /= T{2};
|
||||||
|
|
||||||
|
CHECK (off.x >= 0 && off.x <= 1);
|
||||||
|
CHECK (off.y >= 0 && off.y <= 1);
|
||||||
|
|
||||||
|
pos += off;
|
||||||
|
*cursor++ = pos.difference2 (p_rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort (std::begin (distances), std::end (distances));
|
||||||
|
CHECK_GE (distances[0], 0);
|
||||||
|
CHECK (bounds ().contains (distances[0]));
|
||||||
|
return distances[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
#include "../lerp.hpp"
|
||||||
|
|
||||||
|
namespace util { namespace noise { namespace basis {
|
||||||
|
template struct worley<float>;
|
||||||
|
template struct worley<double>;
|
||||||
|
} } }
|
37
noise/basis/worley.hpp
Normal file
37
noise/basis/worley.hpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* 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 <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __UTIL_NOISE_BASIS_WORLEY_HPP
|
||||||
|
#define __UTIL_NOISE_BASIS_WORLEY_HPP
|
||||||
|
|
||||||
|
#include "../basis.hpp"
|
||||||
|
#include "../../point.hpp"
|
||||||
|
#include "../../range.hpp"
|
||||||
|
|
||||||
|
namespace util { namespace noise { namespace basis {
|
||||||
|
template <typename T>
|
||||||
|
struct worley {
|
||||||
|
worley (seed_t);
|
||||||
|
worley ();
|
||||||
|
|
||||||
|
range<T> bounds (void) const;
|
||||||
|
T operator() (util::point<2,T>) const;
|
||||||
|
|
||||||
|
seed_t seed;
|
||||||
|
};
|
||||||
|
} } }
|
||||||
|
#endif
|
@ -14,9 +14,14 @@
|
|||||||
* Copyright 2012 Danny Robson <danny@nerdcruft.net>
|
* Copyright 2012 Danny Robson <danny@nerdcruft.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "noise/fractal.hpp"
|
#include "fractal.hpp"
|
||||||
|
|
||||||
#include "debug.hpp"
|
#include "basis/value.hpp"
|
||||||
|
#include "basis/perlin.hpp"
|
||||||
|
#include "basis/worley.hpp"
|
||||||
|
#include "lerp.hpp"
|
||||||
|
|
||||||
|
#include "../debug.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@ -119,19 +124,19 @@ fbm<T,B>::operator() (util::point<2,T> p) const {
|
|||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template struct util::noise::fbm<float, util::noise::cellular<float>>;
|
template struct util::noise::fbm<float, util::noise::basis::worley<float>>;
|
||||||
template struct util::noise::fbm<float, util::noise::gradient<float,util::lerp::linear>>;
|
template struct util::noise::fbm<float, util::noise::basis::perlin<float,util::lerp::linear>>;
|
||||||
template struct util::noise::fbm<float, util::noise::gradient<float,util::lerp::quintic>>;
|
template struct util::noise::fbm<float, util::noise::basis::perlin<float,util::lerp::quintic>>;
|
||||||
template struct util::noise::fbm<float, util::noise::value<float,util::lerp::trunc>>;
|
template struct util::noise::fbm<float, util::noise::basis::value<float,util::lerp::trunc>>;
|
||||||
template struct util::noise::fbm<float, util::noise::value<float,util::lerp::linear>>;
|
template struct util::noise::fbm<float, util::noise::basis::value<float,util::lerp::linear>>;
|
||||||
template struct util::noise::fbm<float, util::noise::value<float,util::lerp::quintic>>;
|
template struct util::noise::fbm<float, util::noise::basis::value<float,util::lerp::quintic>>;
|
||||||
|
|
||||||
template struct util::noise::fbm<double, util::noise::cellular<double>>;
|
template struct util::noise::fbm<double, util::noise::basis::worley<double>>;
|
||||||
template struct util::noise::fbm<double, util::noise::gradient<double,util::lerp::linear>>;
|
template struct util::noise::fbm<double, util::noise::basis::perlin<double,util::lerp::linear>>;
|
||||||
template struct util::noise::fbm<double, util::noise::gradient<double,util::lerp::quintic>>;
|
template struct util::noise::fbm<double, util::noise::basis::perlin<double,util::lerp::quintic>>;
|
||||||
template struct util::noise::fbm<double, util::noise::value<double,util::lerp::trunc>>;
|
template struct util::noise::fbm<double, util::noise::basis::value<double,util::lerp::trunc>>;
|
||||||
template struct util::noise::fbm<double, util::noise::value<double,util::lerp::linear>>;
|
template struct util::noise::fbm<double, util::noise::basis::value<double,util::lerp::linear>>;
|
||||||
template struct util::noise::fbm<double, util::noise::value<double,util::lerp::quintic>>;
|
template struct util::noise::fbm<double, util::noise::basis::value<double,util::lerp::quintic>>;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -208,17 +213,17 @@ rmf<T,B>::operator() (util::point<2,T> p) const {
|
|||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template struct util::noise::rmf<float, util::noise::cellular<float>>;
|
template struct util::noise::rmf<float, util::noise::basis::worley<float>>;
|
||||||
template struct util::noise::rmf<float, util::noise::gradient<float,util::lerp::linear>>;
|
template struct util::noise::rmf<float, util::noise::basis::perlin<float,util::lerp::linear>>;
|
||||||
template struct util::noise::rmf<float, util::noise::gradient<float,util::lerp::quintic>>;
|
template struct util::noise::rmf<float, util::noise::basis::perlin<float,util::lerp::quintic>>;
|
||||||
template struct util::noise::rmf<float, util::noise::value<float,util::lerp::linear>>;
|
template struct util::noise::rmf<float, util::noise::basis::value<float,util::lerp::linear>>;
|
||||||
template struct util::noise::rmf<float, util::noise::value<float,util::lerp::quintic>>;
|
template struct util::noise::rmf<float, util::noise::basis::value<float,util::lerp::quintic>>;
|
||||||
|
|
||||||
template struct util::noise::rmf<double, util::noise::cellular<double>>;
|
template struct util::noise::rmf<double, util::noise::basis::worley<double>>;
|
||||||
template struct util::noise::rmf<double, util::noise::gradient<double,util::lerp::linear>>;
|
template struct util::noise::rmf<double, util::noise::basis::perlin<double,util::lerp::linear>>;
|
||||||
template struct util::noise::rmf<double, util::noise::gradient<double,util::lerp::quintic>>;
|
template struct util::noise::rmf<double, util::noise::basis::perlin<double,util::lerp::quintic>>;
|
||||||
template struct util::noise::rmf<double, util::noise::value<double,util::lerp::linear>>;
|
template struct util::noise::rmf<double, util::noise::basis::value<double,util::lerp::linear>>;
|
||||||
template struct util::noise::rmf<double, util::noise::value<double,util::lerp::quintic>>;
|
template struct util::noise::rmf<double, util::noise::basis::value<double,util::lerp::quintic>>;
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -264,11 +269,11 @@ hmf<T,B>::operator() (util::point<2,T> p) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template struct util::noise::hmf<float, util::noise::cellular<float>>;
|
template struct util::noise::hmf<float, util::noise::basis::worley<float>>;
|
||||||
template struct util::noise::hmf<float, util::noise::gradient<float,util::lerp::linear>>;
|
template struct util::noise::hmf<float, util::noise::basis::perlin<float,util::lerp::linear>>;
|
||||||
template struct util::noise::hmf<float, util::noise::gradient<float,util::lerp::quintic>>;
|
template struct util::noise::hmf<float, util::noise::basis::perlin<float,util::lerp::quintic>>;
|
||||||
template struct util::noise::hmf<float, util::noise::value<float,util::lerp::linear>>;
|
template struct util::noise::hmf<float, util::noise::basis::value<float,util::lerp::linear>>;
|
||||||
template struct util::noise::hmf<float, util::noise::value<float,util::lerp::quintic>>;
|
template struct util::noise::hmf<float, util::noise::basis::value<float,util::lerp::quintic>>;
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -314,8 +319,8 @@ hetero<T,B>::operator() (util::point<2,T> p) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template struct util::noise::hetero<float, util::noise::cellular<float>>;
|
template struct util::noise::hetero<float, util::noise::basis::worley<float>>;
|
||||||
template struct util::noise::hetero<float, util::noise::gradient<float,util::lerp::linear>>;
|
template struct util::noise::hetero<float, util::noise::basis::perlin<float,util::lerp::linear>>;
|
||||||
template struct util::noise::hetero<float, util::noise::gradient<float,util::lerp::quintic>>;
|
template struct util::noise::hetero<float, util::noise::basis::perlin<float,util::lerp::quintic>>;
|
||||||
template struct util::noise::hetero<float, util::noise::value<float,util::lerp::linear>>;
|
template struct util::noise::hetero<float, util::noise::basis::value<float,util::lerp::linear>>;
|
||||||
template struct util::noise::hetero<float, util::noise::value<float,util::lerp::quintic>>;
|
template struct util::noise::hetero<float, util::noise::basis::value<float,util::lerp::quintic>>;
|
||||||
|
@ -19,13 +19,13 @@
|
|||||||
|
|
||||||
#include "basis.hpp"
|
#include "basis.hpp"
|
||||||
|
|
||||||
|
#include "../point.hpp"
|
||||||
|
|
||||||
namespace util {
|
namespace util {
|
||||||
namespace noise {
|
namespace noise {
|
||||||
/// Base noise summation
|
/// Base noise summation
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct fractal {
|
struct fractal {
|
||||||
using seed_t = uint64_t;
|
|
||||||
|
|
||||||
fractal (seed_t);
|
fractal (seed_t);
|
||||||
fractal ();
|
fractal ();
|
||||||
virtual ~fractal ();
|
virtual ~fractal ();
|
||||||
@ -48,8 +48,6 @@ namespace util {
|
|||||||
/// gain: per octave amplitude scaling factor. typically 1/f.
|
/// gain: per octave amplitude scaling factor. typically 1/f.
|
||||||
template <typename T, typename B>
|
template <typename T, typename B>
|
||||||
struct fbm : public fractal<T> {
|
struct fbm : public fractal<T> {
|
||||||
using seed_t = typename basis<T>::seed_t;
|
|
||||||
|
|
||||||
static constexpr unsigned DEFAULT_OCTAVES = 8;
|
static constexpr unsigned DEFAULT_OCTAVES = 8;
|
||||||
static constexpr T DEFAULT_FREQUENCY = T(0.1);
|
static constexpr T DEFAULT_FREQUENCY = T(0.1);
|
||||||
static constexpr T DEFAULT_LACUNARITY = 2;
|
static constexpr T DEFAULT_LACUNARITY = 2;
|
||||||
@ -84,8 +82,6 @@ namespace util {
|
|||||||
/// lacunarity: per octave frequency scaling factor
|
/// lacunarity: per octave frequency scaling factor
|
||||||
template <typename T, typename B>
|
template <typename T, typename B>
|
||||||
struct rmf : public fractal<T> {
|
struct rmf : public fractal<T> {
|
||||||
using seed_t = typename basis<T>::seed_t;
|
|
||||||
|
|
||||||
static constexpr unsigned DEFAULT_OCTAVES = 5;
|
static constexpr unsigned DEFAULT_OCTAVES = 5;
|
||||||
static constexpr T DEFAULT_FREQUENCY = T(1);
|
static constexpr T DEFAULT_FREQUENCY = T(1);
|
||||||
static constexpr T DEFAULT_LACUNARITY = 2;
|
static constexpr T DEFAULT_LACUNARITY = 2;
|
||||||
@ -116,8 +112,6 @@ namespace util {
|
|||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
template <typename T, typename B>
|
template <typename T, typename B>
|
||||||
struct hmf : public fractal<T> {
|
struct hmf : public fractal<T> {
|
||||||
using seed_t = typename basis<T>::seed_t;
|
|
||||||
|
|
||||||
hmf ();
|
hmf ();
|
||||||
|
|
||||||
T H;
|
T H;
|
||||||
@ -141,8 +135,6 @@ namespace util {
|
|||||||
/// Heterogeneous procedural terrain fucntion: stats by altitude method
|
/// Heterogeneous procedural terrain fucntion: stats by altitude method
|
||||||
template <typename T, typename B>
|
template <typename T, typename B>
|
||||||
struct hetero : public fractal<T> {
|
struct hetero : public fractal<T> {
|
||||||
using seed_t = typename basis<T>::seed_t;
|
|
||||||
|
|
||||||
hetero ();
|
hetero ();
|
||||||
|
|
||||||
T H;
|
T H;
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
#include "image.hpp"
|
#include "image.hpp"
|
||||||
#include "noise.hpp"
|
#include "noise.hpp"
|
||||||
#include "noise/lerp.hpp"
|
#include "noise/lerp.hpp"
|
||||||
|
#include "noise/basis/value.hpp"
|
||||||
|
#include "noise/basis/perlin.hpp"
|
||||||
|
#include "noise/basis/worley.hpp"
|
||||||
#include "extent.hpp"
|
#include "extent.hpp"
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -11,10 +14,10 @@ main (void)
|
|||||||
util::image::buffer<float> img (size);
|
util::image::buffer<float> img (size);
|
||||||
|
|
||||||
// setup the noise generator
|
// setup the noise generator
|
||||||
//util::noise::fbm<float, util::noise::cellular<float>> b;
|
//util::noise::fbm<float, util::noise::basis::worley<float>> b;
|
||||||
//util::noise::rmf<float, util::noise::cellular<float>> b;
|
//util::noise::rmf<float, util::noise::basis::worley<float>> b;
|
||||||
//util::noise::hmf<float, util::noise::gradient<float,util::lerp::quintic>> b;
|
//util::noise::hmf<float, util::noise::basis::perlin<float,util::lerp::quintic>> b;
|
||||||
util::noise::hetero<float, util::noise::gradient<float,util::lerp::quintic>> b;
|
util::noise::hetero<float, util::noise::basis::perlin<float,util::lerp::quintic>> b;
|
||||||
//b.octaves = 3;
|
//b.octaves = 3;
|
||||||
b.frequency = 10.f / size.w;
|
b.frequency = 10.f / size.w;
|
||||||
b.lacunarity = 2;
|
b.lacunarity = 2;
|
||||||
|
Loading…
Reference in New Issue
Block a user