using std::vector;
-#include <simgear/environment/visual_enviro.hxx>
+//#include <simgear/environment/visual_enviro.hxx>
#include <simgear/scene/util/RenderConstants.hxx>
#include <simgear/scene/util/SGUpdateVisitor.hxx>
#include "sky.hxx"
double SGCloudField::timer_dt = 0.0;
float SGCloudField::view_distance = 20000.0f;
bool SGCloudField::wrap = true;
+float SGCloudField::RADIUS_LEVEL_1 = 20000.0f;
+float SGCloudField::RADIUS_LEVEL_2 = 5000.0f;
SGVec3f SGCloudField::view_vec, SGCloudField::view_X, SGCloudField::view_Y;
// Always update the altitude transform, as this allows
// the clouds to rise and fall smoothly depending on environment updates.
- osg::Vec3f alt = orient * osg::Vec3f(0.0f, 0.0f, (float) asl);
- altitude_transform->setPosition(alt);
+ altitude_transform->setPosition(osg::Vec3f(0.0f, 0.0f, (float) asl));
// Similarly, always determine the effects of the wind
osg::Vec3f wind = osg::Vec3f(-cos((direction + 180)* SGD_DEGREES_TO_RADIANS) * speed * dt,
if (!wrap) {
// If we're not wrapping the cloudfield, then we make no effort to reposition
return false;
- }
+ }
if ((old_pos - osg_pos).length() > fieldSize*2) {
// Big movement - reposition centered to current location.
osg::ref_ptr<osg::PositionAttitudeTransform> pat =(osg::PositionAttitudeTransform*) lodnode2->getChild(k);
pat->setPosition(pat->getPosition() + shift);
}
- }
- }
+ }
+ }
}
}
void SGCloudField::addCloudToTree(osg::ref_ptr<osg::PositionAttitudeTransform> transform,
float lon, float lat, float alt, float x, float y) {
+
+ // Get the base position
+ SGGeod loc = SGGeod::fromDegFt(lon, lat, 0.0);
+
+ // Determine any shift by x/y
+ if ((x != 0.0f) || (y != 0.0f)) {
+ double crs;
+
+ if (y == 0.0f) {
+ crs = (x < 0.0f) ? -90.0 : 90.0;
+ } else {
+ crs = SG_RADIANS_TO_DEGREES * tan(x/y);
+ }
+
+ double dst = sqrt(x*x + y*y);
+ double endcrs;
+
+ SGGeod base_pos = SGGeod::fromDegFt(lon, lat, 0.0f);
+ SGGeodesy::direct(base_pos, crs, dst, loc, endcrs);
+ }
+
+ // The direct call provides the position at 0 alt, so adjust as required.
+ loc.setElevationFt(alt);
+
// Work out where this cloud should go in OSG coordinates.
SGVec3<double> cart;
- SGGeodesy::SGGeodToCart(SGGeod::fromDegFt(lon, lat, alt), cart);
+ SGGeodesy::SGGeodToCart(loc, cart);
+ osg::Vec3f pos = toOsg(cart);
- // Convert to the scenegraph orientation where we just rotate around
- // the y axis 180 degrees.
- osg::Quat orient = toOsg(SGQuatd::fromLonLatDeg(lon, lat) * SGQuatd::fromRealImag(0, SGVec3d(0, 1, 0)));
- osg::Vec3f pos = toOsg(cart) + orient * osg::Vec3f(x, y, 0.0f);
if (old_pos == osg::Vec3f(0.0f, 0.0f, 0.0f)) {
- // First se tup.
+ // First setup.
SGVec3<double> fieldcenter;
- SGGeodesy::SGGeodToCart(SGGeod::fromDegFt(lon, lat, 0.0f), fieldcenter);
+ SGGeodesy::SGGeodToCart(SGGeod::fromDegFt(loc.getLongitudeDeg(), loc.getLatitudeDeg(), 0.0f), fieldcenter);
+ // Convert to the scenegraph orientation where we just rotate around
+ // the y axis 180 degrees.
+ osg::Quat orient = toOsg(SGQuatd::fromLonLatDeg(loc.getLongitudeDeg(), loc.getLatitudeDeg()) * SGQuatd::fromRealImag(0, SGVec3d(0, 1, 0)));
field_transform->setPosition(toOsg(fieldcenter));
field_transform->setAttitude(orient);
old_pos = toOsg(fieldcenter);
-}
+ }
pos = pos - field_transform->getPosition();
- pos = orient.inverse() * pos;
+ //pos = orient.inverse() * pos;
+ pos = field_transform->getAttitude().inverse() * pos;
// We have a two level dynamic quad tree which the cloud will be added
// to. If there are no appropriate nodes in the quad tree, they are
// New cloud is within RADIUS_LEVEL_1 of the center of the LOD node.
//cout << "Adding cloud to existing LoD level 1 node. Distance:" << (lodnode1->getCenter() - pos).length() << "\n";
found = true;
- }
- }
+ }
+ }
if (!found) {
lodnode1 = new osg::LOD();
placed_root->addChild(lodnode1.get());
//cout << "Adding cloud to new LoD node\n";
- }
+ }
// Now check if there is a second level LOD node at an appropriate distance
found = false;