#ifndef _CLOUDFIELD_HXX
#define _CLOUDFIELD_HXX
-#include <plib/sg.h>
#include <simgear/compiler.h>
#include <vector>
+#include <map>
+#include <osgDB/ReaderWriter>
+
+#include <osg/ref_ptr>
+#include <osg/Array>
+#include <osg/Geometry>
+#include <osg/Group>
+#include <osg/Switch>
+
+namespace osg
+{
+ class Fog;
+ class StateSet;
+ class Vec4f;
+}
+
+#include <simgear/misc/sg_path.hxx>
+#include <simgear/structure/Singleton.hxx>
+#include <simgear/math/SGMath.hxx>
using std::vector;
class SGNewCloud;
-class culledCloud {
-public:
- SGNewCloud *aCloud;
- sgVec3 eyePos;
- float dist;
- float heading;
- float alt;
- bool operator<(const culledCloud &b) const {
- return (this->dist < b.dist);
- }
-};
-typedef vector<culledCloud> list_of_culledCloud;
+namespace simgear
+{
+ class EffectGeode;
+}
+
+typedef std::map<int, osg::ref_ptr<osg::PositionAttitudeTransform> > CloudHash;
/**
- * A layer of 3D clouds.
+ * A layer of 3D clouds, defined by lat/long/alt.
*/
class SGCloudField {
class Cloud {
public:
SGNewCloud *aCloud;
- sgVec3 pos;
+ SGVec3f pos;
bool visible;
};
+ float Rnd(float);
+
+ // Radius of the LoD nodes for the dynamic quadtrees.
+ static float RADIUS_LEVEL_1;
+ static float RADIUS_LEVEL_2;
- typedef vector<Cloud> list_of_Cloud;
-
- // cull all clouds of a tiled field
- void cullClouds(sgVec3 eyePos, sgMat4 mat);
+ // this is a relative position only, with that we can move all clouds at once
+ SGVec3f relative_position;
- void applyDensity(void);
+ osg::ref_ptr<osg::Group> field_root;
+ osg::ref_ptr<osg::Group> placed_root;
+ osg::ref_ptr<osg::PositionAttitudeTransform> field_transform;
+ osg::ref_ptr<osg::PositionAttitudeTransform> altitude_transform;
+ osg::ref_ptr<osg::LOD> field_lod;
- list_of_Cloud theField;
- // this is a relative position only, with that we can move all clouds at once
- sgVec3 relative_position;
-// double lon, lat;
+ osg::Vec3f old_pos;
+ CloudHash cloud_hash;
- sgFrustum frustum;
+ struct CloudFog : public simgear::Singleton<CloudFog>
+ {
+ CloudFog();
+ osg::ref_ptr<osg::Fog> fog;
+ };
- sgMat4 transform;
- double deltax, deltay, alt;
- double last_lon, last_lat, last_course;
- sgSphere field_sphere;
- float last_density;
- bool draw_in_3d;
+ void removeCloudFromTree(osg::ref_ptr<osg::PositionAttitudeTransform> transform);
+ void addCloudToTree(osg::ref_ptr<osg::PositionAttitudeTransform> transform, float lon, float lat, float alt, float x, float y);
+ void applyVisRangeAndCoverage(void);
public:
~SGCloudField();
void clear(void);
+ bool isDefined3D(void);
// add one cloud, data is not copied, ownership given
- void addCloud( sgVec3 pos, SGNewCloud *cloud);
-
- // for debug only
- void buildTestLayer(void);
-
- // Render a cloud field
- void Render( float *sun_color );
-
- // reposition the cloud layer at the specified origin and orientation
- void reposition( sgVec3 p, sgVec3 up, double lon, double lat, double alt, double dt, float direction, float speed);
-
- bool is3D(void) { return draw_in_3d; }
-
- // visibility distance for clouds in meters
- static float CloudVis;
-
- static sgVec3 view_vec, view_X, view_Y;
-
- static float density;
- static double timer_dt;
- static double fieldSize;
- static bool enable3D;
-
- // return the size of the memory pool used by texture impostors
- static int get_CacheSize(void);
- static int get_CacheResolution(void);
- static float get_CloudVis(void) { return CloudVis; }
- static float get_density(void) { return density; }
- static bool get_enable3dClouds(void) { return enable3D; }
-
- static void set_CacheSize(int sizeKb);
- static void set_CacheResolution(int resolutionPixels);
- static void set_CloudVis(float distance);
- static void set_density(float density);
- static void set_enable3dClouds(bool enable);
+ void addCloud( SGVec3f& pos, osg::ref_ptr<simgear::EffectGeode> cloud);
+
+ /**
+ * Add a new cloud with a given index at a specific point defined by lon/lat and an x/y offset
+ */
+ bool addCloud(float lon, float lat, float alt, int index, osg::ref_ptr<simgear::EffectGeode> geode);
+ bool addCloud(float lon, float lat, float alt, float x, float y, int index, osg::ref_ptr<simgear::EffectGeode> geode);
+
+ // Cloud handling functions.
+ bool deleteCloud(int identifier);
+ bool repositionCloud(int identifier, float lon, float lat, float alt);
+ bool repositionCloud(int identifier, float lon, float lat, float alt, float x, float y);
+
+
+ /**
+ * reposition the cloud layer at the specified origin and
+ * orientation.
+ * @param p position vector
+ * @param up the local up vector
+ * @param lon specifies a rotation about the Z axis
+ * @param lat specifies a rotation about the new Y axis
+ * @param dt the time elapsed since the last call
+ * @param asl altitude of the layer
+ * @param speed of cloud layer movement (due to wind)
+ * @param direction of cloud layer movement (due to wind)
+ */
+ bool reposition( const SGVec3f& p, const SGVec3f& up,
+ double lon, double lat, double dt, int asl, float speed, float direction);
+
+ osg::Group* getNode() { return field_root.get(); }
+
+ // visibility distance for clouds in meters
+ static float CloudVis;
+
+ static SGVec3f view_vec, view_X, view_Y;
+
+ static float view_distance;
+ static double timer_dt;
+ static float fieldSize;
+ static bool wrap;
+
+ static bool getWrap(void) { return wrap; }
+ static void setWrap(bool w) { wrap = w; }
+
+ static float getVisRange(void) { return view_distance; }
+ static void setVisRange(float d) { view_distance = d; }
+ void applyVisRange(void);
+
+ static osg::Fog* getFog()
+ {
+ return CloudFog::instance()->fog.get();
+ }
+ static void updateFog(double visibility, const osg::Vec4f& color);
};
#endif // _CLOUDFIELD_HXX