Gamedev Framework (gf)  0.6.0
A C++11 framework for 2D games
Heightmap.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016-2017 Julien Bernard
4  *
5  * This software is provided 'as-is', without any express or implied
6  * warranty. In no event will the authors be held liable for any damages
7  * arising from the use of this software.
8  *
9  * Permission is granted to anyone to use this software for any purpose,
10  * including commercial applications, and to alter it and redistribute it
11  * freely, subject to the following restrictions:
12  *
13  * 1. The origin of this software must not be misrepresented; you must not
14  * claim that you wrote the original software. If you use this software
15  * in a product, an acknowledgment in the product documentation would be
16  * appreciated but is not required.
17  * 2. Altered source versions must be plainly marked as such, and must not be
18  * misrepresented as being the original software.
19  * 3. This notice may not be removed or altered from any source distribution.
20  */
21 #ifndef GF_HEIGHTMAP_H
22 #define GF_HEIGHTMAP_H
23 
24 #include <tuple>
25 
26 #include "Array2D.h"
27 #include "ColorRamp.h"
28 #include "Image.h"
29 #include "Noise.h"
30 #include "Portability.h"
31 #include "Rect.h"
32 
33 namespace gf {
34 #ifndef DOXYGEN_SHOULD_SKIP_THIS
35 inline namespace v1 {
36 #endif
37 
38  /**
39  * @ingroup core
40  * @brief A heightmap
41  *
42  * @sa gf::midpointDisplacement2D(), gf::diamondSquare2D()
43  */
44  class GF_API Heightmap {
45  public:
46  /**
47  * @brief Constructor
48  *
49  * @param size The size of the heightmap
50  */
51  Heightmap(Vector2i size);
52 
53  /**
54  * @brief Get the size of the heightmap
55  *
56  * @returns The current size of the heightmap
57  */
58  Vector2i getSize() const {
59  return m_data.getSize();
60  }
61 
62  /**
63  * @brief Reset the heightmap
64  *
65  * The values are all set to @f$ 0.0 @f$
66  */
67  void reset();
68 
69  /**
70  * @brief Get the value at the specified position
71  *
72  * @param position A position
73  * @returns The value at the given position
74  */
75  double getValue(Vector2i position) const {
76  return m_data(position);
77  }
78 
79  /**
80  * @brief Set the value at the specified position
81  *
82  * @param position A position
83  * @param value The new value
84  */
85  void setValue(Vector2i position, double value) {
86  m_data(position) = value;
87  }
88 
89  /**
90  * @brief Get the minimum and maximum of the heightmap
91  *
92  * @returns A pair with the first element being the minimum and the second element the maximum
93  */
94  std::tuple<double, double> getMinMax() const;
95 
96  /**
97  * @name Shaping
98  * @{
99  */
100 
101  /**
102  * @brief Normalize the heightmap
103  *
104  * @param min The new minimum value (defaults to @f$ 0.0 @f$)
105  * @param max The new maximum value (defaults to @f$ 1.0 @f$)
106  */
107  void normalize(double min = 0.0, double max = 1.0);
108 
109  /**
110  * @brief Add a hill to the heightmap
111  *
112  * @param center The center of the hill
113  * @param radius The radius of the hill
114  * @param height The height of the hill
115  */
116  void addHill(Vector2d center, double radius, double height);
117 
118  /**
119  * @brief Dig a hill in the heightmap
120  *
121  * @param center The center of the hill
122  * @param radius The radius of the hill
123  * @param height The height of the hill
124  */
125  void digHill(Vector2d center, double radius, double height);
126 
127  /**
128  * @brief Add a noise to the heightmap
129  *
130  * @param noise The noise to use
131  * @param scale The scale of the noise
132  */
133  void addNoise(Noise2D& noise, double scale = 1.0);
134 
135  /**
136  * @brief Add a constant to the heightmap
137  *
138  * @param value The value of the constant
139  */
140  void addValue(double value);
141 
142  /**
143  * @brief Scale the values of the heightmap
144  *
145  * @param value The factor of scaling
146  */
147  void scale(double value);
148 
149  /**
150  * @brief Clamp the values of the heightmap
151  *
152  * @param min The minimum value (defaults to @f$ 0.0 @f$)
153  * @param max The maximum value (defaults to @f$ 1.0 @f$)
154  * @sa normalize()
155  */
156  void clamp(double min = 0.0, double max = 1.0);
157 
158  /**
159  * @}
160  */
161 
162  /**
163  * @name Erosion
164  * @{
165  */
166 
167  /**
168  * @brief Compute the slope at a position
169  *
170  * The slope is defined as "the greatest of the height differences between
171  * the cell and its four neighbours in a Von Neumann neighbourhood".
172  *
173  * @f[ \text{slope}(x, y) = \max(|h(x,y) - h(x - 1, y)|, |h(x,y) - h(x + 1, y)|, |h(x,y) - h(x, y - 1)|, |h(x,y) - h(x, y + 1)|) @f]
174  *
175  * @param position The given position
176  */
177  double getSlope(Vector2i position) const;
178 
179  /**
180  * @brief Apply thermal erosion to the heightmap
181  *
182  * @param iterations The number of iterations
183  * @param talus The minimum difference for a move of material (typically @f$ \frac{4}{N} @f$)
184  * @param fraction The fraction of material that moves (typically @f$ 0.5 @f$)
185  */
186  void thermalErosion(unsigned iterations, double talus, double fraction);
187 
188  /**
189  * @brief Apply hydraulic erosision to the heightmap
190  *
191  * @param iterations The number of iterations
192  * @param rainAmount The amount of rain each cell receives at each iteration (typically @f$ 0.01 @f$)
193  * @param solubility The solubility of the terrain (typically @f$ 0.01 @f$)
194  * @param evaporation The proportion of evaporated water at each iteration (typically @f$ 0.5 @f$)
195  * @param capacity The maximum proportion of material that can be carried by water (typically @f$ 0.01 @f$)
196  */
197  void hydraulicErosion(unsigned iterations, double rainAmount, double solubility, double evaporation, double capacity);
198 
199  /**
200  * @brief Apply fast erosion to the heightmap
201  *
202  * @param iterations The number of iterations
203  * @param talus The maximum difference for a move of material (typically @f$ \frac{8}{N} @f$ or more)
204  * @param fraction The fraction of material that moves (typically @f$ 0.5 @f$)
205  */
206  void fastErosion(unsigned iterations, double talus, double fraction);
207 
208  /**
209  * @brief Compute the erosion score for the heightmap
210  *
211  * The erosion score is the average slope divided by the standard
212  * deviation of slopes. A high erosion score means that the terrain has
213  * large flat areas and has some steep areas.
214  */
215  double getErosionScore() const;
216 
217  /**
218  * @}
219  */
220 
221  /**
222  * @brief Rendering mode
223  */
224  enum class Render {
225  Colored, ///< Export to a simply colored image
226  Shaded, ///< Export to a shaded image
227  };
228 
229  /**
230  * @name Export
231  * @{
232  */
233 
234  /**
235  * @brief Get a sub-map of the heightmap
236  *
237  * @param area The area of the sub-map in the heightmap
238  */
239  Heightmap subMap(RectI area) const;
240 
241  /**
242  * @brief Export to a grayscale image
243  *
244  * The heightmap is assumed to be normalized.
245  *
246  * @returns A grayscale image representing the heightmap
247  *
248  * @sa copyToColoredImage()
249  */
250  Image copyToGrayscaleImage() const;
251 
252  /**
253  * @brief Export to a colored image
254  *
255  * The heightmap is assumed to be normalized.
256  *
257  * The color ramp assumes that the water level is at @f$ 0.5 @f$. The
258  * actual water level can be specified and the ramp is automatically
259  * adapted on the fly.
260  *
261  * @param ramp A color ramp
262  * @param waterLevel The actual water level (defaults to @f$ 0.5 @f$)
263  * @param render The rendering mode
264  * @returns A colored image representing the heightmap
265  *
266  * @sa copyToGrayscaleImage()
267  */
268  Image copyToColoredImage(const ColorRamp& ramp, double waterLevel = 0.5, Render render = Render::Colored) const;
269 
270  /**
271  * @}
272  */
273 
274  private:
275  Array2D<double, int> m_data;
276  };
277 
278 #ifndef DOXYGEN_SHOULD_SKIP_THIS
279 }
280 #endif
281 }
282 
283 #endif // GF_HEIGHTMAP_H
void setValue(Vector2i position, double value)
Set the value at the specified position.
Definition: Heightmap.h:85
A two-dimensional array.
Definition: Array2D.h:63
void digHill(Vector2d center, double radius, double height)
Dig a hill in the heightmap.
double getErosionScore() const
Compute the erosion score for the heightmap.
void fastErosion(unsigned iterations, double talus, double fraction)
Apply fast erosion to the heightmap.
void addNoise(Noise2D &noise, double scale=1.0)
Add a noise to the heightmap.
A color ramp.
Definition: ColorRamp.h:41
Image copyToColoredImage(const ColorRamp &ramp, double waterLevel=0.5, Render render=Render::Colored) const
Export to a colored image.
void addHill(Vector2d center, double radius, double height)
Add a hill to the heightmap.
Export to a shaded image.
A heightmap.
Definition: Heightmap.h:44
Heightmap(Vector2i size)
Constructor.
2D A noise function
Definition: Noise.h:35
void scale(double value)
Scale the values of the heightmap.
Export to a simply colored image.
Vector2i getSize() const
Get the size of the heightmap.
Definition: Heightmap.h:58
Render
Rendering mode.
Definition: Heightmap.h:224
Class for loading, manipulating and saving images.
Definition: Image.h:92
The namespace for gf classes.
Definition: Action.h:34
void hydraulicErosion(unsigned iterations, double rainAmount, double solubility, double evaporation, double capacity)
Apply hydraulic erosision to the heightmap.
void reset()
Reset the heightmap.
double getSlope(Vector2i position) const
Compute the slope at a position.
void clamp(double min=0.0, double max=1.0)
Clamp the values of the heightmap.
double getValue(Vector2i position) const
Get the value at the specified position.
Definition: Heightmap.h:75
std::tuple< double, double > getMinMax() const
Get the minimum and maximum of the heightmap.
void normalize(double min=0.0, double max=1.0)
Normalize the heightmap.
#define GF_API
Definition: Portability.h:35
void addValue(double value)
Add a constant to the heightmap.
Image copyToGrayscaleImage() const
Export to a grayscale image.
void thermalErosion(unsigned iterations, double talus, double fraction)
Apply thermal erosion to the heightmap.
Heightmap subMap(RectI area) const
Get a sub-map of the heightmap.