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

Last change on this file since 296 was 296, checked in by Torben Dannhauer, 13 years ago
File size: 28.4 KB
Line 
1/* -*-c++-*- osgVisual - Copyright (C) 2009-2011 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        if(hour_) t.SetHour( hour_ );
98        if(minute_) t.SetMinutes( minute_ );
99        if(second_) 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        if(year_) t.SetYear( year_ );
111        if(month_) t.SetMonth( month_ );
112        if(day_) 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    osg::Vec3d up(x, y, z);
265    up.normalize();
266
267    osg::Vec3d north(0, 0, 1);  // Z is north
268    osg::Vec3d east = north ^ up;       // Cross product
269    east.normalize();
270
271    atmosphere->SetUpVector(up.x(), up.y(), up.z());
272    atmosphere->SetRightVector(east.x(), east.y(), east.z());
273
274    osg::Matrixd proj = sceneCamera->getProjectionMatrix();
275    double dProj[16];
276
277    int i = 0;
278    for (int row = 0; row < 4; row++)
279    {
280        for (int col = 0; col < 4; col++)
281        {
282            dProj[i] = proj(row, col);
283            i++;
284        }
285    }
286    //atmosphere->SetProjectionMatrix(dProj);
287}
288
289void visual_skySilverLining::shutdown()
290{
291        if (isInitialized())
292        {
293                // Remove this Node from scenegraph
294                sceneRoot->removeChild( this );
295               
296                // Remove updatecallback
297                this->removeUpdateCallback( updateCallback );
298                updateCallback = NULL;
299
300                // delete drawables
301                skyDrawable->shutdown();
302                this->removeDrawable(skyDrawable);
303                this->removeDrawable(cloudsDrawable);
304        }
305}
306
307void visual_skySilverLining::setVisibility(double visibility_)
308{
309        if (isInitialized())
310        {
311                atmosphere->GetConditions()->SetVisibility( visibility_ );
312        }
313
314}
315
316double visual_skySilverLining::getVisibility()
317{
318        if (isInitialized())
319        {
320                return atmosphere->GetConditions()->GetVisibility();
321        }
322        else
323                return -1;
324}
325
326void visual_skySilverLining::setTurbidity(double turbidity_)
327{
328        if (isInitialized())
329        {
330                atmosphere->GetConditions()->SetTurbidity( turbidity_ );
331        }
332}
333
334double visual_skySilverLining::getTurbidity()
335{
336        if (isInitialized())
337        {
338                return atmosphere->GetConditions()->GetTurbidity();
339        }
340        else
341                return -1;
342}
343
344void visual_skySilverLining::clearAllWindVolumes()
345{
346        if (isInitialized())
347        {
348                atmosphere->GetConditions()->ClearWindVolumes();
349        }
350}
351
352bool visual_skySilverLining::insideWind(double height_, double& bottom_, double& top_, double& speed_, double& direction_)
353{
354        if (isInitialized())
355        {
356                // Calculation earth radius on the wind positionl approximated through the now used position.
357                double radius;
358                if ( util::calculateEarthRadiusAtWGS84Coordinate(lat, lon, sceneRoot, radius) )
359                {
360                        // go through all wind volumes an check them for inside()
361                        //std::map<int, SilverLining::WindVolume> windvolumes = atmosphere->GetConditions()->GetWindVolumes();
362                        SL_MAP(int, SilverLining::WindVolume) windvolumes = atmosphere->GetConditions()->GetWindVolumes();
363                        for(unsigned int i=0; i<windvolumes.size(); i++)
364                        {
365                                if( windvolumes[i].Inside(radius + height_) )
366                                {
367                                        // save wind data
368                                        bottom_ = windvolumes[i].GetMinAltitude();
369                                        top_ = windvolumes[i].GetMaxAltitude() - radius;
370                                        speed_ = windvolumes[i].GetWindSpeed() - radius;
371                                        direction_ = windvolumes[i].GetDirection();
372                                        // return that wind was found
373                                        return true;
374                                }
375                        }       // For END
376                }       // If valid radius END
377        }       // If initialized() END
378        bottom_ = -1;
379        top_ = -1;
380        speed_ = -1;
381        direction_ = -1;
382        return false;
383}
384
385void visual_skySilverLining::addWindVolume(double bottom_, double top_, double speed_, int direction_)
386{
387        if (isInitialized())           
388        {
389                // Calculation earth radius on current lat lon position
390                double radius;
391                if ( util::calculateEarthRadiusAtWGS84Coordinate(lat, lon, sceneRoot, radius) )
392                {
393                        // correct wind value:
394                        if ( direction_ < 180 )
395                                direction_ += 180;
396                        else direction_ -= 180;
397
398                        // Setting up Wind
399                        SilverLining::WindVolume wv;
400                        wv.SetDirection( direction_ );
401                        wv.SetMinAltitude( radius + bottom_ );
402                        wv.SetMaxAltitude( radius + top_ );
403                        wv.SetWindSpeed( speed_ );
404                        atmosphere->GetConditions()->SetWind(wv);
405                }
406        }
407}
408
409void visual_skySilverLining::setLightPollution(double lightPollution_)
410{
411        if (isInitialized())
412        {
413                return atmosphere->GetConditions()->SetLightPollution( lightPollution_ );
414        }
415}
416
417double visual_skySilverLining::getLightPollution()
418{
419        if (isInitialized())
420        {
421                return atmosphere->GetConditions()->GetLightPollution();
422        }
423        else
424                return -1;
425
426}
427
428void visual_skySilverLining::addCloudLayer(int slot_, double baseLength_, double baseWidth_, double thickness_, double baseHeight_, double density_, CloudTypes cloudtype_ )
429{
430        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
431        {
432                // create cloudlayer order and pass to skyDrawable to instantiate.
433                cloudlayerOrder newCL;
434                newCL.slot = slot_;
435                newCL.lat = lat;
436                newCL.lon = lon;
437                newCL.baseLength = baseLength_;
438                newCL.baseWidth = baseWidth_;
439                newCL.thickness = thickness_;
440                newCL.baseHeight = baseHeight_;
441                newCL.density = density_;
442                newCL.cloudtype = cloudtype_;
443                newCL.assocCloudLayerSlot = &cloudLayerSlots[slot_];
444               
445                skyDrawable->addCloudLayerOrder( newCL );
446
447        }        // If isInitialized() END
448}
449
450void visual_skySilverLining::removeCloudLayer( int slot_ )
451{
452        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
453        {
454                atmosphere->GetConditions()->RemoveCloudLayer( cloudLayerSlots[slot_].cloudLayerHandle );
455                cloudLayerSlots[slot_].used = false;
456                cloudLayerSlots[slot_].cloudLayerHandle = -1;
457                cloudLayerSlots[slot_].cloudLayerPointer = NULL;
458                cloudLayerSlots[slot_].enabled = false;
459        }
460}
461
462void visual_skySilverLining::clearAllSlots()
463{
464        if (isInitialized())
465        {
466                atmosphere->GetConditions()->RemoveAllCloudLayers();
467                for( int i=0; i<MAX_CLOUDLAYER_SLOTS; i++ )
468                {
469                        cloudLayerSlots[i].used = false;
470                        cloudLayerSlots[i].cloudLayerHandle = -1;
471                        cloudLayerSlots[i].cloudLayerPointer = NULL;
472                        cloudLayerSlots[i].enabled = false;
473                }
474        }
475}
476
477SilverLining::CloudLayer* visual_skySilverLining::getCloudLayer( int slot_ )
478{
479        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
480        {
481                if ( cloudLayerSlots[slot_].used )
482                        return cloudLayerSlots[slot_].cloudLayerPointer; 
483        }
484
485        return NULL;
486}
487
488void visual_skySilverLining::setEnabled(int slot_, bool enabled_ )
489{
490        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
491        {
492                cloudLayerSlots[slot_].enabled = enabled_;
493        }
494}
495
496bool visual_skySilverLining::isEnabled( int slot_ )
497{
498        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
499        {
500                return cloudLayerSlots[slot_].enabled;
501        }
502        return false;
503}
504
505void visual_skySilverLining::fadeVisibility( int slot_, int fadetimeMS_ )
506{
507        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
508        {
509                if (cloudLayerSlots[slot_].enabled)
510                {
511                        cloudLayerSlots[slot_].enabled = false;
512                        cloudLayerSlots[slot_].cloudLayerPointer->SetEnabled( false, fadetimeMS_ );
513                }
514                else
515                {
516                        cloudLayerSlots[slot_].enabled = true;
517                        cloudLayerSlots[slot_].cloudLayerPointer->SetEnabled( true, fadetimeMS_ );
518                }
519        }
520}
521
522std::string visual_skySilverLining::getCloudLayerTypeName( int slot_ )
523{
524        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
525        {
526                return cloudLayerSlots[slot_].typeName;
527        }
528        return "";
529}
530
531void visual_skySilverLining::clearGlobalPrecipitation()
532{
533        if (isInitialized())
534        {
535                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::NONE, 0.0 );
536        }
537}
538
539void visual_skySilverLining::setGlobalPrecipitation( double rate_mmPerHour_rain_, double rate_mmPerHour_drySnow_, double rate_mmPerHour_wetSnow_, double rate_mmPerHour_sleet_ )
540{
541        if ( isInitialized() )
542        {
543                // Delete old Precipitation
544                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::NONE, 0.0 );
545               
546                // Set new Precipitation
547                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::RAIN, rate_mmPerHour_rain_ );
548                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::WET_SNOW, rate_mmPerHour_drySnow_ );
549                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::DRY_SNOW, rate_mmPerHour_wetSnow_ );
550                atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::SLEET, rate_mmPerHour_sleet_ );
551        }
552}
553       
554bool 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_ )
555{
556        if (isInitialized())
557        {
558                // Init
559                bool hasPrecipitation = false;
560                double x = 0;
561                double y = 0;
562                double z = 0;
563                //// If -1 : Use sky internal values
564                if ( lat_ == -1 )
565                        lat_ = lat;
566                if ( lon_ == -1 )
567                        lon_ = lon;
568                if ( height_ == -1 )
569                        height_ = height;
570
571                // Set precipitation to zero;
572                rate_mmPerHour_rain = 0;
573                rate_mmPerHour_drySnow = 0;
574                rate_mmPerHour_wetSnow = 0;
575                rate_mmPerHour_sleet = 0;
576
577                // Get global position
578                util::calculateXYZAtWGS84Coordinate(lat_, lon_, height_, sceneRoot, x, y, z);
579
580                // Look up every cloud layer for it's precipitation.
581                for( int i=0; i<MAX_CLOUDLAYER_SLOTS; i++ )
582                {
583                        if ( cloudLayerSlots[i].used )  // IF used, Pointer should be valid
584                        {
585                                if( cloudLayerSlots[i].cloudLayerPointer->HasPrecipitationAtPosition(x, y, z) )
586                                {
587                                        hasPrecipitation = true;
588                                        SL_MAP (int, double) precipitationMap = cloudLayerSlots[i].cloudLayerPointer->GetPrecipitation();
589                                        for( SL_MAP (int, double)::iterator it = precipitationMap.begin(); it != precipitationMap.end(); it++ )
590                                        {
591                                                switch(it->first)
592                                                {
593                                                        case SilverLining::CloudLayer::RAIN : rate_mmPerHour_rain += it->second;
594                                                                break;
595                                                        case SilverLining::CloudLayer::DRY_SNOW : rate_mmPerHour_drySnow += it->second;
596                                                                break;
597                                                        case SilverLining::CloudLayer::WET_SNOW : rate_mmPerHour_wetSnow += it->second;
598                                                                break;
599                                                        case SilverLining::CloudLayer::SLEET : rate_mmPerHour_sleet += it->second;
600                                                                break;
601                                                        default: OSG_NOTIFY( osg::FATAL ) << "ERROR: visual_skySilverLining::getOverallPrecipitationAtLocation() : Wrong precipitation type in map!" << std::endl;
602                                                                break;
603                                                };
604                                        }
605                                }       // If slot has Precipitation END
606                        }       // If used END
607                }       // For all slots END
608
609                OSG_NOTIFY( osg::ALWAYS ) << "Rain: " << rate_mmPerHour_rain << ", dry snow: " << rate_mmPerHour_drySnow << ", wet snow: " << rate_mmPerHour_wetSnow << ", sleet: " << rate_mmPerHour_sleet << std::endl;
610                return hasPrecipitation;
611
612        }       // If initialized END
613        return false;
614}
615
616
617bool 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_ )
618{
619        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
620        {
621                if( cloudLayerSlots[slot_].used )       // IF used, Pointer should be valid
622                {
623                        double x = 0;
624                        double y = 0;
625                        double z = 0;
626                        rate_mmPerHour_rain = 0;
627                        rate_mmPerHour_drySnow = 0;
628                        rate_mmPerHour_wetSnow = 0;
629                        rate_mmPerHour_sleet = 0;
630                        //// If -1 : Use sky internal values
631                        if ( lat_ == -1 )
632                                lat_ = lat;
633                        if ( lon_ == -1 )
634                                lon_ = lon;
635                        if ( height_ == -1 )
636                                height_ = height;
637
638                        // Get global position
639                        util::calculateXYZAtWGS84Coordinate(lat_, lon_, height_, sceneRoot, x, y, z);
640
641                        // Check for precipitation
642                        if( cloudLayerSlots[slot_].cloudLayerPointer->HasPrecipitationAtPosition(x, y, z) )
643                        {
644                                SL_MAP (int, double) precipitationMap = cloudLayerSlots[slot_].cloudLayerPointer->GetPrecipitation();
645                                for( SL_MAP (int, double)::iterator it = precipitationMap.begin(); it != precipitationMap.end(); it++ )
646                                {
647                                        switch(it->first)
648                                        {
649                                                case SilverLining::CloudLayer::RAIN : rate_mmPerHour_rain = it->second;
650                                                        break;
651                                                case SilverLining::CloudLayer::DRY_SNOW : rate_mmPerHour_drySnow = it->second;
652                                                        break;
653                                                case SilverLining::CloudLayer::WET_SNOW : rate_mmPerHour_wetSnow = it->second;
654                                                        break;
655                                                case SilverLining::CloudLayer::SLEET : rate_mmPerHour_sleet = it->second;
656                                                        break;
657                                                default: OSG_NOTIFY( osg::FATAL ) << "ERROR: visual_skySilverLining::getSlotPrecipitationAtLocation() : Wrong precipitation type in map!" << std::endl;
658                                                        break;
659                                        };
660                                }       // FOR END
661                                OSG_NOTIFY( osg::ALWAYS ) << "Rain: " << rate_mmPerHour_rain << ", dry snow: " << rate_mmPerHour_drySnow << ", wet snow: " << rate_mmPerHour_wetSnow << ", sleet: " << rate_mmPerHour_sleet << std::endl;
662                                return true;
663                        }       // If slot has Precipitation END
664                        else 
665                                return false;
666                }       // If used END
667                else
668                        return false;
669        }       // If initialized END
670        return false;
671}
672
673bool visual_skySilverLining::getSlotPrecipitation( int slot_, double& rate_mmPerHour_rain, double& rate_mmPerHour_drySnow, double& rate_mmPerHour_wetSnow, double& rate_mmPerHour_sleet )
674{
675        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
676        {
677                if( cloudLayerSlots[slot_].used )       // IF used, Pointer should be valid
678                {
679                        rate_mmPerHour_rain = 0;
680                        rate_mmPerHour_drySnow = 0;
681                        rate_mmPerHour_wetSnow = 0;
682                        rate_mmPerHour_sleet = 0;
683
684                        // Check for precipitation
685
686                                SL_MAP (int, double) precipitationMap = cloudLayerSlots[slot_].cloudLayerPointer->GetPrecipitation();
687                                for( SL_MAP (int, double)::iterator it = precipitationMap.begin(); it != precipitationMap.end(); it++ )
688                                {
689                                        switch(it->first)
690                                        {
691                                                case SilverLining::CloudLayer::RAIN : rate_mmPerHour_rain = it->second;
692                                                        break;
693                                                case SilverLining::CloudLayer::DRY_SNOW : rate_mmPerHour_drySnow = it->second;
694                                                        break;
695                                                case SilverLining::CloudLayer::WET_SNOW : rate_mmPerHour_wetSnow = it->second;
696                                                        break;
697                                                case SilverLining::CloudLayer::SLEET : rate_mmPerHour_sleet = it->second;
698                                                        break;
699                                                default: OSG_NOTIFY( osg::FATAL ) << "ERROR: visual_skySilverLining::getSlotPrecipitation() : Wrong precipitation type in map!" << std::endl;
700                                                        break;
701                                        };
702                                }       // FOR END
703                               
704                                if ( rate_mmPerHour_rain>0 || rate_mmPerHour_drySnow>0 || rate_mmPerHour_wetSnow>0 || rate_mmPerHour_sleet>0)
705                                {
706                                        OSG_NOTIFY( osg::ALWAYS ) << "Rain: " << rate_mmPerHour_rain << ", dry snow: " << rate_mmPerHour_drySnow << ", wet snow: " << rate_mmPerHour_wetSnow << ", sleet: " << rate_mmPerHour_sleet << std::endl;
707                                        return true;
708                                }
709                                else
710                                        return false;
711                }       // If used END
712                else
713                        return false;
714        }       // If initialized END
715        return false;
716}
717
718void visual_skySilverLining::clearAllPrecipitation( int slot_ )
719{
720        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
721        {
722                if( cloudLayerSlots[slot_].used )       // IF used, Pointer should be valid
723                {
724                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::NONE, 0.0 );
725                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::NONE, 0.0 ); // Second Call to clear precipitation rate.
726                }
727        }
728}
729
730void visual_skySilverLining::setSlotPrecipitation( int slot_, double rate_mmPerHour_rain_, double rate_mmPerHour_drySnow_, double rate_mmPerHour_wetSnow_, double rate_mmPerHour_sleet_ )
731{
732        if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
733        {
734                if( cloudLayerSlots[slot_].used )       // IF used, Pointer should be valid
735                {
736                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::RAIN, rate_mmPerHour_rain_ );
737                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::DRY_SNOW, rate_mmPerHour_drySnow_ );
738                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::WET_SNOW, rate_mmPerHour_wetSnow_ );
739                        cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::SLEET, rate_mmPerHour_sleet_ );
740                }
741        }
742}
743
744void visual_skySilverLining::configureCloudlayerbyXML( xmlNode* cloudlayerNode_ )
745{
746        std::string node_name=reinterpret_cast<const char*>(cloudlayerNode_->name);
747        if(cloudlayerNode_->type == XML_ELEMENT_NODE && node_name == "clouds")
748        {
749                for (cloudlayerNode_= cloudlayerNode_->children; cloudlayerNode_; cloudlayerNode_ = cloudlayerNode_->next)
750                {
751                        node_name=reinterpret_cast<const char*>(cloudlayerNode_->name);
752                        if(cloudlayerNode_->type == XML_ELEMENT_NODE && node_name == "cloudlayer")
753                        {
754                                int slot = -1;
755                                bool enabled;
756                                int fadetime = -1, baselength = -1, basewidth = -1, thickness = -1, baseHeight = -1 ;
757                                float density = -1.0, rate_mmPerHour_rain = -1.0, rate_mmPerHour_drySnow = -1.0, rate_mmPerHour_wetSnow = -1.0, rate_mmPerHour_sleet = -1.0;
758                                CloudTypes ctype = CUMULUS_CONGESTUS; 
759
760                                xmlAttr  *attr = cloudlayerNode_->properties;
761                                while ( attr ) 
762                                { 
763                                        std::string attr_name=reinterpret_cast<const char*>(attr->name);
764                                        std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
765                                        if( attr_name == "slot" ) slot = util::strToInt(attr_value);
766                                        if( attr_name == "enabled" ) enabled = util::strToBool(attr_value);
767                                        if( attr_name == "fadetime" ) fadetime = util::strToInt(attr_value);
768                                        if( attr_name == "type" )
769                                        {
770                                                if(attr_value=="CIRROCUMULUS")
771                                                        ctype = CIRROCUMULUS;
772                                                if(attr_value=="CIRRUS_FIBRATUS")
773                                                        ctype = CIRRUS_FIBRATUS;
774                                                if(attr_value=="STRATUS")
775                                                        ctype = STRATUS;
776                                                if(attr_value=="CUMULUS_MEDIOCRIS")
777                                                        ctype = CUMULUS_MEDIOCRIS;
778                                                if(attr_value=="CUMULUS_CONGESTUS")
779                                                        ctype = CUMULUS_CONGESTUS;
780                                                if(attr_value=="CUMULONIMBUS_CAPPILATUS")
781                                                        ctype = CUMULONIMBUS_CAPPILATUS;
782                                                if(attr_value=="STRATOCUMULUS")
783                                                        ctype = STRATOCUMULUS;
784                                        }
785                                        attr = attr->next; 
786                                }
787
788                                if(!cloudlayerNode_->children)
789                                {
790                                        OSG_NOTIFY( osg::ALWAYS ) << "ERROR - visual_skySilverLining::configureCloudlayerbyXML: Missing geometry specification for a cloudlayer." << std::endl;
791                                        return;
792                                }
793
794                                for (xmlNode *cur_node = cloudlayerNode_->children; cur_node; cur_node = cur_node->next)
795                                {
796                                        node_name=reinterpret_cast<const char*>(cur_node->name);
797                                        if(cur_node->type == XML_ELEMENT_NODE && node_name == "geometry")
798                                        {
799                                                xmlAttr  *attr = cur_node->properties;
800                                                while ( attr ) 
801                                                { 
802                                                        std::string attr_name=reinterpret_cast<const char*>(attr->name);
803                                                        std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
804                                                        if( attr_name == "baselength" ) baselength = util::strToInt(attr_value);
805                                                        if( attr_name == "basewidth" )  basewidth = util::strToInt(attr_value);
806                                                        if( attr_name == "thickness" )  thickness = util::strToInt(attr_value);
807                                                        if( attr_name == "baseHeight" ) baseHeight = util::strToInt(attr_value);
808                                                        if( attr_name == "density" ) density = util::strToDouble(attr_value);
809
810                                                        attr = attr->next; 
811                                                }
812                                        }
813
814                                        if(cur_node->type == XML_ELEMENT_NODE && node_name == "precipitation")
815                                        {
816                                                xmlAttr  *attr = cur_node->properties;
817                                                while ( attr ) 
818                                                { 
819                                                        std::string attr_name=reinterpret_cast<const char*>(attr->name);
820                                                        std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
821                                                        if( attr_name == "rate_mmPerHour_rain" ) rate_mmPerHour_rain = util::strToDouble(attr_value);
822                                                        if( attr_name == "rate_mmPerHour_drySnow" ) rate_mmPerHour_drySnow = util::strToDouble(attr_value);
823                                                        if( attr_name == "rate_mmPerHour_wetSnow" ) rate_mmPerHour_wetSnow = util::strToDouble(attr_value);
824                                                        if( attr_name == "rate_mmPerHour_sleet" ) rate_mmPerHour_sleet = util::strToDouble(attr_value);
825
826                                                        attr = attr->next; 
827                                                }
828                                        }
829                                }
830
831                                if(slot!=-1 && baselength!=-1 && basewidth!=-1 && thickness!=-1 && baseHeight!=-1 && density!=-1 )
832                                        addCloudLayer( slot, baselength, basewidth, thickness, baseHeight, density, ctype );
833
834                                if(slot!=-1 && rate_mmPerHour_rain!=-1 && rate_mmPerHour_drySnow!=-1 && thickness!=-1 && baseHeight!=-1 && density!=-1 )
835                                        setSlotPrecipitation( slot, rate_mmPerHour_rain, rate_mmPerHour_drySnow, rate_mmPerHour_wetSnow, rate_mmPerHour_sleet );
836                        }       // If Node = cloudlayer END
837                }       // FOR-loop end
838        }       // If Clouds END
839                else
840        OSG_NOTIFY( osg::ALWAYS ) << "ERROR - visual_skySilverLining::configureCloudlayerbyXML: Node is not a <clouds> node." << std::endl;
841}
Note: See TracBrowser for help on using the repository browser.