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

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

sky silverlining vereinfacht.

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