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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user