source: osgVisual/trunk/src/sky_Silverlining/visual_skySilverLining.cpp @ 182

Last change on this file since 182 was 182, checked in by Torben Dannhauer, 13 years ago

Adapted Sky_Silverlining to be aware of the XML configuration. The sky can now be disabled by XML configuration.

All calls to sky must be wrapped with if(sky.valid()) { ...} to ensure that it is only called when available.

File size: 24.0 KB
Line 
1/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
2 *
3 * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
9 * You have to aquire licenses for all used proprietary modules.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * OpenSceneGraph Public License for more details.
15*/
16
17#include <visual_skySilverLining.h>
18
19using namespace osgVisual;
20
21visual_skySilverLining::visual_skySilverLining(osgViewer::Viewer* viewer_, std::string configFileName, bool& disabled)
22{
23        OSG_NOTIFY( osg::ALWAYS ) << "Initialize visual_skySilverlining...";
24
25        atmosphereInitialized = false;
26        postInitialized = false;
27        atmosphere = NULL;
28        viewer = viewer_;
29        lat = 0;
30        lon = 0;
31
32        for( int i=0; i<MAX_CLOUDLAYER_SLOTS; i++ )
33        {
34                cloudLayerSlots.push_back( cloudLayerSlot() );
35                cloudLayerSlots.back().slot_id = i;
36        }
37
38        // Check if the module is en- or diabled by XML configuration.
39        xmlDoc* tmpDoc;
40        xmlNode* config = util::getModuleXMLConfig( configFileName, "sky_silverlining", tmpDoc, disabled );
41        if( disabled)
42                OSG_NOTIFY( osg::ALWAYS ) << "..disabled by XML configuration file." << std::endl;
43        else
44                OSG_NOTIFY( osg::ALWAYS ) << std::endl;
45        if(config)
46                xmlFreeDoc(tmpDoc); xmlCleanupParser();
47
48}
49
50visual_skySilverLining::~visual_skySilverLining(void)
51{
52        this->removeUpdateCallback( updateCallback );
53        if ( atmosphere != NULL )
54                delete atmosphere;
55}
56
57void visual_skySilverLining::skyUpdateCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
58{
59        //std::cout << "Sky silverlining update callback" << std::endl;
60        // Check if atmosphere is initialized.
61        if (!sky->isInitialized())
62                return;
63
64        // on first time: perform Post-Init.
65        sky->postInit();
66
67        // Update sky
68        double lat, lon, height;
69        util::getWGS84ofCamera( sceneCamera, csn, lat, lon, height );
70        //std::cout << "lat: " << osg::RadiansToDegrees(lat) << ", lon: " << osg::RadiansToDegrees(lon) << ", height: " << height << std::endl;
71        sky->setLocation( lat, lon, height );
72}
73
74void visual_skySilverLining::setDateTime( int year_, int month_, int day_, int hour_, int minute_, int second_, bool daylightSaving_, double timezoneOffset_ )
75{
76        // Check if atmosphere is initialized.
77        if (!isInitialized())
78                return;
79
80        SilverLining::LocalTime t = atmosphere->GetConditions()->GetTime();
81        t.SetYear( year_ );
82        t.SetMonth( month_ );
83        t.SetDay( day_ );
84        t.SetHour( hour_ );
85        t.SetMinutes( minute_ );
86        t.SetSeconds( second_ );
87        t.SetObservingDaylightSavingsTime( daylightSaving_ );
88        t.SetTimeZone( timezoneOffset_ );
89}
90
91void visual_skySilverLining::setTime( int hour_, int minute_, int second_ )
92{
93        // Check if atmosphere is initialized.
94        if (!isInitialized())
95                return;
96       
97        SilverLining::LocalTime t = atmosphere->GetConditions()->GetTime();
98        t.SetHour( hour_ );
99        t.SetMinutes( minute_ );
100        t.SetSeconds( second_ );
101        atmosphere->GetConditions()->SetTime( t );
102}
103
104void visual_skySilverLining::setDate( int year_, int month_, int day_ )
105{
106        // Check if atmosphere is initialized.
107        if (!isInitialized())
108                return;
109
110        SilverLining::LocalTime t = atmosphere->GetConditions()->GetTime();
111        t.SetYear( year_ );
112        t.SetMonth( month_ );
113        t.SetDay( day_ );
114}
115
116void visual_skySilverLining::setDateByEpoch( int secondsSince1970_ )
117{
118        // Check if atmosphere is initialized.
119        if (!isInitialized())
120                return;
121       
122        SilverLining::LocalTime t = atmosphere->GetConditions()->GetTime();
123        t.SetFromEpochSeconds( secondsSince1970_ );
124}
125
126void visual_skySilverLining::setLocation(double lat_, double lon_, double alt_)
127{
128        // Check if atmosphere is initialized.
129        if (!isInitialized())
130                return;
131
132        lat = lat_;
133        lon = lon_;
134        height = alt_;
135       
136        SilverLining::Location loc = atmosphere->GetConditions()->GetLocation();
137        loc.SetAltitude(alt_);
138        loc.SetLatitude(lat_);
139        loc.SetLongitude(lon_);         
140        atmosphere->GetConditions()->SetLocation( loc );
141
142        updateUpVector();
143}
144
145
146bool visual_skySilverLining::isInitialized()
147{
148        // Check if atmosphere is initialized. If not: make a deep lookup. If initialized, perform. Otherwise return
149        if (!atmosphereInitialized)
150        {
151                skySilverLining_atmosphereReference *ar = dynamic_cast<skySilverLining_atmosphereReference *>(viewer->getCamera()->getUserData());
152                if (ar != NULL )
153                {
154                        if (ar->atmosphereInitialized)
155                                atmosphereInitialized = true;
156                }
157        }
158        return(atmosphereInitialized);
159}
160
161void visual_skySilverLining::init(osg::Group *distortedRoot, osg::CoordinateSystemNode *sceneGraphRoot)
162{
163        sceneRoot = sceneGraphRoot;
164
165        // Use projection matrix callback oder fixed Cullsettings?
166        bool useProjMatrixCallback = true;
167
168        // add Sky to SceneGraphRoot
169        sceneGraphRoot->addChild( this );
170
171        // Deactivate culling for the sky node (required by the silverlining sky framework)
172        this->setCullingActive(false);
173
174        // Instantiate an Atmosphere and associate it with this camera. If you have multiple cameras
175        // in multiple contexts, be sure to instantiate seperate Atmosphere objects for each.
176    // ***IMPORTANT!**** Check that the path to the resources folder for SilverLining in SkyDrawable.cpp
177    // SkyDrawable::initializeSilverLining matches with where you installed SilverLining.
178        atmosphere = new SilverLining::Atmosphere(SILVERLINING_LICENSEE, SILVERLINING_LICENSE);
179
180    // Add the sky (calls Atmosphere::BeginFrame and handles initialization once you're in
181    // the rendering thread)
182        skyDrawable = new skySilverLining_skyDrawable(viewer, sceneRoot);
183
184        if(distortedRoot)       // if distortion used:
185        {
186                int rootKids = distortedRoot->getNumChildren();
187                for (int i = 0; i < rootKids; i++)
188                {
189                        osg::Node *n = distortedRoot->getChild(i);
190                        osg::Camera *cam = dynamic_cast<osg::Camera*>(n);
191                        if (cam && cam->getRenderOrder() == osg::Camera::PRE_RENDER)
192                                sceneCamera = cam;
193                }
194        }
195        else    // if no distortion used:
196                sceneCamera = viewer->getCamera();
197
198        osg::Camera *mainCamera = viewer->getCamera();
199        if (!useProjMatrixCallback)
200        {
201                mainCamera->setClearMask(0);
202                mainCamera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
203                double fovy, aspect, zNear, zFar;
204                mainCamera->getProjectionMatrixAsPerspective(fovy, aspect, zNear, zFar);
205                mainCamera->setProjectionMatrixAsPerspective(fovy, aspect, 2, 125000);
206        }
207        else
208        {
209                cb = new skySilverLining_projectionMatrixCallback( atmosphere, viewer->getCamera(), sceneRoot);
210                sceneCamera->setClampProjectionMatrixCallback(cb);
211                cb->setSkyDrawable(skyDrawable);
212        }
213
214        // append atmosphere pointer to the cameras.
215        sceneCamera->setClearMask(0);
216        osg::ref_ptr<skySilverLining_atmosphereReference> ar = new skySilverLining_atmosphereReference;
217        ar->atmosphere = atmosphere;
218        sceneCamera->setUserData(ar);
219        mainCamera->setUserData(ar);
220
221        // Create and install updateCallback (for position etc.)
222        updateCallback = new skyUpdateCallback( sceneGraphRoot, sceneCamera, this );
223        this->setUpdateCallback( updateCallback );
224
225    // Use a RenderBin to enforce that the sky gets drawn first, then the scene, then the clouds
226        skyDrawable->getOrCreateStateSet()->setRenderBinDetails(-1, "RenderBin");
227
228    // Add the models
229    sceneGraphRoot->getOrCreateStateSet()->setRenderBinDetails(1, "RenderBin");
230
231    // Add the clouds (note, you need this even if you don't want clouds - it calls
232    // Atmosphere::EndFrame() )
233        cloudsDrawable = new skySilverLining_cloudsDrawable(viewer);
234        cloudsDrawable->getOrCreateStateSet()->setRenderBinDetails(99, "RenderBin");
235
236        // Add drawable to this geode to get rendered
237        this->addDrawable(skyDrawable);
238        this->addDrawable(cloudsDrawable);
239
240        //SilverLining::Atmosphere::EnableHDR( true );
241}
242
243void visual_skySilverLining::postInit()
244{
245        // Only allow one execution
246        //if(postInitialized)
247        //      return;
248        //else postInitialized = true;
249
250        // Execute Updatecallback once before adding Clouds.
251        //updateCallback->operator ()(this, NULL);
252
253        //atmosphere->GetConditions()->SetFog( 0.8, 1, 1, 1);   // use this for simulation real fog.
254
255        //Todo: secure memory-manager of timer*. oder remove paragraph
256        //MyMillisecondTimer *timer = new MyMillisecondTimer();
257 //   atmosphere->GetConditions()->SetMillisecondTimer(timer);
258        //atmosphere->GetConditions()->EnableTimePassage(true, -1);
259}
260
261void visual_skySilverLining::updateUpVector()
262{
263        double x,y,z;
264    util::getXYZofCamera(sceneCamera, x, y, z);
265
266    osg::Vec3d up(x, y, z);
267
268    up.normalize();
269    osg::Vec3d north(0, 0, 1);  // Z is north
270    osg::Vec3d east = north ^ up;       // Cross product
271    east.normalize();
272
273    atmosphere->SetUpVector(up.x(), up.y(), up.z());
274    atmosphere->SetRightVector(east.x(), east.y(), east.z());
275
276    osg::Matrixd proj = sceneCamera->getProjectionMatrix();
277    double dProj[16];
278
279    int i = 0;
280    for (int row = 0; row < 4; row++)
281    {
282        for (int col = 0; col < 4; col++)
283        {
284            dProj[i] = proj(row, col);
285            i++;
286        }
287    }
288    //atmosphere->SetProjectionMatrix(dProj);
289}
290
291void visual_skySilverLining::shutdown()
292{
293        if (isInitialized())
294        {
295                // Remove this Node from scenegraph
296                sceneRoot->removeChild( this );
297               
298                // Remove updatecallback
299                this->removeUpdateCallback( updateCallback );
300                updateCallback = NULL;
301
302                // delete drawables
303                skyDrawable->shutdown();
304                this->removeDrawable(skyDrawable);
305                this->removeDrawable(cloudsDrawable);
306        }
307}
308
309void visual_skySilverLining::setVisibility(double visibility_)
310{
311        if (isInitialized())
312        {
313                atmosphere->GetConditions()->SetVisibility( visibility_ );
314        }
315
316}
317
318double visual_skySilverLining::getVisibility()
319{
320        if (isInitialized())
321        {
322                return atmosphere->GetConditions()->GetVisibility();
323        }
324        else
325                return -1;
326}
327
328void visual_skySilverLining::setTurbidity(double turbidity_)
329{
330        if (isInitialized())
331        {
332                atmosphere->GetConditions()->SetTurbidity( turbidity_ );
333        }
334}
335
336double visual_skySilverLining::getTurbidity()
337{
338        if (isInitialized())
339        {
340                return atmosphere->GetConditions()->GetTurbidity();
341        }
342        else
343                return -1;
344}
345
346void visual_skySilverLining::clearAllWindVolumes()
347{
348        if (isInitialized())
349        {
350                atmosphere->GetConditions()->ClearWindVolumes();
351        }
352}
353
354bool visual_skySilverLining::insideWind(double height_, double& bottom_, double& top_, double& speed_, double& direction_)
355{
356        if (isInitialized())
357        {
358                // Calculation earth radius on the wind positionl approximated through the now used position.
359                double radius;
360                if ( util::calculateEarthRadiusAtWGS84Coordinate(lat, lon, sceneRoot, radius) )
361                {
362                        // go through all wind volumes an check them for inside()
363                        //std::map<int, SilverLining::WindVolume> windvolumes = atmosphere->GetConditions()->GetWindVolumes();
364                        SL_MAP(int, SilverLining::WindVolume) windvolumes = atmosphere->GetConditions()->GetWindVolumes();
365                        for(unsigned int i=0; i<windvolumes.size(); i++)
366                        {
367                                if( windvolumes[i].Inside(radius + height_) )
368                                {
369                                        // save wind data
370                                        bottom_ = windvolumes[i].GetMinAltitude();
371                                        top_ = windvolumes[i].GetMaxAltitude() - radius;
372                                        speed_ = windvolumes[i].GetWindSpeed() - radius;
373                                        direction_ = windvolumes[i].GetDirection();
374                                        // return that wind was found
375                                        return true;
376                                }
377                        }       // For END
378                }       // If valid radius END
379        }       // If initialized() END
380        bottom_ = -1;
381        top_ = -1;
382        speed_ = -1;
383        direction_ = -1;
384        return false;
385}
386
387void visual_skySilverLining::addWindVolume(double bottom_, double top_, double speed_, int direction_)
388{
389        if (isInitialized())           
390        {
391                // Calculation earth radius on current lat lon position
392                double radius;
393                if ( util::calculateEarthRadiusAtWGS84Coordinate(lat, lon, sceneRoot, radius) )
394                {
395                        // correct wind value:
396                        if ( direction_ < 180 )
397                                direction_ += 180;
398                        else direction_ -= 180;
399
400                        // Setting up Wind
401                        SilverLining::WindVolume wv;
402                        wv.SetDirection( direction_ );
403                        wv.SetMinAltitude( radius + bottom_ );
404                        wv.SetMaxAltitude( radius + top_ );
405                        wv.SetWindSpeed( speed_ );
406                        atmosphere->GetConditions()->SetWind(wv);
407                }
408        }
409}
410
411void visual_skySilverLining::setLightPollution(double lightPollution_)
412{
413        if (isInitialized())
414        {
415                return atmosphere->GetConditions()->SetLightPollution( lightPollution_ );
416        }
417}
418
419double visual_skySilverLining::getLightPollution()
420{
421        if (isInitialized())
422        {
423                return atmosphere->GetConditions()->GetLightPollution();
424        }
425        else
426                return -1;
427
428}
429
430void visual_skySilverLining::addCloudLayer(int slot_, double baseLength_, double baseWidth_, double thickness_, double baseHeight_, double density_, CloudTypes cloudtype_ )
431{
432        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
433        {
434                // create cloudlayer order and pass to skyDrawable to instantiate.
435                cloudlayerOrder newCL;
436                newCL.slot = slot_;
437                newCL.lat = lat;
438                newCL.lon = lon;
439                newCL.baseLength = baseLength_;
440                newCL.baseWidth = baseWidth_;
441                newCL.thickness = thickness_;
442                newCL.baseHeight = baseHeight_;
443                newCL.density = density_;
444                newCL.cloudtype = cloudtype_;
445                newCL.assocCloudLayerSlot = &cloudLayerSlots[slot_];
446               
447                skyDrawable->addCloudLayerOrder( newCL );
448
449        }        // If isInitialized() END
450}
451
452void visual_skySilverLining::removeCloudLayer( int slot_ )
453{
454        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
455        {
456                atmosphere->GetConditions()->RemoveCloudLayer( cloudLayerSlots[slot_].cloudLayerHandle );
457                cloudLayerSlots[slot_].used = false;
458                cloudLayerSlots[slot_].cloudLayerHandle = -1;
459                cloudLayerSlots[slot_].cloudLayerPointer = NULL;
460                cloudLayerSlots[slot_].enabled = false;
461        }
462}
463
464void visual_skySilverLining::clearAllSlots()
465{
466        if (isInitialized())
467        {
468                atmosphere->GetConditions()->RemoveAllCloudLayers();
469                for( int i=0; i<MAX_CLOUDLAYER_SLOTS; i++ )
470                {
471                        cloudLayerSlots[i].used = false;
472                        cloudLayerSlots[i].cloudLayerHandle = -1;
473                        cloudLayerSlots[i].cloudLayerPointer = NULL;
474                        cloudLayerSlots[i].enabled = false;
475                }
476        }
477}
478
479SilverLining::CloudLayer* visual_skySilverLining::getCloudLayer( int slot_ )
480{
481        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
482        {
483                if ( cloudLayerSlots[slot_].used )
484                        return cloudLayerSlots[slot_].cloudLayerPointer; 
485        }
486
487        return NULL;
488}
489
490void visual_skySilverLining::setEnabled(int slot_, bool enabled_ )
491{
492        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
493        {
494                cloudLayerSlots[slot_].enabled = enabled_;
495        }
496}
497
498bool visual_skySilverLining::isEnabled( int slot_ )
499{
500        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
501        {
502                return cloudLayerSlots[slot_].enabled;
503        }
504        return false;
505}
506
507void visual_skySilverLining::fadeVisibility( int slot_, int fadetimeMS_ )
508{
509        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
510        {
511                if (cloudLayerSlots[slot_].enabled)
512                {
513                        cloudLayerSlots[slot_].enabled = false;
514                        cloudLayerSlots[slot_].cloudLayerPointer->SetEnabled( false, fadetimeMS_ );
515                }
516                else
517                {
518                        cloudLayerSlots[slot_].enabled = true;
519                        cloudLayerSlots[slot_].cloudLayerPointer->SetEnabled( true, fadetimeMS_ );
520                }
521        }
522}
523
524std::string visual_skySilverLining::getCloudLayerTypeName( int slot_ )
525{
526        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
527        {
528                return cloudLayerSlots[slot_].typeName;
529        }
530        return "";
531}
532
533void visual_skySilverLining::clearGlobalPrecipitation()
534{
535        if (isInitialized())
536        {
537                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::NONE, 0.0 );
538        }
539}
540
541void visual_skySilverLining::setGlobalPrecipitation( double rate_mmPerHour_rain_, double rate_mmPerHour_drySnow_, double rate_mmPerHour_wetSnow_, double rate_mmPerHour_sleet_ )
542{
543        if ( isInitialized() )
544        {
545                // Delete old Precipitation
546                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::NONE, 0.0 );
547               
548                // Set new Precipitation
549                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::RAIN, rate_mmPerHour_rain_ );
550                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::WET_SNOW, rate_mmPerHour_drySnow_ );
551                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::DRY_SNOW, rate_mmPerHour_wetSnow_ );
552                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::SLEET, rate_mmPerHour_sleet_ );
553        }
554}
555       
556bool visual_skySilverLining::getOverallPrecipitationAtLocation( double& rate_mmPerHour_rain, double& rate_mmPerHour_drySnow, double& rate_mmPerHour_wetSnow, double& rate_mmPerHour_sleet, double lat_, double lon_, double height_ )
557{
558        if (isInitialized())
559        {
560                // Init
561                bool hasPrecipitation = false;
562                double x = 0;
563                double y = 0;
564                double z = 0;
565                //// If -1 : Use sky internal values
566                if ( lat_ == -1 )
567                        lat_ = lat;
568                if ( lon_ == -1 )
569                        lon_ = lon;
570                if ( height_ == -1 )
571                        height_ = height;
572
573                // Set precipitation to zero;
574                rate_mmPerHour_rain = 0;
575                rate_mmPerHour_drySnow = 0;
576                rate_mmPerHour_wetSnow = 0;
577                rate_mmPerHour_sleet = 0;
578
579                // Get global position
580                util::calculateXYZAtWGS84Coordinate(lat_, lon_, height_, sceneRoot, x, y, z);
581
582                // Look up every cloud layer for it's precipitation.
583                for( int i=0; i<MAX_CLOUDLAYER_SLOTS; i++ )
584                {
585                        if ( cloudLayerSlots[i].used )  // IF used, Pointer should be valid
586                        {
587                                if( cloudLayerSlots[i].cloudLayerPointer->HasPrecipitationAtPosition(x, y, z) )
588                                {
589                                        hasPrecipitation = true;
590                                        SL_MAP (int, double) precipitationMap = cloudLayerSlots[i].cloudLayerPointer->GetPrecipitation();
591                                        for( SL_MAP (int, double)::iterator it = precipitationMap.begin(); it != precipitationMap.end(); it++ )
592                                        {
593                                                switch(it->first)
594                                                {
595                                                        case SilverLining::CloudLayer::RAIN : rate_mmPerHour_rain += it->second;
596                                                                break;
597                                                        case SilverLining::CloudLayer::DRY_SNOW : rate_mmPerHour_drySnow += it->second;
598                                                                break;
599                                                        case SilverLining::CloudLayer::WET_SNOW : rate_mmPerHour_wetSnow += it->second;
600                                                                break;
601                                                        case SilverLining::CloudLayer::SLEET : rate_mmPerHour_sleet += it->second;
602                                                                break;
603                                                        default: OSG_NOTIFY( osg::FATAL ) << "ERROR: visual_skySilverLining::getOverallPrecipitationAtLocation() : Wrong precipitation type in map!" << std::endl;
604                                                                break;
605                                                };
606                                        }
607                                }       // If slot has Precipitation END
608                        }       // If used END
609                }       // For all slots END
610
611                OSG_NOTIFY( osg::ALWAYS ) << "Rain: " << rate_mmPerHour_rain << ", dry snow: " << rate_mmPerHour_drySnow << ", wet snow: " << rate_mmPerHour_wetSnow << ", sleet: " << rate_mmPerHour_sleet << std::endl;
612                return hasPrecipitation;
613
614        }       // If initialized END
615        return false;
616}
617
618
619bool visual_skySilverLining::getSlotPrecipitationAtLocation( int slot_, double& rate_mmPerHour_rain, double& rate_mmPerHour_drySnow, double& rate_mmPerHour_wetSnow, double& rate_mmPerHour_sleet, double lat_, double lon_, double height_ )
620{
621        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
622        {
623                if( cloudLayerSlots[slot_].used )       // IF used, Pointer should be valid
624                {
625                        double x = 0;
626                        double y = 0;
627                        double z = 0;
628                        rate_mmPerHour_rain = 0;
629                        rate_mmPerHour_drySnow = 0;
630                        rate_mmPerHour_wetSnow = 0;
631                        rate_mmPerHour_sleet = 0;
632                        //// If -1 : Use sky internal values
633                        if ( lat_ == -1 )
634                                lat_ = lat;
635                        if ( lon_ == -1 )
636                                lon_ = lon;
637                        if ( height_ == -1 )
638                                height_ = height;
639
640                        // Get global position
641                        util::calculateXYZAtWGS84Coordinate(lat_, lon_, height_, sceneRoot, x, y, z);
642
643                        // Check for precipitation
644                        if( cloudLayerSlots[slot_].cloudLayerPointer->HasPrecipitationAtPosition(x, y, z) )
645                        {
646                                SL_MAP (int, double) precipitationMap = cloudLayerSlots[slot_].cloudLayerPointer->GetPrecipitation();
647                                for( SL_MAP (int, double)::iterator it = precipitationMap.begin(); it != precipitationMap.end(); it++ )
648                                {
649                                        switch(it->first)
650                                        {
651                                                case SilverLining::CloudLayer::RAIN : rate_mmPerHour_rain = it->second;
652                                                        break;
653                                                case SilverLining::CloudLayer::DRY_SNOW : rate_mmPerHour_drySnow = it->second;
654                                                        break;
655                                                case SilverLining::CloudLayer::WET_SNOW : rate_mmPerHour_wetSnow = it->second;
656                                                        break;
657                                                case SilverLining::CloudLayer::SLEET : rate_mmPerHour_sleet = it->second;
658                                                        break;
659                                                default: OSG_NOTIFY( osg::FATAL ) << "ERROR: visual_skySilverLining::getSlotPrecipitationAtLocation() : Wrong precipitation type in map!" << std::endl;
660                                                        break;
661                                        };
662                                }       // FOR END
663                                OSG_NOTIFY( osg::ALWAYS ) << "Rain: " << rate_mmPerHour_rain << ", dry snow: " << rate_mmPerHour_drySnow << ", wet snow: " << rate_mmPerHour_wetSnow << ", sleet: " << rate_mmPerHour_sleet << std::endl;
664                                return true;
665                        }       // If slot has Precipitation END
666                        else 
667                                return false;
668                }       // If used END
669                else
670                        return false;
671        }       // If initialized END
672        return false;
673}
674
675bool visual_skySilverLining::getSlotPrecipitation( int slot_, double& rate_mmPerHour_rain, double& rate_mmPerHour_drySnow, double& rate_mmPerHour_wetSnow, double& rate_mmPerHour_sleet )
676{
677        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
678        {
679                if( cloudLayerSlots[slot_].used )       // IF used, Pointer should be valid
680                {
681                        rate_mmPerHour_rain = 0;
682                        rate_mmPerHour_drySnow = 0;
683                        rate_mmPerHour_wetSnow = 0;
684                        rate_mmPerHour_sleet = 0;
685
686                        // Check for precipitation
687
688                                SL_MAP (int, double) precipitationMap = cloudLayerSlots[slot_].cloudLayerPointer->GetPrecipitation();
689                                for( SL_MAP (int, double)::iterator it = precipitationMap.begin(); it != precipitationMap.end(); it++ )
690                                {
691                                        switch(it->first)
692                                        {
693                                                case SilverLining::CloudLayer::RAIN : rate_mmPerHour_rain = it->second;
694                                                        break;
695                                                case SilverLining::CloudLayer::DRY_SNOW : rate_mmPerHour_drySnow = it->second;
696                                                        break;
697                                                case SilverLining::CloudLayer::WET_SNOW : rate_mmPerHour_wetSnow = it->second;
698                                                        break;
699                                                case SilverLining::CloudLayer::SLEET : rate_mmPerHour_sleet = it->second;
700                                                        break;
701                                                default: OSG_NOTIFY( osg::FATAL ) << "ERROR: visual_skySilverLining::getSlotPrecipitation() : Wrong precipitation type in map!" << std::endl;
702                                                        break;
703                                        };
704                                }       // FOR END
705                               
706                                if ( rate_mmPerHour_rain>0 || rate_mmPerHour_drySnow>0 || rate_mmPerHour_wetSnow>0 || rate_mmPerHour_sleet>0)
707                                {
708                                        OSG_NOTIFY( osg::ALWAYS ) << "Rain: " << rate_mmPerHour_rain << ", dry snow: " << rate_mmPerHour_drySnow << ", wet snow: " << rate_mmPerHour_wetSnow << ", sleet: " << rate_mmPerHour_sleet << std::endl;
709                                        return true;
710                                }
711                                else
712                                        return false;
713                }       // If used END
714                else
715                        return false;
716        }       // If initialized END
717        return false;
718}
719
720void visual_skySilverLining::clearAllPrecipitation( int slot_ )
721{
722        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
723        {
724                if( cloudLayerSlots[slot_].used )       // IF used, Pointer should be valid
725                {
726                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::NONE, 0.0 );
727                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::NONE, 0.0 ); // Second Call to clear precipitation rate.
728                }
729        }
730}
731
732void visual_skySilverLining::setSlotPrecipitation( int slot_, double rate_mmPerHour_rain_, double rate_mmPerHour_drySnow_, double rate_mmPerHour_wetSnow_, double rate_mmPerHour_sleet_ )
733{
734        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
735        {
736                if( cloudLayerSlots[slot_].used )       // IF used, Pointer should be valid
737                {
738                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::RAIN, rate_mmPerHour_rain_ );
739                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::DRY_SNOW, rate_mmPerHour_drySnow_ );
740                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::WET_SNOW, rate_mmPerHour_wetSnow_ );
741                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::SLEET, rate_mmPerHour_sleet_ );
742                }
743        }
744}
Note: See TracBrowser for help on using the repository browser.