[80a6a52] | 1 | #ifndef __GEOWORLDSTRATUM_H__
|
---|
| 2 | #define __GEOWORLDSTRATUM_H__
|
---|
| 3 |
|
---|
| 4 | #include <assert.h>
|
---|
| 5 |
|
---|
| 6 | #include <vector>
|
---|
| 7 | #include <fstream>
|
---|
| 8 |
|
---|
| 9 | #include <mars_util.h>
|
---|
| 10 | #include <gwtypes.h>
|
---|
| 11 | #include <gwutil.h>
|
---|
| 12 |
|
---|
| 13 | namespace geoworld
|
---|
| 14 | {
|
---|
| 15 | class StratumData
|
---|
| 16 | {
|
---|
| 17 | public:
|
---|
| 18 | typedef std::vector< GeoStratumField::View * > FieldList;
|
---|
| 19 |
|
---|
| 20 | class Offset
|
---|
| 21 | {
|
---|
| 22 | public:
|
---|
| 23 | StratumData * const data;
|
---|
| 24 | const StratumData * const_data;
|
---|
| 25 | const signed int x, y;
|
---|
| 26 |
|
---|
| 27 | Offset (StratumData * const pData, const signed int x, const signed int y)
|
---|
| 28 | : data(pData), const_data(pData), x(x), y(y) {}
|
---|
| 29 | Offset (const StratumData * pData, const signed int x, const signed int y)
|
---|
| 30 | : data(NULL), const_data(pData), x(x), y(y) {}
|
---|
| 31 |
|
---|
| 32 | void operator >> (StratumData & other) const
|
---|
| 33 | { const_data->copySection(other, x, y); }
|
---|
| 34 | void operator << (const StratumData & other)
|
---|
| 35 | {
|
---|
| 36 | assert(data != NULL);
|
---|
| 37 | other.copySection(*data, x, y);
|
---|
| 38 | }
|
---|
| 39 | };
|
---|
| 40 |
|
---|
| 41 | FieldList fields;
|
---|
| 42 | GeoHeightMap::View * baseview; // DEPS: Unbounded view depends on GeoHeightMap::Precision
|
---|
| 43 |
|
---|
| 44 | StratumData (const size_t nLayers, const unsigned short nWidth, const unsigned short nHeight, const mars::GridType engt = mars::Normal);
|
---|
| 45 | StratumData (StratumData * pParent, const unsigned short nLeft, const unsigned short nTop, const unsigned short nRight, const unsigned short nBottom);
|
---|
| 46 | ~StratumData();
|
---|
| 47 |
|
---|
| 48 | void operator >> (StratumData & dest) const;
|
---|
| 49 | void operator << (const StratumData & src);
|
---|
| 50 | inline void operator >> (Offset dest) const
|
---|
| 51 | {
|
---|
| 52 | copySection(*dest.data, dest.x, dest.y);
|
---|
| 53 | }
|
---|
| 54 | inline void operator << (const Offset src)
|
---|
| 55 | {
|
---|
| 56 | src.const_data->copySection(*this, src.x, src.y);
|
---|
| 57 | }
|
---|
| 58 |
|
---|
| 59 | private:
|
---|
| 60 | const StratumData * _pParent;
|
---|
| 61 |
|
---|
| 62 | void copySection (StratumData & dest, const signed int x, const signed int y) const;
|
---|
| 63 |
|
---|
| 64 | };
|
---|
| 65 |
|
---|
| 66 | class StratumView
|
---|
| 67 | {
|
---|
| 68 | private:
|
---|
| 69 | typedef std::vector< std::pair< size_t, size_t > > IdxMap;
|
---|
| 70 | typedef std::vector< size_t > ElemCounts;
|
---|
| 71 |
|
---|
| 72 | mars::RangeX< GeoHeightMap::Precision > _z;
|
---|
| 73 | GeoHeightMap::Precision _zBase, _zBasedMin;
|
---|
| 74 |
|
---|
| 75 | mutable StratumData _data;
|
---|
| 76 |
|
---|
| 77 | IdxMap _idx0map; // DEPS: Implication made in fetchSurfaceViewIndices()
|
---|
| 78 | ElemCounts _counts;
|
---|
| 79 | const WorldUnit _one;
|
---|
| 80 |
|
---|
| 81 | mutable size_t _nViewRefCount;
|
---|
| 82 | GW_MUTEX(atomic);
|
---|
| 83 |
|
---|
| 84 | protected:
|
---|
| 85 | StratumView(const size_t nLayers, const mars::BBox< WorldUnit > & bbox, const WorldUnit z0, const WorldUnit zN, const WorldUnit zBase, const unsigned short nLOD, const mars::GridType engt = mars::Normal);
|
---|
| 86 | StratumView(StratumData * pParentData, const mars::BBox< WorldUnit > & bbox, const WorldUnit z0, const WorldUnit zN, const WorldUnit zBase, const unsigned short nLOD);
|
---|
| 87 | StratumView(const StratumView * const pParent, const mars::BBox< WorldUnit > & bbox);
|
---|
| 88 | StratumView(StratumView && move) : _z(move._z), _zBase(move._zBase), _zBasedMin(move._zBasedMin), _data(move._data), _idx0map(move._idx0map), _counts(move._counts), _one(move._one), _nViewRefCount(move._nViewRefCount), abswidth(move.abswidth), absheight(move.absheight), absdepth(move.absdepth), width(move.width), height(move.height), depth(move.depth), lod(move.lod), layers(move.layers) {}
|
---|
| 89 |
|
---|
| 90 | inline static StratumView createHosted (const size_t nLayers, const WorldUnit nLeft, const WorldUnit nTop, const WorldUnit nBasement, const WorldUnit nRight, const WorldUnit nBottom, const WorldUnit nCeiling, const unsigned short nLOD, const mars::GridType engt = mars::Normal)
|
---|
| 91 | {
|
---|
| 92 | return createHosted(nLayers, mars::BBox< WorldUnit > (nLeft, nTop, nRight, nBottom), nBasement, nCeiling, nLOD, engt);
|
---|
| 93 | }
|
---|
| 94 | inline static StratumView createHosted (const size_t nLayers, const mars::BBox< WorldUnit > & bbox, const WorldUnit nBasement, const WorldUnit nCeiling, const unsigned short nLOD, const mars::GridType engt = mars::Normal)
|
---|
| 95 | {
|
---|
| 96 | return StratumView(
|
---|
| 97 | nLayers,
|
---|
| 98 | bbox,
|
---|
| 99 | nBasement,
|
---|
| 100 | nCeiling,
|
---|
| 101 | nBasement,
|
---|
| 102 | nLOD,
|
---|
| 103 | engt
|
---|
| 104 | );
|
---|
| 105 | }
|
---|
| 106 |
|
---|
| 107 | const GeoStratumField::Element & getDominantElement( std::vector< unsigned short > & indices ) const;
|
---|
| 108 |
|
---|
| 109 | public:
|
---|
| 110 | const unsigned long abswidth, absheight, absdepth;
|
---|
| 111 | const unsigned short width, height, depth, lod;
|
---|
| 112 |
|
---|
| 113 | class Ex : public std::exception
|
---|
| 114 | {
|
---|
| 115 | public:
|
---|
| 116 | const std::string message;
|
---|
| 117 |
|
---|
| 118 | Ex (const char * szMsg) : message(szMsg) {}
|
---|
| 119 | };
|
---|
| 120 |
|
---|
| 121 | class Offset
|
---|
| 122 | {
|
---|
| 123 | public:
|
---|
| 124 | StratumView * const view;
|
---|
| 125 | const StratumView * const_view;
|
---|
| 126 | const WorldUnit x, y;
|
---|
| 127 |
|
---|
| 128 | Offset (StratumView * const pView, const WorldUnit x, const WorldUnit y)
|
---|
| 129 | : view(pView), const_view(pView), x(x), y(y) {}
|
---|
| 130 | Offset (const StratumView * pView, const WorldUnit x, const WorldUnit y)
|
---|
| 131 | : view(NULL), const_view(pView), x(x), y(y) {}
|
---|
| 132 |
|
---|
| 133 | void operator >> (StratumView & other) const
|
---|
| 134 | {
|
---|
| 135 | const_view->_data >> StratumData::Offset(&other._data, x >> const_view->lod, y >> const_view->lod);
|
---|
| 136 | }
|
---|
| 137 | void operator << (const StratumView & other)
|
---|
| 138 | {
|
---|
| 139 | assert(view != NULL);
|
---|
| 140 | other._data << StratumData::Offset(&view->_data, x >> const_view->lod, y >> const_view->lod);
|
---|
| 141 | }
|
---|
| 142 | };
|
---|
| 143 |
|
---|
| 144 | typedef StratumView View;
|
---|
| 145 |
|
---|
| 146 | const size_t layers;
|
---|
| 147 |
|
---|
| 148 | ~StratumView();
|
---|
| 149 |
|
---|
| 150 | inline StratumData::FieldList::iterator beginFields () { return _data.fields.begin(); }
|
---|
| 151 | inline StratumData::FieldList::iterator endFields () { return _data.fields.end(); }
|
---|
| 152 | inline StratumData::FieldList::const_iterator beginFields () const { return _data.fields.begin(); }
|
---|
| 153 | inline StratumData::FieldList::const_iterator endFields () const { return _data.fields.end(); }
|
---|
| 154 |
|
---|
| 155 | inline GeoStratumField::View & field(const size_t c) { return *_data.fields[c]; }
|
---|
| 156 | inline const GeoStratumField::View & field(const size_t c) const { return *_data.fields[c]; }
|
---|
| 157 |
|
---|
| 158 | template< typename Fn >
|
---|
| 159 | void warp (const signed int x, const signed int y, const GeoHeightMap::Precision nAmt, const Fn & fn)
|
---|
| 160 | {
|
---|
| 161 | const signed int
|
---|
| 162 | xlo = static_cast< signed int > (x >> lod),
|
---|
| 163 | ylo = static_cast< signed int > (y >> lod);
|
---|
| 164 | GeoHeightMap::Precision zi = 0;
|
---|
| 165 |
|
---|
| 166 | (*_data.baseview)(xlo, ylo) += static_cast< GeoHeightMap::Precision > (static_cast< float > (nAmt) * fn.f(0.0f));
|
---|
| 167 |
|
---|
| 168 | for (size_t c = 0; c < _data.fields.size(); ++c)
|
---|
| 169 | {
|
---|
| 170 | GeoStratumField::View & view = *_data.fields[c];
|
---|
| 171 | const GeoHeightMap::Precision nAlt0 = view.altitude(xlo, ylo);
|
---|
| 172 |
|
---|
| 173 | zi += nAlt0;
|
---|
| 174 | view.altitude(xlo, ylo) += nAmt * fn.f(zi);
|
---|
| 175 | }
|
---|
| 176 | }
|
---|
| 177 |
|
---|
| 178 | void fetchViewElements (std::set< GeoStratumField::Element > & st) const;
|
---|
| 179 | void fetchViewIndices (std::set< unsigned short > & st) const;
|
---|
| 180 | const GeoStratumField::Element & getDominantElementVN3 (const WorldUnit x, const WorldUnit y, const WorldUnit z) const;
|
---|
| 181 | const GeoStratumField::Element & getDominantElementVN (const WorldUnit x, const WorldUnit y) const;
|
---|
| 182 |
|
---|
| 183 | inline GeoHeightMap::Precision & altitude(const WorldUnit x, const WorldUnit y)
|
---|
| 184 | { return (*_data.baseview)(x >> lod, y >> lod); }
|
---|
| 185 | inline const GeoHeightMap::Precision & altitude(const WorldUnit x, const WorldUnit y) const
|
---|
| 186 | { return (*_data.baseview)(x >> lod, y >> lod); }
|
---|
| 187 |
|
---|
| 188 | unsigned short getIndex (const WorldUnit x, const WorldUnit y, const WorldUnit z) const;
|
---|
| 189 | const GeoStratumField::Element & getElement (const WorldUnit x, const WorldUnit y, const WorldUnit z) const;
|
---|
| 190 | inline const GeoStratumField::Element & getElement (const size_t nIdx) const
|
---|
| 191 | {
|
---|
| 192 | const std::pair< size_t, size_t > & pair = _idx0map[nIdx];
|
---|
| 193 | return _data.fields[pair.first] ->getElement(nIdx - pair.second);
|
---|
| 194 | }
|
---|
| 195 | signed int findIndex (const GeoStratumField::Element & elem) const;
|
---|
| 196 |
|
---|
| 197 | // Retrieve total concatenated range of all strata and top-level DEM
|
---|
| 198 | mars::Range< WorldUnit > getRange() const;
|
---|
| 199 |
|
---|
| 200 | inline GeoHeightMap::View & getBase () { return *_data.baseview; }
|
---|
| 201 | inline const GeoHeightMap::View & getBase () const { return *_data.baseview; }
|
---|
| 202 | inline GeoStratumField::View & operator [] (const size_t c) { return *_data.fields[c]; }
|
---|
| 203 | inline const GeoStratumField::View & operator [] (const size_t c) const { return *_data.fields[c]; }
|
---|
| 204 | inline size_t size() const { return _data.fields.size(); }
|
---|
| 205 |
|
---|
| 206 | virtual void updateIndexMap ();
|
---|
| 207 |
|
---|
| 208 | const StratumView * createView( const WorldUnit nLeft, const WorldUnit nTop, const WorldUnit nShallow, const WorldUnit nRight, const WorldUnit nBottom, const WorldUnit nDeep ) const;
|
---|
| 209 | const StratumView * createView( const WorldUnit nLeft, const WorldUnit nTop, const WorldUnit nRight, const WorldUnit nBottom ) const;
|
---|
| 210 |
|
---|
| 211 | StratumView * createView( const WorldUnit nLeft, const WorldUnit nTop, const WorldUnit nShallow, const WorldUnit nRight, const WorldUnit nBottom, const WorldUnit nDeep );
|
---|
| 212 | StratumView * createView( const WorldUnit nLeft, const WorldUnit nTop, const WorldUnit nRight, const WorldUnit nBottom );
|
---|
| 213 |
|
---|
| 214 | void releaseView (const StratumView * pView) const;
|
---|
| 215 |
|
---|
| 216 | inline void operator >> (StratumView & dest) const
|
---|
| 217 | {
|
---|
| 218 | assert(width == dest.width && height == dest.height && lod == dest.lod);
|
---|
| 219 | _data >> dest._data;
|
---|
| 220 | dest.updateIndexMap();
|
---|
| 221 | }
|
---|
| 222 | inline void operator << (const StratumView & src)
|
---|
| 223 | {
|
---|
| 224 | assert(width == src.width && height == src.height && lod == src.lod);
|
---|
| 225 | _data << src._data;
|
---|
| 226 | updateIndexMap();
|
---|
| 227 | }
|
---|
| 228 | inline void operator >> (Offset dest) const
|
---|
| 229 | {
|
---|
| 230 | assert(lod == dest.view->lod);
|
---|
| 231 | _data >> StratumData::Offset(&dest.view->_data, dest.x >> lod, dest.y >> lod);
|
---|
| 232 | dest.view->updateIndexMap();
|
---|
| 233 | }
|
---|
| 234 | inline void operator << (const Offset src)
|
---|
| 235 | {
|
---|
| 236 | assert(lod == src.const_view->lod);
|
---|
| 237 | _data << StratumData::Offset(&src.const_view->_data, src.x >> lod, src.y >> lod);
|
---|
| 238 | updateIndexMap();
|
---|
| 239 | }
|
---|
| 240 |
|
---|
| 241 | void applyDEM(const GeoHeightMap::View & hmv, const unsigned short nDEMLOD);
|
---|
| 242 | };
|
---|
| 243 |
|
---|
| 244 | class Stratum : public StratumView
|
---|
| 245 | {
|
---|
| 246 | private:
|
---|
| 247 | WorldUnit _nActualDepth;
|
---|
| 248 |
|
---|
| 249 | public:
|
---|
| 250 | Stratum (const size_t nLayers, const WorldUnit nWidth, const WorldUnit nHeight, const WorldUnit nDepth, const unsigned short nLOD, const mars::GridType engt = mars::Normal);
|
---|
| 251 | // Stratum (const Stratum & copy);
|
---|
| 252 |
|
---|
| 253 | inline void operator >> (StratumView & dest) const
|
---|
| 254 | { StratumView::operator >> (dest); }
|
---|
| 255 | inline void operator << (const StratumView & other)
|
---|
| 256 | { StratumView::operator << (other); }
|
---|
| 257 | inline void operator >> (Offset dest) const
|
---|
| 258 | { StratumView::operator >> (dest); }
|
---|
| 259 | inline void operator << (const Offset src)
|
---|
| 260 | { StratumView::operator << (src); }
|
---|
| 261 |
|
---|
| 262 | std::ostream & operator >> (std::ostream & outs) const;
|
---|
| 263 | std::istream & operator << (std::istream & ins);
|
---|
| 264 | };
|
---|
| 265 | }
|
---|
| 266 |
|
---|
| 267 | #endif
|
---|