* 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/math/SGMath.hxx>
#include <simgear/scene/sky/sky.hxx>
#include <simgear/scene/sky/cloud.hxx>
#include <Main/fg_props.hxx>
+#include <Main/globals.hxx>
+#include <Scenery/scenery.hxx>
#include "precipitation_mgr.hxx"
extern SGSky *thesky;
-void WorldCoordinate( osg::Matrix&, double,
- double, double, double);
-
/**
* @brief FGPrecipitation Manager constructor
*
*/
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);
+ group = new osg::Group();
+ transform = new osg::MatrixTransform();
+ precipitation = new SGPrecipitation();
- // Move the precipitation object to player position
- transform->setMatrix(position);
- transform->addChild(precipitation->build());
+ // By default, no precipitation
+ precipitation->setRainIntensity(0);
+ precipitation->setSnowIntensity(0);
- group->addChild(transform);
+ transform->addChild(precipitation->build());
+ group->addChild(transform.get());
}
*/
FGPrecipitationMgr::~FGPrecipitationMgr()
{
- delete precipitation;
+
}
+/**
+ * SGSubsystem initialization
+ */
+void FGPrecipitationMgr::init()
+{
+ // Read latitude and longitude position
+ SGGeod geod = SGGeod::fromDegM(fgGetDouble("/position/longitude-deg", 0.0),
+ fgGetDouble("/position/latitude-deg", 0.0),
+ 0.0);
+ osg::Matrix position(geod.makeZUpFrame());
+ // Move the precipitation object to player position
+ transform->setMatrix(position);
+ // Add to scene graph
+ osg::Group* scenery = globals->get_scenery()->get_scene_graph();
+ scenery->addChild(getObject());
+}
/**
* @brief Get OSG precipitation object
*/
osg::Group * FGPrecipitationMgr::getObject(void)
{
- return this->group;
+ return this->group.get();
}
*/
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;
+ 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)
+void FGPrecipitationMgr::update(double dt)
{
- 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;
+ 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();
}
-
-
#include <simgear/math/polar3d.hxx>
#include <simgear/math/sg_geodesy.hxx>
#include <simgear/math/sg_random.h>
+#include <simgear/math/SGMath.hxx>
#include <simgear/misc/sgstream.hxx>
#include <simgear/scene/material/mat.hxx>
#include <simgear/scene/material/matlib.hxx>
{
}
-void WorldCoordinate( osg::Matrix& obj_pos, double lat,
- double lon, double elev, double hdg )
+static void WorldCoordinate(osg::Matrix& obj_pos, double lat,
+ double lon, double elev, double hdg)
{
- double lon_rad = lon * SGD_DEGREES_TO_RADIANS;
- double lat_rad = lat * SGD_DEGREES_TO_RADIANS;
- double hdg_rad = hdg * SGD_DEGREES_TO_RADIANS;
-
- // setup transforms
- Point3D geod( lon_rad, lat_rad, elev );
- Point3D world_pos = sgGeodToCart( geod );
-
- double sin_lat = sin( lat_rad );
- double cos_lat = cos( lat_rad );
- double cos_lon = cos( lon_rad );
- double sin_lon = sin( lon_rad );
- double sin_hdg = sin( hdg_rad ) ;
- double cos_hdg = cos( hdg_rad ) ;
-
- obj_pos(0, 0) = cos_hdg * sin_lat * cos_lon - sin_hdg * sin_lon;
- obj_pos(0, 1) = cos_hdg * sin_lat * sin_lon + sin_hdg * cos_lon;
- obj_pos(0, 2) = -cos_hdg * cos_lat;
- obj_pos(0, 3) = SG_ZERO;
-
- obj_pos(1, 0) = -sin_hdg * sin_lat * cos_lon - cos_hdg * sin_lon;
- obj_pos(1, 1) = -sin_hdg * sin_lat * sin_lon + cos_hdg * cos_lon;
- obj_pos(1, 2) = sin_hdg * cos_lat;
- obj_pos(1, 3) = SG_ZERO;
-
- obj_pos(2, 0) = cos_lat * cos_lon;
- obj_pos(2, 1) = cos_lat * sin_lon;
- obj_pos(2, 2) = sin_lat;
- obj_pos(2, 3) = SG_ZERO;
-
- obj_pos(3, 0) = world_pos.x();
- obj_pos(3, 1) = world_pos.y();
- obj_pos(3, 2) = world_pos.z();
- obj_pos(3, 3) = SG_ONE ;
+ SGGeod geod = SGGeod::fromDegM(lon, lat, elev);
+ obj_pos = geod.makeZUpFrame();
+ // hdg is not a compass heading, but a counter-clockwise rotation
+ // around the Z axis
+ obj_pos.preMult(osg::Matrix::rotate(hdg * SGD_DEGREES_TO_RADIANS,
+ 0.0, 0.0, 1.0));
}