1 // ridgedmulti.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.ridgedmulti;
23 
24 private {
25     import noise.mod.modulebase;
26 }
27 
28 /// @addtogroup libnoise
29 /// @{
30 
31 /// @addtogroup modules
32 /// @{
33 
34 /// @addtogroup generatormodules
35 /// @{
36 
37 /// Default frequency for the module::RidgedMulti noise module.
38 const double DEFAULT_RIDGED_FREQUENCY = 1.0;
39 
40 /// Default lacunarity for the module::RidgedMulti noise module.
41 const double DEFAULT_RIDGED_LACUNARITY = 2.0;
42 
43 /// Default number of octaves for the module::RidgedMulti noise
44 /// module.
45 const int DEFAULT_RIDGED_OCTAVE_COUNT = 6;
46 
47 /// Default noise quality for the module::RidgedMulti noise
48 /// module.
49 const NoiseQuality DEFAULT_RIDGED_QUALITY = NoiseQuality.QUALITY_STD;
50 
51 /// Default noise seed for the module::RidgedMulti noise module.
52 const int DEFAULT_RIDGED_SEED = 0;
53 
54 /// Maximum number of octaves for the module::RidgedMulti noise
55 /// module.
56 const int RIDGED_MAX_OCTAVE = 30;
57 
58 /// Noise module that outputs 3-dimensional ridged-multifractal noise.
59 ///
60 /// @image html moduleridgedmulti.png
61 ///
62 /// This noise module, heavily based on the Perlin-noise module, generates
63 /// ridged-multifractal noise.  Ridged-multifractal noise is generated in
64 /// much of the same way as Perlin noise, except the output of each octave
65 /// is modified by an absolute-value function.  Modifying the octave
66 /// values in this way produces ridge-like formations.
67 ///
68 /// Ridged-multifractal noise does not use a persistence value.  This is
69 /// because the persistence values of the octaves are based on the values
70 /// generated from from previous octaves, creating a feedback loop (or
71 /// that's what it looks like after reading the code.)
72 ///
73 /// This noise module outputs ridged-multifractal-noise values that
74 /// usually range from -1.0 to +1.0, but there are no guarantees that all
75 /// output values will exist within that range.
76 ///
77 /// @note For ridged-multifractal noise generated with only one octave,
78 /// the output value ranges from -1.0 to 0.0.
79 ///
80 /// Ridged-multifractal noise is often used to generate craggy mountainous
81 /// terrain or marble-like textures.
82 ///
83 /// This noise module does not require any source modules.
84 ///
85 /// <b>Octaves</b>
86 ///
87 /// The number of octaves control the <i>amount of detail</i> of the
88 /// ridged-multifractal noise.  Adding more octaves increases the detail
89 /// of the ridged-multifractal noise, but with the drawback of increasing
90 /// the calculation time.
91 ///
92 /// An application may specify the number of octaves that generate
93 /// ridged-multifractal noise by calling the SetOctaveCount() method.
94 ///
95 /// <b>Frequency</b>
96 ///
97 /// An application may specify the frequency of the first octave by
98 /// calling the SetFrequency() method.
99 ///
100 /// <b>Lacunarity</b>
101 ///
102 /// The lacunarity specifies the frequency multipler between successive
103 /// octaves.
104 ///
105 /// The effect of modifying the lacunarity is subtle; you may need to play
106 /// with the lacunarity value to determine the effects.  For best results,
107 /// set the lacunarity to a number between 1.5 and 3.5.
108 ///
109 /// <b>References &amp; Acknowledgments</b>
110 ///
111 /// <a href=http://www.texturingandmodeling.com/Musgrave.html>F.
112 /// Kenton "Doc Mojo" Musgrave's texturing page</a> - This page contains
113 /// links to source code that generates ridged-multfractal noise, among
114 /// other types of noise.  The source file <a
115 /// href=http://www.texturingandmodeling.com/CODE/MUSGRAVE/CLOUD/fractal.c>
116 /// fractal.c</a> contains the code I used in my ridged-multifractal class
117 /// (see the @a RidgedMultifractal() function.)  This code was written by F.
118 /// Kenton Musgrave, the person who created
119 /// <a href=http://www.pandromeda.com/>MojoWorld</a>.  He is also one of
120 /// the authors in <i>Texturing and Modeling: A Procedural Approach</i>
121 /// (Morgan Kaufmann, 2002. ISBN 1-55860-848-6.)
122 class RidgedMulti : Mod
123 {
124 
125   public:
126 
127     /// Constructor.
128     ///
129     /// The default number of octaves is set to
130     /// module::DEFAULT_RIDGED_OCTAVE_COUNT.
131     ///
132     /// The default frequency is set to
133     /// module::DEFAULT_RIDGED_FREQUENCY.
134     ///
135     /// The default lacunarity is set to
136     /// module::DEFAULT_RIDGED_LACUNARITY.
137     ///
138     /// The default seed value is set to
139     /// module::DEFAULT_RIDGED_SEED.
140     this()
141     {
142         super(this.GetSourceModCount ());
143         m_frequency = DEFAULT_RIDGED_FREQUENCY;
144         m_lacunarity = DEFAULT_RIDGED_LACUNARITY;
145         m_noiseQuality = DEFAULT_RIDGED_QUALITY;
146         m_octaveCount = DEFAULT_RIDGED_OCTAVE_COUNT;
147         m_seed = DEFAULT_RIDGED_SEED;
148         this.CalcSpectralWeights ();
149     }
150 
151     /// Returns the frequency of the first octave.
152     ///
153     /// @returns The frequency of the first octave.
154     double GetFrequency () const
155     {
156       return m_frequency;
157     }
158 
159     /// Returns the lacunarity of the ridged-multifractal noise.
160     ///
161     /// @returns The lacunarity of the ridged-multifractal noise.
162     /// 
163     /// The lacunarity is the frequency multiplier between successive
164     /// octaves.
165     double GetLacunarity () const
166     {
167       return m_lacunarity;
168     }
169 
170     /// Returns the quality of the ridged-multifractal noise.
171     ///
172     /// @returns The quality of the ridged-multifractal noise.
173     ///
174     /// See NoiseQuality for definitions of the various
175     /// coherent-noise qualities.
176     NoiseQuality GetNoiseQuality () const
177     {
178       return m_noiseQuality;
179     }
180 
181     /// Returns the number of octaves that generate the
182     /// ridged-multifractal noise.
183     ///
184     /// @returns The number of octaves that generate the
185     /// ridged-multifractal noise.
186     ///
187     /// The number of octaves controls the amount of detail in the
188     /// ridged-multifractal noise.
189     int GetOctaveCount () const
190     {
191       return m_octaveCount;
192     }
193 
194     /// Returns the seed value used by the ridged-multifractal-noise
195     /// function.
196     ///
197     /// @returns The seed value.
198     int GetSeed () const
199     {
200       return m_seed;
201     }
202 
203     override int GetSourceModCount () const
204     {
205       return 0;
206     }
207 
208     // Multifractal code originally written by F. Kenton "Doc Mojo" Musgrave,
209     // 1998.  Modified by jas for use with libnoise.
210     override double GetValue (double x, double y, double z) const
211     {
212       x *= m_frequency;
213       y *= m_frequency;
214       z *= m_frequency;
215 
216       double signal = 0.0;
217       double value  = 0.0;
218       double weight = 1.0;
219 
220       // These parameters should be user-defined; they may be exposed in a
221       // future version of libnoise.
222       double offset = 1.0;
223       double gain = 2.0;
224 
225       for (int curOctave = 0; curOctave < m_octaveCount; curOctave++) {
226 
227         // Make sure that these floating-point values have the same range as a 32-
228         // bit integer so that we can pass them to the coherent-noise functions.
229         double nx, ny, nz;
230         nx = MakeInt32Range (x);
231         ny = MakeInt32Range (y);
232         nz = MakeInt32Range (z);
233 
234         // Get the coherent-noise value.
235         int seed = (m_seed + curOctave) & 0x7fffffff;
236         signal = GradientCoherentNoise3D (nx, ny, nz, seed, m_noiseQuality);
237 
238         // Make the ridges.
239         signal = fabs (signal);
240         signal = offset - signal;
241 
242         // Square the signal to increase the sharpness of the ridges.
243         signal *= signal;
244 
245         // The weighting from the previous octave is applied to the signal.
246         // Larger values have higher weights, producing sharp points along the
247         // ridges.
248         signal *= weight;
249 
250         // Weight successive contributions by the previous signal.
251         weight = signal * gain;
252         if (weight > 1.0) {
253           weight = 1.0;
254         }
255         if (weight < 0.0) {
256           weight = 0.0;
257         }
258 
259         // Add the signal to the output value.
260         value += (signal * m_pSpectralWeights[curOctave]);
261 
262         // Go to the next octave.
263         x *= m_lacunarity;
264         y *= m_lacunarity;
265         z *= m_lacunarity;
266       }
267 
268       return (value * 1.25) - 1.0;
269     }
270 
271     /// Sets the frequency of the first octave.
272     ///
273     /// @param frequency The frequency of the first octave.
274     void SetFrequency (double frequency)
275     {
276       m_frequency = frequency;
277     }
278 
279     /// Sets the lacunarity of the ridged-multifractal noise.
280     ///
281     /// @param lacunarity The lacunarity of the ridged-multifractal noise.
282     /// 
283     /// The lacunarity is the frequency multiplier between successive
284     /// octaves.
285     ///
286     /// For best results, set the lacunarity to a number between 1.5 and
287     /// 3.5.
288     void SetLacunarity (double lacunarity)
289     {
290       m_lacunarity = lacunarity;
291       CalcSpectralWeights ();
292     }
293 
294     /// Sets the quality of the ridged-multifractal noise.
295     ///
296     /// @param noiseQuality The quality of the ridged-multifractal noise.
297     ///
298     /// See NoiseQuality for definitions of the various
299     /// coherent-noise qualities.
300     void SetNoiseQuality (NoiseQuality noiseQuality)
301     {
302       m_noiseQuality = noiseQuality;
303     }
304 
305     /// Sets the number of octaves that generate the ridged-multifractal
306     /// noise.
307     ///
308     /// @param octaveCount The number of octaves that generate the
309     /// ridged-multifractal noise.
310     ///
311     /// @pre The number of octaves ranges from 1 to
312     /// module::RIDGED_MAX_OCTAVE.
313     ///
314     /// @throw new ExceptionInvalidParam An invalid parameter was
315     /// specified; see the preconditions for more information.
316     ///
317     /// The number of octaves controls the amount of detail in the
318     /// ridged-multifractal noise.
319     ///
320     /// The larger the number of octaves, the more time required to
321     /// calculate the ridged-multifractal-noise value.
322     void SetOctaveCount (int octaveCount)
323     {
324       if (octaveCount > RIDGED_MAX_OCTAVE) {
325         throw new ExceptionInvalidParam ();
326       }
327       m_octaveCount = octaveCount;
328     }
329 
330     /// Sets the seed value used by the ridged-multifractal-noise
331     /// function.
332     ///
333     /// @param seed The seed value.
334     void SetSeed (int seed)
335     {
336       m_seed = seed;
337     }
338 
339   protected:
340 
341     /// Calculates the spectral weights for each octave.
342     ///
343     /// This method is called when the lacunarity changes.
344     void CalcSpectralWeights ()
345     {
346       // This exponent parameter should be user-defined; it may be exposed in a
347       // future version of libnoise.
348       double h = 1.0;
349 
350       double frequency = 1.0;
351       for (int i = 0; i < RIDGED_MAX_OCTAVE; i++) {
352         // Compute weight for each frequency.
353         m_pSpectralWeights[i] = pow (frequency, -h);
354         frequency *= m_lacunarity;
355       }
356     }
357 
358     /// Frequency of the first octave.
359     double m_frequency;
360 
361     /// Frequency multiplier between successive octaves.
362     double m_lacunarity;
363 
364     /// Quality of the ridged-multifractal noise.
365     NoiseQuality m_noiseQuality;
366 
367     /// Total number of octaves that generate the ridged-multifractal
368     /// noise.
369     int m_octaveCount;
370 
371     /// Contains the spectral weights for each octave.
372     double[RIDGED_MAX_OCTAVE] m_pSpectralWeights;
373 
374     /// Seed value used by the ridged-multfractal-noise function.
375     int m_seed;
376 
377 };
378 
379 /// @}
380 
381 /// @}
382 
383 /// @}