source: Revenant/geoworld/src/synthsession.cpp@ 8125274

port/mars-tycoon
Last change on this file since 8125274 was 80a6a52, checked in by Jonathan Neufeld <support@…>, 3 years ago

Get to a compile state for terrain procedural generation

  • Property mode set to 100644
File size: 9.0 KB
RevLine 
[80a6a52]1#include "synthsession.h"
2
3#include <stack>
4#include <map>
5#include <vector>
6#include <list>
7#include <iostream>
8#include <vector>
9#include <sstream>
10
11#include <time.h>
12
13#include <lodepng.h>
14
15namespace geoworld
16{
17 SynthesisSession::SynthesisSession()
18 : _pWorld(NULL), _pPgWorld(NULL), _pFile(NULL), _pDepSynth(NULL) {}
19
20 SynthesisSession::~SynthesisSession()
21 {
22 delete _pPgWorld;
23 delete _pWorld;
24 delete _pFile;
25 delete _pDepSynth;
26 }
27
28 void SynthesisSession::spawnRandomly( MorphList & outlist, const GeoMorphRegistry & registry, const size_t nCount, const unsigned long nWWidth, const unsigned long nWHeight, const unsigned short nLOD )
29 {
30 using namespace mars;
31
32 float fFrequencySum = 0;
33 typedef std::list< std::pair< RangeX< float >, GeoMorphFactory * > > FactoryList;
34
35 FactoryList factories;
36
37 for (GeoMorphRegistry::GMFactorySet::const_iterator i = registry.beginGM(); i != registry.endGM(); ++i)
38 {
39 const float fFreq = (*i)->getFrequency();
40
41 factories.push_back(
42 FactoryList::value_type (
43 RangeX< float > (fFrequencySum, fFrequencySum + fFreq),
44 *i
45 )
46 );
47 fFrequencySum += fFreq;
48 }
49
50 const unsigned long
51 nLODWWidth = nWWidth >> nLOD,
52 nLODHeight = nWHeight >> nLOD;
53
54 ptr< GeoMorph > pMorph;
55
56 for (size_t c = 0; c < nCount; ++c)
57 {
58 const float fRand = RANDf(fFrequencySum);
59
60 for (FactoryList::const_iterator i = factories.begin(); i != factories.end(); ++i)
61 {
62 if (i->first.contains(fRand))
63 {
64 const GeoMorphFactory * pFact = i->second;
65
66 const ISurfaceBoundedGeoMorphFactory * pSBGMF = dynamic_cast< const ISurfaceBoundedGeoMorphFactory * > (pFact);
67 if (pSBGMF != NULL)
68 {
69 pMorph =
70 pSBGMF ->
71 createRandomInstance(
72 RAND(nLODWWidth),
73 RAND(nLODHeight)
74 );
75 }
76
77 const IOpenGeoMorphFactory * pOGMF = dynamic_cast< const IOpenGeoMorphFactory * > (pFact);
78 if (pOGMF != NULL)
79 {
80 pMorph = pOGMF->createRandomInstance();
81 }
82 outlist.push_back(pMorph);
83 }
84 }
85 }
86 }
87
88 void SynthesisSession::generate( const std::string & sFileName, const GeoMorphRegistry & registry, const unsigned long nWorldWidth, const unsigned long nWorldHeight, const unsigned short nWorldDepth)
89 {
90 using namespace mars;
91
92 MorphList morphs, rejects;
93
94 delete _pPgWorld;
95 delete _pWorld;
96 delete _pFile;
97 delete _pDepSynth;
98
99 _pFile = FileSource::create(sFileName, nWorldWidth, nWorldHeight, nWorldDepth, _config.tiledim, _config.macro.lod, _config.geohost.layercount);
100 _pDepSynth = new DepositSynthesizer(&_mindb, _cfgdepsynth, _pFile->geohost.getWorldWidth(), _pFile->geohost.getWorldHeight(), _pFile->getWorldDepth(), _pFile->geohost.getLOD());
101 _pWorld = new GeoWorld(_pDepSynth, _config.macro.lod, 0, _pFile);
102
103 fire(&ISynthesisSessionListener::onGenerate, _pWorld);
104
105 fire(&ISynthesisSessionListener::onGenerateGeoHostLayers, _pWorld, _pDepSynth);
106 _pDepSynth->generateStrata();
107
108 {
109 MyMacroListener listener (this, _pWorld);
110
111 _pWorld->addListener(&listener);
112
113 for (GeoMorphRegistry::GTFactorySet::const_iterator i = registry.beginGT(GTP_Pre); i != registry.endGT(GTP_Pre); ++i)
114 {
115 const IOpenGeoMorphFactory * pOpenGMFact = dynamic_cast< IOpenGeoMorphFactory * > (*i);
116
117 if (pOpenGMFact != NULL)
118 {
119 morphs.push_back(pOpenGMFact->createRandomInstance());
120 }
121 }
122
123 spawnRandomly(morphs, registry, _config.macro.morphcount, _pWorld->getWidth(), _pWorld->getHeight(), _pWorld->getLOD());
124
125 GeoWorldAccesser accessor0(_pWorld);
126 const unsigned short
127 nWidth = static_cast< unsigned short > (_pWorld->getMaxGeoMorphWidth()),
128 nHeight = static_cast< unsigned short > (_pWorld->getMaxGeoMorphHeight());
129
130 for (MorphList::iterator i = morphs.begin(); i != morphs.end(); ++i)
131 {
132 (*i)->init(*this, accessor0, nWidth, nHeight);
133 fire(&ISynthesisSessionListener::onInitMorph, _pWorld, i->pointer());
134 }
135 fire(&ISynthesisSessionListener::onPrepareMorphs, _pWorld, morphs);
136 _pWorld->addMorphs(morphs, rejects);
137
138 fire(&ISynthesisSessionListener::onRaster, _pWorld);
139 _pWorld->runMorphs(_mindb, rejects);
140 if (!rejects.empty())
141 fire(&ISynthesisSessionListener::onRejects, _pWorld, rejects);
142
143 _pWorld->removeListener(&listener);
144 }
145 fire(&ISynthesisSessionListener::onSpawnMinerals, _pWorld, _pDepSynth);
146 _pDepSynth->generateMinerals(0);
147
148 fire(&ISynthesisSessionListener::onCreateMiddleTier, _pWorld, sFileName);
149
150 _pWorld->write(_config.macro.coarseness);
151 _pPgWorld = new PagedGeoWorld (_pDepSynth, _pFile, _config.passes.count);
152
153 generate(_pPgWorld, registry);
154
155 *_pDepSynth >> _pFile->geohost;
156 *_pDepSynth >> _pFile->minerals;
157
158 _pFile->commit();
159
160 DEMDUMP << _pWorld->getLowHM();
161 DEMDUMP << _pDepSynth->getStratum().getBase();
162 }
163
164 void SynthesisSession::generate( PagedGeoWorld * pPgWorld, const GeoMorphRegistry & registry )
165 {
166 const unsigned short
167 nWidth = static_cast< unsigned short > (pPgWorld->getMaxGeoMorphWidth()),
168 nHeight = static_cast< unsigned short > (pPgWorld->getMaxGeoMorphHeight());
169 MorphList morphs, rejects;
170
171 if (pPgWorld->getPassCount() > 0)
172 fire(&ISynthesisSessionListener::onGenerate2, pPgWorld);
173 for (unsigned int i = 0; i < pPgWorld->getPassCount(); ++i)
174 {
175 MyMicroListener listener (this, pPgWorld, i);
176
177 pPgWorld->addListener(&listener);
178
179 rejects.clear();
180 morphs.clear();
181 fire(&ISynthesisSessionListener::onPass2, pPgWorld, i);
182
183 spawnRandomly(morphs, registry, _config.passes.morphcount.next(), pPgWorld->getWorldWidth(), pPgWorld->getWorldHeight(), pPgWorld->getLOD());
184
185 ReadOnlyPagedGeoWorldAccesser accessor1(pPgWorld);
186
187 for (MorphList::iterator j = morphs.begin(); j != morphs.end(); ++j)
188 {
189 (*j)->init(*this, accessor1, nWidth, nHeight);
190 fire(&ISynthesisSessionListener::onInitMorph2, pPgWorld, i, j->pointer());
191 }
192 accessor1.releaseCache();
193
194 fire(&ISynthesisSessionListener::onPrepareMorphs2, pPgWorld, i, morphs);
195 pPgWorld->addMorphs(morphs, rejects, i);
196
197 fire(&ISynthesisSessionListener::onRaster2, pPgWorld, i);
198
199 pPgWorld->runMorphs(i, rejects);
200 if (!rejects.empty())
201 fire(&ISynthesisSessionListener::onRejects2, pPgWorld, i, rejects);
202
203 pPgWorld->removeListener(&listener);
204
205 fire(&ISynthesisSessionListener::onSpawnMinerals2, pPgWorld, i, _pDepSynth);
206 _pDepSynth->generateMinerals(i + 1);
207 }
208 }
209
210 bool SynthesisSession::init( IMineralsDBReader & minreader, IDepositSynthConfigReader & depsynthreader, ISynthesisSessionConfigReader & cfgreader)
211 {
212 bool bResult;
213
214 bResult = minreader.load(&_mindb);
215 if (bResult)
216 _mindb.init();
217
218 bResult = cfgreader.load(_config) && bResult;
219 bResult = depsynthreader.load(_cfgdepsynth) && bResult;
220
221 return bResult;
222 }
223
224 const LockedGWSection & SynthesisSession::ReadOnlyPagedGeoWorldAccesser::acquireSection( const long x, const long y ) const
225 {
226 const unsigned short
227 nTileDim = _pPgWld->getTileDimension();
228
229 const mars::BBox< long >
230 bbox (x, y, x, y),
231 bboxActual = LockedGWSection::computeLockedSection(bbox, nTileDim, false);
232
233 assert(bboxActual.inside(x, y));
234 if (_mapLockedSections.find(bboxActual) == _mapLockedSections.end())
235 return *(_mapLockedSections[bboxActual] = _pPgWld->lockro(bbox, false));
236 else
237 return *_mapLockedSections[bboxActual];
238 }
239
240 SynthesisSession::ReadOnlyPagedGeoWorldAccesser::~ReadOnlyPagedGeoWorldAccesser()
241 {
242 for (LockedSectionsMap::const_iterator i = _mapLockedSections.begin(); i != _mapLockedSections.end(); ++i)
243 _pPgWld->unlock(i->second);
244 }
245
246 SynthesisSession::ReadOnlyPagedGeoWorldAccesser::ReadOnlyPagedGeoWorldAccesser( const PagedGeoWorld * pPagedGeoWorld )
247 : BaseAccessor(pPagedGeoWorld->getAgentMaps()), _pPgWld (pPagedGeoWorld) {}
248
249 geoworld::MorphList SynthesisSession::ReadOnlyPagedGeoWorldAccesser::compilePasses( const PagedGeoWorld * pPgGW )
250 {
251 MorphList morphs;
252
253 for (unsigned short i = 0; i < pPgGW->getPassCount(); ++i)
254 morphs.insert(morphs.end(), pPgGW->beginPass(i), pPgGW->endPass(i));
255
256 return morphs;
257 }
258
259 void SynthesisSession::ReadOnlyPagedGeoWorldAccesser::releaseCache()
260 {
261 for (LockedSectionsMap::const_iterator i = _mapLockedSections.begin(); i != _mapLockedSections.end(); ++i)
262 _pPgWld->unlock(i->second);
263 _mapLockedSections.clear();
264 }
265
266 SynthesisSession::GeoWorldAccesser::GeoWorldAccesser( GeoWorld * const pGeoWorld )
267 : BaseAccessor(pGeoWorld->getAgentMaps()), _pGeoWorld(pGeoWorld), _hm(pGeoWorld->getLowHM()) {}
268
269 void SynthesisSession::MyMicroListener::runningMorphs( MorphList::const_iterator i0, MorphList::const_iterator iN, const size_t i, const size_t nCount, const size_t nTotal )
270 {
271 size_t c = i;
272 for (MorphList::const_iterator k = i0; k != iN; ++k)
273 _pObservable->fire(&ISynthesisSessionListener::onDoMorph2, _pPgWorld, _nPass, *k, c++, nTotal);
274 }
275
276 SynthesisSession::MyMicroListener::~MyMicroListener()
277 {
278 if (!_rejects.empty())
279 _pObservable->fire(&ISynthesisSessionListener::onRejects2, _pPgWorld, _nPass, _rejects);
280 }
281
282 SynthesisSession::MyMicroListener::MyMicroListener( SynthesisSession * pObservable, PagedGeoWorld * const pPgWorld, const unsigned short nPass )
283 : _pObservable (pObservable), _pPgWorld(pPgWorld), _nPass(nPass)
284 {
285
286 }
287
288}
Note: See TracBrowser for help on using the repository browser.