//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
-// Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
//
#include <simgear/compiler.h>
#include <vector>
+#include <osgDB/ReaderWriter>
-SG_USING_STD(vector);
+#include <osg/ref_ptr>
+#include <osg/Array>
+#include <osg/Geometry>
+#include <osg/Group>
+#include <osg/Switch>
-class SGNewCloud;
+namespace osg
+{
+ class Fog;
+ class StateSet;
+ class Vec4f;
+}
-class culledCloud {
-public:
- SGNewCloud *aCloud;
- sgVec3 eyePos;
- float dist;
- bool operator<(const culledCloud &b) const {
- return this->dist < b.dist;
- }
-};
-typedef vector<culledCloud> list_of_culledCloud;
+#include <simgear/misc/sg_path.hxx>
+#include <simgear/structure/Singleton.hxx>
+
+using std::vector;
+
+class SGNewCloud;
+/**
+ * A layer of 3D clouds.
+ */
class SGCloudField {
private:
SGNewCloud *aCloud;
sgVec3 pos;
bool visible;
-// float dist;
-// bool culled;
-
-// bool operator<(const Cloud &b) {
-// return this->dist < b.dist;
-// }
};
+ float Rnd(float);
+
+ // We create a quadtree two levels deep
+ static const int BRANCH_SIZE = 16;
+ static const int QUADTREE_SIZE = 32;
- typedef vector<Cloud> list_of_Cloud;
-
- // cull all clouds of a tiled field
- void cullClouds(sgVec3 eyePos, sgMat4 mat);
-
- void applyDensity(void);
-
- 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;
+ // double lon, lat;
- sgFrustum frustum;
+ osg::ref_ptr<osg::Group> field_root;
+ osg::ref_ptr<osg::MatrixTransform> field_transform;
+ osg::ref_ptr<osg::PositionAttitudeTransform> altitude_transform;
+ osg::ref_ptr<osg::Switch> field_group[QUADTREE_SIZE][QUADTREE_SIZE];
+ osg::ref_ptr<osg::LOD> quad[BRANCH_SIZE][BRANCH_SIZE];
+
+ osg::ref_ptr<osg::LOD> field_lod;
- sgMat4 transform;
double deltax, deltay, alt;
- double last_lon, last_lat, last_course;
-
- float last_density;
-
+ double last_course;
+ sgSphere field_sphere;
+ float last_coverage;
+ float coverage;
+ SGGeoc cld_pos;
+ int reposition_count;
+ struct CloudFog : public simgear::Singleton<CloudFog>
+ {
+ CloudFog();
+ osg::ref_ptr<osg::Fog> fog;
+ };
public:
SGCloudField();
~SGCloudField();
- // 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(void);
+ void clear(void);
- // reposition the cloud layer at the specified origin and orientation
- void reposition( sgVec3 p, sgVec3 up, double lon, double lat, double alt, double dt);
+ // add one cloud, data is not copied, ownership given
+ void addCloud( SGVec3f& pos, SGNewCloud *cloud);
+
+ /**
+ * 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
+ */
+ bool reposition( const SGVec3f& p, const SGVec3f& up,
+ double lon, double lat, double dt, int asl);
+
+ osg::Group* getNode() { return field_root.get(); }
// visibility distance for clouds in meters
static float CloudVis;
- static float density;
-
- 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);
+ static sgVec3 view_vec, view_X, view_Y;
+
+ static float view_distance;
+ static double timer_dt;
+ static float fieldSize;
+
+ bool defined3D;
+
+ float getCoverage(void) { return coverage; }
+ void setCoverage(float c) { coverage = c; }
+
+ static float getVisRange(void) { return view_distance; }
+ static void setVisRange(float d) { view_distance = d; }
+
+ void applyCoverage(void);
+ void applyVisRange(void);
+
+ typedef std::map<std::string, osg::ref_ptr<osg::StateSet> > StateSetMap;
+ static StateSetMap cloudTextureMap;
+
+ static osg::Fog* getFog()
+ {
+ return CloudFog::instance()->fog.get();
+ }
+ static void updateFog(double visibility, const osg::Vec4f& color);
};
#endif // _CLOUDFIELD_HXX