mercator  0.4.0
A terrain generation library for the Worldforge system.
Forest.cpp
1 // This file may be redistributed and modified only under the terms of
2 // the GNU General Public License (See COPYING for details).
3 // Copyright (C) 2004 Alistair Riddoch
4 
5 #ifdef HAVE_CONFIG_H
6 #include "config.h"
7 #endif
8 
9 #include "iround.h"
10 
11 #include "Forest.h"
12 #include "Plant.h"
13 #include "Area.h"
14 
15 #include <wfmath/MersenneTwister.h>
16 #include <wfmath/intersect.h>
17 
18 #include <iostream>
19 #include <cmath>
20 
21 namespace Mercator {
22 
24 Forest::Forest(unsigned long seed) :
25  m_area(nullptr),
26  m_seed(seed),
27  m_randCache(seed, std::make_unique<ZeroSpiralOrdering>())
28 {
29 }
30 
35 Forest::~Forest() = default;
36 
38 void Forest::setArea(Area* area)
39 {
40  m_area = area;
41 }
42 
43 static const float plant_chance = 0.04f;
44 static const float plant_min_height = 5.f;
45 static const float plant_height_range = 20.f;
46 
47 
68 {
69  if (!m_area) return;
70  WFMath::AxisBox<2> bbox(m_area->bbox());
71 
72  // Fill the plant store with plants.
73  m_plants.clear();
74  WFMath::MTRand rng;
75 
76  int lx = I_ROUND(bbox.lowCorner().x()),
77  ly = I_ROUND(bbox.lowCorner().y()),
78  hx = I_ROUND(bbox.highCorner().x()),
79  hy = I_ROUND(bbox.highCorner().y());
80 
81  PlantSpecies::const_iterator I;
82  PlantSpecies::const_iterator Iend = m_species.end();
83 
84  for(int j = ly; j < hy; ++j) {
85  for(int i = lx; i < hx; ++i) {
86  if (!m_area->contains(i,j)) {
87  continue;
88  }
89  double prob = m_randCache(i,j);
90  I = m_species.begin();
91  for (; I != Iend; ++I) {
92  const Species & species = *I;
93  if (prob > species.m_probability) {
94  prob -= species.m_probability;
95  // Next species
96  continue;
97  }
98 
99 // std::cout << "Plant at [" << i << ", " << j << "]"
100 // << std::endl << std::flush;
101  //this is a bit of a hack
102  rng.seed((int)(prob / I->m_probability * 123456));
103 
104  Plant & plant = m_plants[i][j];
105  // plant.setHeight(rng() * plant_height_range + plant_min_height);
106  plant.m_displacement = WFMath::Point<2>(
107  (rng.rand<WFMath::CoordType>() - 0.5f) * species.m_deviation,
108  (rng.rand<WFMath::CoordType>() - 0.5f) * species.m_deviation);
109  plant.m_orientation = WFMath::Quaternion(2, rng.rand<WFMath::CoordType>() * 2 * WFMath::numeric_constants<WFMath::CoordType>::pi());
110 // auto J = species.m_parameters.begin();
111 // auto Jend = species.m_parameters.end();
112 // for (; J != Jend; ++J) {
113 // plant.setParameter(J->first, rng.rand<WFMath::CoordType>() * J->second.range + J->second.min);
114 // }
115  break;
116  }
117  }
118  }
119 }
120 
121 }
Mercator::Plant
This is the simple class for representing instances of vegetation.
Definition: Plant.h:19
Mercator::Plant::m_displacement
WFMath::Point< 2 > m_displacement
Position of the vegetation relative to its grid point.
Definition: Plant.h:21
Mercator::Species
Data about a species of plant in a Forest.
Definition: Forest.h:39
Mercator::Area::contains
bool contains(WFMath::CoordType x, WFMath::CoordType z) const
Determine if a point is contained by the shape of this area.
Definition: Area.cpp:237
Mercator::Forest::Forest
Forest(unsigned long seed=0)
Construct a new forest with the given seed.
Definition: Forest.cpp:24
Mercator::Forest::species
PlantSpecies & species()
Accessor for list of species in this forest.
Definition: Forest.h:96
Mercator::Forest::populate
void populate()
This function uses a pseudo-random technique to populate the forest with trees. This algorithm as the...
Definition: Forest.cpp:67
Mercator::Area
Region of terrain surface which is modified.
Definition: Area.h:29
Mercator::Forest::~Forest
~Forest()
Destruct a forest.
Mercator::Plant::m_orientation
WFMath::Quaternion m_orientation
Orientation of the vegetation.
Definition: Plant.h:23
Mercator::Effector::bbox
const WFMath::AxisBox< 2 > & bbox() const
Accessor for the bounding box of the geometric shape.
Definition: Effector.h:37
Mercator::Forest::setArea
void setArea(Area *a)
Assign an area to this forest.
Definition: Forest.cpp:38
ZeroSpiralOrdering
A spiral around 0,0.
Definition: RandCache.h:79