source: osgVisual/trunk/src/sky_Silverlining/visual_skySilverLining.cpp @ 210

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

restructured XML config file: <cloudlayer> is now wrapped by <clouds>

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