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