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

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

Moved memory leak detection from source file to headerfile. Its still in the class but at least not in the source file.

The leak detection works, but the false positives are not stopped.
Use Linux/Valgrind? to make your final leak detection beyond the easy first approach in MSVC

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