1
0
Fork 0

Stuart Buchanan:

Improvements to the cloudsystem:
        - A new xml format
        - Texture indexing based on the position of the sprite in the cloud
          mass, allowing more control over the texture set.
        - Improved fog and shading
        - Better sprite distribution
        - A more natural distribution of clouds, so no more obvious grids.
This commit is contained in:
durk 2009-10-02 05:44:56 +00:00 committed by Tim Moore
parent 4023bdaf26
commit 47a7952f89
7 changed files with 117 additions and 79 deletions

View file

@ -33,6 +33,7 @@
#include <string> #include <string>
#include <math.h> #include <math.h>
#include <time.h> #include <time.h>
#ifdef _MSC_VER #ifdef _MSC_VER
# include <float.h> # include <float.h>
# define finite _finite # define finite _finite

View file

@ -74,9 +74,11 @@ void FGClouds::init(void) {
} }
} }
void FGClouds::buildCloud(SGPropertyNode *cloud_def_root, SGPropertyNode *box_def_root, const string& name, sgVec3 pos, SGCloudField *layer) { // Build an invidual cloud. Returns the extents of the cloud for coverage calculations
double FGClouds::buildCloud(SGPropertyNode *cloud_def_root, SGPropertyNode *box_def_root, const string& name, double grid_z_rand, SGCloudField *layer) {
SGPropertyNode *box_def=NULL; SGPropertyNode *box_def=NULL;
SGPropertyNode *cld_def=NULL; SGPropertyNode *cld_def=NULL;
double extent = 0.0;
SGPath texture_root = globals->get_fg_root(); SGPath texture_root = globals->get_fg_root();
texture_root.append("Textures"); texture_root.append("Textures");
@ -90,55 +92,97 @@ void FGClouds::buildCloud(SGPropertyNode *cloud_def_root, SGPropertyNode *box_de
box_def = box_def_root->getChild(base_name.c_str()); box_def = box_def_root->getChild(base_name.c_str());
} }
if( !box_def ) if( !box_def )
return; return 0.0;
} }
double x = sg_random() * SGCloudField::fieldSize - (SGCloudField::fieldSize / 2.0);
double y = sg_random() * SGCloudField::fieldSize - (SGCloudField::fieldSize / 2.0);
double z = grid_z_rand * (sg_random() - 0.5);
sgVec3 pos={x,y,z};
for(int i = 0; i < box_def->nChildren() ; i++) { for(int i = 0; i < box_def->nChildren() ; i++) {
SGPropertyNode *abox = box_def->getChild(i); SGPropertyNode *abox = box_def->getChild(i);
if( strcmp(abox->getName(), "box") == 0) { if( strcmp(abox->getName(), "box") == 0) {
double x = abox->getDoubleValue("x") + pos[0];
double y = abox->getDoubleValue("y") + pos[1];
double z = abox->getDoubleValue("z") + pos[2];
SGVec3f newpos = SGVec3f(x, z, y);
string type = abox->getStringValue("type", "cu-small"); string type = abox->getStringValue("type", "cu-small");
cld_def = cloud_def_root->getChild(type.c_str()); cld_def = cloud_def_root->getChild(type.c_str());
if ( !cld_def ) return; if ( !cld_def ) return 0.0;
double min_width = cld_def->getDoubleValue("min-cloud-width-m", 500.0); double w = abox->getDoubleValue("width", 1000.0);
double max_width = cld_def->getDoubleValue("max-cloud-width-m", 1000.0); double h = abox->getDoubleValue("height", 1000.0);
double min_height = cld_def->getDoubleValue("min-cloud-height-m", min_width); int hdist = abox->getIntValue("hdist", 1);
double max_height = cld_def->getDoubleValue("max-cloud-height-m", max_width); int vdist = abox->getIntValue("vdist", 1);
double min_sprite_width = cld_def->getDoubleValue("min-sprite-width-m", 200.0);
double max_sprite_width = cld_def->getDoubleValue("max-sprite-width-m", min_sprite_width);
double min_sprite_height = cld_def->getDoubleValue("min-sprite-height-m", min_sprite_width);
double max_sprite_height = cld_def->getDoubleValue("max-sprite-height-m", max_sprite_width);
int num_sprites = cld_def->getIntValue("num-sprites", 20);
int num_textures_x = cld_def->getIntValue("num-textures-x", 1);
int num_textures_y = cld_def->getIntValue("num-textures-y", 1);
double bottom_shade = cld_def->getDoubleValue("bottom-shade", 1.0);
string texture = cld_def->getStringValue("texture", "cl_cumulus.rgb");
SGNewCloud *cld = double c = abox->getDoubleValue("count", 5);
new SGNewCloud(type, int count = (int) (c + (sg_random() - 0.5) * c);
texture_root,
texture, extent = max(w*w, extent);
min_width,
max_width, for (int j = 0; j < count; j++) {
min_height,
max_height, // Locate the clouds randomly in the defined space. The hdist and
min_sprite_width, // vdist values control the horizontal and vertical distribution
max_sprite_width, // by simply summing random components.
min_sprite_height, double x = 0.0;
max_sprite_height, double y = 0.0;
bottom_shade, double z = 0.0;
num_sprites,
num_textures_x, for (int k = 0; k < hdist; k++)
num_textures_y); {
layer->addCloud(newpos, cld); x += (sg_random() / hdist);
y += (sg_random() / hdist);
}
for (int k = 0; k < vdist; k++)
{
z += (sg_random() / vdist);
}
x = w * (x - 0.5) + pos[0]; // N/S
y = w * (y - 0.5) + pos[1]; // E/W
z = h * z + pos[2]; // Up/Down. pos[2] is the cloudbase
SGVec3f newpos = SGVec3f(x, y, z);
double min_width = cld_def->getDoubleValue("min-cloud-width-m", 500.0);
double max_width = cld_def->getDoubleValue("max-cloud-width-m", 1000.0);
double min_height = cld_def->getDoubleValue("min-cloud-height-m", min_width);
double max_height = cld_def->getDoubleValue("max-cloud-height-m", max_width);
double min_sprite_width = cld_def->getDoubleValue("min-sprite-width-m", 200.0);
double max_sprite_width = cld_def->getDoubleValue("max-sprite-width-m", min_sprite_width);
double min_sprite_height = cld_def->getDoubleValue("min-sprite-height-m", min_sprite_width);
double max_sprite_height = cld_def->getDoubleValue("max-sprite-height-m", max_sprite_width);
int num_sprites = cld_def->getIntValue("num-sprites", 20);
int num_textures_x = cld_def->getIntValue("num-textures-x", 1);
int num_textures_y = cld_def->getIntValue("num-textures-y", 1);
double bottom_shade = cld_def->getDoubleValue("bottom-shade", 1.0);
string texture = cld_def->getStringValue("texture", "cu.png");
SGNewCloud *cld =
new SGNewCloud(type,
texture_root,
texture,
min_width,
max_width,
min_height,
max_height,
min_sprite_width,
max_sprite_width,
min_sprite_height,
max_sprite_height,
bottom_shade,
num_sprites,
num_textures_x,
num_textures_y);
layer->addCloud(newpos, cld);
}
} }
} }
// Return the maximum extent of the cloud
return extent;
} }
void FGClouds::buildLayer(int iLayer, const string& name, double alt, double coverage) { void FGClouds::buildLayer(int iLayer, const string& name, double alt, double coverage) {
@ -179,10 +223,6 @@ void FGClouds::buildLayer(int iLayer, const string& name, double alt, double cov
// At this point, we know we've got some 3D clouds to generate. // At this point, we know we've got some 3D clouds to generate.
thesky->get_cloud_layer(iLayer)->set_enable3dClouds(true); thesky->get_cloud_layer(iLayer)->set_enable3dClouds(true);
double grid_x_size = layer_def->getDoubleValue("grid-x-size", 1000.0);
double grid_y_size = layer_def->getDoubleValue("grid-y-size", 1000.0);
double grid_x_rand = layer_def->getDoubleValue("grid-x-rand", grid_x_size);
double grid_y_rand = layer_def->getDoubleValue("grid-y-rand", grid_y_size);
double grid_z_rand = layer_def->getDoubleValue("grid-z-rand"); double grid_z_rand = layer_def->getDoubleValue("grid-z-rand");
for(int i = 0; i < layer_def->nChildren() ; i++) { for(int i = 0; i < layer_def->nChildren() ; i++) {
@ -207,31 +247,25 @@ void FGClouds::buildLayer(int iLayer, const string& name, double alt, double cov
} }
totalCount = 1.0 / totalCount; totalCount = 1.0 / totalCount;
for(double px = 0.0; px < SGCloudField::fieldSize; px += grid_x_size) { // Determine how much cloud coverage we need in m^2.
for(double py = 0.0; py < SGCloudField::fieldSize; py += grid_y_size) { double cov = coverage * SGCloudField::fieldSize * SGCloudField::fieldSize;
double x = px + grid_x_rand * (sg_random() - 0.5) - (SGCloudField::fieldSize / 2.0);
double y = py + grid_y_rand * (sg_random() - 0.5) - (SGCloudField::fieldSize / 2.0);
double z = grid_z_rand * (sg_random() - 0.5);
if (sg_random() < coverage) { while (cov > 0.0f) {
double choice = sg_random(); double choice = sg_random();
for(int i = 0; i < CloudVarietyCount ; i ++) { for(int i = 0; i < CloudVarietyCount ; i ++) {
choice -= tCloudVariety[i].count * totalCount; choice -= tCloudVariety[i].count * totalCount;
if( choice <= 0.0 ) { if( choice <= 0.0 ) {
sgVec3 pos={x,z,y}; cov -= buildCloud(cloud_def_root,
box_def_root,
buildCloud(cloud_def_root, tCloudVariety[i].name,
box_def_root, grid_z_rand,
tCloudVariety[i].name, layer);
pos, break;
layer);
break;
}
}
} }
} }
}
}
// Now we've built any clouds, enable them and set the density (coverage) // Now we've built any clouds, enable them and set the density (coverage)
//layer->setCoverage(coverage); //layer->setCoverage(coverage);

View file

@ -42,7 +42,7 @@ class FGEnvironmentCtrl;
class FGClouds { class FGClouds {
private: private:
void buildCloud(SGPropertyNode *cloud_def_root, SGPropertyNode *box_def_root, const string& name, sgVec3 pos, SGCloudField *layer); double buildCloud(SGPropertyNode *cloud_def_root, SGPropertyNode *box_def_root, const string& name, double grid_z_rand, SGCloudField *layer);
void buildLayer(int iLayer, const string& name, double alt, double coverage); void buildLayer(int iLayer, const string& name, double alt, double coverage);
void buildCloudLayers(void); void buildCloudLayers(void);

View file

@ -100,9 +100,12 @@ void uiuc_getwind()
/* Get wind vector */ /* Get wind vector */
double windmag = 0; //Wind magnitude double windmag = 0; //Wind magnitude
double a = 0; //Parabola: Altitude = a*windmag^2 + zoff double a = 0; //Parabola: Altitude = a*windmag^2 + zoff
double x = pow(uref,2.);
a = zref/pow(uref,2.); if (x) {
if (Altitude >= zoff) a = zref/x;
}
if ((Altitude >= zoff) && (a > 0))
windmag = sqrt(Altitude/a); windmag = sqrt(Altitude/a);
else else
windmag = 0.; windmag = 0.;

View file

@ -46,7 +46,7 @@
#define PACKAGE "FlightGear" #define PACKAGE "FlightGear"
/* Define to package version - use in main.cxx */ /* Define to package version - use in main.cxx */
#define FLIGHTGEAR_VERSION "MSVC6-WIN32-1.9.0" #define FLIGHTGEAR_VERSION "MSVC6-WIN32-1.9.1"
/* Define as the return type of signal handlers (int or void). */ /* Define as the return type of signal handlers (int or void). */
#define RETSIGTYPE void #define RETSIGTYPE void
@ -64,7 +64,7 @@
#define TM_IN_SYS_TIME 1 #define TM_IN_SYS_TIME 1
/* Define to version number */ /* Define to version number */
#define VERSION "1.9.0" #define VERSION "1.9.1"
/* Define if compiling on a Winbloze (95, NT, etc.) platform */ /* Define if compiling on a Winbloze (95, NT, etc.) platform */
#define WIN32 1 #define WIN32 1

View file

@ -19,7 +19,7 @@
#define PACKAGE "FlightGear" #define PACKAGE "FlightGear"
/* Define to package version - use in main.cxx */ /* Define to package version - use in main.cxx */
#define FLIGHTGEAR_VERSION "MSVC7.1-WIN32-1.9.0" #define FLIGHTGEAR_VERSION "MSVC7.1-WIN32-1.9.1"
/* Define as the return type of signal handlers (int or void). */ /* Define as the return type of signal handlers (int or void). */
#define RETSIGTYPE void #define RETSIGTYPE void
@ -37,7 +37,7 @@
#define TM_IN_SYS_TIME 1 #define TM_IN_SYS_TIME 1
/* Define to version number */ /* Define to version number */
#define VERSION "1.9.0" #define VERSION "1.9.1"
#ifndef FG_VERSION /* allow override */ #ifndef FG_VERSION /* allow override */
#define FG_VERSION 7 #define FG_VERSION 7
#endif /* FG_VERSION */ #endif /* FG_VERSION */

View file

@ -50,7 +50,7 @@
#define PACKAGE "FlightGear" #define PACKAGE "FlightGear"
/* Define to package version - use in main.cxx */ /* Define to package version - use in main.cxx */
#define FLIGHTGEAR_VERSION "MSVC8-WIN32-1.9.0" #define FLIGHTGEAR_VERSION "MSVC8-WIN32-1.9.1"
/* Define as the return type of signal handlers (int or void). */ /* Define as the return type of signal handlers (int or void). */
#define RETSIGTYPE void #define RETSIGTYPE void
@ -68,7 +68,7 @@
#define TM_IN_SYS_TIME 1 #define TM_IN_SYS_TIME 1
/* Define to version number */ /* Define to version number */
#define VERSION "1.9.0" #define VERSION "1.9.1"
/* Define if compiling on a Winbloze (95, NT, etc.) platform */ /* Define if compiling on a Winbloze (95, NT, etc.) platform */
#define WIN32 1 #define WIN32 1