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
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
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
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
141 _lib.TCOD_random_delete(self._random)
142 _lib.TCOD_noise_delete(self._noise)
143
144 __all__ = ['Noise']
145