source: geovis/trunk/Renderer.h @ 4636

Last change on this file since 4636 was 4636, checked in by ldelgass, 7 years ago

screen coords command now takes a list of coordinates

File size: 13.4 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(const 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    bool worldToScreen(std::vector<osg::Vec3d>& coords, bool invertY = true);
379
380    void setMaximumFrameRateInHertz(double rate)
381    {
382        if (rate > 60.0)
383            rate = 60.0;
384        if (rate < 0.25)
385            rate = 0.25;
386        _minFrameTime = 1.0/rate;
387        if (_viewer.valid()) {
388            osgUtil::IncrementalCompileOperation *op =
389                _viewer->getDatabasePager()->getIncrementalCompileOperation();
390            if (op != NULL) {
391                TRACE("Setting DB Pager target frame rate to %g", rate);
392                op->setTargetFrameRate(rate);
393            }
394        }
395    }
396
397    void setMaximumBitrate(double bitsPerSecond)
398    {
399        unsigned long bitsPerFrame = (_windowWidth * _windowHeight * 3 + 16) * 8;
400        double fps = bitsPerSecond / ((double)bitsPerFrame);
401        setMaximumFrameRateInHertz(fps);
402    }
403
404    double getMaximumFrameRateInHertz()
405    {
406        return (1.0/_minFrameTime);
407    }
408
409    double getMaximumBitrate()
410    {
411        unsigned long bitsPerFrame = (_windowWidth * _windowHeight * 3 + 16) * 8;
412        return ((double)bitsPerFrame * getMaximumFrameRateInHertz());
413    }
414
415    void markFrameStart();
416
417    void markFrameEnd();
418
419    long getTimeout();
420
421    void mapNodeUpdate();
422
423    std::string getCanonicalPath(const std::string& url) const;
424
425private:
426    typedef std::tr1::unordered_map<ColorMapId, osg::ref_ptr<osg::TransferFunction1D> > ColorMapHashmap;
427    typedef std::tr1::unordered_map<ViewpointId, osgEarth::Viewpoint> ViewpointHashmap;
428
429    void setupCache();
430
431    void initViewer();
432
433    void finalizeViewer();
434   
435    void initControls();
436
437    void initEarthManipulator();
438
439    void initMouseCoordsTool(CoordinateDisplayType type = COORDS_LATLONG_DECIMAL_DEGREES,
440                             int precision = -1);
441
442    osgEarth::Util::MGRSFormatter::Precision getMGRSPrecision(int precisionInMeters);
443
444    void initColorMaps();
445
446    void initCamera();
447
448    bool isPagerIdle();
449
450    bool checkNeedToDoFrame();
451
452    osgGA::EventQueue *getEventQueue();
453
454    bool _needsRedraw;
455    int _windowWidth, _windowHeight;
456    float _bgColor[3];
457
458    double _minFrameTime;
459    double _lastFrameTime;
460    double _renderTime;
461    osg::Timer_t _startFrameTime;
462    osg::Timer_t _renderStartTime;
463    osg::Timer_t _renderStopTime;
464
465    ColorMapHashmap _colorMaps;
466
467    std::string _resourcePath;
468    std::string _baseURI;
469    std::string _cacheDir;
470
471    osg::ref_ptr<osg::Group> _sceneRoot;
472    osg::ref_ptr<osg::Group> _graticule;
473    osg::ref_ptr<osg::Group> _annotations;
474    osg::ref_ptr<osg::Group> _placeNodes;
475    std::set<osgEarth::Annotation::AnnotationNode *> _hovered;
476    osg::ref_ptr<osgEarth::MapNode> _mapNode;
477    osg::ref_ptr<osgEarth::Map> _map;
478    osg::ref_ptr<osgViewer::Viewer> _viewer;
479    osg::ref_ptr<ScreenCaptureCallback> _captureCallback;
480    osg::ref_ptr<osgEarth::Util::AutoClipPlaneCullCallback> _clipPlaneCullCallback;
481    osg::ref_ptr<MouseCoordsTool> _mouseCoordsTool;
482    osg::ref_ptr<MouseCoordsCallback> _coordsCallback;
483    osg::ref_ptr<osgEarth::Util::Controls::HBox> _hbox;
484    osg::ref_ptr<osgEarth::Util::Controls::LabelControl> _copyrightLabel;
485    osg::ref_ptr<osgEarth::Util::Controls::LabelControl> _scaleLabel;
486    osg::ref_ptr<osgEarth::Util::Controls::Frame> _scaleBar;
487    ScaleBarUnits _scaleBarUnits;
488    osg::ref_ptr<osgEarth::Util::EarthManipulator> _manipulator;
489    osg::ref_ptr<osgGA::StateSetManipulator> _stateManip;
490    osg::ref_ptr<osgEarth::Util::VerticalScale> _verticalScale;
491    ViewpointHashmap _viewpoints;
492};
493
494class MapNodeCallback : public osg::NodeCallback
495{
496public:
497    MapNodeCallback(Renderer *renderer) :
498        _renderer(renderer)
499    {}
500
501    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
502    {
503        _renderer->mapNodeUpdate();
504        traverse(node, nv);
505    }
506private:
507    Renderer *_renderer;
508};
509
510}
511
512#endif
Note: See TracBrowser for help on using the repository browser.