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 `here |
||
9 | <http://doryen.eptalys.net/data/libtcod/doc/1.5.1/html2/noise.html>`_. |
||
10 | """ |
||
11 | |||
12 | |||
13 | import random as _random |
||
14 | |||
15 | from tcod import ffi as _ffi |
||
16 | from tcod import lib as _lib |
||
17 | |||
18 | import tdl as _tdl |
||
19 | from . import style as _style |
||
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 | class Noise(object): |
||
33 | """An advanced noise generator. |
||
34 | |||
35 | .. deprecated:: 3.2 |
||
36 | This class has been replaced by :any:`tcod.noise.Noise`. |
||
37 | |||
38 | Args: |
||
39 | algorithm (Text): The primary noise algorithm to be used. |
||
40 | |||
41 | Can be one of 'PERLIN', 'SIMPLEX', 'WAVELET' |
||
42 | |||
43 | - 'PERLIN' - |
||
44 | A popular noise generator. |
||
45 | - 'SIMPLEX' - |
||
46 | In theory this is a slightly faster generator with |
||
47 | less noticeable directional artifacts. |
||
48 | - 'WAVELET' - |
||
49 | A noise generator designed to reduce aliasing and |
||
50 | not lose detail when summed into a fractal |
||
51 | (as with the 'FBM' and 'TURBULENCE' modes.) |
||
52 | This works faster at higher dimensions. |
||
53 | |||
54 | mode (Text): A secondary parameter to determine how noise is generated. |
||
55 | |||
56 | Can be one of 'FLAT', 'FBM', 'TURBULENCE' |
||
57 | |||
58 | - 'FLAT' - |
||
59 | Generates the simplest form of noise. |
||
60 | This mode does not use the hurst, lacunarity, |
||
61 | and octaves parameters. |
||
62 | - 'FBM' - |
||
63 | Generates fractal brownian motion. |
||
64 | - 'TURBULENCE' - |
||
65 | Generates detailed noise with smoother and more |
||
66 | natural transitions. |
||
67 | |||
68 | hurst (float): The hurst exponent. |
||
69 | |||
70 | This describes the raggedness of the resultant noise, |
||
71 | with a higher value leading to a smoother noise. |
||
72 | It should be in the 0.0-1.0 range. |
||
73 | |||
74 | This is only used in 'FBM' and 'TURBULENCE' modes. |
||
75 | |||
76 | lacunarity (float): A multiplier that determines how quickly the |
||
77 | frequency increases for each successive octave. |
||
78 | |||
79 | The frequency of each successive octave is equal to |
||
80 | the product of the previous octave's frequency and |
||
81 | the lacunarity value. |
||
82 | |||
83 | This is only used in 'FBM' and 'TURBULENCE' modes. |
||
84 | |||
85 | octaves (float): Controls the amount of detail in the noise. |
||
86 | |||
87 | This is only used in 'FBM' and 'TURBULENCE' modes. |
||
88 | |||
89 | seed (Hashable): You can use any hashable object to be a seed for the |
||
90 | noise generator. |
||
91 | |||
92 | If None is used then a random seed will be generated. |
||
93 | """ |
||
94 | |||
95 | def __init__(self, algorithm='PERLIN', mode='FLAT', |
||
96 | hurst=0.5, lacunarity=2.0, octaves=4.0, seed=None, dimensions=4): |
||
0 ignored issues
–
show
|
|||
97 | if algorithm.upper() not in _NOISE_TYPES: |
||
98 | raise _tdl.TDLError('No such noise algorithm as %s' % algorithm) |
||
99 | self._algorithm = algorithm.upper() |
||
100 | |||
101 | if mode.upper() not in _NOISE_MODES: |
||
102 | raise _tdl.TDLError('No such mode as %s' % mode) |
||
103 | self._mode = mode.upper() |
||
104 | |||
105 | if seed is None: |
||
106 | seed = _random.getrandbits(32) |
||
107 | try: |
||
108 | seed = int(seed) |
||
109 | except TypeError: |
||
110 | seed = hash(seed) |
||
111 | self._seed = seed |
||
112 | # convert values into ctypes to speed up later functions |
||
113 | self._dimensions = min(_MAX_DIMENSIONS, int(dimensions)) |
||
114 | if self._algorithm == 'WAVELET': |
||
115 | self._dimensions = min(self._dimensions, 3) # Wavelet only goes up to 3 |
||
0 ignored issues
–
show
|
|||
116 | self._random = _lib.TCOD_random_new_from_seed( |
||
117 | _MERSENNE_TWISTER, |
||
118 | _ffi.cast('uint32_t', self._seed), |
||
119 | ) |
||
120 | self._hurst = hurst |
||
121 | self._lacunarity = lacunarity |
||
122 | self._noise = _lib.TCOD_noise_new(self._dimensions, self._hurst, |
||
123 | self._lacunarity, self._random) |
||
124 | _lib.TCOD_noise_set_type(self._noise, _NOISE_TYPES[self._algorithm]) |
||
125 | self._noiseFunc = _NOISE_MODES[self._mode] |
||
0 ignored issues
–
show
The name
_noiseFunc does not conform to the attribute naming conventions ([a-z_][a-z0-9_]{2,30}$ ).
This check looks for invalid names for a range of different identifiers. You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements. If your project includes a Pylint configuration file, the settings contained in that file take precedence. To find out more about Pylint, please refer to their site. ![]() |
|||
126 | self._octaves = octaves |
||
127 | self._useOctaves = (self._mode != 'FLAT') |
||
0 ignored issues
–
show
The name
_useOctaves does not conform to the attribute naming conventions ([a-z_][a-z0-9_]{2,30}$ ).
This check looks for invalid names for a range of different identifiers. You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements. If your project includes a Pylint configuration file, the settings contained in that file take precedence. To find out more about Pylint, please refer to their site. ![]() |
|||
128 | self._arrayType = 'float[%i]' % self._dimensions |
||
0 ignored issues
–
show
The name
_arrayType does not conform to the attribute naming conventions ([a-z_][a-z0-9_]{2,30}$ ).
This check looks for invalid names for a range of different identifiers. You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements. If your project includes a Pylint configuration file, the settings contained in that file take precedence. To find out more about Pylint, please refer to their site. ![]() |
|||
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 | return self.__class__(*self.__getstate__()) |
||
135 | |||
136 | def __getstate__(self): |
||
137 | return (self._algorithm, self._mode, |
||
138 | self._hurst, self._lacunarity, self._octaves, |
||
139 | self._seed, self._dimensions) |
||
140 | |||
141 | def __setstate__(self, state): |
||
142 | self.__init__(*state) |
||
143 | |||
144 | def get_point(self, *position): |
||
145 | """Return the noise value of a specific position. |
||
146 | |||
147 | Example usage: value = noise.getPoint(x, y, z) |
||
148 | |||
149 | Args: |
||
150 | position (Tuple[float, ...]): The point to sample at. |
||
151 | |||
152 | Returns: |
||
153 | float: The noise value at position. |
||
154 | |||
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 | array = _ffi.new(self._arrayType, position) |
||
162 | if self._useOctaves: |
||
163 | return (self._noiseFunc(self._noise, array, self._octaves) + 1) * 0.5 |
||
0 ignored issues
–
show
|
|||
164 | return (self._noiseFunc(self._noise, array) + 1) * 0.5 |
||
165 | |||
166 | |||
167 | __all__ = [_var for _var in locals().keys() if _var[0] != '_'] |
||
168 | |||
169 | Noise.getPoint = _style.backport(Noise.get_point) |
||
170 |
This check looks for lines that are too long. You can specify the maximum line length.