1 // displace.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.displace;
23 
24 private {
25     import noise.mod.modulebase;
26 }
27 
28 /// @addtogroup libnoise
29 /// @{
30 
31 /// @addtogroup modules
32 /// @{
33 
34 /// @defgroup transformermodules Transformer Mods
35 /// @addtogroup transformermodules
36 /// @{
37 
38 /// Noise module that uses three source modules to displace each
39 /// coordinate of the input value before returning the output value from
40 /// a source module.
41 ///
42 /// @image html moduledisplace.png
43 ///
44 /// Unlike most other noise modules, the index value assigned to a source
45 /// module determines its role in the displacement operation:
46 /// - Source module 0 (left in the diagram) outputs a value.
47 /// - Source module 1 (lower left in the diagram) specifies the offset to
48 ///   apply to the @a x coordinate of the input value.
49 /// - Source module 2 (lower center in the diagram) specifies the
50 ///   offset to apply to the @a y coordinate of the input value.
51 /// - Source module 3 (lower right in the diagram) specifies the offset
52 ///   to apply to the @a z coordinate of the input value.
53 ///
54 /// The GetValue() method modifies the ( @a x, @a y, @a z ) coordinates of
55 /// the input value using the output values from the three displacement
56 /// modules before retrieving the output value from the source module.
57 ///
58 /// The module::Turbulence noise module is a special case of the
59 /// displacement module; internally, there are three Perlin-noise modules
60 /// that perform the displacement operation.
61 ///
62 /// This noise module requires four source modules.
63 class Displace : Mod
64 {
65 
66   public:
67 
68   /// Constructor.
69   this()
70   {
71     super(this.GetSourceModCount());
72   }
73 
74   override int GetSourceModCount () const
75   {
76     return 4;
77   }
78 
79   override double GetValue (double x, double y, double z) const
80   {
81     assert (m_pSourceMod[0] !is null);
82     assert (m_pSourceMod[1] !is null);
83     assert (m_pSourceMod[2] !is null);
84     assert (m_pSourceMod[3] !is null);
85 
86     // Get the output values from the three displacement modules.  Add each
87     // value to the corresponding coordinate in the input value.
88     double xDisplace = x + (m_pSourceMod[1].GetValue (x, y, z));
89     double yDisplace = y + (m_pSourceMod[2].GetValue (x, y, z));
90     double zDisplace = z + (m_pSourceMod[3].GetValue (x, y, z));
91 
92     // Retrieve the output value using the offsetted input value instead of
93     // the original input value.
94     return m_pSourceMod[0].GetValue (xDisplace, yDisplace, zDisplace);
95   }
96 
97   /// Returns the @a x displacement module.
98   ///
99   /// @returns A reference to the @a x displacement module.
100   ///
101   /// @pre This displacement module has been added to this noise module
102   /// via a call to SetSourceMod() or SetXDisplaceMod().
103   ///
104   /// @throw new ExceptionNoMod See the preconditions for more
105   /// information.
106   ///
107   /// The GetValue() method displaces the input value by adding the output
108   /// value from this displacement module to the @a x coordinate of the
109   /// input value before returning the output value from the source
110   /// module.
111   ref const(Mod) GetXDisplaceMod () const
112   {
113     if (m_pSourceMod == null || m_pSourceMod[1] == null) {
114       throw new ExceptionNoMod ();
115     }
116     return *(m_pSourceMod[1]);
117   }
118 
119   /// Returns the @a y displacement module.
120   ///
121   /// @returns A reference to the @a y displacement module.
122   ///
123   /// @pre This displacement module has been added to this noise module
124   /// via a call to SetSourceMod() or SetYDisplaceMod().
125   ///
126   /// @throw new ExceptionNoMod See the preconditions for more
127   /// information.
128   ///
129   /// The GetValue() method displaces the input value by adding the output
130   /// value from this displacement module to the @a y coordinate of the
131   /// input value before returning the output value from the source
132   /// module.
133   ref const(Mod) GetYDisplaceMod () const
134   {
135     if (m_pSourceMod == null || m_pSourceMod[2] == null) {
136       throw new ExceptionNoMod ();
137     }
138     return *(m_pSourceMod[2]);
139   }
140 
141   /// Returns the @a z displacement module.
142   ///
143   /// @returns A reference to the @a z displacement module.
144   ///
145   /// @pre This displacement module has been added to this noise module
146   /// via a call to SetSourceMod() or SetZDisplaceMod().
147   ///
148   /// @throw new ExceptionNoMod See the preconditions for more
149   /// information.
150   ///
151   /// The GetValue() method displaces the input value by adding the output
152   /// value from this displacement module to the @a z coordinate of the
153   /// input value before returning the output value from the source
154   /// module.
155   ref const(Mod) GetZDisplaceMod () const
156   {
157     if (m_pSourceMod == null || m_pSourceMod[3] == null) {
158       throw new ExceptionNoMod ();
159     }
160     return *(m_pSourceMod[3]);
161   }
162 
163   /// Sets the @a x, @a y, and @a z displacement modules.
164   ///
165   /// @param xDisplaceMod Displacement module that displaces the @a x
166   /// coordinate of the input value.
167   /// @param yDisplaceMod Displacement module that displaces the @a y
168   /// coordinate of the input value.
169   /// @param zDisplaceMod Displacement module that displaces the @a z
170   /// coordinate of the input value.
171   ///
172   /// The GetValue() method displaces the input value by adding the output
173   /// value from each of the displacement modules to the corresponding
174   /// coordinates of the input value before returning the output value
175   /// from the source module.
176   ///
177   /// This method assigns an index value of 1 to the @a x displacement
178   /// module, an index value of 2 to the @a y displacement module, and an
179   /// index value of 3 to the @a z displacement module.
180   ///
181   /// These displacement modules must exist throughout the lifetime of
182   /// this noise module unless another displacement module replaces it.
183   void SetDisplaceMods (ref const(Mod) xDisplaceMod,
184     ref const(Mod) yDisplaceMod, ref const(Mod) zDisplaceMod)
185   {
186     SetXDisplaceMod (xDisplaceMod);
187     SetYDisplaceMod (yDisplaceMod);
188     SetZDisplaceMod (zDisplaceMod);
189   }
190 
191   /// Sets the @a x displacement module.
192   ///
193   /// @param xDisplaceMod Displacement module that displaces the @a x
194   /// coordinate.
195   ///
196   /// The GetValue() method displaces the input value by adding the output
197   /// value from this displacement module to the @a x coordinate of the
198   /// input value before returning the output value from the source
199   /// module.
200   ///
201   /// This method assigns an index value of 1 to the @a x displacement
202   /// module.  Passing this displacement module to this method produces
203   /// the same results as passing this displacement module to the
204   /// SetSourceMod() method while assigning it an index value of 1.
205   ///
206   /// This displacement module must exist throughout the lifetime of this
207   /// noise module unless another displacement module replaces it.
208   void SetXDisplaceMod (ref const(Mod) xDisplaceMod)
209   {
210     assert (m_pSourceMod !is null);
211     m_pSourceMod[1] = &xDisplaceMod;
212   }
213 
214   /// Sets the @a y displacement module.
215   ///
216   /// @param yDisplaceMod Displacement module that displaces the @a y
217   /// coordinate.
218   ///
219   /// The GetValue() method displaces the input value by adding the output
220   /// value from this displacement module to the @a y coordinate of the
221   /// input value before returning the output value from the source
222   /// module.
223   ///
224   /// This method assigns an index value of 2 to the @a y displacement
225   /// module.  Passing this displacement module to this method produces
226   /// the same results as passing this displacement module to the
227   /// SetSourceMod() method while assigning it an index value of 2.
228   ///
229   /// This displacement module must exist throughout the lifetime of this
230   /// noise module unless another displacement module replaces it.
231   void SetYDisplaceMod (ref const(Mod) yDisplaceMod)
232   {
233     assert (m_pSourceMod !is null);
234     m_pSourceMod[2] = &yDisplaceMod;
235   }
236 
237   /// Sets the @a z displacement module.
238   ///
239   /// @param zDisplaceMod Displacement module that displaces the @a z
240   /// coordinate.
241   ///
242   /// The GetValue() method displaces the input value by adding the output
243   /// value from this displacement module to the @a z coordinate of the
244   /// input value before returning the output value from the source
245   /// module.
246   ///
247   /// This method assigns an index value of 3 to the @a z displacement
248   /// module.  Passing this displacement module to this method produces
249   /// the same results as passing this displacement module to the
250   /// SetSourceMod() method while assigning it an index value of 3.
251   ///
252   /// This displacement module must exist throughout the lifetime of this
253   /// noise module unless another displacement module replaces it.
254   void SetZDisplaceMod (ref const(Mod) zDisplaceMod)
255   {
256     assert (m_pSourceMod !is null);
257     m_pSourceMod[3] = &zDisplaceMod;
258   }
259 
260 };
261 
262 /// @}
263 
264 /// @}
265 
266 /// @}