1 | #ifndef __GEOWORLD_H__
|
---|
2 | #define __GEOWORLD_H__
|
---|
3 |
|
---|
4 | #include <mars_grids.h>
|
---|
5 | #include <mars_lookup.h>
|
---|
6 | #include <mars_linalg.h>
|
---|
7 | #include <mars_log.h>
|
---|
8 | #include <mars_events.h>
|
---|
9 | #include <mars_ptr.h>
|
---|
10 | #include <mars_util.h>
|
---|
11 | #include <mars_calc.h>
|
---|
12 |
|
---|
13 | #include <fstream>
|
---|
14 | #include <boost/thread.hpp>
|
---|
15 | #include <list>
|
---|
16 | #include <string>
|
---|
17 | #include <utility>
|
---|
18 | #include <set>
|
---|
19 |
|
---|
20 | #include "sphpack.h"
|
---|
21 | #include "worldfile.h"
|
---|
22 | #include "gwutil.h"
|
---|
23 | #include "PNGDEM.h"
|
---|
24 | #include "geomorph.h"
|
---|
25 | #include "oregen.h"
|
---|
26 |
|
---|
27 | namespace geoworld
|
---|
28 | {
|
---|
29 | class UnlockEx : public std::exception
|
---|
30 | {
|
---|
31 | public:
|
---|
32 | const mars::BBox< long > bbox;
|
---|
33 |
|
---|
34 | UnlockEx (const mars::BBox< long > & bbox)
|
---|
35 | : bbox(bbox) {}
|
---|
36 | };
|
---|
37 |
|
---|
38 | class PGWFileEx : public std::exception
|
---|
39 | {
|
---|
40 | public:
|
---|
41 | const std::string message;
|
---|
42 |
|
---|
43 | PGWFileEx(const char * szMsg) : message(szMsg) {}
|
---|
44 | };
|
---|
45 |
|
---|
46 | class PGWIllegal : public std::exception
|
---|
47 | {
|
---|
48 | public:
|
---|
49 | const std::string message;
|
---|
50 |
|
---|
51 | PGWIllegal(const char * szMsg) : message(szMsg) {}
|
---|
52 | };
|
---|
53 |
|
---|
54 | class LockedGWSection
|
---|
55 | {
|
---|
56 | public:
|
---|
57 | static const unsigned short MAX_LOCK_DIM = 5000;
|
---|
58 | enum StratumSyncOp
|
---|
59 | {
|
---|
60 | SSync_None = 0,
|
---|
61 | SSync_Perfect = 1
|
---|
62 | };
|
---|
63 |
|
---|
64 | class View
|
---|
65 | {
|
---|
66 | private:
|
---|
67 | struct
|
---|
68 | {
|
---|
69 | const GeoHeightMap::View * heightmap;
|
---|
70 | const Stratum::View * stratum;
|
---|
71 | } const_view;
|
---|
72 |
|
---|
73 | struct
|
---|
74 | {
|
---|
75 | GeoHeightMap::View * heightmap;
|
---|
76 | Stratum::View * stratum;
|
---|
77 | } mutable_view;
|
---|
78 |
|
---|
79 | // What? do I look like a Staples store to you?
|
---|
80 | View (const View & copy);
|
---|
81 |
|
---|
82 | public:
|
---|
83 | const unsigned short
|
---|
84 | width, height;
|
---|
85 |
|
---|
86 | View (GeoHeightMap::View * heightmap, Stratum::View * stratum)
|
---|
87 | : width(heightmap->width), height(heightmap->height)
|
---|
88 | {
|
---|
89 | mutable_view.heightmap = heightmap;
|
---|
90 | mutable_view.stratum = stratum;
|
---|
91 | const_view.heightmap = heightmap;
|
---|
92 | const_view.stratum = stratum;
|
---|
93 | }
|
---|
94 | View (const GeoHeightMap::View * heightmap, const Stratum::View * stratum)
|
---|
95 | : width(heightmap->width), height(heightmap->height)
|
---|
96 | {
|
---|
97 | mutable_view.heightmap = NULL;
|
---|
98 | mutable_view.stratum = NULL;
|
---|
99 | const_view.heightmap = heightmap;
|
---|
100 | const_view.stratum = stratum;
|
---|
101 | }
|
---|
102 |
|
---|
103 | inline GeoHeightMap::View * getHeightMap ()
|
---|
104 | {
|
---|
105 | assert(mutable_view.heightmap != NULL);
|
---|
106 | return mutable_view.heightmap;
|
---|
107 | }
|
---|
108 | inline const GeoHeightMap::View * getHeightMap () const { return const_view.heightmap; }
|
---|
109 | inline Stratum::View * getStratum ()
|
---|
110 | {
|
---|
111 | assert(mutable_view.stratum != NULL);
|
---|
112 | return mutable_view.stratum;
|
---|
113 | }
|
---|
114 | inline const Stratum::View * getStratum () const { return const_view.stratum; }
|
---|
115 | };
|
---|
116 |
|
---|
117 | const mars::BBox< long >
|
---|
118 | bbox;
|
---|
119 |
|
---|
120 | LockedGWSection( const mars::BBox< long > & bbox, const long nDepth, const unsigned short nDEMLOD, const size_t nLayers, const unsigned short nStratumLOD );
|
---|
121 | LockedGWSection( const GeoHeightMap & hm, const unsigned short nDEMLOD, const Stratum & stratum );
|
---|
122 |
|
---|
123 | static bool isValid (const mars::BBox< long > & bbox, const unsigned short nTileDim, const bool bPad = true );
|
---|
124 |
|
---|
125 | static mars::BBox< long > computeLockedSection (const mars::BBox< long > & bbox, const unsigned short nTileDim, const bool bPad = true );
|
---|
126 | inline static unsigned short getMaxViewportDim (const unsigned short nTileDim, const bool bPad = true )
|
---|
127 | { return getActualViewportDim(MAX_LOCK_DIM, nTileDim, bPad); }
|
---|
128 | inline static unsigned short getActualViewportDim (const unsigned short nDimTest, const unsigned short nTileDim, const bool bPad = true)
|
---|
129 | { return nDimTest - nTileDim * (bPad ? 2 : 1); } // DEPS: LGWSBBA
|
---|
130 |
|
---|
131 | inline unsigned short getActualWidth () const { return _hm.width; }
|
---|
132 | inline unsigned short getActualHeight () const { return _hm.height; }
|
---|
133 |
|
---|
134 | inline mars::Range< GeoHeightMap::Precision > getElevationRange () const { return _hm.range(); }
|
---|
135 |
|
---|
136 | inline void setStratumSyncOp (const StratumSyncOp & ensso)
|
---|
137 | { _ssop = ensso; }
|
---|
138 | inline const StratumSyncOp & getStratumSyncOp () const
|
---|
139 | { return _ssop; }
|
---|
140 |
|
---|
141 | inline mars::ScalarFieldView< GeoHeightMap::Precision >::Offset at (const long x, const long y)
|
---|
142 | { return GeoHeightMap::Offset(&_hm, static_cast< signed int > (x - bbox.left), static_cast< signed int > (y - bbox.top)); }
|
---|
143 |
|
---|
144 | void operator << (const View & view);
|
---|
145 | void operator >> (View && view) const;
|
---|
146 |
|
---|
147 | inline void operator << (const Stratum::Offset offs)
|
---|
148 | { _stratum << offs; }
|
---|
149 |
|
---|
150 | void blitFrom (const FileSource::MainDEM::Block & block, const unsigned short nTileX, const unsigned short nTileY);
|
---|
151 | void blitTo (FileSource::MainDEM::Block & block, const unsigned short nTileX, const unsigned short nTileY) const;
|
---|
152 | inline void processSyncOp ()
|
---|
153 | {
|
---|
154 | switch (_ssop)
|
---|
155 | {
|
---|
156 | case SSync_Perfect:
|
---|
157 | _stratum.applyDEM(_hm, _nDEMLOD);
|
---|
158 | break;
|
---|
159 | case SSync_None:
|
---|
160 | break;
|
---|
161 | }
|
---|
162 | }
|
---|
163 |
|
---|
164 | void operator >> (PNGDEM & pngdem) const;
|
---|
165 | void operator << (const PNGDEM & pngdem);
|
---|
166 |
|
---|
167 | View * createView (const long nLeft, const long nTop, const long nRight, const long nBottom);
|
---|
168 | const View * createView (const long nLeft, const long nTop, const long nRight, const long nBottom) const;
|
---|
169 |
|
---|
170 | inline void releaseView (const View * pView) const
|
---|
171 | {
|
---|
172 | LOG(mars::Log::Debug) << pView->getHeightMap();
|
---|
173 | _hm.releaseView(pView->getHeightMap());
|
---|
174 | _stratum.releaseView(pView->getStratum());
|
---|
175 | delete pView;
|
---|
176 | }
|
---|
177 |
|
---|
178 | template< typename J, typename JST >
|
---|
179 | inline LockedGWSection & operator += (const mars::ScalarFieldView< J, JST > & other)
|
---|
180 | {
|
---|
181 | _hm += other;
|
---|
182 | return *this;
|
---|
183 | }
|
---|
184 | inline LockedGWSection & operator += (const GeoHeightMap::View & other)
|
---|
185 | {
|
---|
186 | _hm += other;
|
---|
187 | return *this;
|
---|
188 | }
|
---|
189 | template< typename J, typename JST >
|
---|
190 | inline LockedGWSection & operator -= (const mars::ScalarFieldView< J, JST > & other)
|
---|
191 | {
|
---|
192 | _hm -= other;
|
---|
193 | return *this;
|
---|
194 | }
|
---|
195 | inline LockedGWSection & operator -= (const GeoHeightMap::View & other)
|
---|
196 | {
|
---|
197 | _hm -= other;
|
---|
198 | return *this;
|
---|
199 | }
|
---|
200 |
|
---|
201 | inline const GeoHeightMap::Precision & heightmap (const long x, const long y) const
|
---|
202 | {
|
---|
203 | assert (bbox.inside(x, y));
|
---|
204 | return _hm.getw(x - bbox.left, y - bbox.top);
|
---|
205 | }
|
---|
206 | inline GeoHeightMap::Precision & heightmap (const long x, const long y)
|
---|
207 | {
|
---|
208 | assert (bbox.inside(x, y));
|
---|
209 | return _hm.getw(x - bbox.left, y - bbox.top);
|
---|
210 | }
|
---|
211 |
|
---|
212 | inline const GeoHeightMap::Precision getSurfaceMean (const long x, const long y) const
|
---|
213 | {
|
---|
214 | assert(bbox.inside(x - 1, y - 1) && bbox.inside(x + 1, y + 1));
|
---|
215 | return _hm.mean (x - bbox.left, y - bbox.top);
|
---|
216 | }
|
---|
217 | inline const GeoHeightMap::Precision getSurfaceMeanVN( const long x, const long y ) const
|
---|
218 | {
|
---|
219 | assert(bbox.inside(x - 1, y - 1) && bbox.inside(x + 1, y + 1));
|
---|
220 | return _hm.meanVN (x - bbox.left, y - bbox.top);
|
---|
221 | }
|
---|
222 |
|
---|
223 | inline GWCoords createCoordsRVN(const long x, const long y, const unsigned short nScale) const
|
---|
224 | {
|
---|
225 | typedef mars::Numerics< GeoHeightMap::Precision >::UP R;
|
---|
226 |
|
---|
227 | return GWCoords (x, y,
|
---|
228 | static_cast< GWCoords::Precision > (
|
---|
229 | (
|
---|
230 | static_cast< R > (_hm.meanVN(x - nScale - bbox.left, y - nScale - bbox.top)) +
|
---|
231 | static_cast< R > (_hm.meanVN(x + nScale - bbox.left, y - nScale - bbox.top)) +
|
---|
232 | static_cast< R > (_hm.meanVN(x - nScale - bbox.left, y + nScale - bbox.top)) +
|
---|
233 | static_cast< R > (_hm.meanVN(x + nScale - bbox.left, y + nScale - bbox.top)) +
|
---|
234 | static_cast< R > (_hm.meanVN(x - bbox.left, y - bbox.top))
|
---|
235 | ) / 5
|
---|
236 | )
|
---|
237 | );
|
---|
238 | }
|
---|
239 |
|
---|
240 | inline GWCoords createCoords(const long x, const long y) const
|
---|
241 | { return GWCoords (x, y, _hm.meanVN(x - bbox.left, y - bbox.top)); }
|
---|
242 |
|
---|
243 | inline GWCoords createCoords(const GWSurfacePos & pos) const
|
---|
244 | { return createCoords(pos.x, pos.y); }
|
---|
245 |
|
---|
246 | inline GWCoords createCoordsRVN(const GWSurfacePos & pos, const unsigned short nScale) const
|
---|
247 | { return createCoordsRVN(pos.x, pos.y, nScale); }
|
---|
248 |
|
---|
249 | private:
|
---|
250 | GeoHeightMap _hm;
|
---|
251 | unsigned short _nDEMLOD;
|
---|
252 | Stratum _stratum;
|
---|
253 | StratumSyncOp _ssop;
|
---|
254 |
|
---|
255 | /* LGWSBBA: Section bbox computation algorithm:
|
---|
256 | * - Aligned along tile-boundary
|
---|
257 | * - Iff padding:
|
---|
258 | * - Minimum extents minus one-half tile dimension
|
---|
259 | * - Maximum extents plus one-half tile dimension
|
---|
260 | * - Maximum extents plus one tile dimension
|
---|
261 | */
|
---|
262 | };
|
---|
263 |
|
---|
264 | class RegionContainer : private std::list< mars::BBox< long > >
|
---|
265 | {
|
---|
266 | private:
|
---|
267 | const unsigned long
|
---|
268 | _nWWidth, _nWHeight;
|
---|
269 |
|
---|
270 | public:
|
---|
271 | RegionContainer(const unsigned long nWWidth, const unsigned long nWHeight)
|
---|
272 | : _nWWidth(nWWidth), _nWHeight(nWHeight) {}
|
---|
273 |
|
---|
274 | inline void addRegion (const mars::BBox< long > & bbox)
|
---|
275 | {
|
---|
276 | assert(!intersects(bbox));
|
---|
277 | push_back(bbox);
|
---|
278 | }
|
---|
279 | bool removeRegion (const mars::BBox< long > & bbox);
|
---|
280 | bool intersects (const mars::BBox< long > & bbox) const;
|
---|
281 | inline bool empty () const { return std::list< mars::BBox< long > >::empty(); }
|
---|
282 | };
|
---|
283 |
|
---|
284 | class QTMorphs : private mars::QuadTree_BBoxIndexed< GeoMorph, long >
|
---|
285 | {
|
---|
286 | private:
|
---|
287 | unsigned long
|
---|
288 | _nWWidth, _nWHeight;
|
---|
289 |
|
---|
290 | public:
|
---|
291 | using MorphIterator = mars::QuadTree_BBoxIndexed< GeoMorph, long >::EntityRectIterator;
|
---|
292 | using Region = mars::QuadTree_BBoxIndexed< GeoMorph, long >::Region;
|
---|
293 | using VECTOR = mars::QuadTree_BBoxIndexed< GeoMorph, long >::VECTOR;
|
---|
294 |
|
---|
295 | QTMorphs (const unsigned long nWWidth, const unsigned long nWHeight)
|
---|
296 | : QuadTree_BBoxIndexed(std::max(nWWidth, nWHeight)), _nWWidth(nWWidth), _nWHeight(nWHeight) {}
|
---|
297 |
|
---|
298 | bool addMorph (mars::ptr <GeoMorph> gm);
|
---|
299 | inline MorphIterator morphs (const mars::BBox< long > & bbox)
|
---|
300 | { return morphs(Region(bbox.getMinimum(), bbox.getMaximum())); }
|
---|
301 | inline MorphIterator morphs (const long nLeft, const long nTop, const long nRight, const long nBottom)
|
---|
302 | { return morphs(Region(VECTOR(nLeft, nTop), VECTOR(nRight, nBottom))); }
|
---|
303 | inline MorphIterator morphs (const Region & rg)
|
---|
304 | { return contents(rg); }
|
---|
305 | };
|
---|
306 |
|
---|
307 | class AgentMap
|
---|
308 | {
|
---|
309 | private:
|
---|
310 | class FieldTypeWrapper
|
---|
311 | {
|
---|
312 | public:
|
---|
313 | FieldType type;
|
---|
314 |
|
---|
315 | FieldTypeWrapper(const FieldType enftType)
|
---|
316 | : type(enftType) {}
|
---|
317 |
|
---|
318 | inline operator FieldType () const { return type; }
|
---|
319 | };
|
---|
320 |
|
---|
321 | public:
|
---|
322 | FieldType type;
|
---|
323 | const unsigned long width, height;
|
---|
324 | const float base;
|
---|
325 |
|
---|
326 | AgentMap (const FieldType enftType, const unsigned long nWidth, const unsigned long nHeight, const float fBase = 0.0f)
|
---|
327 | : type(enftType), width(nWidth), height(nHeight), _qtField(std::max(nWidth, nHeight)), base(fBase) {}
|
---|
328 |
|
---|
329 | inline void addSpherePack (const mars::ptr< GeoSpherePack > & gsp)
|
---|
330 | { gsp->store(_qtField, mars::ptr< FieldTypeWrapper > (new FieldTypeWrapper(type))); }
|
---|
331 |
|
---|
332 | inline float sample (const long x, const long y, const long z) const
|
---|
333 | { return sample (GWCoords(x, y, z)); }
|
---|
334 | inline mars::vector3Df gradient (const long x, const long y, const long z) const
|
---|
335 | { return gradient (GWCoords(x, y, z)); }
|
---|
336 |
|
---|
337 | float sample (const GWCoords & coords) const;
|
---|
338 | mars::vector3Df gradient (const GWCoords & coords) const;
|
---|
339 |
|
---|
340 | private:
|
---|
341 | typedef mars::QuadTree_SphereIndexed< FieldTypeWrapper, GeoSpherePack::SCALAR > QuadTreeSpherePacks; // TODO: Name collision in worldfile.h
|
---|
342 | typedef std::vector< std::pair< std::string, mars::ptr< GeoSpherePack > > > SphPackList;
|
---|
343 |
|
---|
344 | SphPackList _sphpacks;
|
---|
345 | QuadTreeSpherePacks _qtField;
|
---|
346 | };
|
---|
347 |
|
---|
348 | class AllAgentMaps
|
---|
349 | {
|
---|
350 | public:
|
---|
351 | AgentMap density;
|
---|
352 |
|
---|
353 | AllAgentMaps (const unsigned long nWidth, const unsigned long nHeight);
|
---|
354 |
|
---|
355 | AgentMap & operator [] ( const FieldType enftType );
|
---|
356 | const AgentMap & operator [] ( const FieldType enftType ) const;
|
---|
357 | };
|
---|
358 |
|
---|
359 | // TODO: Move into DepositSynthesizer
|
---|
360 | class MineralsContainer
|
---|
361 | {
|
---|
362 | public:
|
---|
363 | inline void addSpherePack (const std::string & sName, const mars::ptr< GeoSpherePack > & rsp)
|
---|
364 | { _sphpacks.push_back(std::pair< std::string, mars::ptr< GeoSpherePack > > (sName, rsp)); }
|
---|
365 |
|
---|
366 | void flushTo (FileSource::MineralMap & minmap);
|
---|
367 |
|
---|
368 | private:
|
---|
369 | typedef std::vector< std::pair< std::string, mars::ptr< GeoSpherePack > > > SphPackList;
|
---|
370 |
|
---|
371 | SphPackList _sphpacks;
|
---|
372 | };
|
---|
373 |
|
---|
374 | class IGeoWorldListener
|
---|
375 | {
|
---|
376 | public:
|
---|
377 | virtual void runningMorph (const mars::ptr< GeoMorph > & pGM, const size_t i, const size_t nTotal) {};
|
---|
378 | virtual void runningMorphs (MorphList::const_iterator i0, MorphList::const_iterator iN, const size_t i, const size_t nCount, const size_t nTotal) {};
|
---|
379 | virtual void rejectedMorph (const mars::ptr< GeoMorph > & pGM) {};
|
---|
380 | };
|
---|
381 |
|
---|
382 | class PagedGeoWorld : public mars::Observable< IGeoWorldListener >
|
---|
383 | {
|
---|
384 | private:
|
---|
385 | unsigned short
|
---|
386 | _nNumProcs;
|
---|
387 |
|
---|
388 | GW_MUTEX(mutex);
|
---|
389 |
|
---|
390 | mutable FileSource * _pFile;
|
---|
391 | mutable RegionContainer * _plsbboxLockedMutableRegions;
|
---|
392 |
|
---|
393 | DepositSynthesizer
|
---|
394 | * _pDepSynth;
|
---|
395 |
|
---|
396 | struct Pass
|
---|
397 | {
|
---|
398 | QTMorphs quadtree;
|
---|
399 | MorphList list;
|
---|
400 |
|
---|
401 | Pass(const unsigned long nWWidth, const unsigned long nWHeight)
|
---|
402 | : quadtree(nWWidth, nWHeight) {}
|
---|
403 | };
|
---|
404 | typedef std::vector< Pass * > PassList;
|
---|
405 |
|
---|
406 | PassList _passes;
|
---|
407 |
|
---|
408 | AllAgentMaps * _pAgentMaps;
|
---|
409 |
|
---|
410 | protected:
|
---|
411 | typedef std::set< mars::ptr< GeoMorph > > MorphSet;
|
---|
412 |
|
---|
413 | enum Mode
|
---|
414 | {
|
---|
415 | Read,
|
---|
416 | Write
|
---|
417 | };
|
---|
418 |
|
---|
419 | class Picks : public MorphSet
|
---|
420 | {
|
---|
421 | private:
|
---|
422 | mars::BBox< long > _bbox;
|
---|
423 |
|
---|
424 | public:
|
---|
425 | inline const mars::BBox< long > & getBBox() const { return _bbox; }
|
---|
426 | inline void setBBox (const mars::BBox< long > & bbox) { _bbox = bbox; }
|
---|
427 | void computeBBox ();
|
---|
428 | void consume( const IMineralQuery * pQMin, LockedGWSection * pSection, MineralsContainer & ctrMins );
|
---|
429 | };
|
---|
430 |
|
---|
431 | struct WorkItem
|
---|
432 | {
|
---|
433 | mars::ptr< Picks > picks;
|
---|
434 | LockedGWSection * section;
|
---|
435 | MineralsContainer minerals;
|
---|
436 |
|
---|
437 | WorkItem ()
|
---|
438 | : picks(NULL), section(NULL) {}
|
---|
439 |
|
---|
440 | WorkItem(const mars::ptr< Picks > & pPicks)
|
---|
441 | : picks(pPicks), section(NULL) {}
|
---|
442 |
|
---|
443 | WorkItem(const mars::ptr< GeoMorph > & pGM, const mars::BBox< long > & bbox = mars::BBox< long > ())
|
---|
444 | : picks(new Picks())
|
---|
445 | {
|
---|
446 | picks->insert(pGM);
|
---|
447 | if (bbox.empty())
|
---|
448 | picks->computeBBox();
|
---|
449 | else
|
---|
450 | picks->setBBox(bbox);
|
---|
451 | }
|
---|
452 | };
|
---|
453 |
|
---|
454 | struct WorkQueue
|
---|
455 | {
|
---|
456 | typedef std::deque< WorkItem > ItemQueue;
|
---|
457 |
|
---|
458 | ItemQueue inbox, outbox, ready;
|
---|
459 | };
|
---|
460 |
|
---|
461 | class IWorkQueueListener
|
---|
462 | {
|
---|
463 | public:
|
---|
464 | virtual void readyQueue (const WorkQueue::ItemQueue & readyq) {}
|
---|
465 | virtual void collisions (const WorkQueue::ItemQueue & colq) {}
|
---|
466 | virtual void unlockQueue (const WorkQueue::ItemQueue & unlq) {}
|
---|
467 | };
|
---|
468 |
|
---|
469 | class MasterSet : private MorphSet
|
---|
470 | {
|
---|
471 | private:
|
---|
472 | QTMorphs * _pQTMorphs;
|
---|
473 |
|
---|
474 | GW_MUTEX(mutex);
|
---|
475 |
|
---|
476 | public:
|
---|
477 | MasterSet (QTMorphs * pQTMorphs, MorphList::const_iterator iMorphs0, MorphList::const_iterator iMorphsN);
|
---|
478 |
|
---|
479 | bool empty ();
|
---|
480 | mars::ptr< Picks > collect( const QTMorphs::Region & rgBBox );
|
---|
481 | void push (const mars::ptr< Picks > & pPicks);
|
---|
482 |
|
---|
483 | MorphSet::size_type size() const { return MorphSet::size(); }
|
---|
484 |
|
---|
485 | const_iterator begin () const { return MorphSet::begin(); }
|
---|
486 | const_iterator end () const { return MorphSet::end(); }
|
---|
487 | };
|
---|
488 |
|
---|
489 | LockedGWSection * doLock (const mars::BBox< long > & bbox, const bool bPad = true, const bool bReadOnly = false) const;
|
---|
490 |
|
---|
491 | template< Mode MODE, typename TYPE_LockedGWSection >
|
---|
492 | void performIOOperation (TYPE_LockedGWSection * pSection) const;
|
---|
493 |
|
---|
494 | template< Mode MODE >
|
---|
495 | inline void blockOp ( LockedGWSection * pSection, FileSource::MainDEM::Block & block, const unsigned short i, const unsigned short j ) const
|
---|
496 | {
|
---|
497 | switch (MODE)
|
---|
498 | {
|
---|
499 | case Read: readBlock(pSection, block, i, j); break;
|
---|
500 | case Write: writeBlock(pSection, block, i, j); break;
|
---|
501 | }
|
---|
502 | }
|
---|
503 | template< Mode MODE >
|
---|
504 | inline void seekTileOp (const int nTX, const int nTY, const std::ios_base::seekdir dir = std::ios_base::cur) const
|
---|
505 | {
|
---|
506 | switch (MODE)
|
---|
507 | {
|
---|
508 | case Read: _pFile->tilemap.seekg(nTX, nTY, dir); break;
|
---|
509 | case Write: _pFile->tilemap.seekp(nTX, nTY, dir); break;
|
---|
510 | }
|
---|
511 | }
|
---|
512 |
|
---|
513 | void readBlock( LockedGWSection * pSection, FileSource::MainDEM::Block & block, const unsigned short i, const unsigned short j ) const;
|
---|
514 | void writeBlock( const LockedGWSection * pSection, FileSource::MainDEM::Block & block, const unsigned short i, const unsigned short j ) const;
|
---|
515 |
|
---|
516 | void processWorkQueue (PagedGeoWorld::WorkQueue & q, IWorkQueueListener * pListener = NULL);
|
---|
517 |
|
---|
518 | void flushMinerals (MineralsContainer & ctrMins);
|
---|
519 | void flushOutbox( WorkQueue::ItemQueue &outbox );
|
---|
520 | bool isPickValid (const Picks & p) const;
|
---|
521 | bool isValidSectionBBox (const mars::BBox< long > & bbox) const;
|
---|
522 |
|
---|
523 | bool checkGeoMorph( const mars::ptr<GeoMorph> &gm );
|
---|
524 |
|
---|
525 | public:
|
---|
526 | static const unsigned short DEFAULT_NUM_PROCS = 16;
|
---|
527 |
|
---|
528 | PagedGeoWorld (DepositSynthesizer * pDepSynth, FileSource * pFile, const unsigned short nPasses);
|
---|
529 | ~PagedGeoWorld();
|
---|
530 |
|
---|
531 | inline void setNumProcs(const unsigned short nNumProcs) { _nNumProcs = nNumProcs; }
|
---|
532 |
|
---|
533 | inline const unsigned short getLOD () const { return 0; } // TODO: Get rid of LOD for PagedGeoWorld
|
---|
534 | unsigned short getMaxGeoMorphWidth () const;
|
---|
535 | unsigned short getMaxGeoMorphHeight () const;
|
---|
536 |
|
---|
537 | void addMorphs (MorphList & morphs, MorphList & rejects, const unsigned short nPass);
|
---|
538 | bool addMorph (mars::ptr <GeoMorph> & gm, const unsigned short nPass);
|
---|
539 |
|
---|
540 | inline MorphList::const_iterator beginPass (const unsigned short nPass) const { return _passes[nPass]->list.begin(); }
|
---|
541 | inline MorphList::iterator beginPass (const unsigned short nPass) { return _passes[nPass]->list.begin(); }
|
---|
542 | inline MorphList::const_iterator endPass (const unsigned short nPass) const { return _passes[nPass]->list.end(); }
|
---|
543 | inline MorphList::iterator endPass (const unsigned short nPass) { return _passes[nPass]->list.end(); }
|
---|
544 | inline unsigned short getPassCount () const { return _passes.size(); }
|
---|
545 | void runMorphs (const unsigned short nPass, MorphList & rejects);
|
---|
546 |
|
---|
547 | inline const AllAgentMaps & getAgentMaps () const
|
---|
548 | {
|
---|
549 | assert(_pAgentMaps != NULL);
|
---|
550 | return *_pAgentMaps;
|
---|
551 | }
|
---|
552 | inline AllAgentMaps & getAgentMaps ()
|
---|
553 | {
|
---|
554 | assert(_pAgentMaps != NULL);
|
---|
555 | return *_pAgentMaps;
|
---|
556 | }
|
---|
557 |
|
---|
558 | inline LockedGWSection * lock (const mars::BBox< long > & bbox, const bool bPad = true)
|
---|
559 | { return doLock(bbox, bPad, false); }
|
---|
560 | inline const LockedGWSection * lockro (const mars::BBox< long > & bbox, const bool bPad = true) const
|
---|
561 | { return doLock(bbox, bPad, true); }
|
---|
562 |
|
---|
563 | inline LockedGWSection * lock (const long x, const long y, const unsigned short nWidth, const unsigned short nHeight, const bool bPad = true)
|
---|
564 | { return doLock (mars::BBox< long > (x, y, x + nWidth - 1, y + nHeight - 1), bPad, false); }
|
---|
565 | inline const LockedGWSection * lockro (const long x, const long y, const unsigned short nWidth, const unsigned short nHeight, const bool bPad = true) const
|
---|
566 | { return doLock (mars::BBox< long > (x, y, x + nWidth - 1, y + nHeight - 1), bPad, true); }
|
---|
567 |
|
---|
568 | void unlock (LockedGWSection * pSection);
|
---|
569 | void unlock (const LockedGWSection * pSection) const;
|
---|
570 |
|
---|
571 | inline void operator >> (mars::ScalarFieldView< GeoHeightMap::Precision > & view) const
|
---|
572 | {
|
---|
573 | assert(_pFile != NULL);
|
---|
574 | _pFile->tilemap >> view;
|
---|
575 | }
|
---|
576 |
|
---|
577 | inline const unsigned long getWorldWidth () const { return static_cast< unsigned long > (_pFile->tilemap.getTilesWide()) * static_cast< unsigned long > (_pFile->tilemap.getVirtualTileDim()); }
|
---|
578 | inline const unsigned long getWorldHeight () const { return static_cast< unsigned long > (_pFile->tilemap.getTilesHigh()) * static_cast< unsigned long > (_pFile->tilemap.getVirtualTileDim()); }
|
---|
579 | inline const unsigned short getTileDimension () const { return _pFile->tilemap.getVirtualTileDim(); }
|
---|
580 | };
|
---|
581 |
|
---|
582 | class GeoWorld : public mars::Observable< IGeoWorldListener >
|
---|
583 | {
|
---|
584 | private:
|
---|
585 | unsigned short
|
---|
586 | _nLODLowest, _nLODMid,
|
---|
587 | _nTileDim;
|
---|
588 |
|
---|
589 | GeoHeightMap
|
---|
590 | * _phmLowest;
|
---|
591 | DepositSynthesizer
|
---|
592 | * _pDepSynth;
|
---|
593 |
|
---|
594 | MineralsContainer
|
---|
595 | _ctrMins;
|
---|
596 | AllAgentMaps
|
---|
597 | * _pAllAgentMaps;
|
---|
598 |
|
---|
599 | unsigned long
|
---|
600 | _nLowWidth, _nLowHeight;
|
---|
601 |
|
---|
602 | FileSource * _pFile;
|
---|
603 |
|
---|
604 | MorphList _morphs;
|
---|
605 | mutable RegionContainer * _plsbboxLockedMutableRegions;
|
---|
606 |
|
---|
607 | GW_MUTEX(mutex);
|
---|
608 |
|
---|
609 | protected:
|
---|
610 | LockedGWSection * lock (const mars::BBox< long > & bbox, const bool bReadOnly) const;
|
---|
611 | LockedGWSection * lock (const bool bReadOnly) const;
|
---|
612 |
|
---|
613 | void runMorph( const MineralsDB & mindb, mars::ptr< GeoMorph > pGM, LockedGWSection * pLockedSection );
|
---|
614 | bool checkGeoMorph( const mars::ptr<GeoMorph> &gm );
|
---|
615 |
|
---|
616 | public:
|
---|
617 | static const unsigned short MIN_LOWEST_LOD = 2;
|
---|
618 |
|
---|
619 | GeoWorld (
|
---|
620 | DepositSynthesizer * pDepSynth,
|
---|
621 | const unsigned short nLODLowest,
|
---|
622 | const unsigned short nLODMid,
|
---|
623 | FileSource * pFile
|
---|
624 | );
|
---|
625 | ~GeoWorld();
|
---|
626 |
|
---|
627 | inline AllAgentMaps & getAgentMaps () { return *_pAllAgentMaps; }
|
---|
628 | inline const AllAgentMaps & getAgentMaps () const { return *_pAllAgentMaps; }
|
---|
629 |
|
---|
630 | inline unsigned long getWidth () const { return _nLowWidth; }
|
---|
631 | inline unsigned long getHeight () const { return _nLowHeight; }
|
---|
632 | inline unsigned short getLOD () const { return _nLODLowest; }
|
---|
633 | inline unsigned short getDeltaLOD () const { return _nLODLowest - _nLODMid; }
|
---|
634 | unsigned short getMaxGeoMorphWidth () const;
|
---|
635 | unsigned short getMaxGeoMorphHeight () const;
|
---|
636 |
|
---|
637 | void addMorphs( MorphList & morphs, MorphList & rejects );
|
---|
638 | bool addMorph (mars::ptr <GeoMorph> & gm);
|
---|
639 |
|
---|
640 | inline MorphList::const_iterator beginMorphs () const { return _morphs.begin(); }
|
---|
641 | inline MorphList::const_iterator endMorphs () const { return _morphs.end(); }
|
---|
642 | inline MorphList::iterator beginMorphs () { return _morphs.begin(); }
|
---|
643 | inline MorphList::iterator endMorphs () { return _morphs.end(); }
|
---|
644 |
|
---|
645 | inline LockedGWSection * lock ()
|
---|
646 | { return lock(false); }
|
---|
647 | inline const LockedGWSection * lock () const
|
---|
648 | { return lock(true); }
|
---|
649 | inline LockedGWSection * lock (const mars::BBox< long > & bbox)
|
---|
650 | { return lock(bbox, false); }
|
---|
651 | inline const LockedGWSection * lock (const mars::BBox< long > & bbox) const
|
---|
652 | { return lock(bbox, true); }
|
---|
653 |
|
---|
654 | inline LockedGWSection * lock (const long x, const long y, const unsigned short nWidth, const unsigned short nHeight)
|
---|
655 | { return lock (mars::BBox< long > (x, y, x + nWidth - 1, y + nHeight - 1)); }
|
---|
656 | inline const LockedGWSection * lock (const long x, const long y, const unsigned short nWidth, const unsigned short nHeight) const
|
---|
657 | { return lock (mars::BBox< long > (x, y, x + nWidth - 1, y + nHeight - 1)); }
|
---|
658 |
|
---|
659 | void unlock (LockedGWSection * pSection);
|
---|
660 | void unlock (const LockedGWSection * pSection) const;
|
---|
661 |
|
---|
662 | void runMorphs (const MineralsDB & mindb, MorphList & rejects);
|
---|
663 |
|
---|
664 | void write(const float fCoarseness);
|
---|
665 |
|
---|
666 | inline const GeoHeightMap & getLowHM () const { return *_phmLowest; }
|
---|
667 |
|
---|
668 | inline void operator << (const mars::ScalarFieldView< GeoHeightMap::Precision > & view)
|
---|
669 | { *_phmLowest << view; }
|
---|
670 | inline void operator >> (mars::ScalarFieldView< GeoHeightMap::Precision > & view) const
|
---|
671 | { *_phmLowest >> view; }
|
---|
672 | };
|
---|
673 | }
|
---|
674 |
|
---|
675 | #endif
|
---|