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 /// @}