untdl.noise

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