/*
* This file is part of Deliantra, the Roguelike Realtime MMORPG.
*
* Copyright (©) 2010,2011 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
*
* Deliantra is free software: you can redistribute it and/or modify it under
* the terms of the Affero GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the Affero GNU General Public License
* and the GNU General Public License along with this program. If not, see
* .
*
* The authors can be reached via e-mail to
*/
#ifndef NOISE_H_
#define NOISE_H_
#include
#include
#include "global.h"
typedef blitz::TinyVector vec2d;
typedef blitz::TinyVector vec3d;
/////////////////////////////////////////////////////////////////////////////
template
struct permutation
{
T pmap[N];
template
void seed (generator &rng)
{
for (int i = 0; i < N; ++i)
pmap[i] = i;
// fisher-yates to randomly perturb
for (int i = N; --i; )
::swap (pmap[i], pmap[rng (i + 1)]);
}
T operator ()(T v)
{
return pmap[v & (N - 1)];
}
};
template
struct noise_gen;
// modelled after 2d/3d kensler noise without projection
template<>
struct noise_gen
{
permutation<256, uint8_t> rvmap[2];
vec2d rvec[256]; // random unit vectors
noise_gen (uint32_t seed);
vec2d::T_numtype operator() (vec2d P);
};
template<>
struct noise_gen
{
permutation<256, uint8_t> rvmap[3];
noise_gen (uint32_t seed);
vec2d::T_numtype operator() (vec3d P);
// noise projected on a surface with normal n
vec2d::T_numtype operator() (vec3d P, vec3d N);
};
template
struct rotate_nn
{
typename vec_t::T_numtype s, c;
void set (typename vec_t::T_numtype angle)
{
s = sin (angle);
c = cos (angle);
}
void operator ()(vec_t &P) const
{
vec_t o = P;
P[a] = o[a] * c - o[b] * s;
P[b] = o[a] * s + o[b] * c;
}
};
template
struct rotate_xy : rotate_nn
{
};
template
struct rotate_xz : rotate_nn
{
};
template
struct rotate_yz : rotate_nn
{
};
template
struct frac_gen
: noise_gen
{
enum { MAX_OCTAVES = 64 };
typedef typename vec_t::T_numtype value_t;
value_t h, lac, ex[MAX_OCTAVES];
value_t fbm_mul[MAX_OCTAVES];
rotate_xy rot[MAX_OCTAVES];
value_t noise (vec_t P)
{
return operator() (P);
}
frac_gen (value_t hurst_expo = .5f, value_t lacunarity = 2.f);
value_t fBm (vec_t P, int octaves);
value_t turbulence (vec_t P, int octaves);
value_t multifractal (vec_t P, int octaves, value_t offset = 1);
value_t heterofractal (vec_t P, int octaves, value_t offset = 1);
value_t hybridfractal (vec_t P, int octaves, value_t offset = 1, value_t gain = 1);
value_t terrain (vec_t P, int octaves);
value_t terrain2 (vec_t P, int octaves);
value_t ridgedmultifractal (vec_t P, int octaves, value_t offset = 1, value_t gain = 8);
};
#endif