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

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

Debug: if clause based on uninitialized value removed.

File size: 26.6 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
231void visual_skySilverLining::postInit()
232{
233        // Only allow one execution
234        if(postInitialized)
235                return;
236        else postInitialized = true;
237
238        // Execute Updatecallback once before adding Clouds.
239        updateCallback->operator ()(this, NULL);
240
241        setTime(12,00,23);
242        setVisibility(50000);
243        //atmosphere->GetConditions()->SetFog( 0.8, 1, 1, 1);   // use this for simulation real fog.
244
245
246
247        //Todo: secure memory-manager of timer*. oder remove paragraph
248        //MyMillisecondTimer *timer = new MyMillisecondTimer();
249 //   atmosphere->GetConditions()->SetMillisecondTimer(timer);
250        //atmosphere->GetConditions()->EnableTimePassage(true, -1);
251
252        //addWindVolume( 0.0, 15000.0, 300.0, 90.0 );
253       
254        //addCloudLayer( 0, 300000, 300000, 600.0, 2351.0, 0.5, STRATUS );
255        //addCloudLayer( 0, 5000000, 5000000, 600.0, 7351.0, 0.2, CIRRUS_FIBRATUS );
256        //addCloudLayer( 0, 50000, 50000, 600.0, 7351.0, 0.2, CIRROCUMULUS );
257        ///addCloudLayer( 1, 200000, 200000, 3000, 2000.0, 0.05, CUMULUS_CONGESTUS );
258        //cloudLayerSlots[1].cloudLayerPointer->SetPrecipitation(SilverLining::CloudLayer::SLEET, 25.0 );
259
260}
261
262void visual_skySilverLining::updateUpVector()
263{
264        // Allowed deltaLat and deltaLon between Updating the upvector
265        double deltaLatToUpdate = osg::DegreesToRadians( 0.1 ); // 0.5 deg
266        double deltaLonToUpdate = osg::DegreesToRadians( 0.1 ); // 0.5 deg
267
268        if ( fabs(lat-upVectorLat) > deltaLatToUpdate || fabs(lon-upVectorLon) > deltaLonToUpdate )
269        {
270                // Get ellipsoid model
271                osg::EllipsoidModel* ellipsoid = sceneRoot->getEllipsoidModel();
272                if ( !ellipsoid )
273                        return;
274
275                //OSG_NOTIFY( osg::ALWAYS ) << "update Upvector.." << std::endl;
276
277                // Calculate up vector
278                double x,y,z;
279                util::getXYZofCamera(sceneCamera, x, y, z);
280                osg::Vec3d upVector = ellipsoid->computeLocalUpVector( x, y, z );
281                upVector.normalize();
282               
283                // Calculate side vector
284                osg::Matrixd localToWorld;
285                ellipsoid->computeLocalToWorldTransformFromLatLongHeight(lat, lon, height, localToWorld);
286
287                osg::Vec3d sideVector(localToWorld(0, 0), localToWorld(0, 1), localToWorld(0, 2));
288                sideVector.normalize();
289
290                // Update silverlining vectors
291                //std::cout << "upVector: X: " << upVector.x() << ", Y: "<<  upVector.y() << ", Z: "<< upVector.z() << std::endl;
292                //std::cout << "sideVector: X: " << sideVector.x() << ", Y: "<<  sideVector.y() << ", Z: "<< sideVector.z() << std::endl;
293                atmosphere->SetUpVector( upVector.x(), upVector.y(), upVector.z() );
294                atmosphere->SetRightVector( sideVector.x(), sideVector.y(), sideVector.z() );
295
296                // Note new upvector lat/lon
297                upVectorLon = lon;
298                upVectorLat = lat;
299        }       // If update requiered END
300}
301
302void visual_skySilverLining::shutdown()
303{
304        if (isInitialized())
305        {
306                // Remove this Node from scenegraph
307                sceneRoot->removeChild( this );
308               
309                // Remove updatecallback
310                this->removeUpdateCallback( updateCallback );
311                updateCallback = NULL;
312
313                // delete drawables
314                skyDrawable->shutdown();
315                this->removeDrawable(skyDrawable);
316                this->removeDrawable(cloudsDrawable);
317        }
318}
319
320void visual_skySilverLining::setVisibility(double visibility_)
321{
322        if (isInitialized())
323        {
324                atmosphere->GetConditions()->SetVisibility( visibility_ );
325        }
326
327}
328
329double visual_skySilverLining::getVisibility()
330{
331        if (isInitialized())
332        {
333                return atmosphere->GetConditions()->GetVisibility();
334        }
335        else
336                return -1;
337}
338
339void visual_skySilverLining::setTurbidity(double turbidity_)
340{
341        if (isInitialized())
342        {
343                atmosphere->GetConditions()->SetTurbidity( turbidity_ );
344        }
345}
346
347double visual_skySilverLining::getTurbidity()
348{
349        if (isInitialized())
350        {
351                return atmosphere->GetConditions()->GetTurbidity();
352        }
353        else
354                return -1;
355}
356
357void visual_skySilverLining::clearAllWindVolumes()
358{
359        if (isInitialized())
360        {
361                atmosphere->GetConditions()->ClearWindVolumes();
362        }
363}
364
365bool visual_skySilverLining::insideWind(double height_, double& bottom_, double& top_, double& speed_, double& direction_)
366{
367        if (isInitialized())
368        {
369                // Calculation earth radius on the wind positionl approximated through the now used position.
370                double radius;
371                if ( util::calculateEarthRadiusAtWGS84Coordinate(lat, lon, sceneRoot, radius) )
372                {
373                        // go through all wind volumes an check them for inside()
374                        std::map<int, SilverLining::WindVolume> windvolumes = atmosphere->GetConditions()->GetWindVolumes();
375                        for(unsigned int i=0; i<windvolumes.size(); i++)
376                        {
377                                if( windvolumes[i].Inside(radius + height_) )
378                                {
379                                        // save wind data
380                                        bottom_ = windvolumes[i].GetMinAltitude();
381                                        top_ = windvolumes[i].GetMaxAltitude() - radius;
382                                        speed_ = windvolumes[i].GetWindSpeed() - radius;
383                                        direction_ = windvolumes[i].GetDirection();
384                                        // return that wind was found
385                                        return true;
386                                }
387                        }       // For END
388                }       // If valid radius END
389        }       // If initialized() END
390        bottom_ = -1;
391        top_ = -1;
392        speed_ = -1;
393        direction_ = -1;
394        return false;
395}
396
397void visual_skySilverLining::addWindVolume(double bottom_, double top_, double speed_, int direction_)
398{
399        if (isInitialized())           
400        {
401                // Calculation earth radius on current lat lon position
402                double radius;
403                if ( util::calculateEarthRadiusAtWGS84Coordinate(lat, lon, sceneRoot, radius) )
404                {
405                        // correct wind value:
406                        if ( direction_ < 180 )
407                                direction_ += 180;
408                        else direction_ -= 180;
409
410                        // Setting up Wind
411                        SilverLining::WindVolume wv;
412                        wv.SetDirection( direction_ );
413                        wv.SetMinAltitude( radius + bottom_ );
414                        wv.SetMaxAltitude( radius + top_ );
415                        wv.SetWindSpeed( speed_ );
416                        atmosphere->GetConditions()->SetWind(wv);
417                }
418        }
419}
420
421void visual_skySilverLining::setLightPollution(double lightPollution_)
422{
423        if (isInitialized())
424        {
425                return atmosphere->GetConditions()->SetLightPollution( lightPollution_ );
426        }
427}
428
429double visual_skySilverLining::getLightPollution()
430{
431        if (isInitialized())
432        {
433                return atmosphere->GetConditions()->GetLightPollution();
434        }
435        else
436                return -1;
437
438}
439
440void visual_skySilverLining::addCloudLayer(int slot_, double baseLength_, double baseWidth_, double thickness_, double baseHeight_, double density_, CloudTypes cloudtype_ )
441{
442        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
443        {
444                // Calculation earth radius on current lat lon position
445                double radius;
446                if ( util::calculateEarthRadiusAtWGS84Coordinate(lat, lon, sceneRoot, radius) )
447                {
448                        // generate Cloud Layer
449                        SilverLining::CloudLayer *cloudLayer_;
450                        cloudLayer_ = SilverLining::CloudLayerFactory::Create(cloudtype_);
451                        cloudLayer_->SetBaseAltitude( baseHeight_ + radius);
452                       
453                        cloudLayer_->SetThickness(thickness_);
454                        cloudLayer_->SetBaseLength(baseLength_);
455                        cloudLayer_->SetBaseWidth(baseWidth_);
456                        cloudLayer_->SetDensity(density_);
457                        cloudLayer_->SetLayerPosition( 0.0, 0.0 );
458                        cloudLayer_->GenerateShadowMaps(false);
459
460                        //Save cloudlayer information into SLOT
461                        cloudLayerSlots[slot_].used = true;
462                        cloudLayerSlots[slot_].enabled = true;
463                        cloudLayerSlots[slot_].cloudLayerPointer = cloudLayer_;
464                        switch(cloudtype_)
465                        {
466                        case 0: cloudLayerSlots[slot_].typeName = "CIRROCUMULUS";                               // High planar cloud puffs             
467                                break;
468                        case 1: cloudLayerSlots[slot_].typeName = "CIRRUS_FIBRATUS";                    // High, thicker and fibrous clouds that signal changing weather
469                        break;
470                        case 2: cloudLayerSlots[slot_].typeName = "NIMBOSTRATUS";               // Low rain clouds that cover the sky
471                        break;
472                        case 3: cloudLayerSlots[slot_].typeName = "CUMULUS_MEDIOCRIS";          // Low, puffy clouds on fair days
473                        break;
474                        case 4: cloudLayerSlots[slot_].typeName = "CUMULUS_CONGESTUS";          // Large cumulus clouds that could turn into a thunderhead
475                        break;
476                        case 5: cloudLayerSlots[slot_].typeName = "CUMULONIMBUS_CAPPILATUS";    // Big storm clouds.
477                        break;
478                        case 6: cloudLayerSlots[slot_].typeName = "CUMULUS_CONGESTUS_INFINITE"; // Cumulus congestus layer that wraps to surround the camera at all times.
479                        break;
480                        case 7: cloudLayerSlots[slot_].typeName = "CUMULUS_MEDIOCRIS_INFINITE"; // Cumulus mediocris layer that wraps to surround the camera at all times.
481                                break;
482                        default: OSG_NOTIFY( osg::FATAL ) << "visual_skySilverlining::addCloudLayer - Invalid cloud type." << std::cout;
483                                 break;
484                        };
485               
486                        // Pass cloudlayer for seeding and adding to sky framework to the render thread
487                        skyDrawable->addCloudLayer( &cloudLayerSlots[slot_] );
488                } // If valid radius END
489        }        // If isInitialized() END
490}
491
492void visual_skySilverLining::removeCloudLayer( int slot_ )
493{
494        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
495        {
496                atmosphere->GetConditions()->RemoveCloudLayer( cloudLayerSlots[slot_].cloudLayerHandle );
497                cloudLayerSlots[slot_].used = false;
498                cloudLayerSlots[slot_].cloudLayerHandle = -1;
499                cloudLayerSlots[slot_].cloudLayerPointer = NULL;
500                cloudLayerSlots[slot_].enabled = false;
501        }
502}
503
504void visual_skySilverLining::clearAllSlots()
505{
506        if (isInitialized())
507        {
508                atmosphere->GetConditions()->RemoveAllCloudLayers();
509                for( int i=0; i<MAX_CLOUDLAYER_SLOTS; i++ )
510                {
511                        cloudLayerSlots[i].used = false;
512                        cloudLayerSlots[i].cloudLayerHandle = -1;
513                        cloudLayerSlots[i].cloudLayerPointer = NULL;
514                        cloudLayerSlots[i].enabled = false;
515                }
516        }
517}
518
519SilverLining::CloudLayer* visual_skySilverLining::getCloudLayer( int slot_ )
520{
521        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
522        {
523                if ( cloudLayerSlots[slot_].used )
524                        return cloudLayerSlots[slot_].cloudLayerPointer; 
525        }
526
527        return NULL;
528}
529
530void visual_skySilverLining::setEnabled(int slot_, bool enabled_ )
531{
532        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
533        {
534                cloudLayerSlots[slot_].enabled = enabled_;
535        }
536}
537
538bool visual_skySilverLining::isEnabled( int slot_ )
539{
540        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
541        {
542                return cloudLayerSlots[slot_].enabled;
543        }
544        return false;
545}
546
547void visual_skySilverLining::fadeVisibility( int slot_, int fadetimeMS_ )
548{
549        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
550        {
551                if (cloudLayerSlots[slot_].enabled)
552                {
553                        cloudLayerSlots[slot_].enabled = false;
554                        cloudLayerSlots[slot_].cloudLayerPointer->SetEnabled( false, fadetimeMS_ );
555                }
556                else
557                {
558                        cloudLayerSlots[slot_].enabled = true;
559                        cloudLayerSlots[slot_].cloudLayerPointer->SetEnabled( true, fadetimeMS_ );
560                }
561        }
562}
563
564std::string visual_skySilverLining::getCloudLayerTypeName( int slot_ )
565{
566        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
567        {
568                return cloudLayerSlots[slot_].typeName;
569        }
570        return "";
571}
572
573void visual_skySilverLining::clearGlobalPrecipitation()
574{
575        if (isInitialized())
576        {
577                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::NONE, 0.0 );
578        }
579}
580
581void visual_skySilverLining::setGlobalPrecipitation( double rate_mmPerHour_rain_, double rate_mmPerHour_drySnow_, double rate_mmPerHour_wetSnow_, double rate_mmPerHour_sleet_ )
582{
583        if ( isInitialized() )
584        {
585                // Delete old Precipitation
586                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::NONE, 0.0 );
587               
588                // Set new Precipitation
589                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::RAIN, rate_mmPerHour_rain_ );
590                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::WET_SNOW, rate_mmPerHour_drySnow_ );
591                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::DRY_SNOW, rate_mmPerHour_wetSnow_ );
592                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::SLEET, rate_mmPerHour_sleet_ );
593        }
594}
595       
596bool 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_ )
597{
598        if (isInitialized())
599        {
600                // Init
601                bool hasPrecipitation = false;
602                double x = 0;
603                double y = 0;
604                double z = 0;
605                //// If -1 : Use sky internal values
606                if ( lat_ == -1 )
607                        lat_ = lat;
608                if ( lon_ == -1 )
609                        lon_ = lon;
610                if ( height_ == -1 )
611                        height_ = height;
612
613                // Set precipitation to zero;
614                rate_mmPerHour_rain = 0;
615                rate_mmPerHour_drySnow = 0;
616                rate_mmPerHour_wetSnow = 0;
617                rate_mmPerHour_sleet = 0;
618
619                // Get global position
620                util::calculateXYZAtWGS84Coordinate(lat_, lon_, height_, sceneRoot, x, y, z);
621
622                // Look up every cloud layer for it's precipitation.
623                for( int i=0; i<MAX_CLOUDLAYER_SLOTS; i++ )
624                {
625                        if ( cloudLayerSlots[i].used )  // IF used, Pointer should be valid
626                        {
627                                if( cloudLayerSlots[i].cloudLayerPointer->HasPrecipitationAtPosition(x, y, z) )
628                                {
629                                        hasPrecipitation = true;
630                                        std::map<int, double> precipitationMap = cloudLayerSlots[i].cloudLayerPointer->GetPrecipitation();
631                                        for( std::map<int, double>::iterator it = precipitationMap.begin(); it != precipitationMap.end(); it++ )
632                                        {
633                                                switch(it->first)
634                                                {
635                                                        case SilverLining::CloudLayer::RAIN : rate_mmPerHour_rain += it->second;
636                                                                break;
637                                                        case SilverLining::CloudLayer::DRY_SNOW : rate_mmPerHour_drySnow += it->second;
638                                                                break;
639                                                        case SilverLining::CloudLayer::WET_SNOW : rate_mmPerHour_wetSnow += it->second;
640                                                                break;
641                                                        case SilverLining::CloudLayer::SLEET : rate_mmPerHour_sleet += it->second;
642                                                                break;
643                                                        default: OSG_NOTIFY( osg::FATAL ) << "ERROR: visual_skySilverLining::getOverallPrecipitationAtLocation() : Wrong precipitation type in map!" << std::endl;
644                                                                break;
645                                                };
646                                        }
647                                }       // If slot has Precipitation END
648                        }       // If used END
649                }       // For all slots END
650
651                OSG_NOTIFY( osg::ALWAYS ) << "Rain: " << rate_mmPerHour_rain << ", dry snow: " << rate_mmPerHour_drySnow << ", wet snow: " << rate_mmPerHour_wetSnow << ", sleet: " << rate_mmPerHour_sleet << std::endl;
652                return hasPrecipitation;
653
654        }       // If initialized END
655        return false;
656}
657
658
659bool 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_ )
660{
661        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
662        {
663                if( cloudLayerSlots[slot_].used )       // IF used, Pointer should be valid
664                {
665                        double x = 0;
666                        double y = 0;
667                        double z = 0;
668                        rate_mmPerHour_rain = 0;
669                        rate_mmPerHour_drySnow = 0;
670                        rate_mmPerHour_wetSnow = 0;
671                        rate_mmPerHour_sleet = 0;
672                        //// If -1 : Use sky internal values
673                        if ( lat_ == -1 )
674                                lat_ = lat;
675                        if ( lon_ == -1 )
676                                lon_ = lon;
677                        if ( height_ == -1 )
678                                height_ = height;
679
680                        // Get global position
681                        util::calculateXYZAtWGS84Coordinate(lat_, lon_, height_, sceneRoot, x, y, z);
682
683                        // Check for precipitation
684                        if( cloudLayerSlots[slot_].cloudLayerPointer->HasPrecipitationAtPosition(x, y, z) )
685                        {
686                                std::map<int, double> precipitationMap = cloudLayerSlots[slot_].cloudLayerPointer->GetPrecipitation();
687                                for( std::map<int, double>::iterator it = precipitationMap.begin(); it != precipitationMap.end(); it++ )
688                                {
689                                        switch(it->first)
690                                        {
691                                                case SilverLining::CloudLayer::RAIN : rate_mmPerHour_rain = it->second;
692                                                        break;
693                                                case SilverLining::CloudLayer::DRY_SNOW : rate_mmPerHour_drySnow = it->second;
694                                                        break;
695                                                case SilverLining::CloudLayer::WET_SNOW : rate_mmPerHour_wetSnow = it->second;
696                                                        break;
697                                                case SilverLining::CloudLayer::SLEET : rate_mmPerHour_sleet = it->second;
698                                                        break;
699                                                default: OSG_NOTIFY( osg::FATAL ) << "ERROR: visual_skySilverLining::getSlotPrecipitationAtLocation() : Wrong precipitation type in map!" << std::endl;
700                                                        break;
701                                        };
702                                }       // FOR END
703                                OSG_NOTIFY( osg::ALWAYS ) << "Rain: " << rate_mmPerHour_rain << ", dry snow: " << rate_mmPerHour_drySnow << ", wet snow: " << rate_mmPerHour_wetSnow << ", sleet: " << rate_mmPerHour_sleet << std::endl;
704                                return true;
705                        }       // If slot has Precipitation END
706                        else 
707                                return false;
708                }       // If used END
709                else
710                        return false;
711        }       // If initialized END
712        return false;
713}
714
715bool visual_skySilverLining::getSlotPrecipitation( int slot_, double& rate_mmPerHour_rain, double& rate_mmPerHour_drySnow, double& rate_mmPerHour_wetSnow, double& rate_mmPerHour_sleet )
716{
717        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
718        {
719                if( cloudLayerSlots[slot_].used )       // IF used, Pointer should be valid
720                {
721                        rate_mmPerHour_rain = 0;
722                        rate_mmPerHour_drySnow = 0;
723                        rate_mmPerHour_wetSnow = 0;
724                        rate_mmPerHour_sleet = 0;
725
726                        // Check for precipitation
727
728                                std::map<int, double> precipitationMap = cloudLayerSlots[slot_].cloudLayerPointer->GetPrecipitation();
729                                for( std::map<int, double>::iterator it = precipitationMap.begin(); it != precipitationMap.end(); it++ )
730                                {
731                                        switch(it->first)
732                                        {
733                                                case SilverLining::CloudLayer::RAIN : rate_mmPerHour_rain = it->second;
734                                                        break;
735                                                case SilverLining::CloudLayer::DRY_SNOW : rate_mmPerHour_drySnow = it->second;
736                                                        break;
737                                                case SilverLining::CloudLayer::WET_SNOW : rate_mmPerHour_wetSnow = it->second;
738                                                        break;
739                                                case SilverLining::CloudLayer::SLEET : rate_mmPerHour_sleet = it->second;
740                                                        break;
741                                                default: OSG_NOTIFY( osg::FATAL ) << "ERROR: visual_skySilverLining::getSlotPrecipitation() : Wrong precipitation type in map!" << std::endl;
742                                                        break;
743                                        };
744                                }       // FOR END
745                               
746                                if ( rate_mmPerHour_rain>0 || rate_mmPerHour_drySnow>0 || rate_mmPerHour_wetSnow>0 || rate_mmPerHour_sleet>0)
747                                {
748                                        OSG_NOTIFY( osg::ALWAYS ) << "Rain: " << rate_mmPerHour_rain << ", dry snow: " << rate_mmPerHour_drySnow << ", wet snow: " << rate_mmPerHour_wetSnow << ", sleet: " << rate_mmPerHour_sleet << std::endl;
749                                        return true;
750                                }
751                                else
752                                        return false;
753                }       // If used END
754                else
755                        return false;
756        }       // If initialized END
757        return false;
758}
759
760void visual_skySilverLining::clearAllPrecipitation( int slot_ )
761{
762        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
763        {
764                if( cloudLayerSlots[slot_].used )       // IF used, Pointer should be valid
765                {
766                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::NONE, 0.0 );
767                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::NONE, 0.0 ); // Second Call to clear precipitation rate.
768                }
769        }
770}
771
772void visual_skySilverLining::setSlotPrecipitation( int slot_, double rate_mmPerHour_rain_, double rate_mmPerHour_drySnow_, double rate_mmPerHour_wetSnow_, double rate_mmPerHour_sleet_ )
773{
774        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
775        {
776                if( cloudLayerSlots[slot_].used )       // IF used, Pointer should be valid
777                {
778                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::RAIN, rate_mmPerHour_rain_ );
779                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::DRY_SNOW, rate_mmPerHour_drySnow_ );
780                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::WET_SNOW, rate_mmPerHour_wetSnow_ );
781                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::SLEET, rate_mmPerHour_sleet_ );
782                }
783        }
784}
Note: See TracBrowser for help on using the repository browser.