source: osgVisual/src/sky_Silverlining/visual_skySilverLining.cpp @ 137

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