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
21namespace Mercator {
22
24Forest::Forest(unsigned long seed) :
25 m_area(nullptr),
26 m_seed(seed),
27 m_randCache(seed, std::make_unique<ZeroSpiralOrdering>())
28{
29}
30
35Forest::~Forest() = default;
36
39{
40 m_area = area;
41}
42
43static const float plant_chance = 0.04f;
44static const float plant_min_height = 5.f;
45static 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}
Region of terrain surface which is modified.
Definition: Area.h:29
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
const WFMath::AxisBox< 2 > & bbox() const
Accessor for the bounding box of the geometric shape.
Definition: Effector.h:37
PlantSpecies & species()
Accessor for list of species in this forest.
Definition: Forest.h:96
~Forest()
Destruct a forest.
Forest(unsigned long seed=0)
Construct a new forest with the given seed.
Definition: Forest.cpp:24
void setArea(Area *a)
Assign an area to this forest.
Definition: Forest.cpp:38
void populate()
This function uses a pseudo-random technique to populate the forest with trees. This algorithm as the...
Definition: Forest.cpp:67
Data about a species of plant in a Forest.
Definition: Forest.h:39
A spiral around 0,0.
Definition: RandCache.h:79
This is the simple class for representing instances of vegetation.
Definition: Plant.h:19
WFMath::Quaternion m_orientation
Orientation of the vegetation.
Definition: Plant.h:23
WFMath::Point< 2 > m_displacement
Position of the vegetation relative to its grid point.
Definition: Plant.h:21