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

Source Code for Module untdl.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 untdl 
 18  # noinspection PyProtectedMember
 
 19  from untdl.__tcod import _lib 
 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  
 
33 -class Noise(object):
34 """An advanced noise generator. 35 """ 36
37 - def __init__(self, algorithm='PERLIN', mode='FLAT', 38 hurst=0.5, lacunarity=2.0, octaves=4.0, seed=None, dimensions=4):
39 """Create a new noise generator specifying a noise algorithm and how 40 it's used. 41 42 @type algorithm: string 43 @param algorithm: The primary noise algorithm to be used. 44 45 Can be one of 'PERLIN', 'SIMPLEX', 'WAVELET' 46 - 'PERLIN' - 47 A popular noise generator. 48 49 - 'SIMPLEX' - 50 In theory this is a slightly faster generator with 51 less noticeable directional artifacts. 52 53 - 'WAVELET' 54 A noise generator designed to reduce aliasing and 55 not lose detail when summed into a fractal 56 (as with the 'FBM' and 'TURBULENCE' modes.) 57 58 This works faster at higher dimensions. 59 60 @type mode: string 61 @param mode: A secondary parameter to determine how noise is generated. 62 63 Can be one of 'FLAT', 'FBM', 'TURBULENCE' 64 - 'FLAT' - 65 Generates the simplest form of noise. 66 This mode does not use the hurst, lacunarity, 67 and octaves parameters. 68 69 - 'FBM' - 70 Generates fractal brownian motion. 71 72 - 'TURBULENCE' - 73 Generates detailed noise with smoother and more 74 natural transitions. 75 76 @type hurst: float 77 @param hurst: The hurst exponent describes the raggedness of the 78 resultant noise, with a higher value leading to a 79 smoother noise. 80 It should be in the 0.0-1.0 range. 81 82 This is only used in 'FBM' and 'TURBULENCE' modes. 83 84 @type lacunarity: float 85 @param lacunarity: A multiplier that determines how quickly the 86 frequency increases for each successive octave. 87 88 The frequency of each successive octave is equal to 89 the product of the previous octave's frequency and 90 the lacunarity value. 91 92 This is only used in 'FBM' and 'TURBULENCE' modes. 93 94 @type octaves: float 95 @param octaves: Controls the amount of detail in the noise. 96 97 This is only used in 'FBM' and 'TURBULENCE' modes. 98 99 @type seed: object 100 @param seed: You can use any hashable object to be a seed for the 101 noise generator. 102 103 If None is used then a random seed will be generated. 104 """ 105 if algorithm.upper() not in _NOISE_TYPES: 106 raise untdl.TDLError('No such noise algorithm as %s' % algorithm) 107 self._algorithm = algorithm.upper() 108 109 if mode.upper() not in _NOISE_MODES: 110 raise untdl.TDLError('No such mode as %s' % mode) 111 self._mode = mode.upper() 112 113 if seed is None: 114 seed = random.getrandbits(32) 115 else: 116 seed = hash(seed) 117 self._seed = seed 118 # convert values into ctypes to speed up later functions 119 self._dimensions = min(_MAX_DIMENSIONS, int(dimensions)) 120 if self._algorithm == 'WAVELET': 121 self._dimensions = min(self._dimensions, 3) # Wavelet only goes up to 3 122 self._random = _lib.TCOD_random_new_from_seed(_MERSENNE_TWISTER, self._seed) 123 self._hurst = ctypes.c_float(hurst) 124 self._lacunarity = ctypes.c_float(lacunarity) 125 self._noise = _lib.TCOD_noise_new(self._dimensions, self._hurst, 126 self._lacunarity, self._random) 127 _lib.TCOD_noise_set_type(self._noise, _NOISE_TYPES[self._algorithm]) 128 self._noiseFunc = _NOISE_MODES[self._mode] 129 self._octaves = ctypes.c_float(octaves) 130 self._useOctaves = (self._mode != 'FLAT') 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.get_point(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 if self._useOctaves: 162 return (self._noiseFunc(self._noise, array, self._octaves) + 1) * 0.5 163 return (self._noiseFunc(self._noise, array) + 1) * 0.5
164
165 - def __del__(self):
166 _lib.TCOD_random_delete(self._random) 167 _lib.TCOD_noise_delete(self._noise)
168 169 __all__ = ['Noise'] 170