/* * This file is part of Deliantra, the Roguelike Realtime MMORPG. * * Copyright (©) 2010 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