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