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

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

working commit for backup purposes, not compiling at this stage.. sorry, will be corrected tomorrow

File size: 28.3 KB
Line 
1/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
2 *
3 * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
9 * You have to aquire licenses for all used proprietary modules.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * OpenSceneGraph Public License for more details.
15*/
16
17#include <visual_skySilverLining.h>
18
19using namespace osgVisual;
20
21visual_skySilverLining::visual_skySilverLining(osgViewer::Viewer* viewer_, 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 == "cloudlayer")
749        {
750                int slot = -1;
751                bool enabled;
752                int fadetime = -1, baselength = -1, basewidth = -1, thickness = -1, baseHeight = -1 ;
753                float density = -1.0, rate_mmPerHour_rain = -1.0, rate_mmPerHour_drySnow = -1.0, rate_mmPerHour_wetSnow = -1.0, rate_mmPerHour_sleet = -1.0;
754                CloudTypes ctype = CUMULUS_CONGESTUS; 
755
756
757
758                xmlAttr  *attr = cloudlayerNode_->properties;
759                while ( attr ) 
760                { 
761                        std::string attr_name=reinterpret_cast<const char*>(attr->name);
762                        std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
763                        if( attr_name == "slot" )
764                        {
765                                std::stringstream sstr(attr_value);
766                                sstr >> slot;
767                        }
768                        if( attr_name == "enabled" )
769                        {
770                                if(attr_value=="yes")
771                                        enabled = true;
772                                else
773                                        enabled = false;
774                        }
775                        if( attr_name == "fadetime" )
776                        {
777                                std::stringstream sstr(attr_value);
778                                sstr >> fadetime;
779                        }
780                        if( attr_name == "type" )
781                        {
782                                if(attr_value=="CIRROCUMULUS")
783                                        ctype = CIRROCUMULUS;
784                                if(attr_value=="CIRRUS_FIBRATUS")
785                                        ctype = CIRRUS_FIBRATUS;
786                                if(attr_value=="STRATUS")
787                                        ctype = STRATUS;
788                                if(attr_value=="CUMULUS_MEDIOCRIS")
789                                        ctype = CUMULUS_MEDIOCRIS;
790                                if(attr_value=="CUMULUS_CONGESTUS")
791                                        ctype = CUMULUS_CONGESTUS;
792                                if(attr_value=="CUMULONIMBUS_CAPPILATUS")
793                                        ctype = CUMULONIMBUS_CAPPILATUS;
794                                if(attr_value=="STRATOCUMULUS")
795                                        ctype = STRATOCUMULUS;
796                        }
797                        attr = attr->next; 
798                }
799
800                cloudlayerNode_ = cloudlayerNode_->children;
801                if(!cloudlayerNode_)
802                {
803                        OSG_NOTIFY( osg::ALWAYS ) << "ERROR - visual_skySilverLining::configureCloudlayerbyXML: Missing geometry specification for a cloudlayer." << std::endl;
804                        return;
805                }
806
807                for (xmlNode *cur_node = cloudlayerNode_; cur_node; cur_node = cur_node->next)
808                {
809                        if(cur_node->type == XML_ELEMENT_NODE && node_name == "geometry")
810                        {
811                                xmlAttr  *attr = cloudlayerNode_->properties;
812                                while ( attr ) 
813                                { 
814                                        std::string attr_name=reinterpret_cast<const char*>(attr->name);
815                                        std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
816                                        if( attr_name == "baselength" )
817                                        {
818                                                std::stringstream sstr(attr_value);
819                                                sstr >> baselength;
820                                        }
821                                        if( attr_name == "basewidth" )
822                                        {
823                                                std::stringstream sstr(attr_value);
824                                                sstr >> basewidth;
825                                        }
826                                        if( attr_name == "thickness" )
827                                        {
828                                                std::stringstream sstr(attr_value);
829                                                sstr >> thickness;
830                                        }
831                                        if( attr_name == "baseHeight" )
832                                        {
833                                                std::stringstream sstr(attr_value);
834                                                sstr >> baseHeight;
835                                        }
836                                        if( attr_name == "density" )
837                                        {
838                                                std::stringstream sstr(attr_value);
839                                                sstr >> density;
840                                        }
841                                        attr = attr->next; 
842                                }
843                        }
844
845                        if(cur_node->type == XML_ELEMENT_NODE && node_name == "precipitation")
846                        {
847                                xmlAttr  *attr = cloudlayerNode_->properties;
848                                while ( attr ) 
849                                { 
850                                        std::string attr_name=reinterpret_cast<const char*>(attr->name);
851                                        std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
852                                        if( attr_name == "rate_mmPerHour_rain" )
853                                        {
854                                                std::stringstream sstr(attr_value);
855                                                sstr >> rate_mmPerHour_rain;
856                                        }
857                                        if( attr_name == "rate_mmPerHour_drySnow" )
858                                        {
859                                                std::stringstream sstr(attr_value);
860                                                sstr >> rate_mmPerHour_drySnow;
861                                        }
862                                        if( attr_name == "rate_mmPerHour_wetSnow" )
863                                        {
864                                                std::stringstream sstr(attr_value);
865                                                sstr >> rate_mmPerHour_wetSnow;
866                                        }
867                                        if( attr_name == "rate_mmPerHour_sleet" )
868                                        {
869                                                std::stringstream sstr(attr_value);
870                                                sstr >> rate_mmPerHour_sleet;
871                                        }
872                                        attr = attr->next; 
873                                }
874                        }
875                }
876
877                if(slot!=-1 && baselength!=-1 && basewidth!=-1 && thickness!=-1 && baseHeight!=-1 && density!=-1 )
878                        addCloudLayer( slot, baselength, basewidth, thickness, baseHeight, density, ctype );
879
880                if(slot!=-1 && rate_mmPerHour_rain!=-1 && rate_mmPerHour_drySnow!=-1 && thickness!=-1 && baseHeight!=-1 && density!=-1 )
881                        setSlotPrecipitation( slot, rate_mmPerHour_rain, rate_mmPerHour_drySnow, rate_mmPerHour_wetSnow, rate_mmPerHour_sleet );
882        }
883        else
884                OSG_NOTIFY( osg::ALWAYS ) << "ERROR - visual_skySilverLining::configureCloudlayerbyXML: Node is not a cloudlayer node." << std::endl;
885}
Note: See TracBrowser for help on using the repository browser.