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