source: geovis/trunk/Renderer.h @ 6518

Last change on this file since 6518 was 6518, checked in by ldelgass, 8 years ago

Protocol additions: add terrainPatch flag, add wkt/wkt_file driver for mask
layers to allow using WKT string literal or file. Add Euler angle rotations
for model layer.

File size: 22.9 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * Copyright (C) 2004-2015  HUBzero Foundation, LLC
4 *
5 * Author: Leif Delgass <ldelgass@purdue.edu>
6 */
7
8#ifndef GEOVIS_RENDERER_H
9#define GEOVIS_RENDERER_H
10
11#include <sys/time.h> // For struct timeval
12#include <ctime> // For time_t
13#include <string>
14#include <vector>
15#include <tr1/unordered_map>
16#include <typeinfo>
17
18#include <osg/ref_ptr>
19#include <osg/Node>
20#include <osg/Image>
21#include <osg/TransferFunction>
22#include <osgText/String>
23#include <osgViewer/Viewer>
24#include <osgGA/StateSetManipulator>
25#include <osgUtil/IncrementalCompileOperation>
26
27#include <osgEarth/Version>
28#include <osgEarth/StringUtils>
29#include <osgEarth/Map>
30#include <osgEarth/Viewpoint>
31#include <osgEarth/ImageLayer>
32#include <osgEarth/ElevationLayer>
33#include <osgEarth/ModelLayer>
34#include <osgEarth/MaskLayer>
35#include <osgEarth/TileSource>
36#include <osgEarth/ModelSource>
37#include <osgEarth/GeoData>
38#include <osgEarthAnnotation/AnnotationNode>
39#include <osgEarthAnnotation/FeatureNode>
40#include <osgEarthUtil/Sky>
41#include <osgEarthUtil/RTTPicker>
42#include <osgEarthUtil/EarthManipulator>
43#include <osgEarthUtil/MouseCoordsTool>
44#include <osgEarthUtil/Controls>
45#include <osgEarthUtil/Formatter>
46#include <osgEarthUtil/MGRSFormatter>
47#include <osgEarthUtil/AutoClipPlaneHandler>
48#include <osgEarthUtil/VerticalScale>
49
50#define USE_RTT_PICKER
51
52#include "Types.h"
53#include "Trace.h"
54#include "MouseCoordsTool.h"
55#include "ScaleBar.h"
56#include "Placard.h"
57
58// Controls if TGA format is sent to client
59//#define RENDER_TARGA
60#define TARGA_BYTES_PER_PIXEL 3
61
62namespace GeoVis {
63
64class ScreenCaptureCallback : public osg::Camera::DrawCallback
65{
66public:
67    ScreenCaptureCallback(osg::Texture2D *texture = NULL) :
68        osg::Camera::DrawCallback(),
69        _texture(texture)
70    {
71        _image = new osg::Image;
72    }
73
74    virtual void operator()(osg::RenderInfo &renderInfo) const
75    {
76        FRAME("Enter ScreenCaptureCallback");
77        int width, height;
78        if (renderInfo.getCurrentCamera() == NULL) {
79            ERROR("No camera");
80            return;
81        }
82        if (renderInfo.getCurrentCamera()->getViewport() == NULL) {
83            ERROR("No viewport");
84            return;
85        }
86        width = (int)renderInfo.getCurrentCamera()->getViewport()->width();
87        height = (int)renderInfo.getCurrentCamera()->getViewport()->height();
88        FRAME("readPixels: %d x %d", width, height);
89#if 0 //USE_OFFSCREEN_FRAMEBUFFER
90        _image = _texture->getImage();
91#else
92#ifdef RENDER_TARGA
93        _image->readPixels(0, 0, width, height,
94                           GL_BGR, GL_UNSIGNED_BYTE);
95#else
96        _image->readPixels(0, 0, width, height,
97                           GL_RGB, GL_UNSIGNED_BYTE);
98#endif
99#endif
100    }
101
102    osg::Image *getImage()
103    {
104        return _image.get();
105    }
106
107    osg::Texture2D *getTexture()
108    {
109        return _texture.get();
110    }
111
112private:
113    osg::ref_ptr<osg::Texture2D> _texture;
114    osg::ref_ptr<osg::Image> _image;
115};
116
117/**
118 * \brief GIS Renderer
119 */
120class Renderer
121{
122public:
123    typedef std::string ColorMapId;
124    typedef std::string ViewpointId;
125
126    enum GraticuleType {
127        GRATICULE_UTM,
128        GRATICULE_MGRS,
129        GRATICULE_GEODETIC,
130        GRATICULE_SHADER
131    };
132
133    enum CoordinateDisplayType {
134        COORDS_LATLONG_DECIMAL_DEGREES,
135        COORDS_LATLONG_DEGREES_DECIMAL_MINUTES,
136        COORDS_LATLONG_DEGREES_MINUTES_SECONDS,
137        COORDS_MGRS
138    };
139
140    enum SelectMode {
141        SELECT_OFF,
142        SELECT_ON
143    };
144
145    Renderer();
146    virtual ~Renderer();
147
148    void setResourcePath(const std::string& path)
149    {
150        TRACE("Set resource path to %s", path.c_str());
151        _resourcePath = path;
152    }
153
154    void setCacheBaseDirectory(const std::string& path)
155    {
156        TRACE("Set cache base dir to %s", path.c_str());
157        _cacheBaseDir = path;
158    }
159
160    std::string getCacheDirectory() const
161    {
162        return _cacheDir;
163    }
164
165    void setupCache();
166
167    std::string getIconFile(const char *name) const;
168
169    std::string getBaseImage() const;
170
171    std::string getPinIcon() const;
172
173    void setAttribution(const std::string& attrib);
174
175    // Colormaps
176
177    void addColorMap(const ColorMapId& id, osg::TransferFunction1D *xfer);
178
179    void deleteColorMap(const ColorMapId& id);
180
181    void setColorMapNumberOfTableEntries(const ColorMapId& id, int numEntries);
182
183    bool renderColorMap(const ColorMapId& id, int width, int height,
184                        osg::Image *imgData,
185                        bool opaque, float bgColor[3],
186                        bool bgr = false,
187                        int bytesPerPixel = 3) const;
188
189    void getColorMapRange(const ColorMapId& id, float *min, float *max) const;
190
191    std::string getColorMapFilePath(const ColorMapId& id) const;
192
193    void saveCLRFile(const std::string& path, osg::TransferFunction1D *xfer);
194
195    // Scene
196
197    void loadEarthFile(const char *path);
198
199    void resetMap(osgEarth::MapOptions::CoordinateSystemType type,
200                  const osg::Vec4f& bgColor = osg::Vec4f(1,1,1,1),
201                  const char *profile = NULL,
202                  double bounds[4] = NULL);
203
204    void clearMap();
205
206    // Map options
207
208    void setCoordinateReadout(bool state,
209                              CoordinateDisplayType type = COORDS_LATLONG_DECIMAL_DEGREES,
210                              int precision = -1);
211
212    void setReadout(int mouseX, int mouseY);
213
214    void clearReadout();
215
216    void setScaleBar(bool state);
217
218    void setScaleBarUnits(ScaleBarUnits units);
219
220    void setGraticule(bool enable, GraticuleType type = GRATICULE_SHADER);
221
222    void setViewerLightType(osg::View::LightingMode mode);
223
224    void setLighting(bool state);
225
226    void setTerrainColor(const osg::Vec4f& color);
227
228    void setTerrainEdges(bool state) {}
229
230    void setTerrainLineColor(const osg::Vec4f& color) {}
231
232    void setTerrainLineWidth(float width) {}
233
234    void setTerrainLighting(bool state);
235
236    void setTerrainVerticalScale(double scale);
237
238    void setTerrainWireframe(bool state);
239
240    void setEphemerisTime(time_t utcTime);
241
242    void setEphemerisTime(int year, int month, int day, double hours);
243
244    void setSkyAmbient(float ambientLevel);
245
246    // Image raster layers
247
248    int getNumImageLayers() const
249    {
250        return (_map.valid() ? _map->getNumImageLayers() : 0);
251    }
252
253    void getImageLayerNames(std::vector<std::string>& names) const
254    {
255        if (_map.valid()) {
256            osgEarth::ImageLayerVector layerVector;
257            _map->getImageLayers(layerVector);
258            osgEarth::ImageLayerVector::const_iterator itr;
259            for (itr = layerVector.begin(); itr != layerVector.end(); ++itr) {
260                //osgEarth::UID uid = (*itr)->getUID();
261                names.push_back((*itr)->getName());
262            }
263        }
264    }
265
266    bool addImageLayer(const char *name,
267                       osgEarth::TileSourceOptions& opts,
268                       unsigned int pos = UINT_MAX,
269                       bool enableCache = true,
270                       bool coverage = false,
271                       bool makeShared = false,
272                       bool visible = true,
273                       unsigned int minLOD = 0,
274                       unsigned int maxLOD = 23);
275
276    void removeImageLayer(const char *name);
277
278    void moveImageLayer(const char *name, unsigned int pos);
279
280    bool getImageLayerExtent(const char *name, osgEarth::GeoExtent &ext);
281
282    void setImageLayerVisibleRange(const char *name, float min, float max);
283
284    void setImageLayerLODRange(const char *name, int min, int max);
285
286    void setImageLayerOpacity(const char *name, double opacity);
287
288    void setImageLayerVisibility(const char *name, bool state);
289
290    void addColorFilter(const char *name, const char *shader);
291
292    void removeColorFilter(const char *name, int idx = -1);
293
294    // Elevation raster layers
295
296    int getNumElevationLayers() const
297    {
298        return (_map.valid() ? _map->getNumElevationLayers() : 0);
299    }
300
301    void getElevationLayerNames(std::vector<std::string>& names) const
302    {
303        if (_map.valid()) {
304            osgEarth::ElevationLayerVector layerVector;
305            _map->getElevationLayers(layerVector);
306            osgEarth::ElevationLayerVector::const_iterator itr;
307            for (itr = layerVector.begin(); itr != layerVector.end(); ++itr) {
308                //osgEarth::UID uid = (*itr)->getUID();
309                names.push_back((*itr)->getName());
310            }
311        }
312    }
313
314    void addElevationLayer(const char *name,
315                           osgEarth::TileSourceOptions& opts,
316                           unsigned int pos = UINT_MAX,
317                           bool enableCache = true,
318                           bool visible = true,
319                           const char *verticalDatum = NULL,
320                           unsigned int minLOD = 0,
321                           unsigned int maxLOD = 23);
322
323    void removeElevationLayer(const char *name);
324
325    void moveElevationLayer(const char *name, unsigned int pos);
326
327    bool getElevationLayerExtent(const char *name, osgEarth::GeoExtent &ext);
328
329    void setElevationLayerVisibleRange(const char *name, float min, float max);
330
331    void setElevationLayerVisibility(const char *name, bool state);
332
333    // Terrain mask layers
334
335    int getNumTerrainMaskLayers() const
336    {
337        if (!_map.valid()) return 0;
338
339        osgEarth::MaskLayerVector layers;
340        _map->getTerrainMaskLayers(layers);
341        return (int)layers.size();
342    }
343
344    void getTerrainMaskLayerNames(std::vector<std::string>& names) const
345    {
346        if (_map.valid()) {
347            osgEarth::MaskLayerVector layerVector;
348            _map->getTerrainMaskLayers(layerVector);
349            osgEarth::MaskLayerVector::const_iterator itr;
350            for (itr = layerVector.begin(); itr != layerVector.end(); ++itr) {
351                //osgEarth::UID uid = (*itr)->getUID();
352                names.push_back((*itr)->getName());
353            }
354        }
355    }
356
357    osgEarth::MaskLayer *getTerrainMaskLayerByName(const std::string& name)
358    {
359        if (!_map.valid())
360            return NULL;
361
362        osgEarth::MaskLayerVector layerVector;
363        _map->getTerrainMaskLayers(layerVector);
364        osgEarth::MaskLayerVector::iterator itr;
365        for (itr = layerVector.begin(); itr != layerVector.end(); ++itr) {
366            if ((*itr)->getName() == name) {
367                return (*itr).get();
368            }
369        }
370        return NULL;
371    }
372
373    void addTerrainMaskLayer(const char *name,
374                             osgEarth::MaskSourceOptions& opts,
375                             unsigned int minLOD = 0);
376
377    void removeTerrainMaskLayer(const char *name);
378
379    bool getTerrainMaskLayerExtent(const char *name, osgEarth::GeoExtent &ext);
380
381    // Model layers
382
383    int getNumModelLayers() const
384    {
385        return (_map.valid() ? _map->getNumModelLayers() : 0);
386    }
387
388    void getModelLayerNames(std::vector<std::string>& names) const
389    {
390        if (_map.valid()) {
391            osgEarth::ModelLayerVector layerVector;
392            _map->getModelLayers(layerVector);
393            osgEarth::ModelLayerVector::const_iterator itr;
394            for (itr = layerVector.begin(); itr != layerVector.end(); ++itr) {
395                //osgEarth::UID uid = (*itr)->getUID();
396                names.push_back((*itr)->getName());
397            }
398        }
399    }
400
401    void addModelLayer(const char *name,
402                       osgEarth::ModelSourceOptions& opts,
403                       unsigned int pos = UINT_MAX,
404                       bool enableCache = true,
405                       bool lighting = true,
406                       bool visible = true,
407                       bool terrainPatch = false);
408
409    void removeModelLayer(const char *name);
410
411    void moveModelLayer(const char *name, unsigned int pos);
412
413    bool getModelLayerExtent(const char *name, osgEarth::GeoExtent &ext);
414
415    //void setModelLayerVisibleRange(const char *name, float min, float max);
416
417    void setModelLayerOpacity(const char *name, double opacity);
418
419    void setModelLayerVisibility(const char *name, bool state);
420
421    // Render window
422
423    void setWindowSize(int width, int height);
424
425    int getWindowWidth() const
426    {
427        return _windowWidth;
428    }
429
430    int getWindowHeight() const
431    {
432        return _windowHeight;
433    }
434
435    // Camera
436
437    void saveNamedViewpoint(const char *name);
438
439    bool restoreNamedViewpoint(const char *name, double durationSecs);
440
441    bool removeNamedViewpoint(const char *name);
442
443    osgEarth::Viewpoint getViewpoint();
444
445    void setViewpoint(const osgEarth::Viewpoint& v, double durationSecs = 0.0);
446
447    double getMaxDistanceFromExtent(const osgEarth::GeoExtent& extent);
448
449    void setViewpointFromExtent(const osgEarth::GeoExtent& ext,
450                                double durationSecs = 0.0);
451
452    void setViewpointFromRect(double xmin, double ymin,
453                              double xmax, double ymax,
454                              const osgEarth::SpatialReference *srs = NULL,
455                              double durationSecs = 0.0);
456
457    void resetCamera(bool resetOrientation = true);
458
459    void setCameraOrientation(const double quat[4], bool absolute = true);
460
461    void panCamera(double x, double y);
462
463    void rotateCamera(double x, double y);
464
465    void zoomCamera(double z);
466
467    void setCameraDistance(double dist);
468
469    // Keyboard events
470
471    void keyPress(int key);
472
473    void keyRelease(int key);
474
475    // Mouse events
476
477    void setThrowingEnabled(bool state);
478
479    void mouseClick(int button, double x, double y);
480
481    void mouseDoubleClick(int button, double x, double y);
482
483    void mouseDrag(int button, double x, double y);
484
485    void mouseRelease(int button, double x, double y);
486
487    void mouseMotion(double x, double y);
488
489    void mouseScroll(int direction);
490
491    void pickPending(bool value)
492    { _pickPending = value; }
493
494    // Rendering an image
495
496    void setBackgroundColor(float color[3]);
497
498    void eventuallyRender();
499
500    bool render();
501
502    osg::Image *getRenderedFrame();
503
504    bool mapMouseCoords(float mouseX, float mouseY,
505                        osgEarth::GeoPoint &pt, bool invertY = true);
506
507    double computeMapScale();
508
509    const osgEarth::SpatialReference *getMapSRS()
510    {
511        if (_mapNode.valid()) {
512            return _mapNode->getMapSRS();
513        } else {
514            return NULL;
515        }
516    }
517
518    void addPlaceNode(double latitude, double longitude, char *labelText);
519
520    void hoverPlaceNode(int x, int y, bool invertY = true);
521
522    void deletePlaceNode(int x, int y, bool invertY = true);
523
524    bool getMousePoint(double *x, double *y, double *z)
525    {
526        return (_coordsCallback.valid() && _coordsCallback->report(x, y, z));
527    }
528
529    bool mouseToLatLong(int mouseX, int mouseY,
530                        double *latitude, double *longitude);
531
532    bool getWorldCoords(const osgEarth::GeoPoint& mapPt, osg::Vec3d *world);
533
534    bool worldToScreen(const osg::Vec3d& world, osg::Vec3d *screen,
535                       bool invertY = true);
536
537    bool worldToScreen(std::vector<osg::Vec3d>& coords, bool invertY = true);
538
539    void setMaximumFrameRateInHertz(double rate)
540    {
541        if (rate > 60.0)
542            rate = 60.0;
543        if (rate < 0.25)
544            rate = 0.25;
545        _minFrameTime = 1.0/rate;
546        if (_viewer.valid()) {
547            osgUtil::IncrementalCompileOperation *op =
548                _viewer->getDatabasePager()->getIncrementalCompileOperation();
549            if (op != NULL) {
550                TRACE("Setting DB Pager target frame rate to %g", rate);
551                op->setTargetFrameRate(rate);
552            }
553        }
554        TRACE("Frame rate target: %.2f Hz", (float)getMaximumFrameRateInHertz());
555        TRACE("Frame time target: %.2f msec", _minFrameTime * 1000.0f);
556    }
557
558    void setMaximumBitrate(double bitsPerSecond)
559    {
560        TRACE("Setting max bitrate to %g", bitsPerSecond);
561        unsigned long bitsPerFrame = (_windowWidth * _windowHeight * 3 + 16) * 8;
562        double fps = bitsPerSecond / ((double)bitsPerFrame);
563        setMaximumFrameRateInHertz(fps);
564        TRACE("Bandwidth target: %.2f Mbps", (float)(getMaximumBitrate()/1.0e6));
565    }
566
567    double getMaximumFrameRateInHertz()
568    {
569        return (1.0/_minFrameTime);
570    }
571
572    double getMaximumBitrate()
573    {
574        unsigned long bitsPerFrame = (_windowWidth * _windowHeight * 3 + 16) * 8;
575        return ((double)bitsPerFrame * getMaximumFrameRateInHertz());
576    }
577
578    void markFrameStart();
579
580    void markFrameEnd();
581
582    void setIdleTimeout(long timeout)
583    {
584        if (timeout != -1L &&
585            (double)timeout < _minFrameTime) {
586            ERROR("Timeout must be more than %g sec", _minFrameTime);
587            return;
588        }
589        TRACE("Setting idle timeout to %ld sec", timeout);
590        _idleTimeout = timeout;
591    }
592
593    long getIdleTimeout()
594    {
595        return _idleTimeout;
596    }
597
598    void getTimeout(struct timeval *tv);
599
600    void mapNodeUpdate();
601
602    std::string getCanonicalPath(const std::string& url) const;
603
604    void writeScene(const std::string& file);
605
606    // Placard info window
607
608    void enablePlacard(const char *layerName, bool state);
609
610    void setPlacardConfig(const Placard& placardConf, const char *layerName);
611
612    Placard getPlacardConfig(const char *layerName)
613    {
614        Placard ret;
615        PlacardHashmap::iterator itr = _placardConfigs.find(layerName);
616        if (itr != _placardConfigs.end()) {
617            ret = itr->second;
618        }
619        return ret;
620    }
621
622    // Selection
623
624    void setSelectMode(SelectMode mode);
625
626    void selectFeatures(std::vector<unsigned long>& featureIDs,
627                        const char *layerName, bool clear = true);
628
629    void deselectFeatures(std::vector<unsigned long>& featureIDs,
630                          const char *layerName);
631
632    void addPlacard(const osgEarth::GeoPoint& location,
633                    osgEarth::Features::Feature *feature,
634                    const char *layerName);
635
636    void clearSelection();
637
638    void addRhumbBox(double latMin, double latMax,
639                     double longMin, double longMax);
640
641    void initBoxSelection(int x, int y);
642    void updateBoxSelection(int x, int y);
643    void getBoxSelection(double *latMin, double *latMax,
644                         double *longMin, double *longMax,
645                         const osgEarth::SpatialReference *outSRS = NULL);
646    void clearBoxSelection();
647
648    // These methods are based on the deprecated annotation API
649    bool select(osgEarth::Annotation::AnnotationNode *node)
650    {
651        if (_selected.find(node) == _selected.end()) {
652            _selected.insert(node);
653            return true;
654        } else {
655            return false;
656        }
657    }
658    std::set<osgEarth::Annotation::AnnotationNode*>& getHovered()
659    { return _hovered; }
660    std::set<osgEarth::Annotation::AnnotationNode*>& getSelected()
661    { return _selected; }
662
663    // Scene Graph
664
665    osg::Group *getSceneRoot()
666    { return _sceneRoot.get(); }
667    osgEarth::MapNode *getMapNode()
668    { return _mapNode.get(); }
669    osg::Group *getAnnotations()
670    {
671        initAnnotations();
672        return _annotations.get();
673    }
674    osg::Group *getPlaceNodes()
675    {
676        initAnnotations();
677        return _placeNodes.get();
678    }
679
680private:
681    typedef std::tr1::unordered_map<ColorMapId, osg::ref_ptr<osg::TransferFunction1D> > ColorMapHashmap;
682    typedef std::tr1::unordered_map<ViewpointId, osgEarth::Viewpoint> ViewpointHashmap;
683    typedef std::tr1::unordered_map<std::string, Placard> PlacardHashmap;
684    typedef std::tr1::unordered_map<std::string, std::set<unsigned long> > FeatureSelectionHashmap;
685
686    void initAnnotations();
687
688    void clearSelectionAnnotationNodes();
689
690    void initViewer();
691
692    void finalizeViewer();
693   
694    void initControls();
695
696    void updateDebugLabel();
697
698    void initEarthManipulator();
699
700    void initMouseCoordsTool(CoordinateDisplayType type = COORDS_LATLONG_DECIMAL_DEGREES,
701                             int precision = -1);
702
703    osgEarth::Util::MGRSFormatter::Precision getMGRSPrecision(int precisionInMeters);
704
705    void initColorMaps();
706
707    void initCamera();
708
709    bool isPagerIdle();
710
711    bool checkNeedToDoFrame();
712
713    osgGA::EventQueue *getEventQueue();
714
715    bool _needsRedraw;
716    int _windowWidth, _windowHeight;
717    double _mapScale;
718    float _bgColor[3];
719
720    long _idleTimeout;
721    double _minFrameTime;
722    double _lastFrameTime;
723    double _renderTime;
724    osg::Timer_t _startFrameTime;
725    osg::Timer_t _renderStartTime;
726    osg::Timer_t _renderStopTime;
727
728    ColorMapHashmap _colorMaps;
729
730    std::string _resourcePath;
731    std::string _cacheBaseDir;
732    std::string _cacheDir;
733    std::string _baseURI;
734    std::string _attribution;
735
736    osg::ref_ptr<osg::Group> _sceneRoot;
737    osg::ref_ptr<osg::Group> _graticule;
738    osg::ref_ptr<osg::Group> _annotations;
739    PlacardHashmap _placardConfigs;
740    double _anchorLat, _anchorLong;
741    SelectMode _selectMode;
742    osg::ref_ptr<osgEarth::Annotation::FeatureNode> _selectionBox;
743#ifdef USE_RTT_PICKER
744    osg::ref_ptr<osgEarth::Util::RTTPicker> _picker;
745#endif
746    bool _pickPending;
747    osg::ref_ptr<osg::Group> _placeNodes;
748    FeatureSelectionHashmap _selectedFeatures;
749    std::set<osgEarth::Annotation::AnnotationNode *> _hovered;
750    std::set<osgEarth::Annotation::AnnotationNode *> _selected;
751    osg::ref_ptr<osgEarth::MapNode> _mapNode;
752    osg::ref_ptr<osgEarth::Map> _map;
753    osg::ref_ptr<osgEarth::Util::SkyNode> _skyNode;
754    osg::ref_ptr<osgViewer::Viewer> _viewer;
755    osg::ref_ptr<ScreenCaptureCallback> _captureCallback;
756    osg::ref_ptr<osgEarth::Util::AutoClipPlaneCullCallback> _clipPlaneCullCallback;
757    osg::ref_ptr<osgEarth::Util::Controls::HBox> _coordsBox;
758    osg::ref_ptr<MouseCoordsTool> _mouseCoordsTool;
759    osg::ref_ptr<MouseCoordsCallback> _coordsCallback;
760    osg::ref_ptr<osgEarth::Util::Controls::HBox> _debugBox;
761    osg::ref_ptr<osgEarth::Util::Controls::LabelControl> _debugLabel;
762    osg::ref_ptr<osgEarth::Util::Controls::HBox> _copyrightScaleBox;
763    osg::ref_ptr<osgEarth::Util::Controls::LabelControl> _copyrightLabel;
764    osg::ref_ptr<osgEarth::Util::Controls::LabelControl> _scaleLabel;
765    osg::ref_ptr<osgEarth::Util::Controls::Frame> _scaleBar;
766    ScaleBarUnits _scaleBarUnits;
767    osg::ref_ptr<osgEarth::Util::EarthManipulator> _manipulator;
768    osg::ref_ptr<osgGA::StateSetManipulator> _stateManip;
769    osg::ref_ptr<osgEarth::Util::VerticalScale> _verticalScale;
770    ViewpointHashmap _viewpoints;
771};
772
773class MapNodeCallback : public osg::NodeCallback
774{
775public:
776    MapNodeCallback(Renderer *renderer) :
777        _renderer(renderer)
778    {}
779
780    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
781    {
782        _renderer->mapNodeUpdate();
783        traverse(node, nv);
784    }
785private:
786    Renderer *_renderer;
787};
788
789class SelectPlaceNodesVisitor : public osg::NodeVisitor
790{
791public:
792    SelectPlaceNodesVisitor(Renderer *renderer,
793                            double latMin, double latMax,
794                            double longMin, double longMax) :
795        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
796        _renderer(renderer),
797        _latMin(latMin), _latMax(latMax),
798        _longMin(longMin), _longMax(longMax)
799    {}
800
801    virtual void apply(osg::Node& node);
802
803private:
804    Renderer *_renderer;
805    double _latMin, _latMax, _longMin, _longMax;
806};
807
808}
809
810#endif
Note: See TracBrowser for help on using the repository browser.