precipitation effects from Nicolas Vivien
This commit is contained in:
parent
7a6376021a
commit
eb26cb3590
6 changed files with 307 additions and 2 deletions
|
@ -9,6 +9,7 @@ libEnvironment_a_SOURCES = \
|
|||
environment_mgr.cxx environment_mgr.hxx \
|
||||
environment_ctrl.cxx environment_ctrl.hxx \
|
||||
fgmetar.cxx fgmetar.hxx fgclouds.cxx fgclouds.hxx \
|
||||
atmosphere.cxx atmosphere.hxx
|
||||
atmosphere.cxx atmosphere.hxx \
|
||||
precipitation_mgr.cxx fgprecipitation_mgr.hxx
|
||||
|
||||
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
|
||||
|
|
228
src/Environment/precipitation_mgr.cxx
Normal file
228
src/Environment/precipitation_mgr.cxx
Normal file
|
@ -0,0 +1,228 @@
|
|||
/**
|
||||
* @file precipitation_mgr.cxx
|
||||
* @author Nicolas VIVIEN
|
||||
* @date 2008-02-10
|
||||
*
|
||||
* @note Copyright (C) 2008 Nicolas VIVIEN
|
||||
*
|
||||
* @brief Precipitation manager
|
||||
* This manager calculate the intensity of precipitation in function of the altitude,
|
||||
* calculate the wind direction and velocity, then update the drawing of precipitation.
|
||||
*
|
||||
* @par Licences
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @par CVS
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgDB/FileUtils>
|
||||
#include <osgUtil/Optimizer>
|
||||
#include <osgUtil/CullVisitor>
|
||||
#include <osgViewer/Viewer>
|
||||
|
||||
#include <osg/Depth>
|
||||
#include <osg/Stencil>
|
||||
#include <osg/ClipPlane>
|
||||
#include <osg/ClipNode>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osgUtil/TransformCallback>
|
||||
|
||||
#include <simgear/constants.h>
|
||||
#include <simgear/scene/sky/sky.hxx>
|
||||
#include <simgear/scene/sky/cloud.hxx>
|
||||
|
||||
#include <Main/fg_props.hxx>
|
||||
|
||||
#include "precipitation_mgr.hxx"
|
||||
|
||||
|
||||
extern SGSky *thesky;
|
||||
|
||||
|
||||
void WorldCoordinate( osg::Matrix&, double,
|
||||
double, double, double);
|
||||
|
||||
/**
|
||||
* @brief FGPrecipitation Manager constructor
|
||||
*
|
||||
* Build a new object to manage the precipitation object
|
||||
*/
|
||||
FGPrecipitationMgr::FGPrecipitationMgr()
|
||||
{
|
||||
osg::Matrix position;
|
||||
double latitude, longitude;
|
||||
|
||||
|
||||
group = new osg::Group();
|
||||
transform = new osg::MatrixTransform();
|
||||
precipitation = new SGPrecipitation();
|
||||
|
||||
|
||||
// By default, none precipitation
|
||||
precipitation->setRainIntensity(0);
|
||||
precipitation->setSnowIntensity(0);
|
||||
|
||||
|
||||
// Read latitude and longitude position
|
||||
latitude = fgGetDouble("/position/latitude-deg", 0.0);
|
||||
longitude = fgGetDouble("/position/longitude-deg", 0.0);
|
||||
|
||||
WorldCoordinate(position, latitude, longitude, 0, 0);
|
||||
|
||||
|
||||
// Move the precipitation object to player position
|
||||
transform->setMatrix(position);
|
||||
transform->addChild(precipitation->build());
|
||||
|
||||
group->addChild(transform);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief FGPrecipitaiton Manager destructor
|
||||
*/
|
||||
FGPrecipitationMgr::~FGPrecipitationMgr()
|
||||
{
|
||||
delete precipitation;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get OSG precipitation object
|
||||
*
|
||||
* @returns A pointer on the OSG object (osg::Group *)
|
||||
*/
|
||||
osg::Group * FGPrecipitationMgr::getObject(void)
|
||||
{
|
||||
return this->group;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Calculate the max alitutude with precipitation
|
||||
*
|
||||
* @returns Elevation max in meter
|
||||
*
|
||||
* This function permits you to know what is the altitude max where we can
|
||||
* find precipitation. The value is returned in meter.
|
||||
*/
|
||||
float FGPrecipitationMgr::getPrecipitationAtAltitudeMax(void)
|
||||
{
|
||||
int i;
|
||||
int max;
|
||||
float result;
|
||||
|
||||
|
||||
// By default (not cloud layer)
|
||||
max = SGCloudLayer::SG_MAX_CLOUD_COVERAGES;
|
||||
result = 0;
|
||||
|
||||
// To avoid messing up
|
||||
if (thesky == NULL)
|
||||
return result;
|
||||
|
||||
// For each cloud layer
|
||||
for (i=0; i<thesky->get_cloud_layer_count(); i++) {
|
||||
int q;
|
||||
|
||||
// Get coverage
|
||||
// Value for q are (meaning / thickness) :
|
||||
// 5 : "clear" / 0
|
||||
// 4 : "cirrus" / ??
|
||||
// 3 : "few" / 65
|
||||
// 2 : "scattered" / 600
|
||||
// 1 : "broken" / 750
|
||||
// 0 : "overcast" / 1000
|
||||
q = thesky->get_cloud_layer(i)->getCoverage();
|
||||
|
||||
// Save the coverage max
|
||||
if (q < max) {
|
||||
max = q;
|
||||
result = thesky->get_cloud_layer(i)->getElevation_m();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Update the precipitation drawing
|
||||
*
|
||||
* @returns true is all is OK
|
||||
*
|
||||
* This function permits you to update the precipitation drawing.
|
||||
* This function is called by the renderer.
|
||||
*/
|
||||
bool FGPrecipitationMgr::update(void)
|
||||
{
|
||||
double dewtemp;
|
||||
double currtemp;
|
||||
double rain_intensity;
|
||||
double snow_intensity;
|
||||
|
||||
float altitudeAircraft;
|
||||
float altitudeCloudLayer;
|
||||
|
||||
// Get the elevation of aicraft and of the cloud layer
|
||||
altitudeAircraft = fgGetDouble("/position/altitude-ft", 0.0);
|
||||
altitudeCloudLayer = this->getPrecipitationAtAltitudeMax() * SG_METER_TO_FEET;
|
||||
|
||||
if (altitudeAircraft > altitudeCloudLayer) {
|
||||
// The aircraft is above the cloud layer
|
||||
rain_intensity = 0;
|
||||
snow_intensity = 0;
|
||||
}
|
||||
else {
|
||||
// The aircraft is bellow the cloud layer
|
||||
rain_intensity = fgGetDouble("/environment/metar/rain-norm", 0.0);
|
||||
snow_intensity = fgGetDouble("/environment/metar/snow-norm", 0.0);
|
||||
}
|
||||
|
||||
// Get the current and dew temperature
|
||||
dewtemp = fgGetDouble("/environment/dewpoint-degc", 0.0);
|
||||
currtemp = fgGetDouble("/environment/temperature-degc", 0.0);
|
||||
|
||||
if (currtemp < dewtemp) {
|
||||
// There is fog... and the weather is very steamy
|
||||
if (rain_intensity == 0)
|
||||
rain_intensity = 0.15;
|
||||
}
|
||||
|
||||
// If the current temperature is below 0°C, we turn off the rain to snow...
|
||||
if (currtemp < 0)
|
||||
precipitation->setFreezing(true);
|
||||
else
|
||||
precipitation->setFreezing(false);
|
||||
|
||||
|
||||
// Set the wind property
|
||||
precipitation->setWindProperty(
|
||||
fgGetDouble("/environment/wind-from-heading-deg", 0.0),
|
||||
fgGetDouble("/environment/wind-speed-kt", 0.0));
|
||||
|
||||
// Set the intensity of precipitation
|
||||
precipitation->setRainIntensity(rain_intensity);
|
||||
precipitation->setSnowIntensity(snow_intensity);
|
||||
|
||||
// Update the drawing...
|
||||
precipitation->update();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
55
src/Environment/precipitation_mgr.hxx
Normal file
55
src/Environment/precipitation_mgr.hxx
Normal file
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* @file precipitation_mgr.hxx
|
||||
* @author Nicolas VIVIEN
|
||||
* @date 2008-02-10
|
||||
*
|
||||
* @note Copyright (C) 2008 Nicolas VIVIEN
|
||||
*
|
||||
* @brief Precipitation manager
|
||||
* This manager calculate the intensity of precipitation in function of the altitude,
|
||||
* calculate the wind direction and velocity, then update the drawing of precipitation.
|
||||
*
|
||||
* @par Licences
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @par CVS
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _PRECIPITATION_MGR_HXX
|
||||
#define _PRECIPITATION_MGR_HXX
|
||||
|
||||
#include <simgear/environment/precipitation.hxx>
|
||||
|
||||
#include "precipitation_mgr.hxx"
|
||||
|
||||
|
||||
class FGPrecipitationMgr {
|
||||
private:
|
||||
osg::Group *group;
|
||||
osg::MatrixTransform *transform;
|
||||
SGPrecipitation *precipitation;
|
||||
float getPrecipitationAtAltitudeMax(void);
|
||||
|
||||
|
||||
public:
|
||||
FGPrecipitationMgr();
|
||||
~FGPrecipitationMgr();
|
||||
bool update(void);
|
||||
osg::Group * getObject(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -71,6 +71,7 @@
|
|||
#include <Time/tmp.hxx>
|
||||
#include <Time/fg_timer.hxx>
|
||||
#include <Environment/environment_mgr.hxx>
|
||||
#include <Environment/precipitation_mgr.hxx>
|
||||
#include <GUI/new_gui.hxx>
|
||||
#include <MultiPlayer/multiplaymgr.hxx>
|
||||
|
||||
|
@ -81,6 +82,8 @@
|
|||
#include "main.hxx"
|
||||
|
||||
|
||||
extern FGPrecipitationMgr *fgPrecipitationMgr;
|
||||
|
||||
|
||||
static double real_delta_time_sec = 0.0;
|
||||
double delta_time_sec = 0.0;
|
||||
|
@ -847,6 +850,11 @@ static void fgIdleFunction ( void ) {
|
|||
globals->get_ephem()->getStars(),
|
||||
fgGetNode("/environment", true));
|
||||
|
||||
|
||||
// Precipitation Manager...
|
||||
fgPrecipitationMgr = new FGPrecipitationMgr();
|
||||
|
||||
|
||||
// Initialize MagVar model
|
||||
SGMagVar *magvar = new SGMagVar();
|
||||
globals->set_mag( magvar );
|
||||
|
|
|
@ -99,6 +99,7 @@
|
|||
#include <GUI/new_gui.hxx>
|
||||
#include <Instrumentation/instrument_mgr.hxx>
|
||||
#include <Instrumentation/HUD/HUD.hxx>
|
||||
#include <Environment/precipitation_mgr.hxx>
|
||||
|
||||
#include <Include/general.hxx>
|
||||
#include "splash.hxx"
|
||||
|
@ -386,6 +387,9 @@ public:
|
|||
// Sky structures
|
||||
SGSky *thesky;
|
||||
|
||||
// Precipitations
|
||||
FGPrecipitationMgr *fgPrecipitationMgr;
|
||||
|
||||
static osg::ref_ptr<osg::FrameStamp> mFrameStamp = new osg::FrameStamp;
|
||||
static osg::ref_ptr<SGUpdateVisitor> mUpdateVisitor= new SGUpdateVisitor;
|
||||
|
||||
|
@ -501,6 +505,11 @@ FGRenderer::init( void ) {
|
|||
stateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||
stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
|
||||
|
||||
|
||||
// Add Precipitation object
|
||||
sceneGroup->addChild( fgPrecipitationMgr->getObject() );
|
||||
|
||||
|
||||
// need to update the light on every frame
|
||||
osg::LightSource* lightSource = new osg::LightSource;
|
||||
lightSource->setUpdateCallback(new FGLightSourceUpdateCallback);
|
||||
|
@ -790,6 +799,10 @@ FGRenderer::update( bool refresh_camera_settings ) {
|
|||
// current_view_origin_airspeed_horiz_kt
|
||||
// );
|
||||
|
||||
// Update precipitation informations...
|
||||
fgPrecipitationMgr->update();
|
||||
|
||||
|
||||
// OSGFIXME
|
||||
// if( is_internal )
|
||||
// shadows->endOfFrame();
|
||||
|
|
|
@ -165,7 +165,7 @@ FGTileEntry::~FGTileEntry ()
|
|||
{
|
||||
}
|
||||
|
||||
static void WorldCoordinate( osg::Matrix& obj_pos, double lat,
|
||||
void WorldCoordinate( osg::Matrix& obj_pos, double lat,
|
||||
double lon, double elev, double hdg )
|
||||
{
|
||||
double lon_rad = lon * SGD_DEGREES_TO_RADIANS;
|
||||
|
|
Loading…
Reference in a new issue