Package tdl :: Module noise
[frames] | no frames]

Source Code for Module tdl.noise

  1  """ 
  2      This module provides advanced noise generation. 
  3   
  4      Noise is sometimes used for over-world generation, height-maps, and 
  5      cloud/mist/smoke effects among other things. 
  6   
  7      You can see examples of the available noise algorithms in the libtcod 
  8      documentation 
  9      U{here<http://doryen.eptalys.net/data/libtcod/doc/1.5.1/html2/noise.html>}. 
 10  """ 
 11   
 12   
 13  import random as _random 
 14   
 15  from tcod import ffi as _ffi 
 16  from tcod import lib as _lib 
 17   
 18  import tdl as _tdl 
 19  from . import style as _style 
 20   
 21  _MERSENNE_TWISTER = 1 
 22  _CARRY_WITH_MULTIPLY = 2 
 23   
 24  _MAX_DIMENSIONS = 4 
 25  _MAX_OCTAVES = 128 
 26   
 27  _NOISE_TYPES = {'PERLIN': 1, 'SIMPLEX': 2, 'WAVELET': 4} 
 28  _NOISE_MODES = {'FLAT': _lib.TCOD_noise_get, 
 29                  'FBM': _lib.TCOD_noise_get_fbm, 
 30                  'TURBULENCE': _lib.TCOD_noise_get_turbulence} 
 31   
32 -class Noise(object):
33 """An advanced noise generator. 34 """ 35
36 - def __init__(self, algorithm='PERLIN', mode='FLAT', 37 hurst=0.5, lacunarity=2.0, octaves=4.0, seed=None, dimensions=4):
38 """Create a new noise generator specifying a noise algorithm and how 39 it's used. 40 41 @type algorithm: string 42 @param algorithm: The primary noise algorithm to be used. 43 44 Can be one of 'PERLIN', 'SIMPLEX', 'WAVELET' 45 - 'PERLIN' - 46 A popular noise generator. 47 48 - 'SIMPLEX' - 49 In theory this is a slightly faster generator with 50 less noticeable directional artifacts. 51 52 - 'WAVELET' 53 A noise generator designed to reduce aliasing and 54 not lose detail when summed into a fractal 55 (as with the 'FBM' and 'TURBULENCE' modes.) 56 57 This works faster at higher dimensions. 58 59 @type mode: string 60 @param mode: A secondary parameter to determine how noise is generated. 61 62 Can be one of 'FLAT', 'FBM', 'TURBULENCE' 63 - 'FLAT' - 64 Generates the simplest form of noise. 65 This mode does not use the hurst, lacunarity, 66 and octaves parameters. 67 68 - 'FBM' - 69 Generates fractal brownian motion. 70 71 - 'TURBULENCE' - 72 Generates detailed noise with smoother and more 73 natural transitions. 74 75 @type hurst: float 76 @param hurst: The hurst exponent describes the raggedness of the 77 resultant noise, with a higher value leading to a 78 smoother noise. 79 It should be in the 0.0-1.0 range. 80 81 This is only used in 'FBM' and 'TURBULENCE' modes. 82 83 @type lacunarity: float 84 @param lacunarity: A multiplier that determines how quickly the 85 frequency increases for each successive octave. 86 87 The frequency of each successive octave is equal to 88 the product of the previous octave's frequency and 89 the lacunarity value. 90 91 This is only used in 'FBM' and 'TURBULENCE' modes. 92 93 @type octaves: float 94 @param octaves: Controls the amount of detail in the noise. 95 96 This is only used in 'FBM' and 'TURBULENCE' modes. 97 98 @type seed: object 99 @param seed: You can use any hashable object to be a seed for the 100 noise generator. 101 102 If None is used then a random seed will be generated. 103 """ 104 if algorithm.upper() not in _NOISE_TYPES: 105 raise _tdl.TDLError('No such noise algorithm as %s' % algorithm) 106 self._algorithm = algorithm.upper() 107 108 if mode.upper() not in _NOISE_MODES: 109 raise _tdl.TDLError('No such mode as %s' % mode) 110 self._mode = mode.upper() 111 112 if seed is None: 113 seed = _random.getrandbits(32) 114 else: 115 seed = hash(seed) 116 self._seed = seed 117 # convert values into ctypes to speed up later functions 118 self._dimensions = min(_MAX_DIMENSIONS, int(dimensions)) 119 if self._algorithm == 'WAVELET': 120 self._dimensions = min(self._dimensions, 3) # Wavelet only goes up to 3 121 self._random = _lib.TCOD_random_new_from_seed(_MERSENNE_TWISTER, self._seed) 122 self._hurst = hurst 123 self._lacunarity = lacunarity 124 self._noise = _lib.TCOD_noise_new(self._dimensions, self._hurst, 125 self._lacunarity, self._random) 126 _lib.TCOD_noise_set_type(self._noise, _NOISE_TYPES[self._algorithm]) 127 self._noiseFunc = _NOISE_MODES[self._mode] 128 self._octaves = octaves 129 self._useOctaves = (self._mode != 'FLAT') 130 self._arrayType = 'float[%i]' % self._dimensions
131 #self._cFloatArray = _ctypes.c_float * self._dimensions 132 #self._array = self._cFloatArray() 133
134 - def __copy__(self):
135 # using the pickle method is a convenient way to clone this object 136 self.__class__(self.__getstate__())
137
138 - def __getstate__(self):
139 return (self._algorithm, self._mode, 140 self._hurst.value, self._lacunarity.value, self._octaves.value, 141 self._seed, self._dimensions)
142
143 - def __setstate__(self, state):
144 self.__init__(*state)
145
146 - def get_point(self, *position):
147 """Return the noise value of a specific position. 148 149 Example usage: value = noise.getPoint(x, y, z) 150 @type position: floats 151 @param position: 152 153 @rtype: float 154 @return: Returns the noise value at position. 155 This will be a floating point in the 0.0-1.0 range. 156 """ 157 #array = self._array 158 #for d, pos in enumerate(position): 159 # array[d] = pos 160 #array = self._cFloatArray(*position) 161 array = _ffi.new(self._arrayType, position) 162 if self._useOctaves: 163 return (self._noiseFunc(self._noise, array, self._octaves) + 1) * 0.5 164 return (self._noiseFunc(self._noise, array) + 1) * 0.5
165
166 - def __del__(self):
167 # dealloc only once 168 if self._random: 169 _lib.TCOD_random_delete(self._random) 170 self._random = None 171 if self._noise: 172 _lib.TCOD_noise_delete(self._noise) 173 self._noise = None
174 175 __all__ = [_var for _var in locals().keys() if _var[0] != '_'] 176 177 Noise.getPoint = _style.backport(Noise.get_point) 178