source: trunk/packages/vizservers/geovis/Renderer.h @ 4575

Last change on this file since 4575 was 4575, checked in by ldelgass, 10 years ago

Add optional coordinate conversion for 'map coords' command, add 'screen coords'
command to project map coords to screen coords.

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