source: geovis/trunk/Renderer.h @ 4635

Last change on this file since 4635 was 4635, checked in by ldelgass, 9 years ago

Add resources directory command line option, preliminary testing of new map
coords syntax

File size: 13.3 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    void setResourcePath(std::string& path)
132    {
133        TRACE("Set resource path to %s", path.c_str());
134        _resourcePath = path;
135    }
136
137    std::string getBaseImage();
138
139    std::string getPinIcon();
140
141    // Colormaps
142
143    void addColorMap(const ColorMapId& id, osg::TransferFunction1D *xfer);
144
145    void deleteColorMap(const ColorMapId& id);
146
147    void setColorMapNumberOfTableEntries(const ColorMapId& id, int numEntries);
148
149    // Scene
150
151    void loadEarthFile(const char *path);
152
153    void resetMap(osgEarth::MapOptions::CoordinateSystemType type,
154                  const char *profile = NULL,
155                  double bounds[4] = NULL);
156
157    void clearMap();
158
159    // Map options
160
161    void setCoordinateReadout(bool state,
162                              CoordinateDisplayType type = COORDS_LATLONG_DECIMAL_DEGREES,
163                              int precision = -1);
164
165    void setReadout(int mouseX, int mouseY);
166
167    void clearReadout();
168
169    void setScaleBar(bool state);
170
171    void setScaleBarUnits(ScaleBarUnits units);
172
173    void setGraticule(bool enable, GraticuleType type = GRATICULE_GEODETIC);
174
175    void setViewerLightType(osg::View::LightingMode mode);
176
177    void setLighting(bool state);
178
179    void setTerrainLighting(bool state);
180
181    void setTerrainVerticalScale(double scale);
182
183    void setTerrainWireframe(bool state);
184
185    // Image raster layers
186
187    int getNumImageLayers() const
188    {
189        return (_map.valid() ? _map->getNumImageLayers() : 0);
190    }
191
192    void getImageLayerNames(std::vector<std::string>& names)
193    {
194        if (_map.valid()) {
195            osgEarth::ImageLayerVector layerVector;
196            _map->getImageLayers(layerVector);
197            osgEarth::ImageLayerVector::const_iterator itr;
198            for (itr = layerVector.begin(); itr != layerVector.end(); ++itr) {
199                //osgEarth::UID uid = (*itr)->getUID();
200                names.push_back((*itr)->getName());
201            }
202        }
203    }
204
205    bool addImageLayer(const char *name, osgEarth::TileSourceOptions& opts,
206                       bool makeShared = false, bool visible = true);
207
208    void removeImageLayer(const char *name);
209
210    void moveImageLayer(const char *name, unsigned int pos);
211
212    void setImageLayerOpacity(const char *name, double opacity);
213
214    void setImageLayerVisibility(const char *name, bool state);
215
216    void addColorFilter(const char *name, const char *shader);
217
218    void removeColorFilter(const char *name, int idx = -1);
219
220    // Elevation raster layers
221
222    int getNumElevationLayers() const
223    {
224        return (_map.valid() ? _map->getNumElevationLayers() : 0);
225    }
226
227    void getElevationLayerNames(std::vector<std::string>& names)
228    {
229        if (_map.valid()) {
230            osgEarth::ElevationLayerVector layerVector;
231            _map->getElevationLayers(layerVector);
232            osgEarth::ElevationLayerVector::const_iterator itr;
233            for (itr = layerVector.begin(); itr != layerVector.end(); ++itr) {
234                //osgEarth::UID uid = (*itr)->getUID();
235                names.push_back((*itr)->getName());
236            }
237        }
238    }
239
240    void addElevationLayer(const char *name, osgEarth::TileSourceOptions& opts);
241
242    void removeElevationLayer(const char *name);
243
244    void moveElevationLayer(const char *name, unsigned int pos);
245
246    void setElevationLayerVisibility(const char *name, bool state);
247
248    // Model layers
249
250    int getNumModelLayers() const
251    {
252        return (_map.valid() ? _map->getNumModelLayers() : 0);
253    }
254
255    void getModelLayerNames(std::vector<std::string>& names)
256    {
257        if (_map.valid()) {
258            osgEarth::ModelLayerVector layerVector;
259            _map->getModelLayers(layerVector);
260            osgEarth::ModelLayerVector::const_iterator itr;
261            for (itr = layerVector.begin(); itr != layerVector.end(); ++itr) {
262                //osgEarth::UID uid = (*itr)->getUID();
263                names.push_back((*itr)->getName());
264            }
265        }
266    }
267
268    void addModelLayer(const char *name, osgEarth::ModelSourceOptions& opts);
269
270    void removeModelLayer(const char *name);
271
272    void moveModelLayer(const char *name, unsigned int pos);
273
274    void setModelLayerOpacity(const char *name, double opacity);
275
276    void setModelLayerVisibility(const char *name, bool state);
277
278    // Render window
279
280    void setWindowSize(int width, int height);
281
282    int getWindowWidth() const
283    {
284        return _windowWidth;
285    }
286
287    int getWindowHeight() const
288    {
289        return _windowHeight;
290    }
291
292    // Camera
293
294    void saveNamedViewpoint(const char *name);
295
296    bool restoreNamedViewpoint(const char *name, double durationSecs);
297
298    bool removeNamedViewpoint(const char *name);
299
300    osgEarth::Viewpoint getViewpoint();
301
302    void setViewpoint(const osgEarth::Viewpoint& v, double durationSecs = 0.0);
303
304    void resetCamera(bool resetOrientation = true);
305
306    void setCameraOrientation(const double quat[4], bool absolute = true);
307
308    void panCamera(double x, double y);
309
310    void rotateCamera(double x, double y);
311
312    void zoomCamera(double z);
313
314    void setCameraDistance(double dist);
315
316    // Keyboard events
317
318    void keyPress(int key);
319
320    void keyRelease(int key);
321
322    // Mouse events
323
324    void setThrowingEnabled(bool state);
325
326    void mouseClick(int button, double x, double y);
327
328    void mouseDoubleClick(int button, double x, double y);
329
330    void mouseDrag(int button, double x, double y);
331
332    void mouseRelease(int button, double x, double y);
333
334    void mouseMotion(double x, double y);
335
336    void mouseScroll(int direction);
337
338    // Rendering an image
339
340    void setBackgroundColor(float color[3]);
341
342    void eventuallyRender();
343
344    bool render();
345
346    osg::Image *getRenderedFrame();
347
348    bool mapMouseCoords(float mouseX, float mouseY,
349                        osgEarth::GeoPoint &pt, bool invertY = true);
350
351    double computeMapScale();
352
353    const osgEarth::SpatialReference *getMapSRS()
354    {
355        if (_mapNode.valid()) {
356            return _mapNode->getMapSRS();
357        } else {
358            return NULL;
359        }
360    }
361
362    void addPlaceNode(double latitude, double longitude, char *labelText);
363
364    void hoverPlaceNode(int x, int y, bool invertY = true);
365
366    void deletePlaceNode(int x, int y, bool invertY = true);
367
368    bool getMousePoint(double *x, double *y, double *z)
369    {
370        return (_coordsCallback.valid() && _coordsCallback->report(x, y, z));
371    }
372
373    bool getWorldCoords(const osgEarth::GeoPoint& mapPt, osg::Vec3d *world);
374
375    bool worldToScreen(const osg::Vec3d& world, osg::Vec3d *screen,
376                       bool invertY = true);
377
378    void setMaximumFrameRateInHertz(double rate)
379    {
380        if (rate > 60.0)
381            rate = 60.0;
382        if (rate < 0.25)
383            rate = 0.25;
384        _minFrameTime = 1.0/rate;
385        if (_viewer.valid()) {
386            osgUtil::IncrementalCompileOperation *op =
387                _viewer->getDatabasePager()->getIncrementalCompileOperation();
388            if (op != NULL) {
389                TRACE("Setting DB Pager target frame rate to %g", rate);
390                op->setTargetFrameRate(rate);
391            }
392        }
393    }
394
395    void setMaximumBitrate(double bitsPerSecond)
396    {
397        unsigned long bitsPerFrame = (_windowWidth * _windowHeight * 3 + 16) * 8;
398        double fps = bitsPerSecond / ((double)bitsPerFrame);
399        setMaximumFrameRateInHertz(fps);
400    }
401
402    double getMaximumFrameRateInHertz()
403    {
404        return (1.0/_minFrameTime);
405    }
406
407    double getMaximumBitrate()
408    {
409        unsigned long bitsPerFrame = (_windowWidth * _windowHeight * 3 + 16) * 8;
410        return ((double)bitsPerFrame * getMaximumFrameRateInHertz());
411    }
412
413    void markFrameStart();
414
415    void markFrameEnd();
416
417    long getTimeout();
418
419    void mapNodeUpdate();
420
421    std::string getCanonicalPath(const std::string& url) const;
422
423private:
424    typedef std::tr1::unordered_map<ColorMapId, osg::ref_ptr<osg::TransferFunction1D> > ColorMapHashmap;
425    typedef std::tr1::unordered_map<ViewpointId, osgEarth::Viewpoint> ViewpointHashmap;
426
427    void setupCache();
428
429    void initViewer();
430
431    void finalizeViewer();
432   
433    void initControls();
434
435    void initEarthManipulator();
436
437    void initMouseCoordsTool(CoordinateDisplayType type = COORDS_LATLONG_DECIMAL_DEGREES,
438                             int precision = -1);
439
440    osgEarth::Util::MGRSFormatter::Precision getMGRSPrecision(int precisionInMeters);
441
442    void initColorMaps();
443
444    void initCamera();
445
446    bool isPagerIdle();
447
448    bool checkNeedToDoFrame();
449
450    osgGA::EventQueue *getEventQueue();
451
452    bool _needsRedraw;
453    int _windowWidth, _windowHeight;
454    float _bgColor[3];
455
456    double _minFrameTime;
457    double _lastFrameTime;
458    double _renderTime;
459    osg::Timer_t _startFrameTime;
460    osg::Timer_t _renderStartTime;
461    osg::Timer_t _renderStopTime;
462
463    ColorMapHashmap _colorMaps;
464
465    std::string _resourcePath;
466    std::string _baseURI;
467    std::string _cacheDir;
468
469    osg::ref_ptr<osg::Group> _sceneRoot;
470    osg::ref_ptr<osg::Group> _graticule;
471    osg::ref_ptr<osg::Group> _annotations;
472    osg::ref_ptr<osg::Group> _placeNodes;
473    std::set<osgEarth::Annotation::AnnotationNode *> _hovered;
474    osg::ref_ptr<osgEarth::MapNode> _mapNode;
475    osg::ref_ptr<osgEarth::Map> _map;
476    osg::ref_ptr<osgViewer::Viewer> _viewer;
477    osg::ref_ptr<ScreenCaptureCallback> _captureCallback;
478    osg::ref_ptr<osgEarth::Util::AutoClipPlaneCullCallback> _clipPlaneCullCallback;
479    osg::ref_ptr<MouseCoordsTool> _mouseCoordsTool;
480    osg::ref_ptr<MouseCoordsCallback> _coordsCallback;
481    osg::ref_ptr<osgEarth::Util::Controls::HBox> _hbox;
482    osg::ref_ptr<osgEarth::Util::Controls::LabelControl> _copyrightLabel;
483    osg::ref_ptr<osgEarth::Util::Controls::LabelControl> _scaleLabel;
484    osg::ref_ptr<osgEarth::Util::Controls::Frame> _scaleBar;
485    ScaleBarUnits _scaleBarUnits;
486    osg::ref_ptr<osgEarth::Util::EarthManipulator> _manipulator;
487    osg::ref_ptr<osgGA::StateSetManipulator> _stateManip;
488    osg::ref_ptr<osgEarth::Util::VerticalScale> _verticalScale;
489    ViewpointHashmap _viewpoints;
490};
491
492class MapNodeCallback : public osg::NodeCallback
493{
494public:
495    MapNodeCallback(Renderer *renderer) :
496        _renderer(renderer)
497    {}
498
499    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
500    {
501        _renderer->mapNodeUpdate();
502        traverse(node, nv);
503    }
504private:
505    Renderer *_renderer;
506};
507
508}
509
510#endif
Note: See TracBrowser for help on using the repository browser.