Modified Files:
simgear/bucket/newbucket.cxx simgear/bucket/newbucket.hxx simgear/io/decode_binobj.cxx simgear/io/sg_binobj.cxx simgear/io/sg_binobj.hxx simgear/math/SGVec2.hxx simgear/math/SGVec3.hxx simgear/math/SGVec4.hxx simgear/scene/material/mat.hxx simgear/scene/material/matlib.cxx simgear/scene/material/matlib.hxx simgear/scene/model/Makefile.am simgear/scene/tgdb/Makefile.am simgear/scene/tgdb/obj.cxx simgear/scene/tgdb/obj.hxx simgear/scene/tgdb/pt_lights.cxx simgear/scene/tgdb/pt_lights.hxx simgear/scene/util/Makefile.am simgear/scene/util/SGNodeMasks.hxx simgear/scene/util/SGTextureStateAttributeVisitor.cxx Added Files: simgear/scene/model/SGOffsetTransform.cxx simgear/scene/model/SGOffsetTransform.hxx simgear/scene/tgdb/SGDirectionalLightBin.hxx simgear/scene/tgdb/SGLightBin.hxx simgear/scene/tgdb/SGOceanTile.cxx simgear/scene/tgdb/SGOceanTile.hxx simgear/scene/tgdb/SGTexturedTriangleBin.hxx simgear/scene/tgdb/SGTriangleBin.hxx simgear/scene/tgdb/SGVasiDrawable.cxx simgear/scene/tgdb/SGVasiDrawable.hxx simgear/scene/tgdb/SGVertexArrayBin.hxx simgear/scene/util/SGEnlargeBoundingBox.cxx simgear/scene/util/SGEnlargeBoundingBox.hxx simgear/scene/util/SGSceneFeatures.cxx simgear/scene/util/SGSceneFeatures.hxx Removed Files: simgear/scene/tgdb/leaf.hxx simgear/scene/tgdb/vasi.hxx: Reorganize tile loaders. Build bigger leafs for the tiles. Move runway light colors into materials.xml. Split out classes that might be useful at other places. Avoid static storage on binobject loading.
This commit is contained in:
parent
52444d177b
commit
560c100484
@ -44,6 +44,9 @@ SGBucket::SGBucket(const double dlon, const double dlat) {
|
||||
set_bucket(dlon, dlat);
|
||||
}
|
||||
|
||||
SGBucket::SGBucket(const SGGeod& geod) {
|
||||
set_bucket(geod);
|
||||
}
|
||||
|
||||
// create an impossible bucket if false
|
||||
SGBucket::SGBucket(const bool is_good) {
|
||||
@ -73,11 +76,6 @@ SGBucket::SGBucket(const long int bindex) {
|
||||
}
|
||||
|
||||
|
||||
// default destructor
|
||||
SGBucket::~SGBucket() {
|
||||
}
|
||||
|
||||
|
||||
// Set the bucket params for the specified lat and lon
|
||||
void SGBucket::set_bucket( double *lonlat ) {
|
||||
set_bucket( lonlat[0], lonlat[1] );
|
||||
@ -135,6 +133,11 @@ void SGBucket::set_bucket( double dlon, double dlat ) {
|
||||
}
|
||||
|
||||
|
||||
void SGBucket::set_bucket(const SGGeod& geod)
|
||||
{
|
||||
set_bucket(geod.getLongitudeDeg(), geod.getLatitudeDeg());
|
||||
}
|
||||
|
||||
// Build the path name for this bucket
|
||||
string SGBucket::gen_base_path() const {
|
||||
// long int index;
|
||||
|
@ -134,6 +134,13 @@ public:
|
||||
*/
|
||||
SGBucket(const double dlon, const double dlat);
|
||||
|
||||
/**
|
||||
* Construct a bucket given a specific location.
|
||||
* @param dlon longitude specified in degrees
|
||||
* @param dlat latitude specified in degrees
|
||||
*/
|
||||
SGBucket(const SGGeod& geod);
|
||||
|
||||
/** Construct a bucket.
|
||||
* @param is_good if false, create an invalid bucket. This is
|
||||
* useful * if you are comparing cur_bucket to last_bucket and
|
||||
@ -147,11 +154,6 @@ public:
|
||||
*/
|
||||
SGBucket(const long int bindex);
|
||||
|
||||
/**
|
||||
* Default destructor.
|
||||
*/
|
||||
~SGBucket();
|
||||
|
||||
/**
|
||||
* Reset a bucket to represent a new lat and lon
|
||||
* @param dlon longitude specified in degrees
|
||||
@ -166,6 +168,13 @@ public:
|
||||
*/
|
||||
void set_bucket( double *lonlat );
|
||||
|
||||
/**
|
||||
* Reset a bucket to represent a new lat and lon
|
||||
* @param dlon longitude specified in degrees
|
||||
* @param dlat latitude specified in degrees
|
||||
*/
|
||||
void set_bucket(const SGGeod& geod);
|
||||
|
||||
/**
|
||||
* Create an impossible bucket.
|
||||
* This is useful if you are comparing cur_bucket to last_bucket
|
||||
|
@ -37,14 +37,14 @@ int main( int argc, char **argv ) {
|
||||
obj.get_gbs_radius());
|
||||
cout << endl;
|
||||
|
||||
point_list nodes = obj.get_wgs84_nodes();
|
||||
std::vector<SGVec3d> nodes = obj.get_wgs84_nodes();
|
||||
cout << "# vertex list" << endl;
|
||||
for ( i = 0; i < (int)nodes.size(); ++i ) {
|
||||
printf("v %.5f %.5f %.5f\n", nodes[i].x(), nodes[i].y(), nodes[i].z() );
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
point_list normals = obj.get_normals();
|
||||
std::vector<SGVec3f> normals = obj.get_normals();
|
||||
cout << "# vertex normal list" << endl;
|
||||
for ( i = 0; i < (int)normals.size(); ++i ) {
|
||||
printf("vn %.5f %.5f %.5f\n",
|
||||
@ -52,7 +52,7 @@ int main( int argc, char **argv ) {
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
point_list texcoords = obj.get_texcoords();
|
||||
std::vector<SGVec2f> texcoords = obj.get_texcoords();
|
||||
cout << "# texture coordinate list" << endl;
|
||||
for ( i = 0; i < (int)texcoords.size(); ++i ) {
|
||||
printf("vt %.5f %.5f\n",
|
||||
|
@ -174,7 +174,7 @@ static void read_object( gzFile fp,
|
||||
int idx_size;
|
||||
bool do_vertices, do_normals, do_colors, do_texcoords;
|
||||
int j, k, idx;
|
||||
static sgSimpleBuffer buf( 32768 ); // 32 Kb
|
||||
sgSimpleBuffer buf( 32768 ); // 32 Kb
|
||||
char material[256];
|
||||
|
||||
// default values
|
||||
@ -280,13 +280,13 @@ static void read_object( gzFile fp,
|
||||
|
||||
// read a binary file and populate the provided structures.
|
||||
bool SGBinObject::read_bin( const string& file ) {
|
||||
Point3D p;
|
||||
SGVec3d p;
|
||||
int i, j, k;
|
||||
unsigned int nbytes;
|
||||
static sgSimpleBuffer buf( 32768 ); // 32 Kb
|
||||
sgSimpleBuffer buf( 32768 ); // 32 Kb
|
||||
|
||||
// zero out structures
|
||||
gbs_center = Point3D( 0 );
|
||||
gbs_center = SGVec3d(0, 0, 0);
|
||||
gbs_radius = 0.0;
|
||||
|
||||
wgs84_nodes.clear();
|
||||
@ -407,7 +407,7 @@ bool SGBinObject::read_bin( const string& file ) {
|
||||
sgEndianSwap( (uint64_t *)&(dptr[1]) );
|
||||
sgEndianSwap( (uint64_t *)&(dptr[2]) );
|
||||
}
|
||||
gbs_center = Point3D( dptr[0], dptr[1], dptr[2] );
|
||||
gbs_center = SGVec3d( dptr[0], dptr[1], dptr[2] );
|
||||
// cout << "Center = " << gbs_center << endl;
|
||||
ptr += sizeof(double) * 3;
|
||||
|
||||
@ -447,7 +447,7 @@ bool SGBinObject::read_bin( const string& file ) {
|
||||
sgEndianSwap( (uint32_t *)&(fptr[1]) );
|
||||
sgEndianSwap( (uint32_t *)&(fptr[2]) );
|
||||
}
|
||||
wgs84_nodes.push_back( Point3D(fptr[0], fptr[1], fptr[2]) );
|
||||
wgs84_nodes.push_back( SGVec3d(fptr[0], fptr[1], fptr[2]) );
|
||||
fptr += 3;
|
||||
}
|
||||
}
|
||||
@ -481,7 +481,8 @@ bool SGBinObject::read_bin( const string& file ) {
|
||||
sgEndianSwap( (uint32_t *)&(fptr[2]) );
|
||||
sgEndianSwap( (uint32_t *)&(fptr[3]) );
|
||||
}
|
||||
colors.push_back( Point3D( fptr[0], fptr[1], fptr[2] ) );
|
||||
SGVec4f color( fptr[0], fptr[1], fptr[2], fptr[3] );
|
||||
colors.push_back( color );
|
||||
fptr += 4;
|
||||
}
|
||||
}
|
||||
@ -508,14 +509,11 @@ bool SGBinObject::read_bin( const string& file ) {
|
||||
int count = nbytes / 3;
|
||||
normals.reserve( count );
|
||||
for ( k = 0; k < count; ++k ) {
|
||||
sgdVec3 normal;
|
||||
sgdSetVec3( normal,
|
||||
(ptr[0]) / 127.5 - 1.0,
|
||||
(ptr[1]) / 127.5 - 1.0,
|
||||
(ptr[2]) / 127.5 - 1.0 );
|
||||
sgdNormalizeVec3( normal );
|
||||
SGVec3f normal((ptr[0]) / 127.5 - 1.0,
|
||||
(ptr[1]) / 127.5 - 1.0,
|
||||
(ptr[2]) / 127.5 - 1.0);
|
||||
|
||||
normals.push_back(Point3D(normal[0], normal[1], normal[2]));
|
||||
normals.push_back(normalize(normal));
|
||||
ptr += 3;
|
||||
}
|
||||
}
|
||||
@ -547,7 +545,7 @@ bool SGBinObject::read_bin( const string& file ) {
|
||||
sgEndianSwap( (uint32_t *)&(fptr[0]) );
|
||||
sgEndianSwap( (uint32_t *)&(fptr[1]) );
|
||||
}
|
||||
texcoords.push_back( Point3D( fptr[0], fptr[1], 0 ) );
|
||||
texcoords.push_back( SGVec2f( fptr[0], fptr[1] ) );
|
||||
fptr += 2;
|
||||
}
|
||||
}
|
||||
@ -612,10 +610,6 @@ bool SGBinObject::read_bin( const string& file ) {
|
||||
bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
const SGBucket& b )
|
||||
{
|
||||
Point3D p;
|
||||
sgVec2 t;
|
||||
sgVec3 pt;
|
||||
sgVec4 color;
|
||||
int i, j;
|
||||
unsigned char idx_mask;
|
||||
int idx_size;
|
||||
@ -738,9 +732,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
sgWriteShort( fp, 1 ); // nelements
|
||||
sgWriteUInt( fp, wgs84_nodes.size() * sizeof(float) * 3 ); // nbytes
|
||||
for ( i = 0; i < (int)wgs84_nodes.size(); ++i ) {
|
||||
p = wgs84_nodes[i] - gbs_center;
|
||||
sgSetVec3( pt, p.x(), p.y(), p.z() );
|
||||
sgWriteVec3( fp, pt );
|
||||
SGVec3f p = toVec3f(wgs84_nodes[i] - gbs_center);
|
||||
sgWriteVec3( fp, p.data() );
|
||||
}
|
||||
|
||||
// dump vertex color list
|
||||
@ -749,12 +742,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
sgWriteShort( fp, 1 ); // nelements
|
||||
sgWriteUInt( fp, colors.size() * sizeof(float) * 4 ); // nbytes
|
||||
for ( i = 0; i < (int)colors.size(); ++i ) {
|
||||
p = colors[i];
|
||||
// Right now we have a place holder for color alpha but we
|
||||
// need to update the interface so the calling program can
|
||||
// provide the info.
|
||||
sgSetVec4( color, p.x(), p.y(), p.z(), 1.0 );
|
||||
sgWriteVec4( fp, color );
|
||||
sgWriteVec4( fp, colors[i].data() );
|
||||
}
|
||||
|
||||
// dump vertex normal list
|
||||
@ -764,7 +752,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
sgWriteUInt( fp, normals.size() * 3 ); // nbytes
|
||||
char normal[3];
|
||||
for ( i = 0; i < (int)normals.size(); ++i ) {
|
||||
p = normals[i];
|
||||
SGVec3f p = normals[i];
|
||||
normal[0] = (unsigned char)((p.x() + 1.0) * 127.5);
|
||||
normal[1] = (unsigned char)((p.y() + 1.0) * 127.5);
|
||||
normal[2] = (unsigned char)((p.z() + 1.0) * 127.5);
|
||||
@ -777,9 +765,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
sgWriteShort( fp, 1 ); // nelements
|
||||
sgWriteUInt( fp, texcoords.size() * sizeof(float) * 2 ); // nbytes
|
||||
for ( i = 0; i < (int)texcoords.size(); ++i ) {
|
||||
p = texcoords[i];
|
||||
sgSetVec2( t, p.x(), p.y() );
|
||||
sgWriteVec2( fp, t );
|
||||
sgWriteVec2( fp, texcoords[i].data() );
|
||||
}
|
||||
|
||||
// dump point groups if they exist
|
||||
@ -1042,7 +1028,6 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
bool SGBinObject::write_ascii( const string& base, const string& name,
|
||||
const SGBucket& b )
|
||||
{
|
||||
Point3D p;
|
||||
int i, j;
|
||||
|
||||
SGPath file = base + "/" + b.gen_base_path() + "/" + name;
|
||||
@ -1084,7 +1069,7 @@ bool SGBinObject::write_ascii( const string& base, const string& name,
|
||||
// dump vertex list
|
||||
fprintf(fp, "# vertex list\n");
|
||||
for ( i = 0; i < (int)wgs84_nodes.size(); ++i ) {
|
||||
p = wgs84_nodes[i] - gbs_center;
|
||||
SGVec3d p = wgs84_nodes[i] - gbs_center;
|
||||
|
||||
fprintf(fp, "v %.5f %.5f %.5f\n", p.x(), p.y(), p.z() );
|
||||
}
|
||||
@ -1092,7 +1077,7 @@ bool SGBinObject::write_ascii( const string& base, const string& name,
|
||||
|
||||
fprintf(fp, "# vertex normal list\n");
|
||||
for ( i = 0; i < (int)normals.size(); ++i ) {
|
||||
p = normals[i];
|
||||
SGVec3f p = normals[i];
|
||||
fprintf(fp, "vn %.5f %.5f %.5f\n", p.x(), p.y(), p.z() );
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
@ -1100,7 +1085,7 @@ bool SGBinObject::write_ascii( const string& base, const string& name,
|
||||
// dump texture coordinates
|
||||
fprintf(fp, "# texture coordinate list\n");
|
||||
for ( i = 0; i < (int)texcoords.size(); ++i ) {
|
||||
p = texcoords[i];
|
||||
SGVec2f p = texcoords[i];
|
||||
fprintf(fp, "vt %.5f %.5f\n", p.x(), p.y() );
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
@ -1126,13 +1111,13 @@ bool SGBinObject::write_ascii( const string& base, const string& name,
|
||||
// make a list of points for the group
|
||||
point_list group_nodes;
|
||||
group_nodes.clear();
|
||||
Point3D bs_center;
|
||||
SGVec3d bs_center;
|
||||
double bs_radius = 0;
|
||||
for ( i = start; i < end; ++i ) {
|
||||
for ( j = 0; j < (int)tris_v[i].size(); ++j ) {
|
||||
group_nodes.push_back( wgs84_nodes[ tris_v[i][j] ] );
|
||||
bs_center = sgCalcCenter( group_nodes );
|
||||
bs_radius = sgCalcBoundingRadius( bs_center, group_nodes );
|
||||
group_nodes.push_back( Point3D::fromSGVec3(wgs84_nodes[ tris_v[i][j] ]) );
|
||||
bs_center = sgCalcCenter( group_nodes ).toSGVec3d();
|
||||
bs_radius = sgCalcBoundingRadius( Point3D::fromSGVec3(bs_center), group_nodes );
|
||||
}
|
||||
}
|
||||
|
||||
@ -1177,13 +1162,13 @@ bool SGBinObject::write_ascii( const string& base, const string& name,
|
||||
// make a list of points for the group
|
||||
point_list group_nodes;
|
||||
group_nodes.clear();
|
||||
Point3D bs_center;
|
||||
SGVec3d bs_center;
|
||||
double bs_radius = 0;
|
||||
for ( i = start; i < end; ++i ) {
|
||||
for ( j = 0; j < (int)strips_v[i].size(); ++j ) {
|
||||
group_nodes.push_back( wgs84_nodes[ strips_v[i][j] ] );
|
||||
bs_center = sgCalcCenter( group_nodes );
|
||||
bs_radius = sgCalcBoundingRadius( bs_center, group_nodes );
|
||||
group_nodes.push_back( Point3D::fromSGVec3(wgs84_nodes[ strips_v[i][j] ]) );
|
||||
bs_center = sgCalcCenter( group_nodes ).toSGVec3d();
|
||||
bs_radius = sgCalcBoundingRadius( Point3D::fromSGVec3(bs_center), group_nodes );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,13 +89,13 @@ typedef group_list::const_iterator const_group_list_iterator;
|
||||
class SGBinObject {
|
||||
unsigned short version;
|
||||
|
||||
Point3D gbs_center;
|
||||
SGVec3d gbs_center;
|
||||
float gbs_radius;
|
||||
|
||||
point_list wgs84_nodes; // vertex list
|
||||
point_list colors; // color list
|
||||
point_list normals; // normal list
|
||||
point_list texcoords; // texture coordinate list
|
||||
std::vector<SGVec3d> wgs84_nodes; // vertex list
|
||||
std::vector<SGVec4f> colors; // color list
|
||||
std::vector<SGVec3f> normals; // normal list
|
||||
std::vector<SGVec2f> texcoords; // texture coordinate list
|
||||
|
||||
group_list pts_v; // points vertex index
|
||||
group_list pts_n; // points normal index
|
||||
@ -125,23 +125,51 @@ public:
|
||||
|
||||
inline unsigned short get_version() const { return version; }
|
||||
|
||||
inline const Point3D& get_gbs_center() const { return gbs_center; }
|
||||
inline void set_gbs_center( const Point3D& p ) { gbs_center = p; }
|
||||
inline Point3D get_gbs_center() const { return Point3D::fromSGVec3(gbs_center); }
|
||||
inline void set_gbs_center( const Point3D& p ) { gbs_center = p.toSGVec3d(); }
|
||||
inline const SGVec3d& get_gbs_center2() const { return gbs_center; }
|
||||
inline void set_gbs_center( const SGVec3d& p ) { gbs_center = p; }
|
||||
|
||||
inline float get_gbs_radius() const { return gbs_radius; }
|
||||
inline void set_gbs_radius( float r ) { gbs_radius = r; }
|
||||
|
||||
inline const point_list& get_wgs84_nodes() const { return wgs84_nodes; }
|
||||
inline void set_wgs84_nodes( const point_list& n ) { wgs84_nodes = n; }
|
||||
inline const std::vector<SGVec3d>& get_wgs84_nodes() const
|
||||
{ return wgs84_nodes; }
|
||||
inline void set_wgs84_nodes( const std::vector<SGVec3d>& n )
|
||||
{ wgs84_nodes = n; }
|
||||
inline void set_wgs84_nodes( const point_list& n )
|
||||
{
|
||||
wgs84_nodes.resize(n.size());
|
||||
for (unsigned i = 0; i < wgs84_nodes.size(); ++i)
|
||||
wgs84_nodes[i] = n[i].toSGVec3d();
|
||||
}
|
||||
|
||||
inline const point_list& get_colors() const { return colors; }
|
||||
inline void set_colors( const point_list& c ) { colors = c; }
|
||||
inline const std::vector<SGVec4f>& get_colors() const { return colors; }
|
||||
inline void set_colors( const std::vector<SGVec4f>& c ) { colors = c; }
|
||||
inline void set_colors( const point_list& c )
|
||||
{
|
||||
colors.resize(c.size());
|
||||
for (unsigned i = 0; i < colors.size(); ++i)
|
||||
colors[i] = SGVec4f(c[i].toSGVec3f(), 1);
|
||||
}
|
||||
|
||||
inline const point_list& get_normals() const { return normals; }
|
||||
inline void set_normals( const point_list& n ) { normals = n; }
|
||||
inline const std::vector<SGVec3f>& get_normals() const { return normals; }
|
||||
inline void set_normals( const std::vector<SGVec3f>& n ) { normals = n; }
|
||||
inline void set_normals( const point_list& n )
|
||||
{
|
||||
normals.resize(n.size());
|
||||
for (unsigned i = 0; i < normals.size(); ++i)
|
||||
normals[i] = n[i].toSGVec3f();
|
||||
}
|
||||
|
||||
inline const point_list& get_texcoords() const { return texcoords; }
|
||||
inline void set_texcoords( const point_list& t ) { texcoords = t; }
|
||||
inline const std::vector<SGVec2f>& get_texcoords() const { return texcoords; }
|
||||
inline void set_texcoords( const std::vector<SGVec2f>& t ) { texcoords = t; }
|
||||
inline void set_texcoords( const point_list& t )
|
||||
{
|
||||
texcoords.resize(t.size());
|
||||
for (unsigned i = 0; i < texcoords.size(); ++i)
|
||||
texcoords[i] = t[i].toSGVec2f();
|
||||
}
|
||||
|
||||
inline const group_list& get_pts_v() const { return pts_v; }
|
||||
inline void set_pts_v( const group_list& g ) { pts_v = g; }
|
||||
|
@ -204,6 +204,15 @@ SGVec2<T>
|
||||
operator*(const SGVec2<T>& v, S s)
|
||||
{ return SGVec2<T>(s*v(0), s*v(1)); }
|
||||
|
||||
/// multiplication as a multiplicator, that is assume that the first vector
|
||||
/// represents a 2x2 diagonal matrix with the diagonal elements in the vector.
|
||||
/// Then the result is the product of that matrix times the second vector.
|
||||
template<typename T>
|
||||
inline
|
||||
SGVec2<T>
|
||||
mult(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
||||
{ return SGVec2<T>(v1(0)*v2(0), v1(1)*v2(1)); }
|
||||
|
||||
/// component wise min
|
||||
template<typename T>
|
||||
inline
|
||||
|
@ -261,6 +261,15 @@ SGVec3<T>
|
||||
operator*(const SGVec3<T>& v, S s)
|
||||
{ return SGVec3<T>(s*v(0), s*v(1), s*v(2)); }
|
||||
|
||||
/// multiplication as a multiplicator, that is assume that the first vector
|
||||
/// represents a 3x3 diagonal matrix with the diagonal elements in the vector.
|
||||
/// Then the result is the product of that matrix times the second vector.
|
||||
template<typename T>
|
||||
inline
|
||||
SGVec3<T>
|
||||
mult(const SGVec3<T>& v1, const SGVec3<T>& v2)
|
||||
{ return SGVec3<T>(v1(0)*v2(0), v1(1)*v2(1), v1(2)*v2(2)); }
|
||||
|
||||
/// component wise min
|
||||
template<typename T>
|
||||
inline
|
||||
|
@ -223,6 +223,15 @@ SGVec4<T>
|
||||
operator*(const SGVec4<T>& v, S s)
|
||||
{ return SGVec4<T>(s*v(0), s*v(1), s*v(2), s*v(3)); }
|
||||
|
||||
/// multiplication as a multiplicator, that is assume that the first vector
|
||||
/// represents a 4x4 diagonal matrix with the diagonal elements in the vector.
|
||||
/// Then the result is the product of that matrix times the second vector.
|
||||
template<typename T>
|
||||
inline
|
||||
SGVec4<T>
|
||||
mult(const SGVec4<T>& v1, const SGVec4<T>& v2)
|
||||
{ return SGVec4<T>(v1(0)*v2(0), v1(1)*v2(1), v1(2)*v2(2), v1(3)*v2(3)); }
|
||||
|
||||
/// component wise min
|
||||
template<typename T>
|
||||
inline
|
||||
|
@ -208,6 +208,20 @@ public:
|
||||
*/
|
||||
SGMaterialGlyph * get_glyph (const string& name) const;
|
||||
|
||||
void set_light_color(const SGVec4f& color)
|
||||
{ emission = color; }
|
||||
const SGVec4f& get_light_color() const
|
||||
{ return emission; }
|
||||
|
||||
SGVec2f get_tex_coord_scale() const
|
||||
{
|
||||
float tex_width = get_xsize();
|
||||
float tex_height = get_ysize();
|
||||
|
||||
return SGVec2f((0 < tex_width) ? 1000.0f/tex_width : 1.0f,
|
||||
(0 < tex_height) ? 1000.0f/tex_height : 1.0f);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
@ -46,7 +46,6 @@
|
||||
#include <osg/BlendFunc>
|
||||
#include <osg/CullFace>
|
||||
#include <osg/Material>
|
||||
// #include <osg/Multisample>
|
||||
#include <osg/Point>
|
||||
#include <osg/PointSprite>
|
||||
#include <osg/PolygonMode>
|
||||
@ -69,114 +68,10 @@
|
||||
SG_USING_NAMESPACE(std);
|
||||
SG_USING_STD(string);
|
||||
|
||||
extern bool SGPointLightsUseSprites;
|
||||
extern bool SGPointLightsEnhancedLighting;
|
||||
extern bool SGPointLightsDistanceAttenuation;
|
||||
|
||||
// FIXME: should make this configurable
|
||||
static const bool sprite_lighting = true;
|
||||
|
||||
// Constructor
|
||||
SGMaterialLib::SGMaterialLib ( void ) {
|
||||
}
|
||||
|
||||
// generate standard colored directional light environment texture map
|
||||
static osg::Texture2D*
|
||||
gen_standard_dir_light_map( int r, int g, int b, int alpha ) {
|
||||
const int env_tex_res = 32;
|
||||
int half_res = env_tex_res / 2;
|
||||
|
||||
osg::Image* image = new osg::Image;
|
||||
image->allocateImage(env_tex_res, env_tex_res, 1,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE);
|
||||
for ( int i = 0; i < env_tex_res; ++i ) {
|
||||
for ( int j = 0; j < env_tex_res; ++j ) {
|
||||
double x = (i - half_res) / (double)half_res;
|
||||
double y = (j - half_res) / (double)half_res;
|
||||
double dist = sqrt(x*x + y*y);
|
||||
if ( dist > 1.0 ) { dist = 1.0; }
|
||||
double bright = cos( dist * SGD_PI_2 );
|
||||
if ( bright < 0.3 ) { bright = 0.3; }
|
||||
unsigned char* env_map = image->data(i, j);
|
||||
env_map[0] = r;
|
||||
env_map[1] = g;
|
||||
env_map[2] = b;
|
||||
env_map[3] = (int)(bright * alpha);
|
||||
}
|
||||
}
|
||||
|
||||
osg::Texture2D* texture = new osg::Texture2D;
|
||||
texture->setImage(image);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
|
||||
// generate standard colored directional light environment texture map
|
||||
static osg::Texture2D*
|
||||
gen_taxiway_dir_light_map( int r, int g, int b, int alpha ) {
|
||||
const int env_tex_res = 32;
|
||||
int half_res = env_tex_res / 2;
|
||||
|
||||
osg::Image* image = new osg::Image;
|
||||
image->allocateImage(env_tex_res, env_tex_res, 1,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE);
|
||||
|
||||
for ( int i = 0; i < env_tex_res; ++i ) {
|
||||
for ( int j = 0; j < env_tex_res; ++j ) {
|
||||
double x = (i - half_res) / (double)half_res;
|
||||
double y = (j - half_res) / (double)half_res;
|
||||
double tmp = sqrt(x*x + y*y);
|
||||
double dist = tmp * tmp;
|
||||
if ( dist > 1.0 ) { dist = 1.0; }
|
||||
double bright = sin( dist * SGD_PI_2 );
|
||||
if ( bright < 0.2 ) { bright = 0.2; }
|
||||
unsigned char* env_map = image->data(i, j);
|
||||
env_map[0] = r;
|
||||
env_map[1] = g;
|
||||
env_map[2] = b;
|
||||
env_map[3] = (int)(bright * alpha);
|
||||
}
|
||||
}
|
||||
|
||||
osg::Texture2D* texture = new osg::Texture2D;
|
||||
texture->setImage(image);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
static osg::Texture2D*
|
||||
gen_standard_light_sprite( int r, int g, int b, int alpha ) {
|
||||
const int env_tex_res = 32;
|
||||
int half_res = env_tex_res / 2;
|
||||
|
||||
osg::Image* image = new osg::Image;
|
||||
image->allocateImage(env_tex_res, env_tex_res, 1,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE);
|
||||
|
||||
for ( int i = 0; i < env_tex_res; ++i ) {
|
||||
for ( int j = 0; j < env_tex_res; ++j ) {
|
||||
double x = (i - half_res) / (double)half_res;
|
||||
double y = (j - half_res) / (double)half_res;
|
||||
double dist = sqrt(x*x + y*y);
|
||||
if ( dist > 1.0 ) { dist = 1.0; }
|
||||
double bright = cos( dist * SGD_PI_2 );
|
||||
if ( bright < 0.01 ) { bright = 0.0; }
|
||||
unsigned char* env_map = image->data(i, j);
|
||||
env_map[0] = r;
|
||||
env_map[1] = g;
|
||||
env_map[2] = b;
|
||||
env_map[3] = (int)(bright * alpha);
|
||||
}
|
||||
}
|
||||
|
||||
osg::Texture2D* texture = new osg::Texture2D;
|
||||
texture->setImage(image);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
|
||||
// Load a library of material properties
|
||||
bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char *season ) {
|
||||
|
||||
@ -191,13 +86,11 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
|
||||
throw;
|
||||
}
|
||||
|
||||
SGSharedPtr<SGMaterial> m;
|
||||
|
||||
int nMaterials = materials.nChildren();
|
||||
for (int i = 0; i < nMaterials; i++) {
|
||||
const SGPropertyNode * node = materials.getChild(i);
|
||||
if (!strcmp(node->getName(), "material")) {
|
||||
m = new SGMaterial( fg_root, node, season );
|
||||
SGSharedPtr<SGMaterial> m = new SGMaterial(fg_root, node, season);
|
||||
|
||||
vector<SGPropertyNode_ptr>names = node->getChildren("name");
|
||||
for ( unsigned int j = 0; j < names.size(); j++ ) {
|
||||
@ -214,268 +107,6 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
|
||||
}
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::StateSet> lightStateSet = new osg::StateSet;
|
||||
{
|
||||
lightStateSet->setRenderBinDetails(9, "DepthSortedBin");
|
||||
lightStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
// lightStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
|
||||
|
||||
lightStateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||
|
||||
lightStateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::OFF);
|
||||
lightStateSet->setAttribute(new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.01));
|
||||
lightStateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON);
|
||||
|
||||
osg::CullFace* cullFace = new osg::CullFace;
|
||||
cullFace->setMode(osg::CullFace::BACK);
|
||||
lightStateSet->setAttributeAndModes(cullFace, osg::StateAttribute::ON);
|
||||
|
||||
osg::BlendFunc* blendFunc = new osg::BlendFunc;
|
||||
blendFunc->setFunction(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA);
|
||||
lightStateSet->setAttributeAndModes(blendFunc, osg::StateAttribute::ON);
|
||||
|
||||
osg::PolygonMode* polygonMode = new osg::PolygonMode;
|
||||
polygonMode->setMode(osg::PolygonMode::FRONT, osg::PolygonMode::POINT);
|
||||
lightStateSet->setAttribute(polygonMode);
|
||||
|
||||
// if (SGPointLightsUseSprites) {
|
||||
osg::PointSprite* pointSprite = new osg::PointSprite;
|
||||
lightStateSet->setTextureAttributeAndModes(0, pointSprite, osg::StateAttribute::ON);
|
||||
// }
|
||||
|
||||
// if (SGPointLightsDistanceAttenuation) {
|
||||
osg::Point* point = new osg::Point;
|
||||
point->setMinSize(2);
|
||||
point->setSize(8);
|
||||
point->setDistanceAttenuation(osg::Vec3(1.0, 0.001, 0.000001));
|
||||
lightStateSet->setAttribute(point);
|
||||
// }
|
||||
|
||||
osg::PolygonOffset* polygonOffset = new osg::PolygonOffset;
|
||||
polygonOffset->setFactor(-1);
|
||||
polygonOffset->setUnits(-1);
|
||||
lightStateSet->setAttributeAndModes(polygonOffset, osg::StateAttribute::ON);
|
||||
|
||||
osg::TexGen* texGen = new osg::TexGen;
|
||||
texGen->setMode(osg::TexGen::SPHERE_MAP);
|
||||
lightStateSet->setTextureAttribute(0, texGen);
|
||||
lightStateSet->setTextureMode(0, GL_TEXTURE_GEN_S, osg::StateAttribute::ON);
|
||||
lightStateSet->setTextureMode(0, GL_TEXTURE_GEN_T, osg::StateAttribute::ON);
|
||||
osg::TexEnv* texEnv = new osg::TexEnv;
|
||||
texEnv->setMode(osg::TexEnv::MODULATE);
|
||||
lightStateSet->setTextureAttribute(0, texEnv);
|
||||
|
||||
osg::Material* material = new osg::Material;
|
||||
lightStateSet->setAttribute(material);
|
||||
}
|
||||
|
||||
|
||||
// hard coded ground light state
|
||||
osg::StateSet *gnd_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
// if (SGPointLightsDistanceAttenuation) {
|
||||
osg::Point* point = new osg::Point;
|
||||
point->setMinSize(1);
|
||||
point->setSize(2);
|
||||
point->setMaxSize(4);
|
||||
point->setDistanceAttenuation(osg::Vec3(1.0, 0.01, 0.0001));
|
||||
while (gnd_lights->getAttribute(osg::StateAttribute::POINT)) {
|
||||
gnd_lights->removeAttribute(osg::StateAttribute::POINT);
|
||||
}
|
||||
gnd_lights->setAttribute(point);
|
||||
// }
|
||||
m = new SGMaterial( gnd_lights );
|
||||
m->add_name("GROUND_LIGHTS");
|
||||
matlib["GROUND_LIGHTS"] = m;
|
||||
|
||||
// hard coded runway white light state
|
||||
osg::Texture2D* texture;
|
||||
if ( sprite_lighting ) {
|
||||
texture = gen_standard_light_sprite(235, 235, 195, 255);
|
||||
} else {
|
||||
texture = gen_standard_dir_light_map(235, 235, 195, 255);
|
||||
}
|
||||
osg::StateSet *rwy_white_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
rwy_white_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
|
||||
|
||||
m = new SGMaterial( rwy_white_lights );
|
||||
m->add_name("RWY_WHITE_LIGHTS");
|
||||
matlib["RWY_WHITE_LIGHTS"] = m;
|
||||
// For backwards compatibility ... remove someday
|
||||
m->add_name("RUNWAY_LIGHTS");
|
||||
matlib["RUNWAY_LIGHTS"] = m;
|
||||
m->add_name("RWY_LIGHTS");
|
||||
matlib["RWY_LIGHTS"] = m;
|
||||
// end of backwards compatitibilty
|
||||
|
||||
// hard coded runway medium intensity white light state
|
||||
if ( sprite_lighting ) {
|
||||
texture = gen_standard_light_sprite( 235, 235, 195, 205 );
|
||||
} else {
|
||||
texture = gen_standard_dir_light_map( 235, 235, 195, 205 );
|
||||
}
|
||||
osg::StateSet *rwy_white_medium_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
rwy_white_medium_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
|
||||
|
||||
m = new SGMaterial( rwy_white_medium_lights );
|
||||
m->add_name("RWY_WHITE_MEDIUM_LIGHTS");
|
||||
matlib["RWY_WHITE_MEDIUM_LIGHTS"] = m;
|
||||
|
||||
// hard coded runway low intensity white light state
|
||||
if ( sprite_lighting ) {
|
||||
texture = gen_standard_light_sprite( 235, 235, 195, 155 );
|
||||
} else {
|
||||
texture = gen_standard_dir_light_map( 235, 235, 195, 155 );
|
||||
}
|
||||
osg::StateSet *rwy_white_low_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
rwy_white_medium_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
|
||||
m = new SGMaterial( rwy_white_low_lights );
|
||||
m->add_name("RWY_WHITE_LOW_LIGHTS");
|
||||
matlib["RWY_WHITE_LOW_LIGHTS"] = m;
|
||||
|
||||
// hard coded runway yellow light state
|
||||
if ( sprite_lighting ) {
|
||||
texture = gen_standard_light_sprite( 235, 215, 20, 255 );
|
||||
} else {
|
||||
texture = gen_standard_dir_light_map( 235, 215, 20, 255 );
|
||||
}
|
||||
osg::StateSet *rwy_yellow_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
rwy_yellow_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
|
||||
m = new SGMaterial( rwy_yellow_lights );
|
||||
m->add_name("RWY_YELLOW_LIGHTS");
|
||||
matlib["RWY_YELLOW_LIGHTS"] = m;
|
||||
|
||||
// hard coded runway medium intensity yellow light state
|
||||
if ( sprite_lighting ) {
|
||||
texture = gen_standard_light_sprite( 235, 215, 20, 205 );
|
||||
} else {
|
||||
texture = gen_standard_dir_light_map( 235, 215, 20, 205 );
|
||||
}
|
||||
osg::StateSet *rwy_yellow_medium_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
rwy_yellow_medium_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
|
||||
m = new SGMaterial( rwy_yellow_medium_lights );
|
||||
m->add_name("RWY_YELLOW_MEDIUM_LIGHTS");
|
||||
matlib["RWY_YELLOW_MEDIUM_LIGHTS"] = m;
|
||||
|
||||
// hard coded runway low intensity yellow light state
|
||||
if ( sprite_lighting ) {
|
||||
texture = gen_standard_light_sprite( 235, 215, 20, 155 );
|
||||
} else {
|
||||
texture = gen_standard_dir_light_map( 235, 215, 20, 155 );
|
||||
}
|
||||
osg::StateSet *rwy_yellow_low_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
rwy_yellow_low_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
|
||||
m = new SGMaterial( rwy_yellow_low_lights );
|
||||
m->add_name("RWY_YELLOW_LOW_LIGHTS");
|
||||
matlib["RWY_YELLOW_LOW_LIGHTS"] = m;
|
||||
|
||||
// hard coded runway red light state
|
||||
if ( sprite_lighting ) {
|
||||
texture = gen_standard_light_sprite( 235, 90, 90, 255 );
|
||||
} else {
|
||||
texture = gen_standard_dir_light_map( 235, 90, 90, 255 );
|
||||
}
|
||||
osg::StateSet *rwy_red_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
rwy_red_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
|
||||
m = new SGMaterial( rwy_red_lights );
|
||||
m->add_name("RWY_RED_LIGHTS");
|
||||
matlib["RWY_RED_LIGHTS"] = m;
|
||||
|
||||
// hard coded medium intensity runway red light state
|
||||
if ( sprite_lighting ) {
|
||||
texture = gen_standard_light_sprite( 235, 90, 90, 205 );
|
||||
} else {
|
||||
texture = gen_standard_dir_light_map( 235, 90, 90, 205 );
|
||||
}
|
||||
osg::StateSet *rwy_red_medium_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
rwy_red_medium_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
|
||||
m = new SGMaterial( rwy_red_medium_lights );
|
||||
m->add_name("RWY_RED_MEDIUM_LIGHTS");
|
||||
matlib["RWY_RED_MEDIUM_LIGHTS"] = m;
|
||||
|
||||
// hard coded low intensity runway red light state
|
||||
if ( sprite_lighting ) {
|
||||
texture = gen_standard_light_sprite( 235, 90, 90, 155 );
|
||||
} else {
|
||||
texture = gen_standard_dir_light_map( 235, 90, 90, 155 );
|
||||
}
|
||||
osg::StateSet *rwy_red_low_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
rwy_red_low_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
|
||||
m = new SGMaterial( rwy_red_low_lights );
|
||||
m->add_name("RWY_RED_LOW_LIGHTS");
|
||||
matlib["RWY_RED_LOW_LIGHTS"] = m;
|
||||
|
||||
// hard coded runway green light state
|
||||
if ( sprite_lighting ) {
|
||||
texture = gen_standard_light_sprite( 20, 235, 20, 255 );
|
||||
} else {
|
||||
texture = gen_standard_dir_light_map( 20, 235, 20, 255 );
|
||||
}
|
||||
osg::StateSet *rwy_green_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
rwy_green_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
|
||||
m = new SGMaterial( rwy_green_lights );
|
||||
m->add_name("RWY_GREEN_LIGHTS");
|
||||
matlib["RWY_GREEN_LIGHTS"] = m;
|
||||
|
||||
// hard coded medium intensity runway green light state
|
||||
if ( sprite_lighting ) {
|
||||
texture = gen_standard_light_sprite( 20, 235, 20, 205 );
|
||||
} else {
|
||||
texture = gen_standard_dir_light_map( 20, 235, 20, 205 );
|
||||
}
|
||||
osg::StateSet *rwy_green_medium_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
rwy_green_medium_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
|
||||
m = new SGMaterial( rwy_green_medium_lights );
|
||||
m->add_name("RWY_GREEN_MEDIUM_LIGHTS");
|
||||
matlib["RWY_GREEN_MEDIUM_LIGHTS"] = m;
|
||||
|
||||
// hard coded low intensity runway green light state
|
||||
if ( sprite_lighting ) {
|
||||
texture = gen_standard_light_sprite( 20, 235, 20, 155 );
|
||||
} else {
|
||||
texture = gen_standard_dir_light_map( 20, 235, 20, 155 );
|
||||
}
|
||||
osg::StateSet *rwy_green_low_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
rwy_green_low_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
|
||||
m = new SGMaterial( rwy_green_low_lights );
|
||||
m->add_name("RWY_GREEN_LOW_LIGHTS");
|
||||
matlib["RWY_GREEN_LOW_LIGHTS"] = m;
|
||||
m->add_name("RWY_GREEN_TAXIWAY_LIGHTS");
|
||||
matlib["RWY_GREEN_TAXIWAY_LIGHTS"] = m;
|
||||
|
||||
// hard coded low intensity taxiway blue light state
|
||||
if ( sprite_lighting ) {
|
||||
texture = gen_standard_light_sprite( 90, 90, 235, 205 );
|
||||
} else {
|
||||
texture = gen_taxiway_dir_light_map( 90, 90, 235, 205 );
|
||||
}
|
||||
osg::StateSet *taxiway_blue_low_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
taxiway_blue_low_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
|
||||
m = new SGMaterial( taxiway_blue_low_lights );
|
||||
m->add_name("RWY_BLUE_TAXIWAY_LIGHTS");
|
||||
matlib["RWY_BLUE_TAXIWAY_LIGHTS"] = m;
|
||||
|
||||
// hard coded runway vasi light state
|
||||
if ( sprite_lighting ) {
|
||||
texture = gen_standard_light_sprite( 235, 235, 195, 255 );
|
||||
} else {
|
||||
texture = gen_standard_dir_light_map( 235, 235, 195, 255 );
|
||||
}
|
||||
osg::StateSet *rwy_vasi_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
// if (SGPointLightsDistanceAttenuation) {
|
||||
point = new osg::Point;
|
||||
point->setMinSize(4);
|
||||
point->setSize(10);
|
||||
point->setDistanceAttenuation(osg::Vec3(1.0, 0.01, 0.0001));
|
||||
while (rwy_vasi_lights->getAttribute(osg::StateAttribute::POINT)) {
|
||||
rwy_vasi_lights->removeAttribute(osg::StateAttribute::POINT);
|
||||
}
|
||||
rwy_vasi_lights->setAttribute(point);
|
||||
// }
|
||||
rwy_vasi_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
|
||||
m = new SGMaterial( rwy_vasi_lights );
|
||||
m->add_name("RWY_VASI_LIGHTS");
|
||||
matlib["RWY_VASI_LIGHTS"] = m;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ class SGMaterialLib {
|
||||
private:
|
||||
|
||||
// associative array of materials
|
||||
typedef map < string, SGSharedPtr<SGMaterial>, less<string> > material_map;
|
||||
typedef map < string, SGSharedPtr<SGMaterial> > material_map;
|
||||
typedef material_map::iterator material_map_iterator;
|
||||
typedef material_map::const_iterator const_material_map_iterator;
|
||||
|
||||
|
@ -12,7 +12,8 @@ include_HEADERS = \
|
||||
persparam.hxx \
|
||||
placement.hxx \
|
||||
placementtrans.hxx \
|
||||
SGMaterialAnimation.hxx
|
||||
SGMaterialAnimation.hxx \
|
||||
SGOffsetTransform.hxx
|
||||
|
||||
libsgmodel_a_SOURCES = \
|
||||
animation.cxx \
|
||||
@ -23,6 +24,7 @@ libsgmodel_a_SOURCES = \
|
||||
placement.cxx \
|
||||
placementtrans.cxx \
|
||||
shadanim.cxx \
|
||||
SGMaterialAnimation.cxx
|
||||
SGMaterialAnimation.cxx \
|
||||
SGOffsetTransform.cxx
|
||||
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
|
68
simgear/scene/model/SGOffsetTransform.cxx
Normal file
68
simgear/scene/model/SGOffsetTransform.cxx
Normal file
@ -0,0 +1,68 @@
|
||||
/* -*-c++-*-
|
||||
*
|
||||
* Copyright (C) 2006-2007 Mathias Froehlich
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include "SGOffsetTransform.hxx"
|
||||
|
||||
SGOffsetTransform::SGOffsetTransform(double scaleFactor) :
|
||||
_scaleFactor(scaleFactor),
|
||||
_rScaleFactor(1/scaleFactor)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
SGOffsetTransform::computeLocalToWorldMatrix(osg::Matrix& matrix,
|
||||
osg::NodeVisitor* nv) const
|
||||
{
|
||||
if (nv && nv->getVisitorType() == osg::NodeVisitor::CULL_VISITOR) {
|
||||
osg::Vec3 center = nv->getEyePoint();
|
||||
osg::Matrix transform;
|
||||
transform(0,0) = _scaleFactor;
|
||||
transform(1,1) = _scaleFactor;
|
||||
transform(2,2) = _scaleFactor;
|
||||
transform(3,0) = center[0]*(1 - _scaleFactor);
|
||||
transform(3,1) = center[1]*(1 - _scaleFactor);
|
||||
transform(3,2) = center[2]*(1 - _scaleFactor);
|
||||
matrix.preMult(transform);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SGOffsetTransform::computeWorldToLocalMatrix(osg::Matrix& matrix,
|
||||
osg::NodeVisitor* nv) const
|
||||
{
|
||||
if (nv && nv->getVisitorType() == osg::NodeVisitor::CULL_VISITOR) {
|
||||
osg::Vec3 center = nv->getEyePoint();
|
||||
osg::Matrix transform;
|
||||
transform(0,0) = _rScaleFactor;
|
||||
transform(1,1) = _rScaleFactor;
|
||||
transform(2,2) = _rScaleFactor;
|
||||
transform(3,0) = center[0]*(1 - _rScaleFactor);
|
||||
transform(3,1) = center[1]*(1 - _rScaleFactor);
|
||||
transform(3,2) = center[2]*(1 - _rScaleFactor);
|
||||
matrix.postMult(transform);
|
||||
}
|
||||
return true;
|
||||
}
|
39
simgear/scene/model/SGOffsetTransform.hxx
Normal file
39
simgear/scene/model/SGOffsetTransform.hxx
Normal file
@ -0,0 +1,39 @@
|
||||
/* -*-c++-*-
|
||||
*
|
||||
* Copyright (C) 2006-2007 Mathias Froehlich
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SG_OFFSET_TRASNFORM_HXX
|
||||
#define SG_OFFSET_TRASNFORM_HXX
|
||||
|
||||
#include <osg/Transform>
|
||||
|
||||
class SGOffsetTransform : public osg::Transform {
|
||||
public:
|
||||
SGOffsetTransform(double scaleFactor);
|
||||
virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,
|
||||
osg::NodeVisitor* nv) const;
|
||||
virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,
|
||||
osg::NodeVisitor* nv) const;
|
||||
private:
|
||||
double _scaleFactor;
|
||||
double _rScaleFactor;
|
||||
};
|
||||
|
||||
#endif
|
@ -6,17 +6,24 @@ noinst_HEADERS =
|
||||
|
||||
include_HEADERS = \
|
||||
apt_signs.hxx \
|
||||
leaf.hxx \
|
||||
obj.hxx \
|
||||
pt_lights.hxx \
|
||||
userdata.hxx \
|
||||
vasi.hxx
|
||||
SGOceanTile.hxx \
|
||||
SGVasiDrawable.hxx \
|
||||
SGDirectionalLightBin.hxx \
|
||||
SGLightBin.hxx \
|
||||
SGOceanTile.hxx \
|
||||
SGTexturedTriangleBin.hxx \
|
||||
SGTriangleBin.hxx \
|
||||
SGVertexArrayBin.hxx
|
||||
|
||||
libsgtgdb_a_SOURCES = \
|
||||
apt_signs.cxx \
|
||||
leaf.cxx \
|
||||
obj.cxx \
|
||||
pt_lights.cxx \
|
||||
userdata.cxx
|
||||
userdata.cxx \
|
||||
SGOceanTile.cxx \
|
||||
SGVasiDrawable.cxx
|
||||
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
|
78
simgear/scene/tgdb/SGDirectionalLightBin.hxx
Normal file
78
simgear/scene/tgdb/SGDirectionalLightBin.hxx
Normal file
@ -0,0 +1,78 @@
|
||||
/* -*-c++-*-
|
||||
*
|
||||
* Copyright (C) 2006-2007 Mathias Froehlich
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SG_DIRECTIONAL_LIGHT_BIN_HXX
|
||||
#define SG_DIRECTIONAL_LIGHT_BIN_HXX
|
||||
|
||||
class SGDirectionalLightBin {
|
||||
public:
|
||||
struct Light {
|
||||
Light(const SGVec3f& p, const SGVec3f& n, const SGVec4f& c) :
|
||||
position(p), normal(n), color(c)
|
||||
{ }
|
||||
SGVec3f position;
|
||||
SGVec3f normal;
|
||||
SGVec4f color;
|
||||
};
|
||||
typedef std::vector<Light> LightList;
|
||||
|
||||
void insert(const Light& light)
|
||||
{ _lights.push_back(light); }
|
||||
void insert(const SGVec3f& p, const SGVec3f& n, const SGVec4f& c)
|
||||
{ insert(Light(p, n, c)); }
|
||||
|
||||
unsigned getNumLights() const
|
||||
{ return _lights.size(); }
|
||||
const Light& getLight(unsigned i) const
|
||||
{ return _lights[i]; }
|
||||
|
||||
// helper for sorting lights back to front ...
|
||||
struct DirectionLess {
|
||||
DirectionLess(const SGVec3f& direction) :
|
||||
_direction(direction)
|
||||
{ }
|
||||
inline bool operator() (const Light& l, const Light& r) const
|
||||
{ return dot(_direction, l.position) < dot(_direction, r.position); }
|
||||
private:
|
||||
SGVec3f _direction;
|
||||
};
|
||||
typedef std::multiset<Light,DirectionLess> LightSet;
|
||||
|
||||
LightList getSortedLights(const SGVec3f& sortDirection) const
|
||||
{
|
||||
LightSet lightSet = LightSet(DirectionLess(sortDirection));
|
||||
for (unsigned i = 0; i < _lights.size(); ++i)
|
||||
lightSet.insert(_lights[i]);
|
||||
|
||||
LightList sortedLights;
|
||||
sortedLights.reserve(_lights.size());
|
||||
LightSet::const_iterator i;
|
||||
for (i = lightSet.begin(); i != lightSet.end(); ++i)
|
||||
sortedLights.push_back(*i);
|
||||
|
||||
return sortedLights;
|
||||
}
|
||||
|
||||
private:
|
||||
LightList _lights;
|
||||
};
|
||||
|
||||
#endif
|
50
simgear/scene/tgdb/SGLightBin.hxx
Normal file
50
simgear/scene/tgdb/SGLightBin.hxx
Normal file
@ -0,0 +1,50 @@
|
||||
/* -*-c++-*-
|
||||
*
|
||||
* Copyright (C) 2006-2007 Mathias Froehlich
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SG_LIGHT_BIN_HXX
|
||||
#define SG_LIGHT_BIN_HXX
|
||||
|
||||
class SGLightBin {
|
||||
public:
|
||||
struct Light {
|
||||
Light(const SGVec3f& p, const SGVec4f& c) :
|
||||
position(p), color(c)
|
||||
{ }
|
||||
SGVec3f position;
|
||||
SGVec4f color;
|
||||
};
|
||||
typedef std::vector<Light> LightList;
|
||||
|
||||
void insert(const Light& light)
|
||||
{ _lights.push_back(light); }
|
||||
void insert(const SGVec3f& p, const SGVec4f& c)
|
||||
{ insert(Light(p, c)); }
|
||||
|
||||
unsigned getNumLights() const
|
||||
{ return _lights.size(); }
|
||||
const Light& getLight(unsigned i) const
|
||||
{ return _lights[i]; }
|
||||
|
||||
private:
|
||||
LightList _lights;
|
||||
};
|
||||
|
||||
#endif
|
131
simgear/scene/tgdb/SGOceanTile.cxx
Normal file
131
simgear/scene/tgdb/SGOceanTile.cxx
Normal file
@ -0,0 +1,131 @@
|
||||
/* -*-c++-*-
|
||||
*
|
||||
* Copyright (C) 2006-2007 Mathias Froehlich
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include "SGOceanTile.hxx"
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <osg/Geode>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/StateSet>
|
||||
|
||||
#include <simgear/bucket/newbucket.hxx>
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
#include <simgear/math/sg_types.hxx>
|
||||
#include <simgear/misc/texcoord.hxx>
|
||||
#include <simgear/scene/material/mat.hxx>
|
||||
#include <simgear/scene/material/matlib.hxx>
|
||||
|
||||
// Generate an ocean tile
|
||||
osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib)
|
||||
{
|
||||
osg::StateSet *stateSet = 0;
|
||||
|
||||
double tex_width = 1000.0;
|
||||
|
||||
// find Ocean material in the properties list
|
||||
SGMaterial *mat = matlib->find( "Ocean" );
|
||||
if ( mat != NULL ) {
|
||||
// set the texture width and height values for this
|
||||
// material
|
||||
tex_width = mat->get_xsize();
|
||||
|
||||
// set ssgState
|
||||
stateSet = mat->get_state();
|
||||
} else {
|
||||
SG_LOG( SG_TERRAIN, SG_ALERT, "Ack! unknown use material name = Ocean");
|
||||
}
|
||||
|
||||
// Calculate center point
|
||||
SGVec3d cartCenter = SGVec3d::fromGeod(b.get_center());
|
||||
Point3D center = Point3D(cartCenter[0], cartCenter[1], cartCenter[2]);
|
||||
|
||||
double clon = b.get_center_lon();
|
||||
double clat = b.get_center_lat();
|
||||
double height = b.get_height();
|
||||
double width = b.get_width();
|
||||
|
||||
// Caculate corner vertices
|
||||
SGGeod geod[4];
|
||||
geod[0] = SGGeod::fromDeg( clon - 0.5*width, clat - 0.5*height );
|
||||
geod[1] = SGGeod::fromDeg( clon + 0.5*width, clat - 0.5*height );
|
||||
geod[2] = SGGeod::fromDeg( clon + 0.5*width, clat + 0.5*height );
|
||||
geod[3] = SGGeod::fromDeg( clon - 0.5*width, clat + 0.5*height );
|
||||
|
||||
int i;
|
||||
SGVec3f normals[4];
|
||||
SGVec3d rel[4];
|
||||
for ( i = 0; i < 4; ++i ) {
|
||||
SGVec3d cart = SGVec3d::fromGeod(geod[i]);
|
||||
rel[i] = cart - center.toSGVec3d();
|
||||
normals[i] = toVec3f(normalize(cart));
|
||||
}
|
||||
|
||||
// Calculate texture coordinates
|
||||
point_list geod_nodes;
|
||||
geod_nodes.clear();
|
||||
geod_nodes.reserve(4);
|
||||
int_list rectangle;
|
||||
rectangle.clear();
|
||||
rectangle.reserve(4);
|
||||
for ( i = 0; i < 4; ++i ) {
|
||||
geod_nodes.push_back( Point3D::fromSGGeod(geod[i]) );
|
||||
rectangle.push_back( i );
|
||||
}
|
||||
point_list texs = sgCalcTexCoords( b, geod_nodes, rectangle,
|
||||
1000.0 / tex_width );
|
||||
|
||||
// Allocate ssg structure
|
||||
osg::Vec3Array *vl = new osg::Vec3Array;
|
||||
osg::Vec3Array *nl = new osg::Vec3Array;
|
||||
osg::Vec2Array *tl = new osg::Vec2Array;
|
||||
|
||||
for ( i = 0; i < 4; ++i ) {
|
||||
vl->push_back(rel[i].osg());
|
||||
nl->push_back(normals[i].osg());
|
||||
tl->push_back(texs[i].toSGVec2f().osg());
|
||||
}
|
||||
|
||||
osg::Vec4Array* cl = new osg::Vec4Array;
|
||||
cl->push_back(osg::Vec4(1, 1, 1, 1));
|
||||
|
||||
osg::Geometry* geometry = new osg::Geometry;
|
||||
geometry->setVertexArray(vl);
|
||||
geometry->setNormalArray(nl);
|
||||
geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
|
||||
geometry->setColorArray(cl);
|
||||
geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
|
||||
geometry->setTexCoordArray(0, tl);
|
||||
osg::DrawArrays* drawArrays;
|
||||
drawArrays = new osg::DrawArrays(GL_TRIANGLE_FAN, 0, vl->size());
|
||||
geometry->addPrimitiveSet(drawArrays);
|
||||
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
geode->setName("Ocean tile");
|
||||
geode->addDrawable(geometry);
|
||||
geode->setStateSet(stateSet);
|
||||
|
||||
return geode;
|
||||
}
|
33
simgear/scene/tgdb/SGOceanTile.hxx
Normal file
33
simgear/scene/tgdb/SGOceanTile.hxx
Normal file
@ -0,0 +1,33 @@
|
||||
/* -*-c++-*-
|
||||
*
|
||||
* Copyright (C) 2006-2007 Mathias Froehlich
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _SG_OceanTile_HXX
|
||||
#define _SG_OceanTile_HXX
|
||||
|
||||
#include <osg/Node>
|
||||
|
||||
class SGBucket;
|
||||
class SGMaterialLib;
|
||||
|
||||
// Generate an ocean tile
|
||||
osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib);
|
||||
|
||||
#endif // _SG_OBJ_HXX
|
164
simgear/scene/tgdb/SGTexturedTriangleBin.hxx
Normal file
164
simgear/scene/tgdb/SGTexturedTriangleBin.hxx
Normal file
@ -0,0 +1,164 @@
|
||||
/* -*-c++-*-
|
||||
*
|
||||
* Copyright (C) 2006-2007 Mathias Froehlich
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SG_TEXTURED_TRIANGLE_BIN_HXX
|
||||
#define SG_TEXTURED_TRIANGLE_BIN_HXX
|
||||
|
||||
#include <osg/Array>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/PrimitiveSet>
|
||||
|
||||
#include <simgear/math/sg_random.h>
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
#include "SGTriangleBin.hxx"
|
||||
|
||||
struct SGVertNormTex {
|
||||
SGVertNormTex()
|
||||
{ }
|
||||
SGVertNormTex(const SGVec3f& v, const SGVec3f& n, const SGVec2f& t) :
|
||||
vertex(v), normal(n), texCoord(t)
|
||||
{ }
|
||||
struct less
|
||||
{
|
||||
inline bool operator() (const SGVertNormTex& l,
|
||||
const SGVertNormTex& r) const
|
||||
{
|
||||
if (l.vertex < r.vertex) return true;
|
||||
else if (r.vertex < l.vertex) return false;
|
||||
else if (l.normal < r.normal) return true;
|
||||
else if (r.normal < l.normal) return false;
|
||||
else return l.texCoord < r.texCoord;
|
||||
}
|
||||
};
|
||||
|
||||
SGVec3f vertex;
|
||||
SGVec3f normal;
|
||||
SGVec2f texCoord;
|
||||
};
|
||||
|
||||
class SGTexturedTriangleBin : public SGTriangleBin<SGVertNormTex> {
|
||||
public:
|
||||
|
||||
// Computes and adds random surface points to the points list.
|
||||
// The random points are computed with a density of (coverage points)/1
|
||||
// The points are offsetted away from the triangles in
|
||||
// offset * positive normal direction.
|
||||
void addRandomSurfacePoints(float coverage, float offset,
|
||||
std::vector<SGVec3f>& points) const
|
||||
{
|
||||
unsigned num = getNumTriangles();
|
||||
for (unsigned i = 0; i < num; ++i) {
|
||||
triangle_ref triangleRef = getTriangleRef(i);
|
||||
SGVec3f v0 = getVertex(triangleRef[0]).vertex;
|
||||
SGVec3f v1 = getVertex(triangleRef[1]).vertex;
|
||||
SGVec3f v2 = getVertex(triangleRef[2]).vertex;
|
||||
SGVec3f normal = cross(v1 - v0, v2 - v0);
|
||||
|
||||
// Compute the area
|
||||
float area = 0.5f*length(normal);
|
||||
if (area <= SGLimitsf::min())
|
||||
continue;
|
||||
|
||||
// For partial units of area, use a zombie door method to
|
||||
// create the proper random chance of a light being created
|
||||
// for this triangle
|
||||
float unit = area + sg_random()*coverage;
|
||||
|
||||
SGVec3f offsetVector = offset*normalize(normal);
|
||||
// generate a light point for each unit of area
|
||||
while ( coverage < unit ) {
|
||||
float a = sg_random();
|
||||
float b = sg_random();
|
||||
if ( a + b > 1 ) {
|
||||
a = 1 - a;
|
||||
b = 1 - b;
|
||||
}
|
||||
float c = 1 - a - b;
|
||||
SGVec3f randomPoint = offsetVector + a*v0 + b*v1 + c*v2;
|
||||
points.push_back(randomPoint);
|
||||
unit -= coverage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
osg::Geometry* buildGeometry(const TriangleVector& triangles) const
|
||||
{
|
||||
// Do not build anything if there is nothing in here ...
|
||||
if (empty() || triangles.empty())
|
||||
return 0;
|
||||
|
||||
// FIXME: do not include all values here ...
|
||||
osg::Vec3Array* vertices = new osg::Vec3Array;
|
||||
osg::Vec3Array* normals = new osg::Vec3Array;
|
||||
osg::Vec2Array* texCoords = new osg::Vec2Array;
|
||||
|
||||
osg::Vec4Array* colors = new osg::Vec4Array;
|
||||
colors->push_back(osg::Vec4(1, 1, 1, 1));
|
||||
|
||||
osg::Geometry* geometry = new osg::Geometry;
|
||||
geometry->setVertexArray(vertices);
|
||||
geometry->setNormalArray(normals);
|
||||
geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
|
||||
geometry->setColorArray(colors);
|
||||
geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
|
||||
geometry->setTexCoordArray(0, texCoords);
|
||||
|
||||
const unsigned invalid = ~unsigned(0);
|
||||
std::vector<unsigned> indexMap(getNumVertices(), invalid);
|
||||
|
||||
osg::DrawElementsUInt* drawElements;
|
||||
drawElements = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);
|
||||
for (index_type i = 0; i < triangles.size(); ++i) {
|
||||
triangle_ref triangle = triangles[i];
|
||||
if (indexMap[triangle[0]] == invalid) {
|
||||
indexMap[triangle[0]] = vertices->size();
|
||||
vertices->push_back(getVertex(triangle[0]).vertex.osg());
|
||||
normals->push_back(getVertex(triangle[0]).normal.osg());
|
||||
texCoords->push_back(getVertex(triangle[0]).texCoord.osg());
|
||||
}
|
||||
drawElements->push_back(indexMap[triangle[0]]);
|
||||
|
||||
if (indexMap[triangle[1]] == invalid) {
|
||||
indexMap[triangle[1]] = vertices->size();
|
||||
vertices->push_back(getVertex(triangle[1]).vertex.osg());
|
||||
normals->push_back(getVertex(triangle[1]).normal.osg());
|
||||
texCoords->push_back(getVertex(triangle[1]).texCoord.osg());
|
||||
}
|
||||
drawElements->push_back(indexMap[triangle[1]]);
|
||||
|
||||
if (indexMap[triangle[2]] == invalid) {
|
||||
indexMap[triangle[2]] = vertices->size();
|
||||
vertices->push_back(getVertex(triangle[2]).vertex.osg());
|
||||
normals->push_back(getVertex(triangle[2]).normal.osg());
|
||||
texCoords->push_back(getVertex(triangle[2]).texCoord.osg());
|
||||
}
|
||||
drawElements->push_back(indexMap[triangle[2]]);
|
||||
}
|
||||
geometry->addPrimitiveSet(drawElements);
|
||||
|
||||
return geometry;
|
||||
}
|
||||
|
||||
osg::Geometry* buildGeometry() const
|
||||
{ return buildGeometry(getTriangles()); }
|
||||
};
|
||||
|
||||
#endif
|
123
simgear/scene/tgdb/SGTriangleBin.hxx
Normal file
123
simgear/scene/tgdb/SGTriangleBin.hxx
Normal file
@ -0,0 +1,123 @@
|
||||
/* -*-c++-*-
|
||||
*
|
||||
* Copyright (C) 2006-2007 Mathias Froehlich
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SG_TRIANGLE_BIN_HXX
|
||||
#define SG_TRIANGLE_BIN_HXX
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "SGVertexArrayBin.hxx"
|
||||
|
||||
template<typename T>
|
||||
class SGTriangleBin : public SGVertexArrayBin<T> {
|
||||
public:
|
||||
#define BUILD_EDGE_MAP
|
||||
typedef typename SGVertexArrayBin<T>::value_type value_type;
|
||||
typedef typename SGVertexArrayBin<T>::index_type index_type;
|
||||
typedef SGVec2<index_type> edge_ref;
|
||||
typedef SGVec3<index_type> triangle_ref;
|
||||
typedef std::vector<triangle_ref> TriangleVector;
|
||||
typedef std::vector<index_type> TriangleList;
|
||||
typedef std::map<edge_ref,TriangleList> EdgeMap;
|
||||
|
||||
void insert(const value_type& v0, const value_type& v1, const value_type& v2)
|
||||
{
|
||||
index_type i0 = SGVertexArrayBin<T>::insert(v0);
|
||||
index_type i1 = SGVertexArrayBin<T>::insert(v1);
|
||||
index_type i2 = SGVertexArrayBin<T>::insert(v2);
|
||||
index_type triangleIndex = _triangleVector.size();
|
||||
_triangleVector.push_back(triangle_ref(i0, i1, i2));
|
||||
#ifdef BUILD_EDGE_MAP
|
||||
_edgeMap[edge_ref(i0, i1)].push_back(triangleIndex);
|
||||
_edgeMap[edge_ref(i1, i2)].push_back(triangleIndex);
|
||||
_edgeMap[edge_ref(i2, i0)].push_back(triangleIndex);
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned getNumTriangles() const
|
||||
{ return _triangleVector.size(); }
|
||||
const triangle_ref& getTriangleRef(index_type i) const
|
||||
{ return _triangleVector[i]; }
|
||||
const TriangleVector& getTriangles() const
|
||||
{ return _triangleVector; }
|
||||
|
||||
#ifdef BUILD_EDGE_MAP
|
||||
// protected: //FIXME
|
||||
void getConnectedSets(std::list<TriangleVector>& connectSets) const
|
||||
{
|
||||
std::vector<bool> processedTriangles(getNumTriangles(), false);
|
||||
for (index_type i = 0; i < getNumTriangles(); ++i) {
|
||||
if (processedTriangles[i])
|
||||
continue;
|
||||
|
||||
TriangleVector currentSet;
|
||||
std::vector<edge_ref> edgeStack;
|
||||
|
||||
{
|
||||
triangle_ref triangleRef = getTriangleRef(i);
|
||||
edgeStack.push_back(edge_ref(triangleRef[0], triangleRef[1]));
|
||||
edgeStack.push_back(edge_ref(triangleRef[1], triangleRef[2]));
|
||||
edgeStack.push_back(edge_ref(triangleRef[2], triangleRef[0]));
|
||||
currentSet.push_back(triangleRef);
|
||||
processedTriangles[i] = true;
|
||||
}
|
||||
|
||||
while (!edgeStack.empty()) {
|
||||
edge_ref edge = edgeStack.back();
|
||||
edgeStack.pop_back();
|
||||
|
||||
typename EdgeMap::const_iterator emiList[2] = {
|
||||
_edgeMap.find(edge),
|
||||
_edgeMap.find(edge_ref(edge[1], edge[0]))
|
||||
};
|
||||
for (unsigned ei = 0; ei < 2; ++ei) {
|
||||
typename EdgeMap::const_iterator emi = emiList[ei];
|
||||
if (emi == _edgeMap.end())
|
||||
continue;
|
||||
|
||||
for (unsigned ti = 0; ti < emi->second.size(); ++ti) {
|
||||
index_type triangleIndex = emi->second[ti];
|
||||
if (processedTriangles[triangleIndex])
|
||||
continue;
|
||||
|
||||
triangle_ref triangleRef = getTriangleRef(triangleIndex);
|
||||
edgeStack.push_back(edge_ref(triangleRef[0], triangleRef[1]));
|
||||
edgeStack.push_back(edge_ref(triangleRef[1], triangleRef[2]));
|
||||
edgeStack.push_back(edge_ref(triangleRef[2], triangleRef[0]));
|
||||
currentSet.push_back(triangleRef);
|
||||
processedTriangles[triangleIndex] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
connectSets.push_back(currentSet);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
TriangleVector _triangleVector;
|
||||
#ifdef BUILD_EDGE_MAP
|
||||
EdgeMap _edgeMap;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
162
simgear/scene/tgdb/SGVasiDrawable.cxx
Normal file
162
simgear/scene/tgdb/SGVasiDrawable.cxx
Normal file
@ -0,0 +1,162 @@
|
||||
/* -*-c++-*-
|
||||
*
|
||||
* Copyright (C) 2006-2007 Mathias Froehlich
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include "SGVasiDrawable.hxx"
|
||||
|
||||
struct SGVasiDrawable::LightData {
|
||||
LightData(const SGVec3f& p, const SGVec3f& n, const SGVec3f& up) :
|
||||
position(p),
|
||||
normal(n),
|
||||
horizontal(normalize(cross(up, n))),
|
||||
normalCrossHorizontal(normalize(cross(n, horizontal)))
|
||||
{ }
|
||||
|
||||
void draw(const SGVec4f& color) const
|
||||
{
|
||||
glBegin(GL_POINTS);
|
||||
glColor4fv(color.data());
|
||||
glNormal3fv(normal.data());
|
||||
glVertex3fv(position.data());
|
||||
glEnd();
|
||||
}
|
||||
|
||||
SGVec3f position;
|
||||
SGVec3f normal;
|
||||
SGVec3f horizontal;
|
||||
SGVec3f normalCrossHorizontal;
|
||||
};
|
||||
|
||||
SGVasiDrawable::SGVasiDrawable(const SGVasiDrawable& vd, const osg::CopyOp&) :
|
||||
_lights(vd._lights),
|
||||
_red(vd._red),
|
||||
_white(vd._white)
|
||||
{
|
||||
setUseDisplayList(false);
|
||||
setSupportsDisplayList(false);
|
||||
}
|
||||
|
||||
SGVasiDrawable::SGVasiDrawable(const SGVec4f& red, const SGVec4f& white) :
|
||||
_red(red),
|
||||
_white(white)
|
||||
{
|
||||
setUseDisplayList(false);
|
||||
setSupportsDisplayList(false);
|
||||
}
|
||||
|
||||
void
|
||||
SGVasiDrawable::addLight(const SGVec3f& position, const SGVec3f& normal,
|
||||
const SGVec3f& up, float azimutDeg)
|
||||
{
|
||||
SGVec3f horizontal(normalize(cross(up, normal)));
|
||||
SGVec3f zeroGlideSlope = normalize(cross(horizontal, up));
|
||||
SGQuatf rotation = SGQuatf::fromAngleAxisDeg(azimutDeg, horizontal);
|
||||
SGVec3f azimutGlideSlope = rotation.transform(zeroGlideSlope);
|
||||
addLight(position, azimutGlideSlope, up);
|
||||
}
|
||||
|
||||
void
|
||||
SGVasiDrawable::addLight(const SGVec3f& position, const SGVec3f& normal,
|
||||
const SGVec3f& up)
|
||||
{
|
||||
_lights.push_back(LightData(position, normal, up));
|
||||
}
|
||||
|
||||
void
|
||||
SGVasiDrawable::drawImplementation(osg::RenderInfo& renderInfo) const
|
||||
{
|
||||
// Make sure we have the current state set
|
||||
// renderInfo.getState()->apply();
|
||||
|
||||
// Retrieve the eye point in local coords
|
||||
osg::Matrix m;
|
||||
m.invert(renderInfo.getState()->getModelViewMatrix());
|
||||
SGVec3f eyePoint(m.preMult(osg::Vec3(0, 0, 0)));
|
||||
|
||||
// paint the points
|
||||
for (unsigned i = 0; i < _lights.size(); ++i)
|
||||
draw(eyePoint, _lights[i]);
|
||||
}
|
||||
|
||||
osg::BoundingBox
|
||||
SGVasiDrawable::computeBound() const
|
||||
{
|
||||
osg::BoundingBox bb;
|
||||
for (unsigned i = 0; i < _lights.size(); ++i)
|
||||
bb.expandBy(_lights[i].position.osg());
|
||||
|
||||
// blow up to avoid being victim to small feature culling ...
|
||||
bb.expandBy(bb._min - osg::Vec3(1, 1, 1));
|
||||
bb.expandBy(bb._max + osg::Vec3(1, 1, 1));
|
||||
return bb;
|
||||
}
|
||||
|
||||
SGVec4f
|
||||
SGVasiDrawable::getColor(float angleDeg) const
|
||||
{
|
||||
float transDeg = 0.05f;
|
||||
if (angleDeg < -transDeg) {
|
||||
return _red;
|
||||
} else if (angleDeg < transDeg) {
|
||||
float fac = angleDeg*0.5f/transDeg + 0.5f;
|
||||
return _red + fac*(_white - _red);
|
||||
} else {
|
||||
return _white;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SGVasiDrawable::draw(const SGVec3f& eyePoint, const LightData& light) const
|
||||
{
|
||||
// vector pointing from the light position to the eye
|
||||
SGVec3f lightToEye = eyePoint - light.position;
|
||||
|
||||
// dont' draw, we are behind it
|
||||
if (dot(lightToEye, light.normal) < SGLimitsf::min())
|
||||
return;
|
||||
|
||||
// Now project the eye point vector into the plane defined by the
|
||||
// glideslope direction and the up direction
|
||||
SGVec3f projLightToEye = lightToEye
|
||||
- light.horizontal*dot(lightToEye, light.horizontal);
|
||||
|
||||
// dont' draw, if we are to near, looks like we are already behind
|
||||
float sqrProjLightToEyeLength = dot(projLightToEye, projLightToEye);
|
||||
if (sqrProjLightToEyeLength < 1e-3*1e-3)
|
||||
return;
|
||||
|
||||
// the scalar product of the glide slope up direction with the eye vector
|
||||
float dotProd = dot(projLightToEye, light.normalCrossHorizontal);
|
||||
float sinAngle = dotProd/sqrt(sqrProjLightToEyeLength);
|
||||
if (sinAngle < -1)
|
||||
sinAngle = -1;
|
||||
if (1 < sinAngle)
|
||||
sinAngle = 1;
|
||||
|
||||
float angleDeg = SGMiscf::rad2deg(asin(sinAngle));
|
||||
light.draw(getColor(angleDeg));
|
||||
}
|
||||
|
63
simgear/scene/tgdb/SGVasiDrawable.hxx
Normal file
63
simgear/scene/tgdb/SGVasiDrawable.hxx
Normal file
@ -0,0 +1,63 @@
|
||||
/* -*-c++-*-
|
||||
*
|
||||
* Copyright (C) 2006-2007 Mathias Froehlich
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _SG_VASI_DRAWABLE_HXX
|
||||
#define _SG_VASI_DRAWABLE_HXX
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <osg/Drawable>
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
|
||||
class SGVasiDrawable : public osg::Drawable {
|
||||
struct LightData;
|
||||
public:
|
||||
META_Object(SimGear, SGVasiDrawable);
|
||||
SGVasiDrawable(const SGVasiDrawable&, const osg::CopyOp&);
|
||||
SGVasiDrawable(const SGVec4f& red = SGVec4f(1, 0, 0, 1),
|
||||
const SGVec4f& white = SGVec4f(1, 1, 1, 1));
|
||||
|
||||
/// Add a red/white switching light pointing into the direction that
|
||||
/// is computed to point in about the given normal with the given
|
||||
/// azimut angle upwards. The up direction is the world up direction
|
||||
/// that defines the horizontal plane.
|
||||
void addLight(const SGVec3f& position, const SGVec3f& normal,
|
||||
const SGVec3f& up, float azimutDeg);
|
||||
|
||||
/// add a red/white switching light pointing towards normal
|
||||
/// at the given position with the given up vector. The up direction
|
||||
/// is the world up direction that defines the horizontal plane.
|
||||
void addLight(const SGVec3f& position, const SGVec3f& normal,
|
||||
const SGVec3f& up);
|
||||
|
||||
virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
|
||||
virtual osg::BoundingBox computeBound() const;
|
||||
|
||||
private:
|
||||
SGVec4f getColor(float angleDeg) const;
|
||||
void draw(const SGVec3f& eyePoint, const LightData& light) const;
|
||||
|
||||
std::vector<LightData> _lights;
|
||||
SGVec4f _red;
|
||||
SGVec4f _white;
|
||||
};
|
||||
|
||||
#endif // _SG_VASI_LIGHT_HXX
|
63
simgear/scene/tgdb/SGVertexArrayBin.hxx
Normal file
63
simgear/scene/tgdb/SGVertexArrayBin.hxx
Normal file
@ -0,0 +1,63 @@
|
||||
/* -*-c++-*-
|
||||
*
|
||||
* Copyright (C) 2006-2007 Mathias Froehlich
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SG_VERTEX_ARRAY_BIN_HXX
|
||||
#define SG_VERTEX_ARRAY_BIN_HXX
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
template<typename T>
|
||||
class SGVertexArrayBin {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef typename value_type::less less;
|
||||
typedef std::vector<value_type> ValueVector;
|
||||
typedef typename ValueVector::size_type index_type;
|
||||
typedef std::map<value_type, index_type, less> ValueMap;
|
||||
|
||||
index_type insert(const value_type& t)
|
||||
{
|
||||
typename ValueMap::iterator i = _valueMap.find(t);
|
||||
if (i != _valueMap.end())
|
||||
return i->second;
|
||||
|
||||
index_type index = _values.size();
|
||||
_valueMap[t] = index;
|
||||
_values.push_back(t);
|
||||
return index;
|
||||
}
|
||||
|
||||
const value_type& getVertex(index_type index) const
|
||||
{ return _values[index]; }
|
||||
|
||||
index_type getNumVertices() const
|
||||
{ return _values.size(); }
|
||||
|
||||
bool empty() const
|
||||
{ return _values.empty(); }
|
||||
|
||||
private:
|
||||
ValueVector _values;
|
||||
ValueMap _valueMap;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,58 +0,0 @@
|
||||
// leaf.hxx -- function to build and ssg leaf from higher level data.
|
||||
//
|
||||
// Written by Curtis Olson, started October 1997.
|
||||
//
|
||||
// Copyright (C) 1997 - 2003 Curtis L. Olson - http://www.flightgear.org/~curt
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _SG_LEAF_HXX
|
||||
#define _SG_LEAF_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
#include <osg/Array>
|
||||
#include <osg/Node>
|
||||
|
||||
#include <simgear/math/sg_types.hxx>
|
||||
|
||||
SG_USING_STD(string);
|
||||
|
||||
|
||||
class SGMaterialLib; // forward declaration.
|
||||
|
||||
|
||||
// Create a ssg leaf
|
||||
osg::Drawable* SGMakeLeaf( const string& path,
|
||||
const GLenum ty, SGMaterial *mat,
|
||||
const point_list& nodes, const point_list& normals,
|
||||
const point_list& texcoords,
|
||||
const int_list& node_index,
|
||||
const int_list& normal_index,
|
||||
const int_list& tex_index,
|
||||
const bool calc_lights, osg::Vec3Array *lights );
|
||||
|
||||
#endif // _SG_LEAF_HXX
|
File diff suppressed because it is too large
Load Diff
@ -25,20 +25,18 @@
|
||||
#ifndef _SG_OBJ_HXX
|
||||
#define _SG_OBJ_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
#include <osg/Array>
|
||||
#include <osg/Node>
|
||||
#include <osg/Group>
|
||||
|
||||
#include <simgear/math/point3d.hxx>
|
||||
#include "SGOceanTile.hxx"
|
||||
|
||||
SG_USING_STD(string);
|
||||
|
||||
@ -46,11 +44,18 @@ class SGBucket;
|
||||
class SGMaterialLib;
|
||||
|
||||
// Generate an ocean tile
|
||||
bool SGGenTile( const string& path, const SGBucket& b,
|
||||
SGMaterialLib *matlib, osg::Group *geometry );
|
||||
inline bool SGGenTile( const std::string&, const SGBucket& b,
|
||||
SGMaterialLib *matlib, osg::Group* group )
|
||||
{
|
||||
// Generate an ocean tile
|
||||
osg::Node* node = SGOceanTile(b, matlib);
|
||||
if (!node)
|
||||
return false;
|
||||
group->addChild(node);
|
||||
return true;
|
||||
}
|
||||
|
||||
osg::Node*
|
||||
SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool use_random_objects);
|
||||
|
||||
|
||||
#endif // _SG_OBJ_HXX
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -29,67 +29,73 @@
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
#include <vector> // STL
|
||||
|
||||
#include <osg/Drawable>
|
||||
#include <osg/Node>
|
||||
#include <osg/Point>
|
||||
|
||||
#include <simgear/math/sg_types.hxx>
|
||||
#include <simgear/scene/material/matlib.hxx>
|
||||
#include <simgear/scene/util/SGSceneFeatures.hxx>
|
||||
|
||||
#include "SGLightBin.hxx"
|
||||
#include "SGDirectionalLightBin.hxx"
|
||||
|
||||
SG_USING_STD(string);
|
||||
SG_USING_STD(vector);
|
||||
|
||||
|
||||
typedef vector < int > int_list;
|
||||
typedef int_list::iterator int_list_iterator;
|
||||
typedef int_list::const_iterator int_point_list_iterator;
|
||||
|
||||
|
||||
// Generate a directional light. This routines creates a
|
||||
// 'directional' light that can only be viewed from within 90 degrees
|
||||
// of the specified dir vector.
|
||||
|
||||
// To accomplish this, he routine creates a triangle with the 1st
|
||||
// point coincident with the specified pt and the 2nd and 3rd points
|
||||
// extending upward. The 1st point is created with an 'alpha' value
|
||||
// of 1 while the 2nd and 3rd points are created with an 'alpha' of
|
||||
// 0.0.
|
||||
|
||||
// If the triangle is drawn in glPolygonMode(GL_FRONT, GL_POINT) mode,
|
||||
// then two important things happen:
|
||||
|
||||
// 1) Only the 3 vertex points are drawn, the 2nd two with an alpha of
|
||||
// 0 so actually only the desired point is rendered.
|
||||
|
||||
// 2) since we are drawing a triangle, back face culling takes care of
|
||||
// eliminating this poing when the view angle relative to dir is
|
||||
// greater than 90 degrees.
|
||||
|
||||
// The final piece of this puzzle is that if we now use environment
|
||||
// mapping on this point, via an appropriate texture we can then
|
||||
// control the intensity and color of the point based on the view
|
||||
// angle relative to 'dir' the optimal view direction of the light
|
||||
// (i.e. the direction the light is pointing.)
|
||||
|
||||
// Yes this get's to be long and convoluted. If you can suggest a
|
||||
// simpler way, please do! :-)
|
||||
|
||||
osg::Node *SGMakeDirectionalLights( const point_list &nodes,
|
||||
const point_list &normals,
|
||||
const int_list &pnt_i,
|
||||
const int_list &nml_i,
|
||||
SGMaterialLib *matlib,
|
||||
const string &material,
|
||||
const SGVec3d& dup );
|
||||
|
||||
// Specify the way we want to draw directional point lights (assuming the
|
||||
// appropriate extensions are available.)
|
||||
|
||||
void SGConfigureDirectionalLights( bool use_point_sprites,
|
||||
inline void SGConfigureDirectionalLights( bool use_point_sprites,
|
||||
bool enhanced_lighting,
|
||||
bool distance_attenuation );
|
||||
bool distance_attenuation ) {
|
||||
static SGSceneFeatures* sceneFeatures = SGSceneFeatures::instance();
|
||||
sceneFeatures->setEnablePointSpriteLights(use_point_sprites);
|
||||
sceneFeatures->setEnableDistanceAttenuationLights(distance_attenuation);
|
||||
}
|
||||
|
||||
class SGPointSpriteLightCullCallback : public osg::NodeCallback {
|
||||
public:
|
||||
SGPointSpriteLightCullCallback(const osg::Vec3& da = osg::Vec3(1, 0.001, 0.0002),
|
||||
float sz = 4);
|
||||
SGPointSpriteLightCullCallback(osg::Point* point);
|
||||
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
|
||||
|
||||
private:
|
||||
osg::ref_ptr<osg::StateSet> _pointSpriteStateSet;
|
||||
osg::ref_ptr<osg::StateSet> _distanceAttenuationStateSet;
|
||||
};
|
||||
|
||||
class SGLightFactory {
|
||||
public:
|
||||
|
||||
static osg::Node*
|
||||
getLight(const SGLightBin::Light& light);
|
||||
|
||||
static osg::Node*
|
||||
getLight(const SGDirectionalLightBin::Light& light);
|
||||
|
||||
static osg::Drawable*
|
||||
getLights(const SGLightBin& lights, unsigned inc = 1, float alphaOff = 0);
|
||||
|
||||
static osg::Drawable*
|
||||
getLights(const SGDirectionalLightBin& lights);
|
||||
|
||||
static osg::Drawable*
|
||||
getVasi(const SGVec3f& up, const SGDirectionalLightBin& lights,
|
||||
const SGVec4f& red, const SGVec4f& white);
|
||||
|
||||
static osg::Node*
|
||||
getSequenced(const SGDirectionalLightBin& lights);
|
||||
|
||||
static osg::Node*
|
||||
getOdal(const SGLightBin& lights);
|
||||
};
|
||||
|
||||
#endif // _SG_PT_LIGHTS_HXX
|
||||
|
@ -1,197 +0,0 @@
|
||||
// vasi.hxx -- a class to hold some critical vasi data
|
||||
//
|
||||
// Written by Curtis Olson, started December 2003.
|
||||
//
|
||||
// Copyright (C) 2003 Curtis L. Olson - http://www.flightgear.org/~curt
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _SG_VASI_HXX
|
||||
#define _SG_VASI_HXX
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <osg/io_utils>
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/Array>
|
||||
#include <osg/NodeCallback>
|
||||
#include <osg/NodeVisitor>
|
||||
#include <osg/Vec3>
|
||||
|
||||
/// Callback that updates the colors of a VASI according to the view direction
|
||||
/// Notet that we need the eyepoint which is only available during culling
|
||||
/// So this will be a cull callback ...
|
||||
class SGVasiUpdateCallback : public osg::NodeCallback {
|
||||
public:
|
||||
SGVasiUpdateCallback(osg::Vec4Array* vasiColorArray,
|
||||
const osg::Vec3& referencePoint,
|
||||
const osg::Vec3& glideSlopeUp,
|
||||
const osg::Vec3& glideSlopeDir) :
|
||||
mVasiColorArray(vasiColorArray),
|
||||
mReferencePoint(referencePoint),
|
||||
mGlideSlopeUp(glideSlopeUp),
|
||||
mGlideSlopeDir(glideSlopeDir)
|
||||
{
|
||||
mGlideSlopeUp.normalize();
|
||||
mGlideSlopeDir.normalize();
|
||||
}
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
// Rerieve the eye point relative to the vasi reference point
|
||||
osg::Vec3 eyePoint = nv->getEyePoint() - mReferencePoint;
|
||||
// Now project the eye point vector into the plane defined by the
|
||||
// glideslope direction and the up direction
|
||||
osg::Vec3 normal = mGlideSlopeUp^mGlideSlopeDir;
|
||||
normal.normalize();
|
||||
osg::Vec3 projEyePoint = eyePoint - normal * (eyePoint*normal);
|
||||
|
||||
double projEyePointLength = projEyePoint.length();
|
||||
if (fabs(projEyePointLength) < 1e-3)
|
||||
set_color(3);
|
||||
else {
|
||||
double aSinAngle = projEyePoint*mGlideSlopeUp/projEyePointLength;
|
||||
if (aSinAngle < -1)
|
||||
aSinAngle = -1;
|
||||
if (1 < aSinAngle)
|
||||
aSinAngle = 1;
|
||||
|
||||
double angle = asin(aSinAngle)*SGD_RADIANS_TO_DEGREES;
|
||||
set_color(angle);
|
||||
}
|
||||
|
||||
// call the base implementation
|
||||
osg::NodeCallback::operator()(node, nv);
|
||||
}
|
||||
|
||||
// color the vasi/papi correctly based on angle in degree
|
||||
void set_color( double angle_deg ) {
|
||||
unsigned count = mVasiColorArray->size();
|
||||
double trans = 0.05;
|
||||
double color = 1;
|
||||
double ref;
|
||||
|
||||
if ( count == 12 ) {
|
||||
// PAPI configuration
|
||||
|
||||
// papi D
|
||||
ref = 3.5;
|
||||
if ( angle_deg < ref - trans ) {
|
||||
color = 0.0;
|
||||
} else if ( angle_deg < ref + trans ) {
|
||||
color = 1.0 - (ref + trans - angle_deg) * (1 / (2 * trans) );
|
||||
} else {
|
||||
color = 1.0;
|
||||
}
|
||||
for ( unsigned i = 0; i < 3; ++i ) {
|
||||
(*mVasiColorArray)[i][1] = color;
|
||||
(*mVasiColorArray)[i][2] = color;
|
||||
}
|
||||
|
||||
// papi C
|
||||
ref = 3.167;
|
||||
if ( angle_deg < ref - trans ) {
|
||||
color = 0.0;
|
||||
} else if ( angle_deg < ref + trans ) {
|
||||
color = 1.0 - (ref + trans - angle_deg) * (1 / (2 * trans) );
|
||||
} else {
|
||||
color = 1.0;
|
||||
}
|
||||
for ( unsigned i = 3; i < 6; ++i ) {
|
||||
(*mVasiColorArray)[i][1] = color;
|
||||
(*mVasiColorArray)[i][2] = color;
|
||||
}
|
||||
|
||||
// papi B
|
||||
ref = 2.833;
|
||||
if ( angle_deg < ref - trans ) {
|
||||
color = 0.0;
|
||||
} else if ( angle_deg < ref + trans ) {
|
||||
color = 1.0 - (ref + trans - angle_deg) * (1 / (2 * trans) );
|
||||
} else {
|
||||
color = 1.0;
|
||||
}
|
||||
for ( unsigned i = 6; i < 9; ++i ) {
|
||||
(*mVasiColorArray)[i][1] = color;
|
||||
(*mVasiColorArray)[i][2] = color;
|
||||
}
|
||||
|
||||
// papi A
|
||||
ref = 2.5;
|
||||
if ( angle_deg < ref - trans ) {
|
||||
color = 0.0;
|
||||
} else if ( angle_deg < ref + trans ) {
|
||||
color = 1.0 - (ref + trans - angle_deg) * (1 / (2 * trans) );
|
||||
} else {
|
||||
color = 1.0;
|
||||
}
|
||||
for ( unsigned i = 9; i < 12; ++i ) {
|
||||
(*mVasiColorArray)[i][1] = color;
|
||||
(*mVasiColorArray)[i][2] = color;
|
||||
}
|
||||
} else if ( count == 36 ) {
|
||||
// probably vasi, first 18 are downwind bar (2.5 deg)
|
||||
ref = 2.5;
|
||||
if ( angle_deg < ref - trans ) {
|
||||
color = 0.0;
|
||||
} else if ( angle_deg < ref + trans ) {
|
||||
color = 1.0 - (ref + trans - angle_deg) * (1 / (2 * trans) );
|
||||
} else {
|
||||
color = 1.0;
|
||||
}
|
||||
for ( unsigned i = 0; i < 18; ++i ) {
|
||||
(*mVasiColorArray)[i][1] = color;
|
||||
(*mVasiColorArray)[i][2] = color;
|
||||
}
|
||||
|
||||
// last 6 are upwind bar (3.0 deg)
|
||||
ref = 3.0;
|
||||
if ( angle_deg < ref - trans ) {
|
||||
color = 0.0;
|
||||
} else if ( angle_deg < ref + trans ) {
|
||||
color = 1.0 - (ref + trans - angle_deg) * (1 / (2 * trans) );
|
||||
} else {
|
||||
color = 1.0;
|
||||
}
|
||||
for ( unsigned i = 18; i < 36; ++i ) {
|
||||
(*mVasiColorArray)[i][1] = color;
|
||||
(*mVasiColorArray)[i][2] = color;
|
||||
}
|
||||
} else {
|
||||
// fail safe
|
||||
cout << "unknown vasi/papi configuration, count = " << count << endl;
|
||||
for ( unsigned i = 0; i < count; ++i ) {
|
||||
(*mVasiColorArray)[i][1] = color;
|
||||
(*mVasiColorArray)[i][2] = color;
|
||||
}
|
||||
}
|
||||
// Finally mark the color array dirty
|
||||
mVasiColorArray->dirty();
|
||||
}
|
||||
|
||||
private:
|
||||
osg::ref_ptr<osg::Vec4Array> mVasiColorArray;
|
||||
osg::Vec3 mReferencePoint;
|
||||
osg::Vec3 mGlideSlopeUp;
|
||||
osg::Vec3 mGlideSlopeDir;
|
||||
};
|
||||
|
||||
#endif // _SG_VASI_HXX
|
@ -7,13 +7,17 @@ noinst_HEADERS =
|
||||
include_HEADERS = \
|
||||
SGNodeMasks.hxx \
|
||||
SGUpdateVisitor.hxx \
|
||||
SGEnlargeBoundingBox.hxx \
|
||||
SGDebugDrawCallback.hxx \
|
||||
SGPickCallback.hxx \
|
||||
SGSceneFeatures.hxx \
|
||||
SGSceneUserData.hxx \
|
||||
SGStateAttributeVisitor.hxx \
|
||||
SGTextureStateAttributeVisitor.hxx
|
||||
|
||||
libsgutil_a_SOURCES = \
|
||||
SGEnlargeBoundingBox.cxx \
|
||||
SGSceneFeatures.cxx \
|
||||
SGSceneUserData.cxx \
|
||||
SGStateAttributeVisitor.cxx \
|
||||
SGTextureStateAttributeVisitor.cxx
|
||||
|
49
simgear/scene/util/SGEnlargeBoundingBox.cxx
Normal file
49
simgear/scene/util/SGEnlargeBoundingBox.cxx
Normal file
@ -0,0 +1,49 @@
|
||||
/* -*-c++-*-
|
||||
*
|
||||
* Copyright (C) 2006-2007 Mathias Froehlich
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include "SGEnlargeBoundingBox.hxx"
|
||||
#include <osg/Drawable>
|
||||
|
||||
SGEnlargeBoundingBox::SGEnlargeBoundingBox(float offset) :
|
||||
_offset(offset)
|
||||
{
|
||||
}
|
||||
|
||||
SGEnlargeBoundingBox::SGEnlargeBoundingBox(const SGEnlargeBoundingBox& cb,
|
||||
const osg::CopyOp& copyOp) :
|
||||
osg::Drawable::ComputeBoundingBoxCallback(cb, copyOp),
|
||||
_offset(cb._offset)
|
||||
{
|
||||
}
|
||||
|
||||
osg::BoundingBox
|
||||
SGEnlargeBoundingBox::computeBound(const osg::Drawable& drawable) const
|
||||
{
|
||||
osg::BoundingBox bound = drawable.computeBound();
|
||||
if (!bound.valid())
|
||||
return bound;
|
||||
return osg::BoundingBox(bound._min - osg::Vec3(_offset, _offset, _offset),
|
||||
bound._max + osg::Vec3(_offset, _offset, _offset));
|
||||
}
|
41
simgear/scene/util/SGEnlargeBoundingBox.hxx
Normal file
41
simgear/scene/util/SGEnlargeBoundingBox.hxx
Normal file
@ -0,0 +1,41 @@
|
||||
/* -*-c++-*-
|
||||
*
|
||||
* Copyright (C) 2006-2007 Mathias Froehlich
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SG_ENLARGE_BOUNDING_BOX_HXX
|
||||
#define SG_ENLARGE_BOUNDING_BOX_HXX
|
||||
|
||||
#include <osg/Drawable>
|
||||
|
||||
// Helper class to enlarge a bounding box of a drawable.
|
||||
// Is usefull to enlarge the mounding box of single point lights that would
|
||||
// be victim to small feature culling otherwise.
|
||||
class SGEnlargeBoundingBox : public osg::Drawable::ComputeBoundingBoxCallback {
|
||||
public:
|
||||
SGEnlargeBoundingBox(float offset = 0);
|
||||
SGEnlargeBoundingBox(const SGEnlargeBoundingBox& cb, const osg::CopyOp&);
|
||||
META_Object(osg, SGEnlargeBoundingBox);
|
||||
virtual osg::BoundingBox computeBound(const osg::Drawable& drawable) const;
|
||||
|
||||
private:
|
||||
float _offset;
|
||||
};
|
||||
|
||||
#endif
|
@ -33,4 +33,7 @@
|
||||
/// If set, the node is pickable
|
||||
#define SG_NODEMASK_PICK_BIT (1<<4)
|
||||
|
||||
/// If set, the node is a gui element
|
||||
#define SG_NODEMASK_GUI_BIT (1<<5)
|
||||
|
||||
#endif
|
||||
|
109
simgear/scene/util/SGSceneFeatures.cxx
Normal file
109
simgear/scene/util/SGSceneFeatures.cxx
Normal file
@ -0,0 +1,109 @@
|
||||
/* -*-c++-*-
|
||||
*
|
||||
* Copyright (C) 2006-2007 Mathias Froehlich
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include "SGSceneFeatures.hxx"
|
||||
|
||||
#include <osg/FragmentProgram>
|
||||
#include <osg/VertexProgram>
|
||||
#include <osg/Point>
|
||||
#include <osg/PointSprite>
|
||||
|
||||
#include <simgear/structure/SGSharedPtr.hxx>
|
||||
#include <simgear/threads/SGThread.hxx>
|
||||
#include <simgear/threads/SGGuard.hxx>
|
||||
|
||||
SGSceneFeatures::SGSceneFeatures() :
|
||||
_shaderLights(true),
|
||||
_pointSpriteLights(true),
|
||||
_distanceAttenuationLights(true)
|
||||
{
|
||||
}
|
||||
|
||||
SGSceneFeatures*
|
||||
SGSceneFeatures::instance()
|
||||
{
|
||||
static SGSharedPtr<SGSceneFeatures> sceneFeatures;
|
||||
if (sceneFeatures)
|
||||
return sceneFeatures;
|
||||
static SGMutex mutex;
|
||||
SGGuard<SGMutex> guard(mutex);
|
||||
if (sceneFeatures)
|
||||
return sceneFeatures;
|
||||
sceneFeatures = new SGSceneFeatures;
|
||||
return sceneFeatures;
|
||||
}
|
||||
|
||||
bool
|
||||
SGSceneFeatures::getHavePointSprites(unsigned contextId) const
|
||||
{
|
||||
return osg::PointSprite::isPointSpriteSupported(contextId);
|
||||
}
|
||||
|
||||
bool
|
||||
SGSceneFeatures::getHaveFragmentPrograms(unsigned contextId) const
|
||||
{
|
||||
const osg::FragmentProgram::Extensions* fpe;
|
||||
fpe = osg::FragmentProgram::getExtensions(contextId, true);
|
||||
if (!fpe)
|
||||
return false;
|
||||
if (!fpe->isFragmentProgramSupported())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SGSceneFeatures::getHaveVertexPrograms(unsigned contextId) const
|
||||
{
|
||||
const osg::VertexProgram::Extensions* vpe;
|
||||
vpe = osg::VertexProgram::getExtensions(contextId, true);
|
||||
if (!vpe)
|
||||
return false;
|
||||
if (!vpe->isVertexProgramSupported())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SGSceneFeatures::getHaveShaderPrograms(unsigned contextId) const
|
||||
{
|
||||
if (!getHaveFragmentPrograms(contextId))
|
||||
return false;
|
||||
return getHaveVertexPrograms(contextId);
|
||||
}
|
||||
|
||||
bool
|
||||
SGSceneFeatures::getHavePointParameters(unsigned contextId) const
|
||||
{
|
||||
const osg::Point::Extensions* pe;
|
||||
pe = osg::Point::getExtensions(contextId, true);
|
||||
if (!pe)
|
||||
return false;
|
||||
if (!pe->isPointParametersSupported())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
75
simgear/scene/util/SGSceneFeatures.hxx
Normal file
75
simgear/scene/util/SGSceneFeatures.hxx
Normal file
@ -0,0 +1,75 @@
|
||||
/* -*-c++-*-
|
||||
*
|
||||
* Copyright (C) 2006-2007 Mathias Froehlich
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SG_SCENE_FEATURES_HXX
|
||||
#define SG_SCENE_FEATURES_HXX
|
||||
|
||||
#include <simgear/structure/SGReferenced.hxx>
|
||||
|
||||
class SGSceneFeatures : public SGReferenced {
|
||||
public:
|
||||
static SGSceneFeatures* instance();
|
||||
|
||||
void setEnablePointSpriteLights(bool enable)
|
||||
{ _pointSpriteLights = enable; }
|
||||
bool getEnablePointSpriteLights(unsigned contextId) const
|
||||
{
|
||||
if (!_pointSpriteLights)
|
||||
return false;
|
||||
return getHavePointSprites(contextId);
|
||||
}
|
||||
|
||||
void setEnableDistanceAttenuationLights(bool enable)
|
||||
{ _distanceAttenuationLights = enable; }
|
||||
bool getEnableDistanceAttenuationLights(unsigned contextId) const
|
||||
{
|
||||
if (!_distanceAttenuationLights)
|
||||
return false;
|
||||
return getHavePointParameters(contextId);
|
||||
}
|
||||
|
||||
void setEnableShaderLights(bool enable)
|
||||
{ _shaderLights = enable; }
|
||||
bool getEnableShaderLights(unsigned contextId) const
|
||||
{
|
||||
if (!_shaderLights)
|
||||
return false;
|
||||
return getHaveShaderPrograms(contextId);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool getHavePointSprites(unsigned contextId) const;
|
||||
bool getHaveFragmentPrograms(unsigned contextId) const;
|
||||
bool getHaveVertexPrograms(unsigned contextId) const;
|
||||
bool getHaveShaderPrograms(unsigned contextId) const;
|
||||
bool getHavePointParameters(unsigned contextId) const;
|
||||
|
||||
private:
|
||||
SGSceneFeatures();
|
||||
SGSceneFeatures(const SGSceneFeatures&);
|
||||
SGSceneFeatures& operator=(const SGSceneFeatures&);
|
||||
|
||||
bool _shaderLights;
|
||||
bool _pointSpriteLights;
|
||||
bool _distanceAttenuationLights;
|
||||
};
|
||||
|
||||
#endif
|
@ -19,6 +19,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include "SGTextureStateAttributeVisitor.hxx"
|
||||
|
||||
SGTextureStateAttributeVisitor::SGTextureStateAttributeVisitor() :
|
||||
|
Loading…
Reference in New Issue
Block a user