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 .__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):
     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                               A slightly faster generator that unlike perlin has
     49                               no 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          @type mode: string
     57          @param mode: A secondary parameter to determine how noise is generated.
     58
     59                       Can be one of 'FLAT', 'FBM', 'TURBULENCE'
     60                        - 'FLAT' -
     61                          Generates the simplest form of noise.
     62                          This mode does not use the hurst, lacunarity,
     63                          and octaves parameters.
     64
     65                        - 'FBM' -
     66                          Generates fractal brownian motion.
     67
     68                        - 'TURBULENCE' -
     69                          Generates detailed noise with smoother and more
     70                          natural transitions.
     71
     72          @type hurst: float
     73          @param hurst: The hurst exponent describes the raggedness of the
     74                        resultant noise, with a higher value leading to a
     75                        smoother noise.
     76                        It should be in the 0.0-1.0 range.
     77
     78                        This is only used in 'FBM' and 'TURBULENCE' modes.
     79
     80          @type lacunarity: float
     81          @param lacunarity: A multiplier that determines how quickly the
     82                             frequency increases for each successive octave.
     83
     84                             The frequency of each successive octave is equal to
     85                             the product of the previous octave's frequency and
     86                             the lacunarity value.
     87
     88                             This is only used in 'FBM' and 'TURBULENCE' modes.
     89
     90          @type octaves: float
     91          @param octaves: Controls the amount of detail in the noise.
     92
     93                          This is only used in 'FBM' and 'TURBULENCE' modes.
     94
     95          @type seed: object
     96          @param seed: You can use any hashable object to be a seed for the
     97                       noise generator.
     98
     99                       If None is used then a random seed will be generated.
    100          """
    101          if algorithm.upper() not in _NOISE_TYPES:
    102              raise tdl.TDLError('No such noise algorithm as %s' % algorithm)
    103          self._algorithm = algorithm.upper()
    104
    105          if mode.upper() not in _NOISE_MODES:
    106              raise tdl.TDLError('No such mode as %s' % mode)
    107          self._mode = mode.upper()
    108
    109          if seed is None:
    110              seed = random.getrandbits(32)
    111          else:
    112              seed = hash(seed)
    113          self._dimensions = _MAX_DIMENSIONS
    114          if self._algorithm == 'WAVELET':
    115              self._dimensions = 3 # Wavelet only goes up to 3
    116          self._random = _lib.TCOD_random_new_from_seed(seed, _MERSENNE_TWISTER)
    117          self._noise = _lib.TCOD_noise_new(self._dimensions, hurst, lacunarity, self._random)
    118          _lib.TCOD_noise_set_type(self._noise, _NOISE_TYPES[self._algorithm])
    119          self._noiseFunc = _NOISE_MODES[self._mode]
    120          self._octaves = ctypes.c_float(octaves)
    121          self._useOctaves = (self._mode != 'FLAT')
    122          self._cFloatArray = ctypes.c_float * self._dimensions
    123
    124 -    def getPoint(self, *position):
    125          """Return the noise value of a specific position.
    126
    127          Example usage: value = noise.getPoint(x, y, z)
    128          @type position: floats
    129          @param position:
    130
    131          @rtype: float
    132          @return: Returns the noise value at position.
    133                   This will be a floating point in the 0.0-1.0 range.
    134          """
    135          array = self._cFloatArray(*position)
    136          if self._useOctaves:
    137              return (self._noiseFunc(self._noise, array, self._octaves) + 1) * 0.5
    138          return (self._noiseFunc(self._noise, array) + 1) * 0.5
    139
    140 -    def __del__(self):
    141          _lib.TCOD_random_delete(self._random)
    142          _lib.TCOD_noise_delete(self._noise)
    143
    144  __all__ = ['Noise']
    145