TDME2  1.9.200
Terrain.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <tdme/tdme.h>
5 
6 #include <unordered_map>
7 #include <unordered_set>
8 #include <vector>
9 
13 #include <tdme/engine/Transform.h>
14 #include <tdme/math/Vector2.h>
15 #include <tdme/math/Vector3.h>
16 
17 using std::unordered_map;
18 using std::unordered_set;
19 using std::vector;
20 
27 
28 /**
29  * Terrain utility
30  * @author Andreas Drewke
31  */
33 {
34 public:
35  static constexpr float STEP_SIZE { 1.0f };
36  static constexpr float PARTITION_SIZE { 64.0f };
37 
38  struct FoliageBrush {
40  float brushScale;
41  float brushDensity;
42  };
43 
46  float count;
48  float rotationXMin;
49  float rotationXMax;
50  float rotationYMin;
51  float rotationYMax;
52  float rotationZMin;
53  float rotationZMax;
54  float scaleMin;
55  float scaleMax;
56  float heightMin;
57  float heightMax;
58  float slopeMin;
59  float slopeMax;
60  };
61 
62 private:
63  /**
64  * Get the terrain vertex for given x and z position without providing y component
65  * @param x x
66  * @param z z
67  * @return terrain vertex
68  */
69  inline static void getTerrainVertex(int x, int z, Vector3& vertex) {
70  vertex.set(
71  static_cast<float>(x) * STEP_SIZE,
72  0.0f,
73  static_cast<float>(z) * STEP_SIZE
74  );
75  }
76  /**
77  * Get the terrain vertex for given x and z position
78  * @param terrainHeightVector terrain height vector
79  * @param verticesPerX vertices per x
80  * @param verticesPerZ vertices per z
81  * @param x x
82  * @param z z
83  * @return terrain vertex
84  */
85  inline static bool getTerrainVertex(const vector<float>& terrainHeightVector, int verticesPerX, int verticesPerZ, int x, int z, Vector3& vertex) {
86  vertex.set(
87  static_cast<float>(x) * STEP_SIZE,
88  0.0f,
89  static_cast<float>(z) * STEP_SIZE
90  );
91  if (x < 0 || x >= verticesPerX) return false;
92  if (z < 0 || z >= verticesPerZ) return false;
93  vertex.set(
94  static_cast<float>(x) * STEP_SIZE,
95  terrainHeightVector[z * verticesPerX + x],
96  static_cast<float>(z) * STEP_SIZE
97  );
98  return true;
99  }
100 
101  /**
102  * Get the terrain vertex for given x and z position
103  * @param x x
104  * @param z z
105  * @param waterHeight water height
106  * @param vertex vertex
107  */
108  inline static void getWaterVertex(int x, int z, float waterHeight, Vector3& vertex) {
109  vertex.set(
110  static_cast<float>(x) * STEP_SIZE,
111  waterHeight,
112  static_cast<float>(z) * STEP_SIZE
113  );
114  }
115 
116  /**
117  * @returns if water includes given position
118  * @param waterPositionSet water position set
119  * @param x x
120  * @param z z
121  */
122  inline static bool hasWaterPosition(const unordered_map<int, unordered_set<int>>& waterPositionSet, int x, int z) {
123  auto waterPositionSetIt = waterPositionSet.find(z);
124  if (waterPositionSetIt == waterPositionSet.end()) return false;
125  auto waterXPositionSetIt = waterPositionSetIt->second.find(x);
126  if (waterXPositionSetIt == waterPositionSetIt->second.end()) return false;
127  return true;
128  }
129 
130  /**
131  * Compute terrain vertex normal for given x and z position
132  * @param terrainHeightVector terrain height vector
133  * @param verticesPerX vertices per x
134  * @param verticesPerZ vertices per z
135  * @param x x
136  * @param z z
137  * @return normal for given vertex index
138  */
139  static const Vector3 computeTerrainVertexNormal(const vector<float>& terrainHeightVector, int verticesPerX, int verticesPerZ, int x, int z);
140 
141  /**
142  * Determine if water can be generated
143  * @param terrainHeightVector terrain height vector
144  * @param verticesPerX vertices per x
145  * @param verticesPerZ vertices per z
146  * @param x x
147  * @param z z
148  * @param waterHeight water height
149  * @return if water can be generated at given position
150  */
151  inline static bool determineWater(const vector<float>& terrainHeightVector, int verticesPerX, int verticesPerZ, int x, int z, float waterHeight) {
152  if (x < 0 || x >= verticesPerX ||
153  z < 0 || z >= verticesPerZ) return false;
154  auto vertexIdx = z * verticesPerX + x;
155  auto terrainVertexHeight = terrainHeightVector[vertexIdx];
156  if (terrainVertexHeight >= waterHeight) return false;
157  return true;
158  }
159 
160  /**
161  * Determine if water can be generated from left to right starting with x and z
162  * @param terrainHeightVector terrain height vector
163  * @param verticesPerX vertices per x
164  * @param verticesPerZ vertices per z
165  * @param x x
166  * @param z z
167  * @param waterHeight water height
168  * @param waterXPositionSet water x position set
169  * @return if water can be generated at given position
170  */
171  inline static void determineWaterXPositionSet(const vector<float>& terrainHeightVector, int verticesPerX, int verticesPerZ, int x, int z, float waterHeight, unordered_set<int>& waterXPositionSet) {
172  auto xMin = -1;
173  auto xMax = +1;
174  while(true == true) {
175  auto terrainHeightVectorX = x + xMin;
176  if (terrainHeightVectorX < 0 || terrainHeightVectorX >= verticesPerX ||
177  z < 0 || z >= verticesPerZ) break;
178  auto vertexIdx = z * verticesPerX + terrainHeightVectorX;
179  auto terrainVertexHeight = terrainHeightVector[vertexIdx];
180  if (terrainVertexHeight >= waterHeight) break;
181  waterXPositionSet.insert(terrainHeightVectorX);
182  xMin--;
183  }
184  while(true == true) {
185  auto terrainHeightVectorX = x + xMax;
186  if (terrainHeightVectorX < 0 || terrainHeightVectorX >= verticesPerX ||
187  z < 0 || z >= verticesPerZ) break;
188  auto vertexIdx = z * verticesPerX + terrainHeightVectorX;
189  auto terrainVertexHeight = terrainHeightVector[vertexIdx];
190  if (terrainVertexHeight >= waterHeight) break;
191  waterXPositionSet.insert(terrainHeightVectorX);
192  xMax++;
193  }
194  if (waterXPositionSet.size() > 2) {
195  waterXPositionSet.insert(x + xMin - 0);
196  waterXPositionSet.insert(x + xMin - 1);
197  waterXPositionSet.insert(x + xMin - 2);
198  waterXPositionSet.insert(x + xMax + 0);
199  waterXPositionSet.insert(x + xMax + 1);
200  waterXPositionSet.insert(x + xMax + 2);
201  }
202  }
203 
204 public:
215  };
216 
217  /**
218  * Create terrain navigation map
219  * @param width width
220  * @param depth depth
221  * @param terrainHeightVector terrain height vector
222  * @param maxNavigationSlope max navigation slope
223  * @return navigation map texture
224  */
225  static Texture* createTerrainNavigationMap(float width, float depth, vector<float>& terrainHeightVector, float maxNavigationSlope = 30.0f);
226 
227  /**
228  * Create terrain models
229  * @param width width
230  * @param depth depth
231  * @param y float y
232  * @param terrainHeightVector terrain height vector
233  * @param terrainBoundingBox terrain bounding box
234  * @param terrainModels terrain models vector
235  * @param createLODLevels create LOD Levels
236  */
237  static void createTerrainModels(float width, float depth, float y, vector<float>& terrainHeightVector, BoundingBox& terrainBoundingBox, vector<Model*>& terrainModels, bool createLODLevels = false);
238 
239  /**
240  * Apply brush to given terrain models
241  * @param terrainBoundingBox terrain bounding box
242  * @param terrainModels terrain models vector
243  * @param terrainHeightVector terrain height vector
244  * @param brushCenterPosition brush center position
245  * @param brushTexture brush texture
246  * @param brushScale brush scale
247  * @param brushStrength brush strength
248  * @param brushOperation brush operation
249  * @param flattenHeight flatten height
250  *
251  */
252  static void applyBrushToTerrainModels(
253  BoundingBox& terrainBoundingBox, // TODO: constness
254  vector<Model*>& terrainModels,
255  vector<float>& terrainHeightVector,
256  const Vector3& brushCenterPosition,
257  Texture* brushTexture,
258  float brushScale,
259  float brushStrength,
260  BrushOperation brushOperation,
261  float flattenHeight = 0.0f
262  );
263 
264  /**
265  * Apply ramp brush to given terrain models
266  * @param terrainBoundingBox terrain bounding box
267  * @param terrainModels terrain models vector
268  * @param terrainHeightVector terrain height vector
269  * @param brushCenterPosition brush center position
270  * @param brushTexture brush texture
271  * @param brushRotation brush rotation
272  * @param brushScale brush scale
273  * @param flattenHeightMin minimum flatten height
274  * @param flattenHeightMax maximum flatten height
275  *
276  */
277  static void applyRampBrushToTerrainModels(
278  BoundingBox& terrainBoundingBox, // TODO: constness
279  vector<Model*>& terrainModels,
280  vector<float>& terrainHeightVector,
281  const Vector3& brushCenterPosition,
282  Texture* brushTexture,
283  float brushRotation,
284  const Vector2& brushScale,
285  float flattenHeightMin,
286  float flattenHeightMax
287  );
288 
289  /**
290  * Update foliage after using terrain brush
291  * @param terrainBoundingBox terrain bounding box
292  * @param terrainHeightVector terrain height vector
293  * @param brushCenterPosition brush center position
294  * @param foliageBrush foliage brush
295  * @param foliageMaps foliage maps
296  * @param updateFoliagePartitions update foliage partitions
297  */
298  static void updateFoliageTerrainBrush(
299  BoundingBox& terrainBoundingBox, // TODO: constness
300  vector<float>& terrainHeightVector,
301  const Vector3& brushCenterPosition,
302  const FoliageBrush& foliageBrush,
303  vector<unordered_map<int, vector<Transform>>>& foliageMaps,
304  unordered_set<int>& updateFoliagePartitions
305  );
306 
307  /**
308  * Update foliage after using terrain ramp brush
309  * @param terrainBoundingBox terrain bounding box
310  * @param terrainHeightVector terrain height vector
311  * @param brushCenterPosition brush center position
312  * @param brushTexture brush texture
313  * @param brushRotation brush rotation
314  * @param brushScale brush scale
315  * @param foliageMaps foliage maps
316  * @param updateFoliagePartitions update foliage partitions
317  */
318  static void updateFoliageTerrainRampBrush(
319  BoundingBox& terrainBoundingBox, // TODO: constness
320  vector<float>& terrainHeightVector,
321  const Vector3& brushCenterPosition,
322  Texture* brushTexture,
323  float brushRotation,
324  const Vector2& brushScale,
325  vector<unordered_map<int, vector<Transform>>>& foliageMaps,
326  unordered_set<int>& updateFoliagePartitions
327  );
328 
329  /**
330  * Compute water positions map using a auto fill like algorithm at given brush center position
331  * @param terrainBoundingBox terrain bounding box
332  * @param terrainHeightVector terrain height vector
333  * @param brushCenterPosition brush center position
334  * @param waterHeight waterHeight
335  * @param waterPositionMap water position map
336  */
337  static bool computeWaterPositionMap(
338  BoundingBox& terrainBoundingBox,
339  const vector<float>& terrainHeightVector,
340  const Vector3& brushCenterPosition,
341  float waterHeight,
342  unordered_map<int, unordered_set<int>>& waterPositionMap
343  );
344 
345  /**
346  * Compute water reflection environment mapping position
347  * @param waterPositionMap water position map
348  * @param waterHeight water height
349  * @return water reflection environment mapping position
350  *
351  */
353  const unordered_map<int, unordered_set<int>>& waterPositionMap,
354  float waterHeight
355  );
356 
357  /**
358  * Create partitioned water models using given water position map
359  * @param terrainBoundingBox terrain bounding box
360  * @param waterPositionMap water position map
361  * @param waterHeight waterHeight
362  * @param waterModelIdx water model index
363  * @param waterModels water models
364  *
365  */
366  static void createWaterModels(
367  BoundingBox& terrainBoundingBox,
368  const unordered_map<int, unordered_set<int>>& waterPositionMap,
369  float waterHeight,
370  int waterModelIdx,
371  vector<Model*>& waterModels
372  );
373 
374  /**
375  * Get terrain models height for e.g. flatten
376  * @param terrainBoundingBox terrain bounding box
377  * @param terrainModels terrain models vector
378  * @param terrainHeightVector terrain height vector
379  * @param brushHeight brush height
380  *
381  */
382  static bool getTerrainModelsHeight(
383  BoundingBox& terrainBoundingBox, // TODO: constness
384  vector<Model*>& terrainModels,
385  vector<float>& terrainHeightVector,
386  const Vector3& brushCenterPosition,
387  float& brushHeight
388  );
389 
390  /**
391  * Create foliage maps
392  * @param terrainBoundingBox terrain bounding box
393  * @param foliageMaps foliage maps
394  */
395  static void createFoliageMaps(
396  BoundingBox& terrainBoundingBox, // TODO: constness
397  vector<unordered_map<int, vector<Transform>>>& foliageMaps
398  );
399 
400  /**
401  * Create foliage maps
402  * @param terrainWidth terrain width
403  * @param terrainDepth terrain depth
404  * @param foliageMaps foliage maps
405  */
406  static void createFoliageMaps(
407  float terrainWidth,
408  float terrainDepth,
409  vector<unordered_map<int, vector<Transform>>>& foliageMaps
410  );
411 
412  /**
413  * Empty foliage maps
414  * @param foliageMaps foliage maps
415  */
416  static void emptyFoliageMaps(
417  vector<unordered_map<int, vector<Transform>>>& foliageMaps
418  );
419 
420  /**
421  * Apply foliage brush
422  * @param terrainBoundingBox terrain bounding box
423  * @param terrainHeightVector terrain height vector
424  * @param brushCenterPosition brush center position
425  * @param foliageBrush foliage brush
426  * @param foliageBrushPrototypes foliage brush prototypes
427  * @param brushOperation brush operation
428  * @param foliageMaps foliage maps
429  * @param newFoliageMaps new foliage maps
430  * @param prototypeScale prototype scale
431  */
432  static void applyFoliageBrush(
433  BoundingBox& terrainBoundingBox, // TODO: constness
434  vector<float>& terrainHeightVector,
435  const Vector3& brushCenterPosition,
436  const FoliageBrush& foliageBrush,
437  const vector<FoliageBrushPrototype>& foliageBrushPrototypes,
438  BrushOperation brushOperation,
439  vector<unordered_map<int, vector<Transform>>>& foliageMaps,
440  vector<unordered_map<int, vector<Transform>>>& newFoliageMaps
441  );
442 
443  /**
444  * Apply foliage delete brush
445  * @param terrainBoundingBox terrain bounding box
446  * @param brushCenterPosition brush center position
447  * @param foliageBrush foliage brush
448  * @param foliageBrushPrototypes foliage brush prototypes
449  * @param brushOperation brush operation
450  * @param foliageMaps foliage maps
451  * @param recreateFoliagePartitions recreate foliage partitions
452  */
453  static void applyFoliageDeleteBrush(
454  BoundingBox& terrainBoundingBox, // TODO: constness
455  const Vector3& brushCenterPosition,
456  const FoliageBrush& foliageBrush,
457  const vector<FoliageBrushPrototype>& foliageBrushPrototypes,
458  BrushOperation brushOperation,
459  vector<unordered_map<int, vector<Transform>>>& foliageMaps,
460  unordered_set<int>& recreateFoliagePartitions
461  );
462 
463  /**
464  * Mirror terrain around X axis
465  * @param flipZ flip Z
466  * @param width width
467  * @param depth depth
468  * @param terrainHeightVector terrain height vector
469  * @param waterPositionMapsHeight water position maps heights
470  * @param waterPositionMaps water position maps
471  * @param foliageMaps foliage maps
472  */
473  static void mirrorXAxis(
474  bool flipZ,
475  float width,
476  float depth,
477  vector<float>& terrainHeightVector,
478  unordered_map<int, float>& waterPositionMapsHeight,
479  unordered_map<int, unordered_map<int, unordered_set<int>>>& waterPositionMaps,
480  vector<unordered_map<int, vector<Transform>>>& foliageMaps
481  );
482 
483  /**
484  * Mirror terrain around Z axis
485  * @param flipX flip X
486  * @param width width
487  * @param depth depth
488  * @param terrainHeightVector terrain height vector
489  * @param waterPositionMapsHeight water position maps heights
490  * @param waterPositionMaps water position maps
491  * @param foliageMaps foliage maps
492  */
493  static void mirrorZAxis(
494  bool flipX,
495  float width,
496  float depth,
497  vector<float>& terrainHeightVector,
498  unordered_map<int, float>& waterPositionMapsHeight,
499  unordered_map<int, unordered_map<int, unordered_set<int>>>& waterPositionMaps,
500  vector<unordered_map<int, vector<Transform>>>& foliageMaps
501  );
502 
503 };
Texture entity.
Definition: Texture.h:24
Transform which contain scale, rotations and translation.
Definition: Transform.h:29
Representation of a 3D model.
Definition: Model.h:35
Axis aligned bounding box used for frustum, this is not directly connectable with physics engine.
Definition: BoundingBox.h:26
Vector2 class representing vector2 mathematical structure and operations with x, y components.
Definition: Vector2.h:20
Vector3 class representing vector3 mathematical structure and operations with x, y,...
Definition: Vector3.h:20
Vector3 & set(float x, float y, float z)
Sets this vector3 by its components.
Definition: Vector3.h:70
Terrain utility.
Definition: Terrain.h:33
static void applyFoliageBrush(BoundingBox &terrainBoundingBox, vector< float > &terrainHeightVector, const Vector3 &brushCenterPosition, const FoliageBrush &foliageBrush, const vector< FoliageBrushPrototype > &foliageBrushPrototypes, BrushOperation brushOperation, vector< unordered_map< int, vector< Transform >>> &foliageMaps, vector< unordered_map< int, vector< Transform >>> &newFoliageMaps)
Apply foliage brush.
Definition: Terrain.cpp:1503
static void getWaterVertex(int x, int z, float waterHeight, Vector3 &vertex)
Get the terrain vertex for given x and z position.
Definition: Terrain.h:108
static void applyRampBrushToTerrainModels(BoundingBox &terrainBoundingBox, vector< Model * > &terrainModels, vector< float > &terrainHeightVector, const Vector3 &brushCenterPosition, Texture *brushTexture, float brushRotation, const Vector2 &brushScale, float flattenHeightMin, float flattenHeightMax)
Apply ramp brush to given terrain models.
Definition: Terrain.cpp:849
static void createFoliageMaps(BoundingBox &terrainBoundingBox, vector< unordered_map< int, vector< Transform >>> &foliageMaps)
Create foliage maps.
Definition: Terrain.cpp:1473
static void determineWaterXPositionSet(const vector< float > &terrainHeightVector, int verticesPerX, int verticesPerZ, int x, int z, float waterHeight, unordered_set< int > &waterXPositionSet)
Determine if water can be generated from left to right starting with x and z.
Definition: Terrain.h:171
static Texture * createTerrainNavigationMap(float width, float depth, vector< float > &terrainHeightVector, float maxNavigationSlope=30.0f)
Create terrain navigation map.
Definition: Terrain.cpp:74
static bool computeWaterPositionMap(BoundingBox &terrainBoundingBox, const vector< float > &terrainHeightVector, const Vector3 &brushCenterPosition, float waterHeight, unordered_map< int, unordered_set< int >> &waterPositionMap)
Compute water positions map using a auto fill like algorithm at given brush center position.
Definition: Terrain.cpp:1168
static constexpr float PARTITION_SIZE
Definition: Terrain.h:36
static void mirrorXAxis(bool flipZ, float width, float depth, vector< float > &terrainHeightVector, unordered_map< int, float > &waterPositionMapsHeight, unordered_map< int, unordered_map< int, unordered_set< int >>> &waterPositionMaps, vector< unordered_map< int, vector< Transform >>> &foliageMaps)
Mirror terrain around X axis.
Definition: Terrain.cpp:2201
static void updateFoliageTerrainBrush(BoundingBox &terrainBoundingBox, vector< float > &terrainHeightVector, const Vector3 &brushCenterPosition, const FoliageBrush &foliageBrush, vector< unordered_map< int, vector< Transform >>> &foliageMaps, unordered_set< int > &updateFoliagePartitions)
Update foliage after using terrain brush.
Definition: Terrain.cpp:1882
static void updateFoliageTerrainRampBrush(BoundingBox &terrainBoundingBox, vector< float > &terrainHeightVector, const Vector3 &brushCenterPosition, Texture *brushTexture, float brushRotation, const Vector2 &brushScale, vector< unordered_map< int, vector< Transform >>> &foliageMaps, unordered_set< int > &updateFoliagePartitions)
Update foliage after using terrain ramp brush.
Definition: Terrain.cpp:2034
static bool determineWater(const vector< float > &terrainHeightVector, int verticesPerX, int verticesPerZ, int x, int z, float waterHeight)
Determine if water can be generated.
Definition: Terrain.h:151
static bool getTerrainVertex(const vector< float > &terrainHeightVector, int verticesPerX, int verticesPerZ, int x, int z, Vector3 &vertex)
Get the terrain vertex for given x and z position.
Definition: Terrain.h:85
static void createTerrainModels(float width, float depth, float y, vector< float > &terrainHeightVector, BoundingBox &terrainBoundingBox, vector< Model * > &terrainModels, bool createLODLevels=false)
Create terrain models.
Definition: Terrain.cpp:173
static const Vector3 computeTerrainVertexNormal(const vector< float > &terrainHeightVector, int verticesPerX, int verticesPerZ, int x, int z)
Compute terrain vertex normal for given x and z position.
Definition: Terrain.cpp:412
static bool getTerrainModelsHeight(BoundingBox &terrainBoundingBox, vector< Model * > &terrainModels, vector< float > &terrainHeightVector, const Vector3 &brushCenterPosition, float &brushHeight)
Get terrain models height for e.g.
Definition: Terrain.cpp:1450
static void applyFoliageDeleteBrush(BoundingBox &terrainBoundingBox, const Vector3 &brushCenterPosition, const FoliageBrush &foliageBrush, const vector< FoliageBrushPrototype > &foliageBrushPrototypes, BrushOperation brushOperation, vector< unordered_map< int, vector< Transform >>> &foliageMaps, unordered_set< int > &recreateFoliagePartitions)
Apply foliage delete brush.
Definition: Terrain.cpp:1751
static constexpr float STEP_SIZE
Definition: Terrain.h:35
static void emptyFoliageMaps(vector< unordered_map< int, vector< Transform >>> &foliageMaps)
Empty foliage maps.
Definition: Terrain.cpp:1496
static Vector3 computeWaterReflectionEnvironmentMappingPosition(const unordered_map< int, unordered_set< int >> &waterPositionMap, float waterHeight)
Compute water reflection environment mapping position.
Definition: Terrain.cpp:1269
static bool hasWaterPosition(const unordered_map< int, unordered_set< int >> &waterPositionSet, int x, int z)
Definition: Terrain.h:122
static void mirrorZAxis(bool flipX, float width, float depth, vector< float > &terrainHeightVector, unordered_map< int, float > &waterPositionMapsHeight, unordered_map< int, unordered_map< int, unordered_set< int >>> &waterPositionMaps, vector< unordered_map< int, vector< Transform >>> &foliageMaps)
Mirror terrain around Z axis.
Definition: Terrain.cpp:2293
static void applyBrushToTerrainModels(BoundingBox &terrainBoundingBox, vector< Model * > &terrainModels, vector< float > &terrainHeightVector, const Vector3 &brushCenterPosition, Texture *brushTexture, float brushScale, float brushStrength, BrushOperation brushOperation, float flattenHeight=0.0f)
Apply brush to given terrain models.
Definition: Terrain.cpp:508
static void getTerrainVertex(int x, int z, Vector3 &vertex)
Get the terrain vertex for given x and z position without providing y component.
Definition: Terrain.h:69
static void createWaterModels(BoundingBox &terrainBoundingBox, const unordered_map< int, unordered_set< int >> &waterPositionMap, float waterHeight, int waterModelIdx, vector< Model * > &waterModels)
Create partitioned water models using given water position map.
Definition: Terrain.cpp:1291