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

Last change on this file since 53 was 53, checked in by Torben Dannhauer, 15 years ago

Update to use osg for sky fog instead OpenGL.

this way the osg fog feature "radialFog" can be used.

File size: 29.1 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        // Check if atmosphere is initialized.
44        if (!sky->isInitialized())
45                return;
46
47        // on first time: perform Post-Init.
48        sky->postInit();
49
50        // Update sky
51        double lat, lon, height, x, y, z;
52        util::getXYZofCamera( sceneCamera, x, y, z);
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        osg::Camera *mainCamera = viewer->getCamera();
169        if (!useProjMatrixCallback)
170        {
171                mainCamera->setClearMask(0);
172                mainCamera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
173                double fovy, aspect, zNear, zFar;
174                mainCamera->getProjectionMatrixAsPerspective(fovy, aspect, zNear, zFar);
175                mainCamera->setProjectionMatrixAsPerspective(fovy, aspect, 2, 125000);
176        }
177
178    int rootKids = distortedRoot->getNumChildren();
179    for (int i = 0; i < rootKids; i++)
180    {
181        osg::Node *n = distortedRoot->getChild(i);
182        osg::Camera *cam = dynamic_cast<osg::Camera*>(n);
183        if (cam)
184        {
185            if (cam->getRenderOrder() == osg::Camera::PRE_RENDER)
186            {
187                cam->setClearMask(0);
188
189                osg::ref_ptr<skySilverLining_atmosphereReference> ar = new skySilverLining_atmosphereReference;
190                                ar->atmosphere = atmosphere;
191                cam->setUserData(ar);
192                                mainCamera->setUserData(ar);
193                                sceneCamera = cam;
194
195                                if (useProjMatrixCallback)
196                                {
197                                        skySilverLining_projectionMatrixCallback *cb = new skySilverLining_projectionMatrixCallback( atmosphere, viewer->getCamera(), sceneRoot);
198                                        cam->setClampProjectionMatrixCallback(cb);
199                                        cb->setSkyDrawable(skyDrawable);
200                                }
201            }
202        }
203    }
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::init(osg::CoordinateSystemNode *sceneGraphRoot)
226{
227        sceneRoot = sceneGraphRoot;
228
229        // Use projection matrix callback oder fixed Cullsettings?
230        bool useProjMatrixCallback = true;
231
232        // add Sky to SceneRoot
233        sceneGraphRoot->addChild( this );
234
235        // Deactivate culling for the sky node (required by the silverlining sky framework)
236        this->setCullingActive(false);
237
238        // Instantiate an Atmosphere and associate it with this camera. If you have multiple cameras
239        // in multiple contexts, be sure to instantiate seperate Atmosphere objects for each.
240    // ***IMPORTANT!**** Check that the path to the resources folder for SilverLining in SkyDrawable.cpp
241    // SkyDrawable::initializeSilverLining matches with where you installed SilverLining.
242        atmosphere = new SilverLining::Atmosphere(SILVERLINING_LICENSEE, SILVERLINING_LICENSE);
243       
244    // Add the sky (calls Atmosphere::BeginFrame and handles initialization once you're in
245    // the rendering thread)
246        skyDrawable = new skySilverLining_skyDrawable(viewer, sceneRoot);
247 
248        if (!useProjMatrixCallback)
249        {
250                viewer->getCamera()->setClearMask(0);
251                viewer->getCamera()->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
252                double fovy, aspect, zNear, zFar;
253                viewer->getCamera()->getProjectionMatrixAsPerspective(fovy, aspect, zNear, zFar);
254                viewer->getCamera()->setProjectionMatrixAsPerspective(fovy, aspect, 2, 125000);
255        }
256        else
257        {
258                cb = new skySilverLining_projectionMatrixCallback( atmosphere, viewer->getCamera(), sceneRoot);
259                viewer->getCamera()->setClampProjectionMatrixCallback(cb);
260                cb->setSkyDrawable(skyDrawable);
261        }
262
263
264    viewer->getCamera()->setClearMask(0);
265
266    osg::ref_ptr<skySilverLining_atmosphereReference> ar = new skySilverLining_atmosphereReference;
267        ar->atmosphere = atmosphere;
268    viewer->getCamera()->setUserData(ar);
269        sceneCamera = viewer->getCamera();
270
271       
272        // Create and install updateCallback (for position etc.)
273        updateCallback = new skyUpdateCallback( sceneGraphRoot, sceneCamera, this );
274        this->setUpdateCallback( updateCallback );
275
276    // Use a RenderBin to enforce that the sky gets drawn first, then the scene, then the clouds
277        skyDrawable->getOrCreateStateSet()->setRenderBinDetails(-1, "RenderBin");
278
279    // Add the models
280    sceneGraphRoot->getOrCreateStateSet()->setRenderBinDetails(1, "RenderBin");
281
282    // Add the clouds (note, you need this even if you don't want clouds - it calls
283    // Atmosphere::EndFrame() )
284        cloudsDrawable = new skySilverLining_cloudsDrawable(viewer);
285        cloudsDrawable->getOrCreateStateSet()->setRenderBinDetails(99, "RenderBin");
286
287        // Add drawable to this geode to get rendered
288        this->addDrawable(skyDrawable);
289        this->addDrawable(cloudsDrawable);
290}
291
292void visual_skySilverLining::postInit()
293{
294        // Only allow one execution
295        if(postInitialized)
296                return;
297        else postInitialized = true;
298
299        // Execute Updatecallback once before adding Clouds.
300        updateCallback->operator ()(this, NULL);
301
302        setTime(16,00,23);
303        setVisibility(5000);
304        //AtmosphericConditions::SetFog()// use this for simulation real fog.
305
306
307
308        //Todo: secure memory-manager of timer*. oder remove paragraph
309        //MyMillisecondTimer *timer = new MyMillisecondTimer();
310 //   atmosphere->GetConditions()->SetMillisecondTimer(timer);
311        //atmosphere->GetConditions()->EnableTimePassage(true, -1);
312
313        //addWindVolume( 0.0, 15000.0, 300.0, 90.0 );
314       
315        //addCloudLayer( 0, 300000, 300000, 600.0, 2351.0, 0.5, NIMBOSTRATUS );
316        //addCloudLayer( 0, 5000000, 5000000, 600.0, 7351.0, 0.2, CIRRUS_FIBRATUS );
317        addCloudLayer( 1, 8000, 10000, 3000, 2000.0, 0.01, CUMULONIMBUS_CAPPILATUS );
318        //addCloudLayer( 1, 25000, 25000, 3000, 2000.0, 0.05, CUMULUS_CONGESTUS );
319        //addCloudLayer( 1, 500000, 500000, 15000, 2000.0, 0.6, STRATUS );
320        //cloudLayerSlots[1].cloudLayerPointer->SetPrecipitation(SilverLining::CloudLayer::RAIN, 15.0 );
321
322}
323
324void visual_skySilverLining::updateUpVector()
325{
326        // Allowed deltaLat and deltaLon between Updating the upvector
327        double deltaLatToUpdate = osg::DegreesToRadians( 0.1 ); // 0.5 deg
328        double deltaLonToUpdate = osg::DegreesToRadians( 0.1 ); // 0.5 deg
329
330        if ( fabs(lat-upVectorLat) > deltaLatToUpdate || fabs(lon-upVectorLon) > deltaLonToUpdate )
331        {
332                // Get ellipsoid model
333                osg::EllipsoidModel* ellipsoid = sceneRoot->getEllipsoidModel();
334                if ( !ellipsoid )
335                        return;
336
337                //OSG_NOTIFY( osg::ALWAYS ) << "update Upvector.." << std::endl;
338
339                // Calculate up vector
340                double x,y,z;
341                util::getXYZofCamera(sceneCamera, x, y, z);
342                osg::Vec3d upVector = ellipsoid->computeLocalUpVector( x, y, z );
343                upVector.normalize();
344               
345                // Calculate side vector
346                osg::Matrixd localToWorld;
347                ellipsoid->computeLocalToWorldTransformFromLatLongHeight(lat, lon, height, localToWorld);
348
349                osg::Vec3d sideVector(localToWorld(0, 0), localToWorld(0, 1), localToWorld(0, 2));
350                sideVector.normalize();
351
352                // Update silverlining vectors
353                //std::cout << "upVector: X: " << upVector.x() << ", Y: "<<  upVector.y() << ", Z: "<< upVector.z() << std::endl;
354                //std::cout << "sideVector: X: " << sideVector.x() << ", Y: "<<  sideVector.y() << ", Z: "<< sideVector.z() << std::endl;
355                atmosphere->SetUpVector( upVector.x(), upVector.y(), upVector.z() );
356                atmosphere->SetRightVector( sideVector.x(), sideVector.y(), sideVector.z() );
357
358                // Note new upvector lat/lon
359                upVectorLon = lon;
360                upVectorLat = lat;
361        }       // If update requiered END
362}
363
364void visual_skySilverLining::shutdown()
365{
366        if (isInitialized())
367        {
368                // Remove this Node from scenegraph
369                sceneRoot->removeChild( this );
370               
371                // Remove updatecallback
372                this->removeUpdateCallback( updateCallback );
373                updateCallback = NULL;
374
375                // delete drawables
376                skyDrawable->shutdown();
377                this->removeDrawable(skyDrawable);
378                this->removeDrawable(cloudsDrawable);
379        }
380}
381
382void visual_skySilverLining::setVisibility(double visibility_)
383{
384        if (isInitialized())
385        {
386                atmosphere->GetConditions()->SetVisibility( visibility_ );
387        }
388
389}
390
391double visual_skySilverLining::getVisibility()
392{
393        if (isInitialized())
394        {
395                return atmosphere->GetConditions()->GetVisibility();
396        }
397        else
398                return -1;
399}
400
401void visual_skySilverLining::setTurbidity(double turbidity_)
402{
403        if (isInitialized())
404        {
405                atmosphere->GetConditions()->SetTurbidity( turbidity_ );
406        }
407}
408
409double visual_skySilverLining::getTurbidity()
410{
411        if (isInitialized())
412        {
413                return atmosphere->GetConditions()->GetTurbidity();
414        }
415        else
416                return -1;
417}
418
419void visual_skySilverLining::clearAllWindVolumes()
420{
421        if (isInitialized())
422        {
423                atmosphere->GetConditions()->ClearWindVolumes();
424        }
425}
426
427bool visual_skySilverLining::insideWind(double height_, double& bottom_, double& top_, double& speed_, double& direction_)
428{
429        if (isInitialized())
430        {
431                // Calculation earth radius on the wind positionl approximated through the now used position.
432                double radius;
433                if ( util::calculateEarthRadiusAtWGS84Coordinate(lat, lon, sceneRoot, radius) )
434                {
435                        // go through all wind volumes an check them for inside()
436                        std::vector<SilverLining::WindVolume> windvolumes = atmosphere->GetConditions()->GetWindVolumes();
437                        for(unsigned int i=0; i<windvolumes.size(); i++)
438                        {
439                                if( windvolumes[i].Inside(radius + height_) )
440                                {
441                                        // save wind data
442                                        bottom_ = windvolumes[i].GetMinAltitude();
443                                        top_ = windvolumes[i].GetMaxAltitude() - radius;
444                                        speed_ = windvolumes[i].GetWindSpeed() - radius;
445                                        direction_ = windvolumes[i].GetDirection();
446                                        // return that wind was found
447                                        return true;
448                                }
449                        }       // For END
450                }       // If valid radius END
451        }       // If initialized() END
452        bottom_ = -1;
453        top_ = -1;
454        speed_ = -1;
455        direction_ = -1;
456        return false;
457}
458
459void visual_skySilverLining::addWindVolume(double bottom_, double top_, double speed_, int direction_)
460{
461        if (isInitialized())           
462        {
463                // Calculation earth radius on current lat lon position
464                double radius;
465                if ( util::calculateEarthRadiusAtWGS84Coordinate(lat, lon, sceneRoot, radius) )
466                {
467                        // correct wind value:
468                        if ( direction_ < 180 )
469                                direction_ += 180;
470                        else direction_ -= 180;
471
472                        // Setting up Wind
473                        SilverLining::WindVolume wv;
474                        wv.SetDirection( direction_ );
475                        wv.SetMinAltitude( radius + bottom_ );
476                        wv.SetMaxAltitude( radius + top_ );
477                        wv.SetWindSpeed( speed_ );
478                        atmosphere->GetConditions()->SetWind(wv);
479                }
480        }
481}
482
483void visual_skySilverLining::setLightPollution(double lightPollution_)
484{
485        if (isInitialized())
486        {
487                return atmosphere->GetConditions()->SetLightPollution( lightPollution_ );
488        }
489}
490
491double visual_skySilverLining::getLightPollution()
492{
493        if (isInitialized())
494        {
495                return atmosphere->GetConditions()->GetLightPollution();
496        }
497        else
498                return -1;
499
500}
501
502void visual_skySilverLining::addCloudLayer(int slot_, double baseLength_, double baseWidth_, double thickness_, double baseHeight_, double density_, CloudTypes cloudtype_ )
503{
504        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
505        {
506                // Calculation earth radius on current lat lon position
507                double radius;
508                if ( util::calculateEarthRadiusAtWGS84Coordinate(lat, lon, sceneRoot, radius) )
509                {
510                        // generate Cloud Layer
511                        SilverLining::CloudLayer *cloudLayer_;
512                        cloudLayer_ = SilverLining::CloudLayerFactory::Create(cloudtype_);
513                        cloudLayer_->SetBaseAltitude( baseHeight_ + radius);
514                       
515                        cloudLayer_->SetThickness(thickness_);
516                        cloudLayer_->SetBaseLength(baseLength_);
517                        cloudLayer_->SetBaseWidth(baseWidth_);
518                        cloudLayer_->SetDensity(density_);
519                        cloudLayer_->SetLayerPosition( 0.0, 0.0 );
520                        cloudLayer_->GenerateShadowMaps(false);
521
522                        //Save cloudlayer information into SLOT
523                        cloudLayerSlots[slot_].used = true;
524                        cloudLayerSlots[slot_].enabled = true;
525                        cloudLayerSlots[slot_].cloudLayerPointer = cloudLayer_;
526                        switch(cloudtype_)
527                        {
528                        case 0: cloudLayerSlots[slot_].typeName = "CIRROCUMULUS";                               // High planar cloud puffs             
529                                break;
530                        case 1: cloudLayerSlots[slot_].typeName = "CIRRUS_FIBRATUS";                    // High, thicker and fibrous clouds that signal changing weather
531                        break;
532                        case 2: cloudLayerSlots[slot_].typeName = "NIMBOSTRATUS";               // Low rain clouds that cover the sky
533                        break;
534                        case 3: cloudLayerSlots[slot_].typeName = "CUMULUS_MEDIOCRIS";          // Low, puffy clouds on fair days
535                        break;
536                        case 4: cloudLayerSlots[slot_].typeName = "CUMULUS_CONGESTUS";          // Large cumulus clouds that could turn into a thunderhead
537                        break;
538                        case 5: cloudLayerSlots[slot_].typeName = "CUMULONIMBUS_CAPPILATUS";    // Big storm clouds.
539                        break;
540                        case 6: cloudLayerSlots[slot_].typeName = "CUMULUS_CONGESTUS_INFINITE"; // Cumulus congestus layer that wraps to surround the camera at all times.
541                        break;
542                        case 7: cloudLayerSlots[slot_].typeName = "CUMULUS_MEDIOCRIS_INFINITE"; // Cumulus mediocris layer that wraps to surround the camera at all times.
543                                break;
544                        default: OSG_NOTIFY( osg::FATAL ) << "visual_skySilverlining::addCloudLayer - Invalid cloud type." << std::cout;
545                                 break;
546                        };
547               
548                        // Pass cloudlayer for seeding and adding to sky framework to the render thread
549                        skyDrawable->addCloudLayer( &cloudLayerSlots[slot_] );
550                } // If valid radius END
551        }        // If isInitialized() END
552}
553
554void visual_skySilverLining::removeCloudLayer( int slot_ )
555{
556        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
557        {
558                atmosphere->GetConditions()->RemoveCloudLayer( cloudLayerSlots[slot_].cloudLayerHandle );
559                cloudLayerSlots[slot_].used = false;
560                cloudLayerSlots[slot_].cloudLayerHandle = -1;
561                cloudLayerSlots[slot_].cloudLayerPointer = NULL;
562                cloudLayerSlots[slot_].enabled = false;
563        }
564}
565
566void visual_skySilverLining::clearAllSlots()
567{
568        if (isInitialized())
569        {
570                atmosphere->GetConditions()->RemoveAllCloudLayers();
571                for( int i=0; i<MAX_CLOUDLAYER_SLOTS; i++ )
572                {
573                        cloudLayerSlots[i].used = false;
574                        cloudLayerSlots[i].cloudLayerHandle = -1;
575                        cloudLayerSlots[i].cloudLayerPointer = NULL;
576                        cloudLayerSlots[i].enabled = false;
577                }
578        }
579}
580
581SilverLining::CloudLayer* visual_skySilverLining::getCloudLayer( int slot_ )
582{
583        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
584        {
585                if ( cloudLayerSlots[slot_].used )
586                        return cloudLayerSlots[slot_].cloudLayerPointer; 
587        }
588
589        return NULL;
590}
591
592void visual_skySilverLining::setEnabled(int slot_, bool enabled_ )
593{
594        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
595        {
596                cloudLayerSlots[slot_].enabled = enabled_;
597        }
598}
599
600bool visual_skySilverLining::isEnabled( int slot_ )
601{
602        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
603        {
604                return cloudLayerSlots[slot_].enabled;
605        }
606        return false;
607}
608
609void visual_skySilverLining::fadeVisibility( int slot_, int fadetimeMS_ )
610{
611        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
612        {
613                if (cloudLayerSlots[slot_].enabled)
614                {
615                        cloudLayerSlots[slot_].enabled = false;
616                        cloudLayerSlots[slot_].cloudLayerPointer->SetEnabled( false, fadetimeMS_ );
617                }
618                else
619                {
620                        cloudLayerSlots[slot_].enabled = true;
621                        cloudLayerSlots[slot_].cloudLayerPointer->SetEnabled( true, fadetimeMS_ );
622                }
623        }
624}
625
626std::string visual_skySilverLining::getCloudLayerTypeName( int slot_ )
627{
628        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
629        {
630                return cloudLayerSlots[slot_].typeName;
631        }
632        return "";
633}
634
635void visual_skySilverLining::clearGlobalPrecipitation()
636{
637        if (isInitialized())
638        {
639                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::NONE, 0.0 );
640        }
641}
642
643void visual_skySilverLining::setGlobalPrecipitation( double rate_mmPerHour_rain_, double rate_mmPerHour_drySnow_, double rate_mmPerHour_wetSnow_, double rate_mmPerHour_sleet_ )
644{
645        if ( isInitialized() )
646        {
647                // Delete old Precipitation
648                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::NONE, 0.0 );
649               
650                // Set new Precipitation
651                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::RAIN, rate_mmPerHour_rain_ );
652                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::WET_SNOW, rate_mmPerHour_drySnow_ );
653                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::DRY_SNOW, rate_mmPerHour_wetSnow_ );
654                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::SLEET, rate_mmPerHour_sleet_ );
655        }
656}
657       
658bool 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_ )
659{
660        if (isInitialized())
661        {
662                // Init
663                bool hasPrecipitation = false;
664                double x = 0;
665                double y = 0;
666                double z = 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                // Set precipitation to zero;
676                rate_mmPerHour_rain = 0;
677                rate_mmPerHour_drySnow = 0;
678                rate_mmPerHour_wetSnow = 0;
679                rate_mmPerHour_sleet = 0;
680
681                // Get global position
682                util::calculateXYZAtWGS84Coordinate(lat_, lon_, height_, sceneRoot, x, y, z);
683
684                // Look up every cloud layer for it's precipitation.
685                for( int i=0; i<MAX_CLOUDLAYER_SLOTS; i++ )
686                {
687                        if ( cloudLayerSlots[i].used )  // IF used, Pointer should be valid
688                        {
689                                if( cloudLayerSlots[i].cloudLayerPointer->HasPrecipitationAtPosition(x, y, z) )
690                                {
691                                        hasPrecipitation = true;
692                                        std::map<int, double> precipitationMap = cloudLayerSlots[i].cloudLayerPointer->GetPrecipitation();
693                                        for( std::map<int, double>::iterator it = precipitationMap.begin(); it != precipitationMap.end(); it++ )
694                                        {
695                                                switch(it->first)
696                                                {
697                                                        case SilverLining::CloudLayer::RAIN : rate_mmPerHour_rain += it->second;
698                                                                break;
699                                                        case SilverLining::CloudLayer::DRY_SNOW : rate_mmPerHour_drySnow += it->second;
700                                                                break;
701                                                        case SilverLining::CloudLayer::WET_SNOW : rate_mmPerHour_wetSnow += it->second;
702                                                                break;
703                                                        case SilverLining::CloudLayer::SLEET : rate_mmPerHour_sleet += it->second;
704                                                                break;
705                                                        default: OSG_NOTIFY( osg::FATAL ) << "ERROR: visual_skySilverLining::getOverallPrecipitationAtLocation() : Wrong precipitation type in map!" << std::endl;
706                                                                break;
707                                                };
708                                        }
709                                }       // If slot has Precipitation END
710                        }       // If used END
711                }       // For all slots END
712
713                OSG_NOTIFY( osg::ALWAYS ) << "Rain: " << rate_mmPerHour_rain << ", dry snow: " << rate_mmPerHour_drySnow << ", wet snow: " << rate_mmPerHour_wetSnow << ", sleet: " << rate_mmPerHour_sleet << std::endl;
714                return hasPrecipitation;
715
716        }       // If initialized END
717        return false;
718}
719
720
721bool 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_ )
722{
723        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
724        {
725                if( cloudLayerSlots[slot_].used )       // IF used, Pointer should be valid
726                {
727                        double x = 0;
728                        double y = 0;
729                        double z = 0;
730                        rate_mmPerHour_rain = 0;
731                        rate_mmPerHour_drySnow = 0;
732                        rate_mmPerHour_wetSnow = 0;
733                        rate_mmPerHour_sleet = 0;
734                        //// If -1 : Use sky internal values
735                        if ( lat_ == -1 )
736                                lat_ = lat;
737                        if ( lon_ == -1 )
738                                lon_ = lon;
739                        if ( height_ == -1 )
740                                height_ = height;
741
742                        // Get global position
743                        util::calculateXYZAtWGS84Coordinate(lat_, lon_, height_, sceneRoot, x, y, z);
744
745                        // Check for precipitation
746                        if( cloudLayerSlots[slot_].cloudLayerPointer->HasPrecipitationAtPosition(x, y, z) )
747                        {
748                                std::map<int, double> precipitationMap = cloudLayerSlots[slot_].cloudLayerPointer->GetPrecipitation();
749                                for( std::map<int, double>::iterator it = precipitationMap.begin(); it != precipitationMap.end(); it++ )
750                                {
751                                        switch(it->first)
752                                        {
753                                                case SilverLining::CloudLayer::RAIN : rate_mmPerHour_rain = it->second;
754                                                        break;
755                                                case SilverLining::CloudLayer::DRY_SNOW : rate_mmPerHour_drySnow = it->second;
756                                                        break;
757                                                case SilverLining::CloudLayer::WET_SNOW : rate_mmPerHour_wetSnow = it->second;
758                                                        break;
759                                                case SilverLining::CloudLayer::SLEET : rate_mmPerHour_sleet = it->second;
760                                                        break;
761                                                default: OSG_NOTIFY( osg::FATAL ) << "ERROR: visual_skySilverLining::getSlotPrecipitationAtLocation() : Wrong precipitation type in map!" << std::endl;
762                                                        break;
763                                        };
764                                }       // FOR END
765                                OSG_NOTIFY( osg::ALWAYS ) << "Rain: " << rate_mmPerHour_rain << ", dry snow: " << rate_mmPerHour_drySnow << ", wet snow: " << rate_mmPerHour_wetSnow << ", sleet: " << rate_mmPerHour_sleet << std::endl;
766                                return true;
767                        }       // If slot has Precipitation END
768                        else 
769                                return false;
770                }       // If used END
771                else
772                        return false;
773        }       // If initialized END
774        return false;
775}
776
777bool visual_skySilverLining::getSlotPrecipitation( int slot_, double& rate_mmPerHour_rain, double& rate_mmPerHour_drySnow, double& rate_mmPerHour_wetSnow, double& rate_mmPerHour_sleet )
778{
779        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
780        {
781                if( cloudLayerSlots[slot_].used )       // IF used, Pointer should be valid
782                {
783                        rate_mmPerHour_rain = 0;
784                        rate_mmPerHour_drySnow = 0;
785                        rate_mmPerHour_wetSnow = 0;
786                        rate_mmPerHour_sleet = 0;
787
788                        // Check for precipitation
789
790                                std::map<int, double> precipitationMap = cloudLayerSlots[slot_].cloudLayerPointer->GetPrecipitation();
791                                for( std::map<int, double>::iterator it = precipitationMap.begin(); it != precipitationMap.end(); it++ )
792                                {
793                                        switch(it->first)
794                                        {
795                                                case SilverLining::CloudLayer::RAIN : rate_mmPerHour_rain = it->second;
796                                                        break;
797                                                case SilverLining::CloudLayer::DRY_SNOW : rate_mmPerHour_drySnow = it->second;
798                                                        break;
799                                                case SilverLining::CloudLayer::WET_SNOW : rate_mmPerHour_wetSnow = it->second;
800                                                        break;
801                                                case SilverLining::CloudLayer::SLEET : rate_mmPerHour_sleet = it->second;
802                                                        break;
803                                                default: OSG_NOTIFY( osg::FATAL ) << "ERROR: visual_skySilverLining::getSlotPrecipitation() : Wrong precipitation type in map!" << std::endl;
804                                                        break;
805                                        };
806                                }       // FOR END
807                               
808                                if ( rate_mmPerHour_rain>0 || rate_mmPerHour_drySnow>0 || rate_mmPerHour_wetSnow>0 || rate_mmPerHour_sleet>0)
809                                {
810                                        OSG_NOTIFY( osg::ALWAYS ) << "Rain: " << rate_mmPerHour_rain << ", dry snow: " << rate_mmPerHour_drySnow << ", wet snow: " << rate_mmPerHour_wetSnow << ", sleet: " << rate_mmPerHour_sleet << std::endl;
811                                        return true;
812                                }
813                                else
814                                        return false;
815                }       // If used END
816                else
817                        return false;
818        }       // If initialized END
819        return false;
820}
821
822void visual_skySilverLining::clearAllPrecipitation( int slot_ )
823{
824        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
825        {
826                if( cloudLayerSlots[slot_].used )       // IF used, Pointer should be valid
827                {
828                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::NONE, 0.0 );
829                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::NONE, 0.0 ); // Second Call to clear precipitation rate.
830                }
831        }
832}
833
834void visual_skySilverLining::setSlotPrecipitation( int slot_, double rate_mmPerHour_rain_, double rate_mmPerHour_drySnow_, double rate_mmPerHour_wetSnow_, double rate_mmPerHour_sleet_ )
835{
836        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
837        {
838                if( cloudLayerSlots[slot_].used )       // IF used, Pointer should be valid
839                {
840                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::RAIN, rate_mmPerHour_rain_ );
841                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::DRY_SNOW, rate_mmPerHour_drySnow_ );
842                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::WET_SNOW, rate_mmPerHour_wetSnow_ );
843                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::SLEET, rate_mmPerHour_sleet_ );
844                }
845        }
846}
Note: See TracBrowser for help on using the repository browser.