[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 |
|
---|
| 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 | }
|
---|