source: geovis/trunk/Renderer.h @ 4632

Last change on this file since 4632 was 4632, checked in by ldelgass, 6 years ago

Add pin annotations for testing

File size: 13.0 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * Copyright (C) 2004-2013  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 <string>
12#include <vector>
13#include <tr1/unordered_map>
14#include <typeinfo>
15
16#include <osg/ref_ptr>
17#include <osg/Node>
18#include <osg/Image>
19#include <osg/TransferFunction>
20#include <osgViewer/Viewer>
21#include <osgGA/StateSetManipulator>
22#include <osgUtil/IncrementalCompileOperation>
23
24#include <osgEarth/StringUtils>
25#include <osgEarth/Map>
26#include <osgEarth/Viewpoint>
27#include <osgEarth/ImageLayer>
28#include <osgEarth/ElevationLayer>
29#include <osgEarth/ModelLayer>
30#include <osgEarth/TileSource>
31#include <osgEarth/ModelSource>
32#include <osgEarth/GeoData>
33#include <osgEarthAnnotation/AnnotationNode>
34#include <osgEarthUtil/EarthManipulator>
35#include <osgEarthUtil/MouseCoordsTool>
36#include <osgEarthUtil/Controls>
37#include <osgEarthUtil/Formatter>
38#include <osgEarthUtil/MGRSFormatter>
39#include <osgEarthUtil/AutoClipPlaneHandler>
40#include <osgEarthUtil/VerticalScale>
41
42#include "Types.h"
43#include "Trace.h"
44#include "MouseCoordsTool.h"
45#include "ScaleBar.h"
46
47// Controls if TGA format is sent to client
48//#define RENDER_TARGA
49#define TARGA_BYTES_PER_PIXEL 3
50
51namespace GeoVis {
52
53class ScreenCaptureCallback : public osg::Camera::DrawCallback
54{
55public:
56    ScreenCaptureCallback(osg::Texture2D *texture = NULL) :
57        osg::Camera::DrawCallback(),
58        _texture(texture)
59    {
60        _image = new osg::Image;
61    }
62
63    virtual void operator()(osg::RenderInfo &renderInfo) const
64    {
65        TRACE("Enter ScreenCaptureCallback");
66        int width, height;
67        if (renderInfo.getCurrentCamera() == NULL) {
68            ERROR("No camera");
69            return;
70        }
71        if (renderInfo.getCurrentCamera()->getViewport() == NULL) {
72            ERROR("No viewport");
73            return;
74        }
75        width = (int)renderInfo.getCurrentCamera()->getViewport()->width();
76        height = (int)renderInfo.getCurrentCamera()->getViewport()->height();
77        TRACE("readPixels: %d x %d", width, height);
78#if 0 //USE_OFFSCREEN_FRAMEBUFFER
79        _image = _texture->getImage();
80#else
81#ifdef RENDER_TARGA
82        _image->readPixels(0, 0, width, height,
83                           GL_BGR, GL_UNSIGNED_BYTE);
84#else
85        _image->readPixels(0, 0, width, height,
86                           GL_RGB, GL_UNSIGNED_BYTE);
87#endif
88#endif
89    }
90
91    osg::Image *getImage()
92    {
93        return _image.get();
94    }
95
96    osg::Texture2D *getTexture()
97    {
98        return _texture.get();
99    }
100
101private:
102    osg::ref_ptr<osg::Texture2D> _texture;
103    osg::ref_ptr<osg::Image> _image;
104};
105
106/**
107 * \brief GIS Renderer
108 */
109class Renderer
110{
111public:
112    typedef std::string ColorMapId;
113    typedef std::string ViewpointId;
114
115    enum GraticuleType {
116        GRATICULE_UTM,
117        GRATICULE_MGRS,
118        GRATICULE_GEODETIC
119    };
120
121    enum CoordinateDisplayType {
122        COORDS_LATLONG_DECIMAL_DEGREES,
123        COORDS_LATLONG_DEGREES_DECIMAL_MINUTES,
124        COORDS_LATLONG_DEGREES_MINUTES_SECONDS,
125        COORDS_MGRS
126    };
127
128    Renderer();
129    virtual ~Renderer();
130
131    // Colormaps
132
133    void addColorMap(const ColorMapId& id, osg::TransferFunction1D *xfer);
134
135    void deleteColorMap(const ColorMapId& id);
136
137    void setColorMapNumberOfTableEntries(const ColorMapId& id, int numEntries);
138
139    // Scene
140
141    void loadEarthFile(const char *path);
142
143    void resetMap(osgEarth::MapOptions::CoordinateSystemType type,
144                  const char *profile = NULL,
145                  double bounds[4] = NULL);
146
147    void clearMap();
148
149    // Map options
150
151    void setCoordinateReadout(bool state,
152                              CoordinateDisplayType type = COORDS_LATLONG_DECIMAL_DEGREES,
153                              int precision = -1);
154
155    void setReadout(int mouseX, int mouseY);
156
157    void clearReadout();
158
159    void setScaleBar(bool state);
160
161    void setScaleBarUnits(ScaleBarUnits units);
162
163    void setGraticule(bool enable, GraticuleType type = GRATICULE_GEODETIC);
164
165    void setViewerLightType(osg::View::LightingMode mode);
166
167    void setLighting(bool state);
168
169    void setTerrainLighting(bool state);
170
171    void setTerrainVerticalScale(double scale);
172
173    void setTerrainWireframe(bool state);
174
175    // Image raster layers
176
177    int getNumImageLayers() const
178    {
179        return (_map.valid() ? _map->getNumImageLayers() : 0);
180    }
181
182    void getImageLayerNames(std::vector<std::string>& names)
183    {
184        if (_map.valid()) {
185            osgEarth::ImageLayerVector layerVector;
186            _map->getImageLayers(layerVector);
187            osgEarth::ImageLayerVector::const_iterator itr;
188            for (itr = layerVector.begin(); itr != layerVector.end(); ++itr) {
189                //osgEarth::UID uid = (*itr)->getUID();
190                names.push_back((*itr)->getName());
191            }
192        }
193    }
194
195    bool addImageLayer(const char *name, osgEarth::TileSourceOptions& opts,
196                       bool makeShared = false, bool visible = true);
197
198    void removeImageLayer(const char *name);
199
200    void moveImageLayer(const char *name, unsigned int pos);
201
202    void setImageLayerOpacity(const char *name, double opacity);
203
204    void setImageLayerVisibility(const char *name, bool state);
205
206    void addColorFilter(const char *name, const char *shader);
207
208    void removeColorFilter(const char *name, int idx = -1);
209
210    // Elevation raster layers
211
212    int getNumElevationLayers() const
213    {
214        return (_map.valid() ? _map->getNumElevationLayers() : 0);
215    }
216
217    void getElevationLayerNames(std::vector<std::string>& names)
218    {
219        if (_map.valid()) {
220            osgEarth::ElevationLayerVector layerVector;
221            _map->getElevationLayers(layerVector);
222            osgEarth::ElevationLayerVector::const_iterator itr;
223            for (itr = layerVector.begin(); itr != layerVector.end(); ++itr) {
224                //osgEarth::UID uid = (*itr)->getUID();
225                names.push_back((*itr)->getName());
226            }
227        }
228    }
229
230    void addElevationLayer(const char *name, osgEarth::TileSourceOptions& opts);
231
232    void removeElevationLayer(const char *name);
233
234    void moveElevationLayer(const char *name, unsigned int pos);
235
236    void setElevationLayerVisibility(const char *name, bool state);
237
238    // Model layers
239
240    int getNumModelLayers() const
241    {
242        return (_map.valid() ? _map->getNumModelLayers() : 0);
243    }
244
245    void getModelLayerNames(std::vector<std::string>& names)
246    {
247        if (_map.valid()) {
248            osgEarth::ModelLayerVector layerVector;
249            _map->getModelLayers(layerVector);
250            osgEarth::ModelLayerVector::const_iterator itr;
251            for (itr = layerVector.begin(); itr != layerVector.end(); ++itr) {
252                //osgEarth::UID uid = (*itr)->getUID();
253                names.push_back((*itr)->getName());
254            }
255        }
256    }
257
258    void addModelLayer(const char *name, osgEarth::ModelSourceOptions& opts);
259
260    void removeModelLayer(const char *name);
261
262    void moveModelLayer(const char *name, unsigned int pos);
263
264    void setModelLayerOpacity(const char *name, double opacity);
265
266    void setModelLayerVisibility(const char *name, bool state);
267
268    // Render window
269
270    void setWindowSize(int width, int height);
271
272    int getWindowWidth() const
273    {
274        return _windowWidth;
275    }
276
277    int getWindowHeight() const
278    {
279        return _windowHeight;
280    }
281
282    // Camera
283
284    void saveNamedViewpoint(const char *name);
285
286    bool restoreNamedViewpoint(const char *name, double durationSecs);
287
288    bool removeNamedViewpoint(const char *name);
289
290    osgEarth::Viewpoint getViewpoint();
291
292    void setViewpoint(const osgEarth::Viewpoint& v, double durationSecs = 0.0);
293
294    void resetCamera(bool resetOrientation = true);
295
296    void setCameraOrientation(const double quat[4], bool absolute = true);
297
298    void panCamera(double x, double y);
299
300    void rotateCamera(double x, double y);
301
302    void zoomCamera(double z);
303
304    void setCameraDistance(double dist);
305
306    // Keyboard events
307
308    void keyPress(int key);
309
310    void keyRelease(int key);
311
312    // Mouse events
313
314    void setThrowingEnabled(bool state);
315
316    void mouseClick(int button, double x, double y);
317
318    void mouseDoubleClick(int button, double x, double y);
319
320    void mouseDrag(int button, double x, double y);
321
322    void mouseRelease(int button, double x, double y);
323
324    void mouseMotion(double x, double y);
325
326    void mouseScroll(int direction);
327
328    // Rendering an image
329
330    void setBackgroundColor(float color[3]);
331
332    void eventuallyRender();
333
334    bool render();
335
336    osg::Image *getRenderedFrame();
337
338    bool mapMouseCoords(float mouseX, float mouseY,
339                        osgEarth::GeoPoint &pt, bool invertY = true);
340
341    double computeMapScale();
342
343    const osgEarth::SpatialReference *getMapSRS()
344    {
345        if (_mapNode.valid()) {
346            return _mapNode->getMapSRS();
347        } else {
348            return NULL;
349        }
350    }
351
352    void addPlaceNode(double latitude, double longitude, char *labelText);
353
354    void hoverPlaceNode(int x, int y, bool invertY = true);
355
356    void deletePlaceNode(int x, int y, bool invertY = true);
357
358    bool getMousePoint(double *x, double *y, double *z)
359    {
360        return (_coordsCallback.valid() && _coordsCallback->report(x, y, z));
361    }
362
363    bool getWorldCoords(const osgEarth::GeoPoint& mapPt, osg::Vec3d *world);
364
365    bool worldToScreen(const osg::Vec3d& world, osg::Vec3d *screen,
366                       bool invertY = true);
367
368    void setMaximumFrameRateInHertz(double rate)
369    {
370        if (rate > 60.0)
371            rate = 60.0;
372        if (rate < 0.25)
373            rate = 0.25;
374        _minFrameTime = 1.0/rate;
375        if (_viewer.valid()) {
376            osgUtil::IncrementalCompileOperation *op =
377                _viewer->getDatabasePager()->getIncrementalCompileOperation();
378            if (op != NULL) {
379                TRACE("Setting DB Pager target frame rate to %g", rate);
380                op->setTargetFrameRate(rate);
381            }
382        }
383    }
384
385    void setMaximumBitrate(double bitsPerSecond)
386    {
387        unsigned long bitsPerFrame = (_windowWidth * _windowHeight * 3 + 16) * 8;
388        double fps = bitsPerSecond / ((double)bitsPerFrame);
389        setMaximumFrameRateInHertz(fps);
390    }
391
392    double getMaximumFrameRateInHertz()
393    {
394        return (1.0/_minFrameTime);
395    }
396
397    double getMaximumBitrate()
398    {
399        unsigned long bitsPerFrame = (_windowWidth * _windowHeight * 3 + 16) * 8;
400        return ((double)bitsPerFrame * getMaximumFrameRateInHertz());
401    }
402
403    void markFrameStart();
404
405    void markFrameEnd();
406
407    long getTimeout();
408
409    void mapNodeUpdate();
410
411    std::string getCanonicalPath(const std::string& url) const;
412
413private:
414    typedef std::tr1::unordered_map<ColorMapId, osg::ref_ptr<osg::TransferFunction1D> > ColorMapHashmap;
415    typedef std::tr1::unordered_map<ViewpointId, osgEarth::Viewpoint> ViewpointHashmap;
416
417    void setupCache();
418
419    void initViewer();
420
421    void finalizeViewer();
422   
423    void initControls();
424
425    void initEarthManipulator();
426
427    void initMouseCoordsTool(CoordinateDisplayType type = COORDS_LATLONG_DECIMAL_DEGREES,
428                             int precision = -1);
429
430    osgEarth::Util::MGRSFormatter::Precision getMGRSPrecision(int precisionInMeters);
431
432    void initColorMaps();
433
434    void initCamera();
435
436    bool isPagerIdle();
437
438    bool checkNeedToDoFrame();
439
440    osgGA::EventQueue *getEventQueue();
441
442    bool _needsRedraw;
443    int _windowWidth, _windowHeight;
444    float _bgColor[3];
445
446    double _minFrameTime;
447    double _lastFrameTime;
448    double _renderTime;
449    osg::Timer_t _startFrameTime;
450    osg::Timer_t _renderStartTime;
451    osg::Timer_t _renderStopTime;
452
453    ColorMapHashmap _colorMaps;
454
455    std::string _baseURI;
456    std::string _cacheDir;
457
458    osg::ref_ptr<osg::Group> _sceneRoot;
459    osg::ref_ptr<osg::Group> _graticule;
460    osg::ref_ptr<osg::Group> _annotations;
461    osg::ref_ptr<osg::Group> _placeNodes;
462    std::set<osgEarth::Annotation::AnnotationNode *> _hovered;
463    osg::ref_ptr<osgEarth::MapNode> _mapNode;
464    osg::ref_ptr<osgEarth::Map> _map;
465    osg::ref_ptr<osgViewer::Viewer> _viewer;
466    osg::ref_ptr<ScreenCaptureCallback> _captureCallback;
467    osg::ref_ptr<osgEarth::Util::AutoClipPlaneCullCallback> _clipPlaneCullCallback;
468    osg::ref_ptr<MouseCoordsTool> _mouseCoordsTool;
469    osg::ref_ptr<MouseCoordsCallback> _coordsCallback;
470    osg::ref_ptr<osgEarth::Util::Controls::HBox> _hbox;
471    osg::ref_ptr<osgEarth::Util::Controls::LabelControl> _copyrightLabel;
472    osg::ref_ptr<osgEarth::Util::Controls::LabelControl> _scaleLabel;
473    osg::ref_ptr<osgEarth::Util::Controls::Frame> _scaleBar;
474    ScaleBarUnits _scaleBarUnits;
475    osg::ref_ptr<osgEarth::Util::EarthManipulator> _manipulator;
476    osg::ref_ptr<osgGA::StateSetManipulator> _stateManip;
477    osg::ref_ptr<osgEarth::Util::VerticalScale> _verticalScale;
478    ViewpointHashmap _viewpoints;
479};
480
481class MapNodeCallback : public osg::NodeCallback
482{
483public:
484    MapNodeCallback(Renderer *renderer) :
485        _renderer(renderer)
486    {}
487
488    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
489    {
490        _renderer->mapNodeUpdate();
491        traverse(node, nv);
492    }
493private:
494    Renderer *_renderer;
495};
496
497}
498
499#endif
Note: See TracBrowser for help on using the repository browser.