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

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

added support cluster implementation via Boost ASIO TCP iostreams.

Status: Skeleton, ready to implement.

Minor: changed Silverlining default clouds.

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