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

Last change on this file since 87 was 87, checked in by Torben Dannhauer, 14 years ago

Introductes VS 2008 Memory Leak Debugging.
Todo: Compile on Linux and compare with Valgrind, VS 2008 seems to be awkward in leak debugging

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