1 // turbulence.h
2 //
3 // Copyright (C) 2003, 2004 Jason Bevins
4 //
5 // This library is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU Lesser General Public License as published by
7 // the Free Software Foundation; either version 2.1 of the License, or (at
8 // your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful, but WITHOUT
11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
13 // License (COPYING.txt) for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this library; if not, write to the Free Software Foundation,
17 // Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 //
19 // The developer's email is jlbezigvins@gmzigail.com (for great email, take
20 // off every 'zig'.)
21 //
22 module noise.mod.turbulence;
23 
24 private {
25   import noise.mod.modulebase;
26   import noise.mod.perlin;
27 }
28 
29 /// @addtogroup libnoise
30 /// @{
31 
32 /// @addtogroup modules
33 /// @{
34 
35 /// @addtogroup transformermodules
36 /// @{
37 
38 /// Default frequency for the module::Turbulence noise module.
39 const double DEFAULT_TURBULENCE_FREQUENCY = DEFAULT_PERLIN_FREQUENCY;
40 
41 /// Default power for the module::Turbulence noise module.
42 const double DEFAULT_TURBULENCE_POWER = 1.0;
43 
44 /// Default roughness for the module::Turbulence noise module.
45 const int DEFAULT_TURBULENCE_ROUGHNESS = 3;
46 
47 /// Default noise seed for the module::Turbulence noise module.
48 const int DEFAULT_TURBULENCE_SEED = DEFAULT_PERLIN_SEED;
49 
50 /// Noise module that randomly displaces the input value before
51 /// returning the output value from a source module.
52 ///
53 /// @image html moduleturbulence.png
54 ///
55 /// @a Turbulence is the pseudo-random displacement of the input value.
56 /// The GetValue() method randomly displaces the ( @a x, @a y, @a z )
57 /// coordinates of the input value before retrieving the output value from
58 /// the source module.  To control the turbulence, an application can
59 /// modify its frequency, its power, and its roughness.
60 ///
61 /// The frequency of the turbulence determines how rapidly the
62 /// displacement amount changes.  To specify the frequency, call the
63 /// SetFrequency() method.
64 ///
65 /// The power of the turbulence determines the scaling factor that is
66 /// applied to the displacement amount.  To specify the power, call the
67 /// SetPower() method.
68 ///
69 /// The roughness of the turbulence determines the roughness of the
70 /// changes to the displacement amount.  Low values smoothly change the
71 /// displacement amount.  High values roughly change the displacement
72 /// amount, which produces more "kinky" changes.  To specify the
73 /// roughness, call the SetRoughness() method.
74 ///
75 /// Use of this noise module may require some trial and error.  Assuming
76 /// that you are using a generator module as the source module, you
77 /// should first:
78 /// - Set the frequency to the same frequency as the source module.
79 /// - Set the power to the reciprocal of the frequency.
80 ///
81 /// From these initial frequency and power values, modify these values
82 /// until this noise module produce the desired changes in your terrain or
83 /// texture.  For example:
84 /// - Low frequency (1/8 initial frequency) and low power (1/8 initial
85 ///   power) produces very minor, almost unnoticeable changes.
86 /// - Low frequency (1/8 initial frequency) and high power (8 times
87 ///   initial power) produces "ropey" lava-like terrain or marble-like
88 ///   textures.
89 /// - High frequency (8 times initial frequency) and low power (1/8
90 ///   initial power) produces a noisy version of the initial terrain or
91 ///   texture.
92 /// - High frequency (8 times initial frequency) and high power (8 times
93 ///   initial power) produces nearly pure noise, which isn't entirely
94 ///   useful.
95 ///
96 /// Displacing the input values result in more realistic terrain and
97 /// textures.  If you are generating elevations for terrain height maps,
98 /// you can use this noise module to produce more realistic mountain
99 /// ranges or terrain features that look like flowing lava rock.  If you
100 /// are generating values for textures, you can use this noise module to
101 /// produce realistic marble-like or "oily" textures.
102 ///
103 /// Internally, there are three module::Perlin noise modules
104 /// that displace the input value; one for the @a x, one for the @a y,
105 /// and one for the @a z coordinate.
106 ///
107 /// This noise module requires one source module.
108 class Turbulence : Mod
109 {
110 
111   public:
112 
113     /// Constructor.
114     ///
115     /// The default frequency is set to
116     /// module::DEFAULT_TURBULENCE_FREQUENCY.
117     ///    
118     /// The default power is set to
119     /// module::DEFAULT_TURBULENCE_POWER.
120     ///
121     /// The default roughness is set to
122     /// module::DEFAULT_TURBULENCE_ROUGHNESS.
123     ///
124     /// The default seed value is set to
125     /// module::DEFAULT_TURBULENCE_SEED.
126     this()
127     {
128         super(this.GetSourceModCount());
129         m_power = DEFAULT_TURBULENCE_POWER;
130         SetSeed (DEFAULT_TURBULENCE_SEED);
131         SetFrequency (DEFAULT_TURBULENCE_FREQUENCY);
132         SetRoughness (DEFAULT_TURBULENCE_ROUGHNESS);
133     }
134 
135     /// Returns the frequency of the turbulence.
136     ///
137     /// @returns The frequency of the turbulence.
138     ///
139     /// The frequency of the turbulence determines how rapidly the
140     /// displacement amount changes.
141     double GetFrequency () const
142     {
143       // Since each module::Perlin noise module has the same frequency, it
144       // does not matter which module we use to retrieve the frequency.
145       return m_xDistortMod.GetFrequency ();
146     }
147 
148     /// Returns the power of the turbulence.
149     ///
150     /// @returns The power of the turbulence.
151     ///
152     /// The power of the turbulence determines the scaling factor that is
153     /// applied to the displacement amount.
154     double GetPower () const
155     {
156       return m_power;
157     }
158 
159     /// Returns the roughness of the turbulence.
160     ///
161     /// @returns The roughness of the turbulence.
162     ///
163     /// The roughness of the turbulence determines the roughness of the
164     /// changes to the displacement amount.  Low values smoothly change
165     /// the displacement amount.  High values roughly change the
166     /// displacement amount, which produces more "kinky" changes.
167     int GetRoughnessCount () const
168     {
169       return m_xDistortMod.GetOctaveCount ();
170     }
171 
172     /// Returns the seed value of the internal Perlin-noise modules that
173     /// are used to displace the input values.
174     ///
175     /// @returns The seed value.
176     ///
177     /// Internally, there are three module::Perlin noise modules
178     /// that displace the input value; one for the @a x, one for the @a y,
179     /// and one for the @a z coordinate.  
180     int GetSeed () const
181     {
182       return m_xDistortMod.GetSeed ();
183     }
184 
185     override int GetSourceModCount () const
186     {
187       return 1;
188     }
189 
190     override double GetValue (double x, double y, double z) const
191     {
192       assert (m_pSourceMod[0] !is null);
193 
194       // Get the values from the three module::Perlin noise modules and
195       // add each value to each coordinate of the input value.  There are also
196       // some offsets added to the coordinates of the input values.  This prevents
197       // the distortion modules from returning zero if the (x, y, z) coordinates,
198       // when multiplied by the frequency, are near an integer boundary.  This is
199       // due to a property of gradient coherent noise, which returns zero at
200       // integer boundaries.
201       double x0, y0, z0;
202       double x1, y1, z1;
203       double x2, y2, z2;
204       x0 = x + (12414.0 / 65536.0);
205       y0 = y + (65124.0 / 65536.0);
206       z0 = z + (31337.0 / 65536.0);
207       x1 = x + (26519.0 / 65536.0);
208       y1 = y + (18128.0 / 65536.0);
209       z1 = z + (60493.0 / 65536.0);
210       x2 = x + (53820.0 / 65536.0);
211       y2 = y + (11213.0 / 65536.0);
212       z2 = z + (44845.0 / 65536.0);
213       double xDistort = x + (m_xDistortMod.GetValue (x0, y0, z0)
214         * m_power);
215       double yDistort = y + (m_yDistortMod.GetValue (x1, y1, z1)
216         * m_power);
217       double zDistort = z + (m_zDistortMod.GetValue (x2, y2, z2)
218         * m_power);
219 
220       // Retrieve the output value at the offsetted input value instead of the
221       // original input value.
222       return m_pSourceMod[0].GetValue (xDistort, yDistort, zDistort);
223     }
224 
225     /// Sets the frequency of the turbulence.
226     ///
227     /// @param frequency The frequency of the turbulence.
228     ///
229     /// The frequency of the turbulence determines how rapidly the
230     /// displacement amount changes.
231     void SetFrequency (double frequency)
232     {
233       // Set the frequency of each Perlin-noise module.
234       m_xDistortMod.SetFrequency (frequency);
235       m_yDistortMod.SetFrequency (frequency);
236       m_zDistortMod.SetFrequency (frequency);
237     }
238 
239     /// Sets the power of the turbulence.
240     ///
241     /// @param power The power of the turbulence.
242     ///
243     /// The power of the turbulence determines the scaling factor that is
244     /// applied to the displacement amount.
245     void SetPower (double power)
246     {
247       m_power = power;
248     }
249 
250     /// Sets the roughness of the turbulence.
251     ///
252     /// @param roughness The roughness of the turbulence.
253     ///
254     /// The roughness of the turbulence determines the roughness of the
255     /// changes to the displacement amount.  Low values smoothly change
256     /// the displacement amount.  High values roughly change the
257     /// displacement amount, which produces more "kinky" changes.
258     ///
259     /// Internally, there are three module::Perlin noise modules
260     /// that displace the input value; one for the @a x, one for the @a y,
261     /// and one for the @a z coordinate.  The roughness value is equal to
262     /// the number of octaves used by the module::Perlin noise
263     /// modules.
264     void SetRoughness (int roughness)
265     {
266       // Set the octave count for each Perlin-noise module.
267       m_xDistortMod.SetOctaveCount (roughness);
268       m_yDistortMod.SetOctaveCount (roughness);
269       m_zDistortMod.SetOctaveCount (roughness);
270     }
271 
272     /// Sets the seed value of the internal noise modules that are used to
273     /// displace the input values.
274     ///
275     /// @param seed The seed value.
276     ///
277     /// Internally, there are three module::Perlin noise modules
278     /// that displace the input value; one for the @a x, one for the @a y,
279     /// and one for the @a z coordinate.  This noise module assigns the
280     /// following seed values to the module::Perlin noise modules:
281     /// - It assigns the seed value (@a seed + 0) to the @a x noise module.
282     /// - It assigns the seed value (@a seed + 1) to the @a y noise module.
283     /// - It assigns the seed value (@a seed + 2) to the @a z noise module.
284     void SetSeed (int seed)
285     {
286       // Set the seed of each module::Perlin noise modules.  To prevent any
287       // sort of weird artifacting, use a slightly different seed for each noise
288       // module.
289       m_xDistortMod.SetSeed (seed    );
290       m_yDistortMod.SetSeed (seed + 1);
291       m_zDistortMod.SetSeed (seed + 2);
292     }
293 
294   protected:
295 
296     /// The power (scale) of the displacement.
297     double m_power;
298 
299     /// Noise module that displaces the @a x coordinate.
300     Perlin m_xDistortMod;
301 
302     /// Noise module that displaces the @a y coordinate.
303     Perlin m_yDistortMod;
304 
305     /// Noise module that displaces the @a z coordinate.
306     Perlin m_zDistortMod;
307 
308 };
309 
310 /// @}
311 
312 /// @}
313 
314 /// @}