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 |
|
---|
15 | namespace 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 | }
|
---|