1 // modulebase.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 
23 #ifndef NOISE_MODULEBASE_H
24 #define NOISE_MODULEBASE_H
25 
26 #include <stdlib.h>
27 #include <assert.h>
28 #include <math.h>
29 #include "../basictypes.h"
30 #include "../exception.h"
31 #include "../noisegen.h"
32 
33 namespace noise
34 {
35 
36   namespace module
37   {
38 
39     /// @addtogroup libnoise
40     /// @{
41 
42     /// @defgroup modules Noise Modules
43     /// @addtogroup modules
44     /// @{
45 
46     /// Abstract base class for noise modules.
47     ///
48     /// A <i>noise module</i> is an object that calculates and outputs a value
49     /// given a three-dimensional input value.
50     ///
51     /// Each type of noise module uses a specific method to calculate an
52     /// output value.  Some of these methods include:
53     ///
54     /// - Calculating a value using a coherent-noise function or some other
55     ///   mathematical function.
56     /// - Mathematically changing the output value from another noise module
57     ///   in various ways.
58     /// - Combining the output values from two noise modules in various ways.
59     ///
60     /// An application can use the output values from these noise modules in
61     /// the following ways:
62     ///
63     /// - It can be used as an elevation value for a terrain height map
64     /// - It can be used as a grayscale (or an RGB-channel) value for a
65     ///   procedural texture
66     /// - It can be used as a position value for controlling the movement of a
67     ///   simulated lifeform.
68     ///
69     /// A noise module defines a near-infinite 3-dimensional texture.  Each
70     /// position in this "texture" has a specific value.
71     ///
72     /// <b>Combining noise modules</b>
73     ///
74     /// Noise modules can be combined with other noise modules to generate
75     /// complex output values.  A noise module that is used as a source of
76     /// output values for another noise module is called a <i>source
77     /// module</i>.  Each of these source modules may be connected to other
78     /// source modules, and so on.
79     ///
80     /// There is no limit to the number of noise modules that can be connected
81     /// together in this way.  However, each connected noise module increases
82     /// the time required to calculate an output value.
83     ///
84     /// <b>Noise-module categories</b>
85     ///
86     /// The noise module classes that are included in libnoise can be roughly
87     /// divided into five categories.
88     ///
89     /// <i>Generator Modules</i>
90     ///
91     /// A generator module outputs a value generated by a coherent-noise
92     /// function or some other mathematical function.
93     ///
94     /// Examples of generator modules include:
95     /// - noise::module::Const: Outputs a constant value.
96     /// - noise::module::Perlin: Outputs a value generated by a Perlin-noise
97     ///   function.
98     /// - noise::module::Voronoi: Outputs a value generated by a Voronoi-cell
99     ///   function.
100     ///
101     /// <i>Modifier Modules</i>
102     ///
103     /// A modifer module mathematically modifies the output value from a
104     /// source module.
105     ///
106     /// Examples of modifier modules include:
107     /// - noise::module::Curve: Maps the output value from the source module
108     ///   onto an arbitrary function curve.
109     /// - noise::module::Invert: Inverts the output value from the source
110     ///   module.
111     ///
112     /// <i>Combiner Modules</i>
113     ///
114     /// A combiner module mathematically combines the output values from two
115     /// or more source modules together.
116     ///
117     /// Examples of combiner modules include:
118     /// - noise::module::Add: Adds the two output values from two source
119     ///   modules.
120     /// - noise::module::Max: Outputs the larger of the two output values from
121     ///   two source modules.
122     ///
123     /// <i>Selector Modules</i>
124     ///
125     /// A selector module uses the output value from a <i>control module</i>
126     /// to specify how to combine the output values from its source modules.
127     ///
128     /// Examples of selector modules include:
129     /// - noise::module::Blend: Outputs a value that is linearly interpolated
130     ///   between the output values from two source modules; the interpolation
131     ///   weight is determined by the output value from the control module.
132     /// - noise::module::Select: Outputs the value selected from one of two
133     ///   source modules chosen by the output value from a control module.
134     ///
135     /// <i>Transformer Modules</i>
136     ///
137     /// A transformer module applies a transformation to the coordinates of
138     /// the input value before retrieving the output value from the source
139     /// module.  A transformer module does not modify the output value.
140     ///
141     /// Examples of transformer modules include:
142     /// - RotatePoint: Rotates the coordinates of the input value around the
143     ///   origin before retrieving the output value from the source module.
144     /// - ScalePoint: Multiplies each coordinate of the input value by a
145     ///   constant value before retrieving the output value from the source
146     ///   module.
147     ///
148     /// <b>Connecting source modules to a noise module</b>
149     ///
150     /// An application connects a source module to a noise module by passing
151     /// the source module to the SetSourceModule() method.
152     ///
153     /// The application must also pass an <i>index value</i> to
154     /// SetSourceModule() as well.  An index value is a numeric identifier for
155     /// that source module.  Index values are consecutively numbered starting
156     /// at zero.
157     ///
158     /// To retrieve a reference to a source module, pass its index value to
159     /// the GetSourceModule() method.
160     ///
161     /// Each noise module requires the attachment of a certain number of
162     /// source modules before it can output a value.  For example, the
163     /// noise::module::Add module requires two source modules, while the
164     /// noise::module::Perlin module requires none.  Call the
165     /// GetSourceModuleCount() method to retrieve the number of source modules
166     /// required by that module.
167     ///
168     /// For non-selector modules, it usually does not matter which index value
169     /// an application assigns to a particular source module, but for selector
170     /// modules, the purpose of a source module is defined by its index value.
171     /// For example, consider the noise::module::Select noise module, which
172     /// requires three source modules.  The control module is the source
173     /// module assigned an index value of 2.  The control module determines
174     /// whether the noise module will output the value from the source module
175     /// assigned an index value of 0 or the output value from the source
176     /// module assigned an index value of 1.
177     ///
178     /// <b>Generating output values with a noise module</b>
179     ///
180     /// Once an application has connected all required source modules to a
181     /// noise module, the application can now begin to generate output values
182     /// with that noise module.
183     ///
184     /// To generate an output value, pass the ( @a x, @a y, @a z ) coordinates
185     /// of an input value to the GetValue() method.
186     ///
187     /// <b>Using a noise module to generate terrain height maps or textures</b>
188     ///
189     /// One way to generate a terrain height map or a texture is to first
190     /// allocate a 2-dimensional array of floating-point values.  For each
191     /// array element, pass the array subscripts as @a x and @a y coordinates
192     /// to the GetValue() method (leaving the @a z coordinate set to zero) and
193     /// place the resulting output value into the array element.
194     ///
195     /// <b>Creating your own noise modules</b>
196     ///
197     /// Create a class that publicly derives from noise::module::Module.
198     ///
199     /// In the constructor, call the base class' constructor while passing the
200     /// return value from GetSourceModuleCount() to it.
201     ///
202     /// Override the GetSourceModuleCount() pure virtual method.  From this
203     /// method, return the number of source modules required by your noise
204     /// module.
205     ///
206     /// Override the GetValue() pure virtual method.  For generator modules,
207     /// calculate and output a value given the coordinates of the input value.
208     /// For other modules, retrieve the output values from each source module
209     /// referenced in the protected @a m_pSourceModule array, mathematically
210     /// combine those values, and return the combined value.
211     ///
212     /// When developing a noise module, you must ensure that your noise module
213     /// does not modify any source module or control module connected to it; a
214     /// noise module can only modify the output value from those source
215     /// modules.  You must also ensure that if an application fails to connect
216     /// all required source modules via the SetSourceModule() method and then
217     /// attempts to call the GetValue() method, your module will raise an
218     /// assertion.
219     ///
220     /// It shouldn't be too difficult to create your own noise module.  If you
221     /// still have some problems, take a look at the source code for
222     /// noise::module::Add, which is a very simple noise module.
223     class Module
224     {
225 
226       public:
227 
228         /// Constructor.
229         Module (int sourceModuleCount);
230 
231         /// Destructor.
232         virtual ~Module ();
233 
234         /// Returns a reference to a source module connected to this noise
235         /// module.
236         ///
237         /// @param index The index value assigned to the source module.
238         ///
239         /// @returns A reference to the source module.
240         ///
241         /// @pre The index value ranges from 0 to one less than the number of
242         /// source modules required by this noise module.
243         /// @pre A source module with the specified index value has been added
244         /// to this noise module via a call to SetSourceModule().
245         ///
246         /// @throw noise::ExceptionNoModule See the preconditions for more
247         /// information.
248         ///
249         /// Each noise module requires the attachment of a certain number of
250         /// source modules before an application can call the GetValue()
251         /// method.
GetSourceModule(int index)252         virtual const Module& GetSourceModule (int index) const
253         {
254           assert (m_pSourceModule != NULL);
255 
256           // The following fix was provided by Will Hawkins:
257           //
258           //   m_pSourceModule[index] != NULL
259           //
260           // was incorrect; it should be:
261           //
262           //   m_pSourceModule[index] == NULL
263           if (index >= GetSourceModuleCount () || index < 0
264             || m_pSourceModule[index] == NULL) {
265             throw noise::ExceptionNoModule ();
266           }
267           return *(m_pSourceModule[index]);
268         }
269 
270         /// Returns the number of source modules required by this noise
271         /// module.
272         ///
273         /// @returns The number of source modules required by this noise
274         /// module.
275         virtual int GetSourceModuleCount () const = 0;
276 
277         /// Generates an output value given the coordinates of the specified
278         /// input value.
279         ///
280         /// @param x The @a x coordinate of the input value.
281         /// @param y The @a y coordinate of the input value.
282         /// @param z The @a z coordinate of the input value.
283         ///
284         /// @returns The output value.
285         ///
286         /// @pre All source modules required by this noise module have been
287         /// passed to the SetSourceModule() method.
288         ///
289         /// Before an application can call this method, it must first connect
290         /// all required source modules via the SetSourceModule() method.  If
291         /// these source modules are not connected to this noise module, this
292         /// method raises a debug assertion.
293         ///
294         /// To determine the number of source modules required by this noise
295         /// module, call the GetSourceModuleCount() method.
296         virtual double GetValue (double x, double y, double z) const = 0;
297 
298         /// Connects a source module to this noise module.
299         ///
300         /// @param index An index value to assign to this source module.
301         /// @param sourceModule The source module to attach.
302         ///
303         /// @pre The index value ranges from 0 to one less than the number of
304         /// source modules required by this noise module.
305         ///
306         /// @throw noise::ExceptionInvalidParam An invalid parameter was
307         /// specified; see the preconditions for more information.
308         ///
309         /// A noise module mathematically combines the output values from the
310         /// source modules to generate the value returned by GetValue().
311         ///
312         /// The index value to assign a source module is a unique identifier
313         /// for that source module.  If an index value has already been
314         /// assigned to a source module, this noise module replaces the old
315         /// source module with the new source module.
316         ///
317         /// Before an application can call the GetValue() method, it must
318         /// first connect all required source modules.  To determine the
319         /// number of source modules required by this noise module, call the
320         /// GetSourceModuleCount() method.
321         ///
322         /// This source module must exist throughout the lifetime of this
323         /// noise module unless another source module replaces that source
324         /// module.
325         ///
326         /// A noise module does not modify a source module; it only modifies
327         /// its output values.
SetSourceModule(int index,const Module & sourceModule)328         virtual void SetSourceModule (int index, const Module& sourceModule)
329         {
330           assert (m_pSourceModule != NULL);
331           if (index >= GetSourceModuleCount () || index < 0) {
332             throw noise::ExceptionInvalidParam ();
333           }
334           m_pSourceModule[index] = &sourceModule;
335         }
336 
337       protected:
338 
339         /// An array containing the pointers to each source module required by
340         /// this noise module.
341         const Module** m_pSourceModule;
342 
343       private:
344 
345         /// Assignment operator.
346         ///
347         /// This assignment operator does nothing and cannot be overridden.
348         /// This restriction is necessary because if this object was copied,
349         /// all source modules assigned to this noise module would need to be
350         /// copied as well.
351         const Module& operator= (const Module& m)
352         {
353           return *this;
354         }
355 
356     };
357 
358     /// @}
359 
360     /// @}
361 
362   }
363 
364 }
365 
366 #endif
367