source: Revenant/geoworld/include/worldfile.h@ 7ef8ec4

port/mars-tycoon
Last change on this file since 7ef8ec4 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: 19.2 KB
Line 
1#ifndef __GWPAGINGUTILITIES_H__
2#define __GWPAGINGUTILITIES_H__
3
4#include <fstream>
5#include <string>
6#include <map>
7#include <set>
8
9#include <mars_calc.h>
10#include <mars_grids.h>
11#include <mars_log.h>
12#include <mars_ptr.h>
13#include <mars_streams.h>
14
15#include "vmpdg.h"
16#include "gwtypes.h"
17#include "sphpack.h"
18#include "mindb.h"
19#include "stratum.h"
20
21namespace geoworld
22{
23 template< typename T, typename ST = mars::Numerics< T > >
24 class TileBlock : public mars::ScalarField< T, ST >
25 {
26 private:
27 TileBlock (const TileBlock & copy);
28
29 public:
30 typedef mars::ScalarFieldView< T, ST > SFType;
31 typedef typename SFType::Offset SFOffs;
32
33 using super = mars::ScalarField< T, ST >;
34 using superview = mars::ScalarFieldView< T, ST >;
35
36 const unsigned short vdim, pdim;
37 const unsigned int vsize, psize;
38
39 TileBlock (const unsigned short nTileDim)
40 : super (nTileDim + 1, nTileDim + 1),
41 vdim(nTileDim), pdim(nTileDim + 1), vsize(static_cast< unsigned int > (mars::SQ(nTileDim))), psize(static_cast< unsigned int > (mars::SQ(nTileDim + 1)))
42 {
43 assert(nTileDim > 0);
44 assert(((nTileDim - 1) & nTileDim) == 0); // Ensures that nTileDim is a power of 2
45 }
46
47 inline void operator >> (super & dest) const
48 { super::operator >> (dest); }
49 inline void operator << (const super & other)
50 { super::operator << (other); }
51 inline void operator >> (superview & dest) const
52 { super::operator >> (dest); }
53 inline void operator << (const superview & other)
54 { super::operator << (other); }
55
56 inline std::istream & operator << (std::istream & ins)
57 { return super::operator << (ins); }
58 inline std::ostream & operator >> (std::ostream & outs) const
59 { return super::operator >> (outs); }
60
61 inline void copyTo (SFType & hm, const unsigned short nBlockX, const unsigned short nBlockY ) const
62 { super::operator >> (SFOffs(&hm, static_cast< signed int > (nBlockX) * vdim, static_cast< signed int > (nBlockY) * vdim)); }
63 inline void copyFrom (const SFType & hm, const unsigned short nBlockX, const unsigned short nBlockY )
64 { super::operator << (SFOffs(&hm, static_cast< signed int > (nBlockX) * vdim, static_cast< signed int > (nBlockY) * vdim)); }
65 };
66
67 class TileMapDetails
68 {
69 private:
70 unsigned short
71 _nLOD,
72 _nTileDim;
73 unsigned int
74 _nTilesW,
75 _nTilesH;
76
77 public:
78 TileMapDetails (const unsigned short nTileDim, const unsigned int nTilesW, const unsigned int nTilesH, const unsigned short nLOD = 0);
79
80 inline unsigned short getLOD () const { return _nLOD; }
81 inline unsigned int getTilesWide () const { return _nTilesW; }
82 inline unsigned int getTilesHigh () const { return _nTilesH; }
83 inline unsigned short getVirtualTileDim () const { return _nTileDim >> _nLOD; }
84 inline unsigned short getPhysicalTileDim () const { return (_nTileDim >> _nLOD) + 1; }
85 inline unsigned long getVirtualWidth () const { return (static_cast< unsigned long > (_nTilesW) * _nTileDim) >> _nLOD; }
86 inline unsigned long getVirtualHeight () const { return (static_cast< unsigned long > (_nTilesH) * _nTileDim) >> _nLOD; }
87 inline unsigned long getTileCount () const { return static_cast< unsigned long > (_nTilesH) * _nTilesW; }
88 inline unsigned int getVirtualTileSize () const { return mars::SQ(static_cast< unsigned int > (_nTileDim >> _nLOD)); }
89 inline unsigned int getPhysicalTileSize () const { return mars::SQ(static_cast< unsigned int > ((_nTileDim >> _nLOD) + 1)); }
90 inline unsigned long getVirtualUnitCount () const { return static_cast< unsigned long > (getTileCount()) * mars::SQ(static_cast< unsigned long > (_nTileDim >> _nLOD)); }
91 inline unsigned long getPhysicalUnitCount () const { return static_cast< unsigned long > (getTileCount()) * mars::SQ(static_cast< unsigned long > ((_nTileDim >> _nLOD) + 1)); }
92 inline unsigned long getWorldWidth () const { return static_cast< unsigned long > (_nTilesW) * _nTileDim; }
93 inline unsigned long getWorldHeight () const { return static_cast< unsigned long > (_nTilesH) * _nTileDim; }
94 };
95
96 class FileChunk
97 {
98 private:
99 std::streampos _szFileOffset;
100
101 protected:
102 const std::streampos & getFileOffset () const;
103 void setFileOffset(const std::streamoff & szFileOffset);
104 bool isSetFileOffset () const;
105
106 public:
107 FileChunk ();
108
109 virtual void init(const std::streamoff & szFileOffset);
110 virtual std::streampos end () const = 0;
111 };
112
113 class StaticFileChunk : public FileChunk
114 {
115 private:
116 std::streamoff _szSize;
117
118 protected:
119 void setSize (const std::streamoff & szSize);
120
121 public:
122 std::streampos end () const;
123 };
124
125 class VariableFileChunk : public FileChunk
126 {
127 private:
128 FileChunk * _pNextChunk, * _pPrevChunk;
129 bool _bDirty;
130 std::streamoff _szChunkEnd;
131 mars::ptr< std::fstream > _pfhFile;
132
133 protected:
134 std::streampos end () const;
135
136 virtual void writeVariableData () = 0;
137 virtual void readVariableData() = 0;
138
139 public:
140 VariableFileChunk (const mars::ptr< std::fstream > & pfhFile);
141
142 virtual void init (FileChunk * pPreviousChunk);
143
144 void dirty();
145 void load();
146 void commit ();
147 };
148
149 namespace filesource {
150 struct InfoHeader
151 {
152 char IDENT[4];
153 unsigned long endian;
154 unsigned short version;
155 unsigned short tdim;
156 unsigned int tx, ty;
157 unsigned short depth;
158
159 struct GeoHost
160 {
161 unsigned short layers, lod;
162
163 inline GeoHost () : layers (0), lod(0) {}
164 } geohost;
165
166 InfoHeader ();
167 bool validate () const;
168 };
169
170 class Ex : public std::exception
171 {
172 public:
173 const std::string message;
174
175 Ex (const char * szMsg) : message(szMsg) {}
176 };
177 }
178
179 template< typename T, typename ST = mars::Numerics< T > >
180 class StreamTileMap : public TileMapDetails, public StaticFileChunk
181 {
182 private:
183 mars::ptr< std::fstream > _pfhFile;
184
185 protected:
186 void assertPosition( const std::streamoff pos0, const std::streamoff pos, const std::ios_base::seekdir dir, const int nTileX, const int nTileY ) const
187 {
188 const std::streamoff
189 dpos = pos - pos0;
190
191 assert(pos < static_cast< std::streampos > (getPhysicalUnitCount()) * sizeof(T) + getFileOffset());
192 switch (dir)
193 {
194 case std::ios::cur:
195 assert(dpos == computeBlockOffset(nTileX, nTileY));
196 break;
197 case std::ios::beg:
198 assert(pos == computeBlockOffset(nTileX, nTileY) + getFileOffset());
199 break;
200 case std::ios::end:
201 assert(pos == (static_cast< std::streampos > (getPhysicalUnitCount()) * sizeof(T) + getFileOffset()) - computeBlockOffset(nTileX, nTileY));
202 break;
203 }
204 }
205
206 std::streamoff computeBlockOffset (const int nTileX, const int nTileY) const
207 {
208 using namespace std;
209
210 return
211 (static_cast< streamoff > (nTileY) * static_cast< streamoff > (getTilesWide()) + static_cast< streamoff > (nTileX))
212 * static_cast< streamoff > (getPhysicalTileSize()) * sizeof(T);
213 }
214
215 public:
216 typedef TileBlock< T, ST > Block;
217
218 StreamTileMap ( mars::ptr< std::fstream > & pfhFile, const unsigned short nTileDim, const unsigned int nTilesW, const unsigned int nTilesH, const unsigned short nLOD = 0 )
219 : _pfhFile(pfhFile), TileMapDetails(nTileDim, nTilesW, nTilesH, nLOD)
220 { setSize(static_cast< std::streamsize > (getPhysicalUnitCount()) * sizeof(T)); }
221
222 void seekg( const int nTileX, const int nTileY, const std::ios_base::seekdir dir = std::ios_base::cur )
223 {
224 assert(getFileOffset() >= sizeof(filesource::InfoHeader));
225 #ifdef _DEBUG
226 const std::streamoff pos0 = _pfhFile->tellg();
227 #endif
228
229 _pfhFile->seekg(computeBlockOffset(nTileX, nTileY) + (dir == std::ios_base::beg ? getFileOffset() : static_cast< std::streampos > (0)), dir);
230 if (_pfhFile->fail())
231 throw filesource::Ex("Seek read failed");
232
233 LOG(mars::Log::Debug) << "tellg=" << _pfhFile->tellg();
234
235 #ifdef _DEBUG
236 assertPosition(pos0, _pfhFile->tellg(), dir, nTileX, nTileY);
237 #endif // _DEBUG
238 }
239
240 void seekp( const int nTileX, const int nTileY, const std::ios_base::seekdir dir = std::ios_base::cur )
241 {
242 assert(getFileOffset() >= sizeof(filesource::InfoHeader));
243 #ifdef _DEBUG
244 const std::streamoff pos0 = _pfhFile->tellp();
245 #endif
246
247 _pfhFile->seekp(computeBlockOffset(nTileX, nTileY) + (dir == std::ios_base::beg ? getFileOffset() : static_cast< std::streampos> (0)), dir);
248 if (_pfhFile->fail())
249 throw filesource::Ex("Seek write failed");
250
251 LOG(mars::Log::Debug) << "tellp=" << _pfhFile->tellp();
252
253 #ifdef _DEBUG
254 assertPosition(pos0, _pfhFile->tellp(), dir, nTileX, nTileY);
255 #endif // _DEBUG
256 }
257
258 inline Block * createBlock () const
259 { return new Block(getVirtualTileDim()); }
260
261 void operator >> (Block & tile)
262 {
263#ifdef _DEBUG
264 const std::streamoff pos0 = _pfhFile->tellg();
265#endif
266 tile << *_pfhFile;
267 if (_pfhFile->fail())
268 throw filesource::Ex("Read failed");
269
270 LOG(mars::Log::Debug) << "tellg=" << _pfhFile->tellg();
271#ifdef _DEBUG
272 assert(_pfhFile->tellg() - pos0 == static_cast< std::streamoff > (getPhysicalTileSize() * sizeof(T)));
273#endif
274 }
275
276 void operator << (const Block & tile)
277 {
278#ifdef _DEBUG
279 const std::streamoff pos0 = _pfhFile->tellp();
280#endif
281 tile >> *_pfhFile;
282 if (_pfhFile->fail())
283 throw filesource::Ex("Write failed");
284
285 LOG(mars::Log::Debug) << "tellp=" << _pfhFile->tellp();
286#ifdef _DEBUG
287 assert(_pfhFile->tellp() - pos0 == static_cast< std::streamoff > (getPhysicalTileSize() * sizeof(T)));
288#endif
289 }
290
291 void operator >> ( mars::ScalarFieldView< T, ST > & view )
292 {
293 Block block (getVirtualTileDim());
294
295 seekg(0, 0, std::ios_base::beg);
296 for (unsigned int j = 0; j < getTilesHigh(); ++j)
297 for (unsigned int i = 0; i < getTilesWide(); ++i)
298 {
299 block << *this;
300 block.copyTo(view, i, j);
301 }
302 }
303 void operator << ( const mars::ScalarFieldView< T, ST > & view )
304 {
305 Block block (getVirtualTileDim());
306
307 seekp(0, 0, std::ios_base::beg);
308 for (unsigned int j = 0; j < getTilesHigh(); ++j)
309 for (unsigned int i = 0; i < getTilesWide(); ++i)
310 {
311 block.copyFrom(view, i, j);
312 block >> *this;
313 }
314 }
315 };
316
317 template< typename T, typename ST >
318 void operator << (TileBlock< T, ST > & tile, StreamTileMap< T, ST > & tmap)
319 { tmap >> tile; }
320
321 template< typename T, typename ST >
322 void operator >> (const TileBlock< T, ST > & tile, StreamTileMap< T, ST > & tmap)
323 { tmap << tile; }
324
325 class FileSource : public TileMapDetails
326 {
327 private:
328 template< typename T >
329 static T dimXp2 (const T nMinDim)
330 {
331 const unsigned int nL2 = mars::LOG2(nMinDim);
332 T t = 1 << nL2;
333
334 if (t < nMinDim)
335 t *= 2;
336 return t;
337 }
338 static FileSource * open (const std::string & sFileName, const std::ios::openmode nMode);
339
340 public:
341 static const unsigned short MAX_TILE_DIM = 1024;
342 static const unsigned int MAX_AXIS_TILES = 1024;
343 static const unsigned short MAX_WORLD_DEPTH = 30000;
344
345 typedef StreamTileMap< GeoHeightMap::Precision > MainDEM;
346
347 inline unsigned short getWorldDepth () const { return _nDepth; }
348
349 MainDEM tilemap;
350
351 class MineralHostMap : public VariableFileChunk, public TileMapDetails
352 {
353 public:
354 typedef StreamTileMap< typename GeoHeightMap::Precision > TopDEM;
355
356 const unsigned short count;
357
358 TopDEM top;
359
360 class LayerMap : public StreamTileMap< typename GeoStratumField::Precision, typename GeoStratumField::ScalarTraits >
361 {
362 public:
363 typedef std::vector< std::string > DefList;
364 typedef mars::Range< GeoStratumField::AltitudePrecision > RangeType;
365
366 RangeType range;
367
368 LayerMap(mars::ptr< std::fstream > & pfhFile, const unsigned short nLOD, const unsigned short nTileDim, const unsigned int nTilesW, const unsigned int nTilesH, const std::vector< std::string > & vsDefs = std::vector< std::string > ());
369
370 inline void operator >> ( GeoStratumField::View & field )
371 { retrieveField(field); }
372 inline void operator << ( const GeoStratumField::View & field)
373 { commitField(field); }
374
375 inline void operator >> (Block & tile)
376 { StreamTileMap::operator >> (tile); }
377 inline void operator << (const Block & tile)
378 { StreamTileMap::operator << (tile); }
379
380 inline DefList::const_iterator beginDefs() const { return _vsDefs.begin(); }
381 inline DefList::const_iterator endDefs() const { return _vsDefs.end(); }
382
383 void putDefs (GeoStratumField::View & field) const;
384 void setDefs (const GeoStratumField::View & field);
385
386 void operator << (mars::ObjectStream & ins)
387 {
388 ins >> _vsDefs;
389 ins >> range;
390 }
391 void operator >> (mars::ObjectStream & outs)
392 {
393 outs << _vsDefs;
394 outs << range;
395 }
396
397 private:
398 DefList _vsDefs;
399
400 void operator >> ( GeoStratumField::ScalarFieldView & view );
401 void operator << ( const GeoStratumField::ScalarFieldView & view );
402
403 inline void retrieveField ( GeoStratumField::View & field )
404 {
405 putDefs(field);
406 StreamTileMap::operator >> (field);
407 }
408 inline void commitField ( const GeoStratumField::View & field)
409 {
410 StreamTileMap::operator << (field);
411 setDefs(field);
412 }
413 };
414
415 class Offset
416 {
417 protected:
418 MineralHostMap * const _pMap;
419
420 public:
421 const signed int x, y;
422
423 Offset (MineralHostMap * const pMap, const signed int x, const signed int y);
424
425 void operator >> (Stratum & stratum);
426 void operator << (const Stratum & stratum);
427 };
428
429 MineralHostMap (mars::ptr< std::fstream > & pfhFile, const unsigned short nLayers, const unsigned short nLOD, const unsigned short nTileDim, const unsigned int nTilesW, const unsigned int nTilesH);
430 ~MineralHostMap ();
431
432 void init(const std::streamoff & szFileOffset, MainDEM * pPrevChunk);
433
434 void operator >> (Stratum & stratum);
435 void operator << (const Stratum & stratum);
436
437 inline LayerMap::Block * createLayerBlock () const
438 { return new LayerMap::Block(getVirtualTileDim()); }
439 inline TopDEM::Block * createTopDEMBlock () const
440 { return new TopDEM::Block(getVirtualTileDim()); }
441
442 inline const LayerMap & layer (const unsigned short i) const { return *_ppLayers[i]; }
443 inline LayerMap & layer (const unsigned short i) { return *_ppLayers[i]; }
444
445 protected:
446 void writeVariableData ();
447 void readVariableData ();
448
449 private:
450 LayerMap ** _ppLayers;
451 std::streamoff _szLayers;
452 mars::ptr< std::fstream > _pfhFile;
453
454 void init(const std::streamoff & szFileOffset) {}
455 } geohost;
456
457 class MineralMap : public TileMapDetails, public VariableFileChunk
458 {
459 public:
460 typedef std::set< MineralPtr > MineralSet;
461 typedef mars::QuadTree_SphereIndexed< MineralPtr, GeoSpherePack::SCALAR > QuadTreeSpherePacks;
462 typedef std::pair< QuadTreeSpherePacks::Region, size_t > SphereIndexReference;
463 typedef std::vector< SphereIndexReference > SphRefVector;
464 typedef std::pair< const MineralPtr, const QuadTreeSpherePacks::Region & > SphereReference;
465
466 class MinDefCache
467 {
468 private:
469 const std::vector< MineralPtr > * _pidxMinDefs;
470
471 public:
472 MinDefCache (const std::vector< MineralPtr > * pidxMinDefs)
473 : _pidxMinDefs(pidxMinDefs) {}
474
475 inline SphereReference convert (const SphereIndexReference & ref) const
476 {
477 assert(ref.second < _pidxMinDefs->size());
478 return SphereReference((*_pidxMinDefs)[ref.second], ref.first);
479 }
480 };
481
482 class TileResult : private SphRefVector
483 {
484 public:
485 class const_iterator : private SphRefVector::const_iterator, public std::iterator< std::input_iterator_tag, SphereReference >
486 {
487 public:
488 const_iterator (const MinDefCache & cache, const SphRefVector::const_iterator & i)
489 : SphRefVector::const_iterator(i), _cache(cache) {}
490
491 inline const SphereReference operator * () const
492 { return _cache.convert(SphRefVector::const_iterator::operator * ()); }
493
494 inline const_iterator & operator ++ ()
495 {
496 SphRefVector::const_iterator::operator ++ ();
497 return *this;
498 }
499
500 inline const_iterator operator ++ (int)
501 {
502 const_iterator i0 = *this;
503 SphRefVector::const_iterator::operator ++ (0);
504 return i0;
505 }
506
507 inline const_iterator & operator -- ()
508 {
509 SphRefVector::const_iterator::operator -- ();
510 return *this;
511 }
512
513 inline const_iterator operator -- (int)
514 {
515 const_iterator i0 = *this;
516 SphRefVector::const_iterator::operator -- (0);
517 return i0;
518 }
519
520 inline const_iterator & operator += (const size_t nOff)
521 {
522 SphRefVector::const_iterator::operator += (nOff);
523 return *this;
524 }
525
526 inline const_iterator operator + (const size_t nOff) const
527 {
528 const_iterator i0 = *this;
529 return i0 += nOff;
530 }
531
532 inline const_iterator & operator -= (const size_t nOff)
533 {
534 SphRefVector::const_iterator::operator -= (nOff);
535 return *this;
536 }
537
538 inline const_iterator operator - (const size_t nOff) const
539 {
540 const_iterator i0 = *this;
541 return i0 -= nOff;
542 }
543
544 inline bool operator != (const const_iterator & other) const {
545 const_iterator i0 = *this;
546 return i0 != other;
547 }
548
549 private:
550 const MinDefCache & _cache;
551 };
552
553 TileResult (const MinDefCache & cache, const SphRefVector & list)
554 : SphRefVector(list), _cache(cache) {}
555
556 inline const SphereReference
557 operator [] (const size_t i) const
558 { return _cache.convert(std::vector< SphereIndexReference >::operator [] (i)); }
559
560 inline const_iterator begin () const { return const_iterator(_cache, SphRefVector::begin()); }
561 inline const_iterator end () const { return const_iterator(_cache, SphRefVector::end()); }
562
563 inline size_t size () const { return SphRefVector::size(); }
564
565 private:
566 MinDefCache _cache;
567 };
568
569 MineralMap (mars::ptr< std::fstream > & pfhFile, const std::ios::openmode nOpenMode, const unsigned short nTileDim, const unsigned int nTilesW, const unsigned int nTilesH);
570
571 void add (const MineralPtr & pMin, const QuadTreeSpherePacks::MyCylindricalRegion & rr);
572
573 TileResult operator () (const unsigned int i, const unsigned int j);
574
575 protected:
576 void writeVariableData();
577 void readVariableData ();
578
579 private:
580 typedef std::map< MineralPtr, size_t > MineralIndex;
581
582 struct MinMapHeader
583 {
584 std::streamoff mapoffs, listsoff; // DEPS: _bInitDefs
585 } _header;
586
587 static QuadTreeSpherePacks createQuadTree (const unsigned short nTileDim, const unsigned int nTilesW, const unsigned int nTilesH);
588
589 std::vector< MineralPtr > _mins;
590 MineralSet _setMinerals;
591 QuadTreeSpherePacks _qtMinerals;
592 mars::ptr< std::fstream > _pfhFile;
593 } minerals;
594
595 static FileSource * create (const std::string & sFileName, const unsigned long nMinWidth, const unsigned long nMinHeight, const unsigned short nDepth, const unsigned short nTileDim, const unsigned short nGeoHostLOD, const unsigned short nGeoHostLayerCount);
596 static inline FileSource * open (const std::string & sFileName)
597 { return open (sFileName, std::ios::in | std::ios::out); }
598 static FileSource * view (const std::string & sFileName)
599 { return open (sFileName, std::ios::in); }
600
601 void applyDEM (const GeoHeightMap * pHM, const float fCoarseness);
602
603 void load ();
604 void commit ();
605
606 ~FileSource();
607
608 protected:
609 FileSource(mars::ptr< std::fstream >& pfhFile, const std::ios_base::openmode nMode, const short unsigned int nTileDim, const unsigned int nTilesW, const unsigned int nTilesH, const short unsigned int nDepth, const short unsigned int nGeoHostLOD, const short unsigned int nGeoHostLayers);
610
611 static bool validate(const filesource::InfoHeader & header, mars::ptr< std::fstream > & pfhFile);
612
613 private:
614 mars::ptr< std::fstream > _pfhFile;
615 std::ios::openmode _nOpenMode;
616 std::streamoff _nHeaderEnd;
617 unsigned short _nDepth;
618 };
619}
620
621#endif
Note: See TracBrowser for help on using the repository browser.