source: geovis/trunk/Renderer.h @ 4629

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

add token to map/screen coord commands

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