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

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