Preparation for making dynamic cloud layers -- moved cloud state out

of sky.[ch]xx and into cloud.[ch]xx, and added setters for modifying
the state of an existing layer.
This commit is contained in:
david
2002-05-16 23:16:39 +00:00
parent 786b1e3a30
commit 255bb6dd07
4 changed files with 225 additions and 167 deletions

View File

@@ -28,35 +28,127 @@
#include <simgear/math/polar3d.hxx>
#include <simgear/math/sg_random.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/misc/sg_path.hxx>
#include "cloud.hxx"
ssgSimpleState *
SGCloudLayer::layer_states[SGCloudLayer::SG_MAX_CLOUD_TYPES];
// Constructor
SGCloudLayer::SGCloudLayer( void ) {
SGCloudLayer::SGCloudLayer( const string &tex_path )
: layer_root(0),
layer_transform(0),
texture_path(tex_path),
layer_asl(0),
layer_thickness(0),
layer_transition(0),
layer_type(SG_CLOUD_CLEAR)
{
rebuild();
}
// Destructor
SGCloudLayer::~SGCloudLayer( void ) {
}
float
SGCloudLayer::getSpan_m () const
{
return layer_span;
}
void
SGCloudLayer::setSpan_m (float span_m)
{
layer_span = span_m;
}
float
SGCloudLayer::getElevation_m () const
{
return layer_asl;
}
void
SGCloudLayer::setElevation_m (float elevation_m)
{
layer_asl = elevation_m;
}
float
SGCloudLayer::getThickness_m () const
{
return layer_thickness;
}
void
SGCloudLayer::setThickness_m (float thickness_m)
{
layer_thickness = thickness_m;
}
float
SGCloudLayer::getTransition_m () const
{
return layer_transition;
}
void
SGCloudLayer::setTransition_m (float transition_m)
{
layer_transition = transition_m;
}
SGCloudLayer::Type
SGCloudLayer::getType () const
{
return layer_type;
}
void
SGCloudLayer::setType (Type type)
{
layer_type = type;
rebuild();
}
// build the cloud object
void SGCloudLayer::build( double s, double asl, double thickness,
double transition, ssgSimpleState *state )
void
SGCloudLayer::rebuild()
{
// Initialize states and sizes if necessary.
if (layer_states[0] == 0) {
SGPath cloud_path;
cloud_path.set(texture_path.str());
cloud_path.append("overcast.rgb");
layer_states[SG_CLOUD_OVERCAST] = SGCloudMakeState(cloud_path.str());
cloud_path.set(texture_path.str());
cloud_path.append("mostlycloudy.rgba");
layer_states[SG_CLOUD_MOSTLY_CLOUDY] =
SGCloudMakeState(cloud_path.str());
cloud_path.set(texture_path.str());
cloud_path.append("mostlysunny.rgba");
layer_states[SG_CLOUD_MOSTLY_SUNNY] = SGCloudMakeState(cloud_path.str());
cloud_path.set(texture_path.str());
cloud_path.append("cirrus.rgba");
layer_states[SG_CLOUD_CIRRUS] = SGCloudMakeState(cloud_path.str());
layer_states[SG_CLOUD_CLEAR] = 0;
}
delete layer_root;
scale = 4000.0;
layer_asl = asl;
layer_thickness = thickness;
layer_transition = transition;
size = s;
last_lon = last_lat = -999.0f;
layer_state = state;
cl = new ssgColourArray( 4 );
vl = new ssgVertexArray( 4 );
tl = new ssgTexCoordArray( 4 );
@@ -67,7 +159,7 @@ void SGCloudLayer::build( double s, double asl, double thickness,
sgVec2 tc;
sgSetVec4( color, 1.0f, 1.0f, 1.0f, 1.0f );
sgSetVec3( vertex, -size, -size, 0.0f );
sgSetVec3( vertex, -layer_span, -layer_span, 0.0f );
sgVec2 base;
sgSetVec2( base, sg_random(), sg_random() );
sgSetVec2( tc, base[0], base[1] );
@@ -75,27 +167,28 @@ void SGCloudLayer::build( double s, double asl, double thickness,
vl->add( vertex );
tl->add( tc );
sgSetVec3( vertex, size, -size, 0.0f );
sgSetVec2( tc, base[0] + size / scale, base[1] );
sgSetVec3( vertex, layer_span, -layer_span, 0.0f );
sgSetVec2( tc, base[0] + layer_span / scale, base[1] );
cl->add( color );
vl->add( vertex );
tl->add( tc );
sgSetVec3( vertex, -size, size, 0.0f );
sgSetVec2( tc, base[0], base[1] + size / scale );
sgSetVec3( vertex, -layer_span, layer_span, 0.0f );
sgSetVec2( tc, base[0], base[1] + layer_span / scale );
cl->add( color );
vl->add( vertex );
tl->add( tc );
sgSetVec3( vertex, size, size, 0.0f );
sgSetVec2( tc, base[0] + size / scale, base[1] + size / scale );
sgSetVec3( vertex, layer_span, layer_span, 0.0f );
sgSetVec2( tc, base[0] + layer_span / scale, base[1] + layer_span / scale );
cl->add( color );
vl->add( vertex );
tl->add( tc );
ssgLeaf *layer =
new ssgVtxTable ( GL_TRIANGLE_STRIP, vl, NULL, tl, cl );
layer->setState( layer_state );
if (layer_states[layer_type] != 0)
layer->setState( layer_states[layer_type] );
// force a repaint of the moon colors with arbitrary defaults
repaint( color );
@@ -234,13 +327,13 @@ bool SGCloudLayer::reposition( sgVec3 p, sgVec3 up, double lon, double lat,
// cout << "base = " << base[0] << "," << base[1] << endl;
tc = tl->get( 1 );
sgSetVec2( tc, base[0] + size / scale, base[1] );
sgSetVec2( tc, base[0] + layer_span / scale, base[1] );
tc = tl->get( 2 );
sgSetVec2( tc, base[0], base[1] + size / scale );
sgSetVec2( tc, base[0], base[1] + layer_span / scale );
tc = tl->get( 3 );
sgSetVec2( tc, base[0] + size / scale, base[1] + size / scale );
sgSetVec2( tc, base[0] + layer_span / scale, base[1] + layer_span / scale );
last_lon = lon;
last_lat = lat;

View File

@@ -33,53 +33,42 @@
SG_USING_STD(string);
#define SG_MAX_CLOUD_TYPES 4 // change this if we add/remove cloud
// types en the enum below
enum SGCloudType {
SG_CLOUD_OVERCAST = 0,
SG_CLOUD_MOSTLY_CLOUDY,
SG_CLOUD_MOSTLY_SUNNY,
SG_CLOUD_CIRRUS
};
class SGCloudLayer {
private:
ssgRoot *layer_root;
ssgTransform *layer_transform;
ssgSimpleState *layer_state;
ssgColourArray *cl;
ssgVertexArray *vl;
ssgTexCoordArray *tl;
// height above sea level (meters)
float layer_asl;
float layer_thickness;
float layer_transition;
float size;
float scale;
// for handling texture coordinates to simulate cloud movement
// from winds, and to simulate the clouds being tied to ground
// position, not view position
// double xoff, yoff;
double last_lon, last_lat;
public:
// Constructor
SGCloudLayer( void );
enum Type {
SG_CLOUD_OVERCAST = 0,
SG_CLOUD_MOSTLY_CLOUDY,
SG_CLOUD_MOSTLY_SUNNY,
SG_CLOUD_CIRRUS,
SG_CLOUD_CLEAR,
SG_MAX_CLOUD_TYPES
};
// Constructors
SGCloudLayer( const string &tex_path );
// Destructor
~SGCloudLayer( void );
float getSpan_m () const;
void setSpan_m (float span_m);
float getElevation_m () const;
void setElevation_m (float elevation_m);
float getThickness_m () const;
void setThickness_m (float thickness_m);
float getTransition_m () const;
void setTransition_m (float transition_m);
Type getType () const;
void setType (Type type);
// build the cloud object
void build( double size, double asl, double thickness,
double transition, ssgSimpleState *state );
void rebuild();
// repaint the cloud colors based on current value of sun_angle,
// sky, and fog colors. This updates the color arrays for
@@ -101,9 +90,34 @@ public:
// draw the cloud layer
void draw();
inline float get_asl() const { return layer_asl; }
inline float get_thickness() const { return layer_thickness; }
inline float get_transition() const { return layer_transition; }
private:
static ssgSimpleState *layer_states[SG_MAX_CLOUD_TYPES];
static int layer_sizes[SG_MAX_CLOUD_TYPES];
ssgRoot *layer_root;
ssgTransform *layer_transform;
ssgLeaf * layer;
ssgColourArray *cl;
ssgVertexArray *vl;
ssgTexCoordArray *tl;
// height above sea level (meters)
SGPath texture_path;
float layer_span;
float layer_asl;
float layer_thickness;
float layer_transition;
Type layer_type;
float scale;
// for handling texture coordinates to simulate cloud movement
// from winds, and to simulate the clouds being tied to ground
// position, not view position
// double xoff, yoff;
double last_lon, last_lat;
};

View File

@@ -47,7 +47,10 @@ SGSky::SGSky( void ) {
// Destructor
SGSky::~SGSky( void ) {
SGSky::~SGSky( void )
{
for (int i = 0; i < cloud_layers.size(); i++)
delete cloud_layers[i];
}
@@ -92,25 +95,6 @@ void SGSky::build( double sun_size, double moon_size,
pre_root->addKid( pre_selector );
post_root->addKid( post_selector );
// add the cloud ssgStates to the material lib
SGPath cloud_path;
cloud_path.set( tex_path.str() );
cloud_path.append( "overcast.rgb" );
cloud_mats[SG_CLOUD_OVERCAST] = SGCloudMakeState( cloud_path.str() );
cloud_path.set( tex_path.str() );
cloud_path.append( "mostlycloudy.rgba" );
cloud_mats[SG_CLOUD_MOSTLY_CLOUDY] = SGCloudMakeState( cloud_path.str() );
cloud_path.set( tex_path.str() );
cloud_path.append( "mostlysunny.rgba" );
cloud_mats[SG_CLOUD_MOSTLY_SUNNY] = SGCloudMakeState( cloud_path.str() );
cloud_path.set( tex_path.str() );
cloud_path.append( "cirrus.rgba" );
cloud_mats[SG_CLOUD_CIRRUS] = SGCloudMakeState( cloud_path.str() );
}
@@ -193,8 +177,8 @@ void SGSky::postDraw( float alt ) {
// check where we are relative to the cloud layers
for ( i = 0; i < (int)cloud_layers.size(); ++i ) {
float asl = cloud_layers[i]->get_asl();
float thickness = cloud_layers[i]->get_thickness();
float asl = cloud_layers[i]->getElevation_m();
float thickness = cloud_layers[i]->getThickness_m();
if ( alt < asl - slop ) {
// below cloud layer
@@ -211,7 +195,7 @@ void SGSky::postDraw( float alt ) {
// determine rendering order
int pos = 0;
while ( pos < (int)cloud_layers.size() &&
alt > cloud_layers[pos]->get_asl())
alt > cloud_layers[pos]->getElevation_m())
{
++pos;
}
@@ -246,48 +230,29 @@ void SGSky::postDraw( float alt ) {
}
}
void SGSky::add_cloud_layer( double asl, double thickness,
double transition, double span,
ssgSimpleState *state ) {
SGCloudLayer *layer = new SGCloudLayer;
layer->build( span, asl, thickness, transition, state );
layer_list_iterator current = cloud_layers.begin();
layer_list_iterator last = cloud_layers.end();
while ( current != last && (*current)->get_asl() < asl ) {
++current;
}
if ( current != last ) {
cloud_layers.insert( current, layer );
} else {
cloud_layers.push_back( layer );
}
// for ( int i = 0; i < (int)cloud_layers.size(); ++i ) {
// cout << "layer " << i << " = " << cloud_layers[i]->get_asl() << endl;
// }
// cout << endl;
void
SGSky::add_cloud_layer( SGCloudLayer * layer )
{
cloud_layers.push_back(layer);
}
void SGSky::add_cloud_layer( double asl, double thickness,
double transition, double span,
const string &tex_path ) {
ssgSimpleState *state = SGCloudMakeState( tex_path );
add_cloud_layer( asl, thickness, transition, span, state );
const SGCloudLayer *
SGSky::get_cloud_layer (int i) const
{
return cloud_layers[i];
}
void SGSky::add_cloud_layer( double asl, double thickness,
double transition, double span,
SGCloudType type ) {
if ( type > 0 && type < SG_MAX_CLOUD_TYPES ) {
add_cloud_layer( asl, thickness, transition, span, cloud_mats[type] );
}
SGCloudLayer *
SGSky::get_cloud_layer (int i)
{
return cloud_layers[i];
}
int
SGSky::get_cloud_layer_count () const
{
return cloud_layers.size();
}
// modify the current visibility based on cloud layers, thickness,
// transition range, and simulated "puffs".
@@ -295,9 +260,9 @@ void SGSky::modify_vis( float alt, float time_factor ) {
float effvis = visibility;
for ( int i = 0; i < (int)cloud_layers.size(); ++i ) {
float asl = cloud_layers[i]->get_asl();
float thickness = cloud_layers[i]->get_thickness();
float transition = cloud_layers[i]->get_transition();
float asl = cloud_layers[i]->getElevation_m();
float thickness = cloud_layers[i]->getThickness_m();
float transition = cloud_layers[i]->getTransition_m();
double ratio = 1.0;
@@ -387,4 +352,3 @@ void SGSky::modify_vis( float alt, float time_factor ) {
effective_visibility = effvis;
}

View File

@@ -191,7 +191,6 @@ private:
SGMoon *moon;
SGStars *planets;
SGStars *stars;
ssgSimpleState *cloud_mats[SG_MAX_CLOUD_TYPES];
layer_list_type cloud_layers;
ssgRoot *pre_root, *post_root;
@@ -350,54 +349,44 @@ public:
}
/**
* Add a cloud layer (distances in meters).
* @param asl cloud base height above sea level
* @param thickness cloud layer thickness
* @param transition thickness of transition layer from 100% out of
* cloud to 100% in cloud. Used for scudded clouds effect.
* @param span horizontal size of cloud object
* @param type type of cloud (chosen from available cloud types)
* Add a cloud layer.
*
* Transfer pointer ownership to this object.
*
* @param layer The new cloud layer to add.
*/
void add_cloud_layer( double asl, double thickness,
double transition, double span,
SGCloudType type );
void add_cloud_layer (SGCloudLayer * layer);
/**
* Add a cloud layer (distances in meters).
* @param asl cloud base height above sea level
* @param thickness cloud layer thickness
* @param transition thickness of transition layer from 100% out of
* cloud to 100% in cloud. Used for scudded clouds effect.
* @param span horizontal size of cloud object
* @param tex_path file name of a cloud texture
* Get a cloud layer (const).
*
* Pointer ownership remains with this object.
*
* @param i The index of the cloud layer, zero-based.
* @return A const pointer to the cloud layer.
*/
void add_cloud_layer( double asl, double thickness,
double transition, double span,
const string &tex_path );
const SGCloudLayer * get_cloud_layer (int i) const;
/**
* Add a cloud layer (distances in meters).
* @param asl cloud base height above sea level
* @param thickness cloud layer thickness
* @param transition thickness of transition layer from 100% out of
* cloud to 100% in cloud. Used for scudded clouds effect.
* @param span horizontal size of cloud object
* @param state pointer to an existing ssgSimpleState
* Get a cloud layer (non-const).
*
* Pointer ownership remains with this object.
*
* @param i The index of the cloud layer, zero-based.
* @return A non-const pointer to the cloud layer.
*/
void add_cloud_layer( double asl, double thickness,
double transition, double span,
ssgSimpleState *state );
SGCloudLayer * get_cloud_layer (int i);
/** @return number of cloud layers */
inline int get_num_layers() const { return cloud_layers.size(); }
/**
* Get a cloud layer
* @param i which cloud layer
* @return cloud layer number i */
inline SGCloudLayer *get_cloud_layer( int i ) const {
return cloud_layers[i];
}
* Return the number of cloud layers currently available.
*
* @return The cloud layer count.
*/
int get_cloud_layer_count () const;
/** @return current effective visibility */
inline float get_visibility() const { return effective_visibility; }
@@ -412,5 +401,3 @@ public:
#endif // _SG_SKY_HXX