root/OpenSceneGraph/trunk/include/osgTerrain/Layer @ 11287

Revision 11287, 20.8 kB (checked in by robert, 5 years ago)

Introduced the use of linear interpolation of evelvations when sampling

Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under 
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#ifndef OSGTERRAIN_LAYER
15#define OSGTERRAIN_LAYER 1
16
17#include <osg/Image>
18#include <osg/Shape>
19#include <osg/Array>
20#include <osg/TransferFunction>
21
22#include <osgTerrain/Locator>
23#include <osgTerrain/ValidDataOperator>
24
25namespace osgTerrain {
26
27#define MAXIMUM_NUMBER_OF_LEVELS 30
28
29/** Extact the setname and filename from a compound string in the from set:setname:filename".
30  * Returns a setname of "" when non set:setname: entry is present.*/
31extern OSGTERRAIN_EXPORT void extractSetNameAndFileName(const std::string& compoundstring, std::string& setname, std::string& filename);
32
33/** Create a compound string in the form set:setname:filename, or just filename if setname is "".*/
34extern OSGTERRAIN_EXPORT std::string createCompondSetNameAndFileName(const std::string& setname, const std::string& filename);
35
36class OSGTERRAIN_EXPORT Layer : public osg::Object
37{
38    public:
39
40        Layer();
41
42        /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
43        Layer(const Layer&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
44       
45        META_Object(osgTerrain, Layer);
46       
47        void setSetName(const std::string& setname) { setName(setname); }
48        const std::string& getSetName() const { return getName(); }
49
50        /** Set the file name of the data associated with this layer. */
51        virtual void setFileName(const std::string& filename) { _filename = filename; }
52
53        /** Get the file name of the layer. */
54        virtual const std::string& getFileName() const { return _filename; }
55
56        /** Return the compound name of the layer in the form set::name::filename string.*/
57        std::string getCompoundName() const { return createCompondSetNameAndFileName(getName(), getFileName()); }
58
59        void setLocator(Locator* locator) { _locator = locator; }
60        Locator* getLocator() { return _locator.get(); }
61        const Locator* getLocator() const { return _locator.get(); }
62       
63        void setMinLevel(unsigned int minLevel) { _minLevel = minLevel; }
64        unsigned int getMinLevel() const { return _minLevel; }
65
66        void setMaxLevel(unsigned int maxLevel) { _maxLevel = maxLevel; }
67        unsigned int getMaxLevel() const { return _maxLevel; }
68
69        void setValidDataOperator(ValidDataOperator* validDataOp) { _validDataOperator = validDataOp; }
70        ValidDataOperator* getValidDataOperator() { return _validDataOperator.get(); }
71        const ValidDataOperator* getValidDataOperator() const { return _validDataOperator.get(); }
72
73
74        virtual unsigned int getNumColumns() const { return 0; }
75        virtual unsigned int getNumRows() const { return 0; }
76
77        void setDefaultValue(const osg::Vec4& value) { _defaultValue = value; }
78        const osg::Vec4& getDefaultValue() const { return _defaultValue; }
79       
80
81        /** Set the minification texture filter to use when do texture associated with this layer.*/
82        void setMinFilter(osg::Texture::FilterMode filter) { _minFilter = filter; }
83
84        /** Get the minification texture filter to use when do texture associated with this layer.*/
85        osg::Texture::FilterMode getMinFilter() const { return _minFilter; }
86
87
88        /** Set the magniification texture filter to use when do texture associated with this layer.*/
89        void setMagFilter(osg::Texture::FilterMode filter) { _magFilter = filter; }
90
91        /** Get the magnification texture filter to use when do texture associated with this layer.*/
92        osg::Texture::FilterMode getMagFilter() const { return _magFilter; }
93
94
95
96        /** Return image associated with layer if supported. */       
97        virtual osg::Image* getImage() { return 0; }
98
99        /** Return const image associated with layer if supported. */       
100        virtual const osg::Image* getImage() const { return 0; }
101
102
103        virtual bool transform(float /*offset*/, float /*scale*/) { return false; }
104
105
106        virtual bool getValue(unsigned int /*i*/, unsigned int /*j*/, float& /*value*/) const { return false; }
107        virtual bool getValue(unsigned int /*i*/, unsigned int /*j*/, osg::Vec2& /*value*/) const { return false; }
108        virtual bool getValue(unsigned int /*i*/, unsigned int /*j*/, osg::Vec3& /*value*/) const { return false; }
109        virtual bool getValue(unsigned int /*i*/, unsigned int /*j*/, osg::Vec4& /*value*/) const { return false; }
110
111        inline bool getValidValue(unsigned int i, unsigned int j, float& value) const
112        {
113            if (getValue(i,j,value)) return _validDataOperator.valid() ? (*_validDataOperator)(value) : true;
114            return false;
115        }
116
117        inline bool getValidValue(unsigned int i, unsigned int j, osg::Vec2& value) const
118        {
119            if (getValue(i,j,value)) return _validDataOperator.valid() ? (*_validDataOperator)(value) : true;
120            return false;
121        }
122
123        inline bool getValidValue(unsigned int i, unsigned int j, osg::Vec3& value) const
124        {
125            if (getValue(i,j,value)) return _validDataOperator.valid() ? (*_validDataOperator)(value) : true;
126            return false;
127        }
128
129        inline bool getValidValue(unsigned int i, unsigned int j, osg::Vec4& value) const
130        {
131            if (getValue(i,j,value)) return _validDataOperator.valid() ? (*_validDataOperator)(value) : true;
132            return false;
133        }
134
135
136        inline void computeIndices(double ndc_x, double ndc_y, unsigned int& i, unsigned int& j, double& ir, double& jr)
137        {
138            ndc_x *= double(getNumColumns()-1);
139            ndc_y *= double(getNumRows()-1);
140            i = (unsigned int)(ndc_x);
141            j = (unsigned int)(ndc_y);
142            ir = ndc_x - double(i);
143            jr = ndc_y - double(j);
144        }
145
146
147        inline bool getInterpolatedValue(double ndc_x, double ndc_y, float& value)
148        {
149            unsigned int i,j;
150            double ir, jr;
151            computeIndices(ndc_x, ndc_y, i, j, ir, jr);
152            value = 0.0f;
153            double div = 0.0f;
154            float v,r;
155           
156            r = (1.0f-ir)*(1.0f-jr);
157            if (r>0.0 && getValue(i,j,v))
158            {
159                value += v*r;
160                div += r;
161            }
162           
163            r = (ir)*(1.0f-jr);
164            if (r>0.0 && getValue(i+1,j,v))
165            {
166                value += v*r;
167                div += r;
168            }
169           
170            r = (ir)*(jr);
171            if (r>0.0 && getValue(i+1,j+1,v))
172            {
173                value += v*r;
174                div += r;
175            }
176           
177            r = (1.0f-ir)*(jr);
178            if (r>0.0 && getValue(i,j+1,v))
179            {
180                value += v*r;
181                div += r;
182            }
183           
184            if (div != 0.0)
185            {
186                value /= div;
187                return true;
188            }
189           
190            value = 0.0;
191            return false;
192        }
193
194        inline bool getInterpolatedValidValue(double ndc_x, double ndc_y, float& value)
195        {
196            unsigned int i,j;
197            double ir, jr;
198            computeIndices(ndc_x, ndc_y, i, j, ir, jr);
199            value = 0.0f;
200            double div = 0.0f;
201            float v,r;
202
203            r = (1.0f-ir)*(1.0f-jr);
204            if (r>0.0 && getValidValue(i,j,v))
205            {
206                value += v*r;
207                div += r;
208            }
209
210            r = (ir)*(1.0f-jr);
211            if (r>0.0 && getValidValue(i+1,j,v))
212            {
213                value += v*r;
214                div += r;
215            }
216
217            r = (ir)*(jr);
218            if (r>0.0 && getValidValue(i+1,j+1,v))
219            {
220                value += v*r;
221                div += r;
222            }
223
224            r = (1.0f-ir)*(jr);
225            if (r>0.0 && getValidValue(i,j+1,v))
226            {
227                value += v*r;
228                div += r;
229            }
230
231            if (div != 0.0)
232            {
233                value /= div;
234                return true;
235            }
236
237            value = 0.0;
238            return false;
239        }
240
241        /** increment the modified count."*/
242        virtual void dirty() {};
243
244        /** Set the modified count value.  */
245        virtual void setModifiedCount(unsigned int /*value*/) {};
246
247        /** Get modified count value. */
248        virtual unsigned int getModifiedCount() const { return 0; }
249
250        virtual osg::BoundingSphere computeBound(bool treatAsElevationLayer) const;
251
252    protected:
253
254        virtual ~Layer();
255
256        std::string                     _filename;
257        osg::ref_ptr<Locator>           _locator;
258        unsigned int                    _minLevel;
259        unsigned int                    _maxLevel;
260        osg::ref_ptr<ValidDataOperator> _validDataOperator;
261        osg::Vec4                       _defaultValue;
262        osg::Texture::FilterMode        _minFilter;
263        osg::Texture::FilterMode        _magFilter;
264
265};
266
267class OSGTERRAIN_EXPORT ImageLayer : public Layer
268{
269    public:
270
271        ImageLayer(osg::Image* image=0);
272
273        /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
274        ImageLayer(const ImageLayer& imageLayer,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
275       
276        META_Object(osgTerrain, ImageLayer);
277
278        void setFileName(const std::string& filename) { _filename = filename; if (_image.valid()) _image->setFileName(filename); }
279        virtual const std::string& getFileName() const { return _image.get() ? _image->getFileName() : _filename; }
280
281        virtual bool transform(float offset, float scale);
282
283        void setImage(osg::Image* image);
284
285        /** Return image associated with layer. */ 
286        virtual osg::Image* getImage() { return _image.get(); }
287
288        /** Return const image associated with layer. */
289        virtual const osg::Image* getImage() const { return _image.get(); }
290
291        virtual unsigned int getNumColumns() const { return _image.valid() ? _image->s() : 0; }
292        virtual unsigned int getNumRows() const { return _image.valid() ? _image->t() : 0;  }
293
294        virtual bool getValue(unsigned int i, unsigned int j, float& value) const;
295        virtual bool getValue(unsigned int i, unsigned int j, osg::Vec2& value) const;
296        virtual bool getValue(unsigned int i, unsigned int j, osg::Vec3& value) const;
297        virtual bool getValue(unsigned int i, unsigned int j, osg::Vec4& value) const;
298
299        virtual void dirty();
300        virtual void setModifiedCount(unsigned int value);
301        virtual unsigned int getModifiedCount() const;
302
303    protected:
304
305        virtual ~ImageLayer() {}
306
307        osg::ref_ptr<osg::Image>    _image;
308
309};
310
311class OSGTERRAIN_EXPORT ContourLayer : public Layer
312{
313    public:
314
315        ContourLayer(osg::TransferFunction1D* tf=0);
316
317        /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
318        ContourLayer(const ContourLayer& tfLayer,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
319       
320        META_Object(osgTerrain, ContourLayer);
321
322        virtual bool transform(float offset, float scale);
323
324        void setTransferFunction(osg::TransferFunction1D* tf);
325        osg::TransferFunction1D* getTransferFunction() { return _tf.get(); }
326        const osg::TransferFunction1D* getTransferFunction() const { return _tf.get(); }
327
328        /** Return image associated with layer. */ 
329        virtual osg::Image* getImage() { return _tf.valid() ? _tf->getImage() : 0; }
330
331        /** Return const image associated with layer. */
332        virtual const osg::Image* getImage() const { return _tf.valid() ? _tf->getImage() : 0; }
333
334
335        virtual unsigned int getNumColumns() const { return _tf.valid() ? _tf->getNumberImageCells() : 0; }
336        virtual unsigned int getNumRows() const { return _tf.valid() ? 1 : 0;  }
337
338        virtual bool getValue(unsigned int i, unsigned int j, float& value) const;
339        virtual bool getValue(unsigned int i, unsigned int j, osg::Vec2& value) const;
340        virtual bool getValue(unsigned int i, unsigned int j, osg::Vec3& value) const;
341        virtual bool getValue(unsigned int i, unsigned int j, osg::Vec4& value) const;
342
343        virtual void dirty();
344        virtual void setModifiedCount(unsigned int value);
345        virtual unsigned int getModifiedCount() const;
346
347    protected:
348
349        virtual ~ContourLayer() {}
350
351        osg::ref_ptr<osg::TransferFunction1D>    _tf;
352
353};
354
355class OSGTERRAIN_EXPORT HeightFieldLayer : public Layer
356{
357    public:
358
359        HeightFieldLayer(osg::HeightField* hf=0);
360
361        /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
362        HeightFieldLayer(const HeightFieldLayer& hfLayer,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
363       
364        META_Object(osgTerrain, HeightFieldLayer);
365
366        void setFileName(const std::string& filename) { _filename = filename; }
367        virtual const std::string& getFileName() const { return _filename; }
368
369        virtual bool transform(float offset, float scale);
370
371        void setHeightField(osg::HeightField* hf);
372        osg::HeightField* getHeightField() { return _heightField.get(); }
373        const osg::HeightField* getHeightField() const { return _heightField.get(); }
374
375        virtual unsigned int getNumColumns() const { return _heightField.valid() ? _heightField->getNumColumns() : 0; }
376        virtual unsigned int getNumRows() const { return _heightField.valid() ? _heightField->getNumRows() : 0;  }
377
378        virtual bool getValue(unsigned int i, unsigned int j, float& value) const;
379        virtual bool getValue(unsigned int i, unsigned int j, osg::Vec2& value) const;
380        virtual bool getValue(unsigned int i, unsigned int j, osg::Vec3& value) const;
381        virtual bool getValue(unsigned int i, unsigned int j, osg::Vec4& value) const;
382
383        virtual void dirty();
384        virtual void setModifiedCount(unsigned int value);
385        virtual unsigned int getModifiedCount() const;
386
387    protected:
388
389        virtual ~HeightFieldLayer() {}
390
391        unsigned int                    _modifiedCount;
392        osg::ref_ptr<osg::HeightField>  _heightField;
393
394};
395
396
397class OSGTERRAIN_EXPORT ProxyLayer : public Layer
398{
399    public:
400
401        ProxyLayer();
402
403        /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
404        ProxyLayer(const ProxyLayer& proxyLayer,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
405       
406        META_Object(osgTerrain, ProxyLayer);
407       
408        /** Return image associated with layer if supported. */       
409        virtual osg::Image* getImage()
410        {
411            return _implementation.valid() ? _implementation->getImage() : 0;
412        }
413
414        /** Return const image associated with layer if supported. */
415        virtual const osg::Image* getImage() const
416        {
417            return _implementation.valid() ? _implementation->getImage() : 0;
418        }
419
420        /** Set the implementation layer that does the actual work.*/
421        void setImplementation(Layer* layer) { _implementation = layer; }
422       
423        /** Get the implementation layer that does the actual work.*/
424        Layer* getImplementation() { return _implementation.get(); }
425
426        /** Get the const implementation layer that does the actual work.*/
427        const Layer* getImplementation() const { return _implementation.get(); }
428
429        virtual void setFileName(const std::string& filename);
430        virtual const std::string& getFileName() const { return _filename; }
431
432        virtual unsigned int getNumColumns() const;
433        virtual unsigned int getNumRows() const;
434       
435        virtual bool transform(float offset, float scale);
436
437        virtual bool getValue(unsigned int i, unsigned int j, float& value) const;
438        virtual bool getValue(unsigned int i, unsigned int j, osg::Vec2& value) const;
439        virtual bool getValue(unsigned int i, unsigned int j, osg::Vec3& value) const;
440        virtual bool getValue(unsigned int i, unsigned int j, osg::Vec4& value) const;
441
442        virtual void dirty();
443        virtual void setModifiedCount(unsigned int value);
444        virtual unsigned int getModifiedCount() const;
445
446        virtual osg::BoundingSphere computeBound(bool treatAsElevationLayer) const;
447
448    protected:
449
450        virtual ~ProxyLayer();
451       
452        osg::ref_ptr<Layer> _implementation;
453
454
455};
456
457class OSGTERRAIN_EXPORT CompositeLayer : public Layer
458{
459    public:
460
461        CompositeLayer();
462
463        /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
464        CompositeLayer(const CompositeLayer& compositeLayer,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
465       
466        META_Object(osgTerrain, CompositeLayer);
467
468        void clear();
469
470        void setSetName(const std::string& setname) { setName(setname); }
471        const std::string& getSetName() const { return getName(); }
472
473        void setSetName(unsigned int i, const std::string& setname) { _layers[i].setname = setname; if (_layers[i].layer.valid()) _layers[i].layer->setName(setname); }
474        const std::string& getSetName(unsigned int i) const { return _layers[i].layer.valid() ? _layers[i].layer->getName() : _layers[i].setname; }
475
476        void setFileName(unsigned int i, const std::string& filename) { _layers[i].filename = filename; if (_layers[i].layer.valid()) _layers[i].layer->setFileName(filename); }
477        const std::string& getFileName(unsigned int i) const { return _layers[i].layer.valid() ? _layers[i].layer->getFileName() : _layers[i].filename; }
478
479        void setCompoundName(unsigned int i, const std::string& compoundname);
480        std::string getCompoundName(unsigned int i) const;
481
482
483        void setLayer(unsigned int i, Layer* layer) { if (i>=_layers.size()) _layers.resize(i+1); _layers[i].layer = layer; }
484        Layer* getLayer(unsigned int i) { return i<_layers.size() ? _layers[i].layer.get() : 0; }
485        const Layer* getLayer(unsigned int i) const { return i<_layers.size() ? _layers[i].layer.get() : 0; }
486
487        void addLayer(const std::string& compoundname);
488        void addLayer(const std::string& setname, const std::string& filename);
489       
490        void addLayer(Layer* layer) { _layers.push_back(CompoundNameLayer(layer->getName(),layer->getFileName(),layer)); }
491
492        void removeLayer(unsigned int i) { _layers.erase(_layers.begin()+i); }
493       
494        unsigned int getNumLayers() const { return _layers.size(); }
495
496    protected:
497
498        virtual ~CompositeLayer() {}
499
500        struct CompoundNameLayer
501        {
502            CompoundNameLayer() {}
503       
504            CompoundNameLayer(const CompoundNameLayer& cnl):
505                setname(cnl.setname),
506                filename(cnl.filename),
507                layer(cnl.layer) {}
508
509            CompoundNameLayer(const std::string& sn, const std::string& fn, Layer* l):
510                setname(sn),
511                filename(fn),
512                layer(l) {}
513
514            CompoundNameLayer& operator = (const CompoundNameLayer& cnl)
515            {
516                if (&cnl==this) return *this;
517               
518                setname = cnl.setname;
519                filename = cnl.filename;
520                layer = cnl.layer;
521                return *this;
522            }
523
524            std::string         setname;
525            std::string         filename;
526            osg::ref_ptr<Layer> layer;
527        };
528       
529        typedef std::vector< CompoundNameLayer > Layers;
530       
531        Layers _layers;
532};
533
534
535class OSGTERRAIN_EXPORT SwitchLayer : public CompositeLayer
536{
537    public:
538
539        SwitchLayer();
540
541        /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
542        SwitchLayer(const SwitchLayer& switchLayer,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
543       
544        META_Object(osgTerrain, SwitchLayer);
545       
546        void setActiveLayer(int i) { _activeLayer = i; }
547        int getActiveLayer() const { return _activeLayer; }
548
549        /** Return image associated with layer if supported. */       
550        virtual osg::Image* getImage()
551        {
552            if (_activeLayer < 0) return 0;           
553            if (_activeLayer >= static_cast<int>(getNumLayers())) return 0;
554            return _layers[_activeLayer].layer->getImage();           
555        }
556
557        /** Return const image associated with layer if supported. */
558        virtual const osg::Image* getImage() const
559        {
560            if (_activeLayer < 0) return 0;           
561            if (_activeLayer >= static_cast<int>(getNumLayers())) return 0;
562            return _layers[_activeLayer].layer->getImage();           
563        }
564
565    protected:
566
567        virtual ~SwitchLayer() {}
568       
569        int _activeLayer;
570};
571
572
573
574}
575
576#endif
Note: See TracBrowser for help on using the browser.