Modified Files:

configure.ac simgear/environment/visual_enviro.cxx
	simgear/ephemeris/ephemeris.cxx
	simgear/ephemeris/ephemeris.hxx simgear/ephemeris/stardata.cxx
	simgear/ephemeris/stardata.hxx simgear/math/SGMatrix.hxx
	simgear/math/SGQuat.hxx simgear/math/SGVec3.hxx
	simgear/math/SGVec4.hxx simgear/scene/Makefile.am
 	simgear/scene/material/mat.cxx simgear/scene/material/mat.hxx
	simgear/scene/material/matlib.cxx
	simgear/scene/material/matlib.hxx
	simgear/scene/material/matmodel.cxx
	simgear/scene/material/matmodel.hxx
	simgear/scene/model/Makefile.am
	simgear/scene/model/animation.cxx
	simgear/scene/model/animation.hxx
	simgear/scene/model/custtrans.hxx
	simgear/scene/model/model.cxx simgear/scene/model/model.hxx
	simgear/scene/model/modellib.cxx
	simgear/scene/model/modellib.hxx
	simgear/scene/model/personality.cxx
	simgear/scene/model/personality.hxx
	simgear/scene/model/placement.cxx
	simgear/scene/model/placement.hxx
	simgear/scene/model/placementtrans.cxx
	simgear/scene/model/placementtrans.hxx
	simgear/scene/model/shadanim.cxx
	simgear/scene/model/shadowvolume.hxx
	simgear/scene/sky/cloud.cxx simgear/scene/sky/cloud.hxx
	simgear/scene/sky/cloudfield.cxx simgear/scene/sky/dome.cxx
	simgear/scene/sky/dome.hxx simgear/scene/sky/moon.cxx
	simgear/scene/sky/moon.hxx simgear/scene/sky/newcloud.cxx
	simgear/scene/sky/oursun.cxx simgear/scene/sky/oursun.hxx
	simgear/scene/sky/sky.cxx simgear/scene/sky/sky.hxx
	simgear/scene/sky/sphere.cxx simgear/scene/sky/sphere.hxx
	simgear/scene/sky/stars.cxx simgear/scene/sky/stars.hxx
	simgear/scene/tgdb/apt_signs.cxx
	simgear/scene/tgdb/apt_signs.hxx simgear/scene/tgdb/leaf.cxx
	simgear/scene/tgdb/leaf.hxx simgear/scene/tgdb/obj.cxx
	simgear/scene/tgdb/obj.hxx simgear/scene/tgdb/pt_lights.cxx
	simgear/scene/tgdb/pt_lights.hxx
	simgear/scene/tgdb/userdata.cxx
	simgear/scene/tgdb/userdata.hxx simgear/scene/tgdb/vasi.hxx
	simgear/screen/jpgfactory.cxx simgear/screen/tr.cxx
	simgear/structure/Makefile.am simgear/threads/SGThread.hxx
Added Files:
	simgear/scene/util/Makefile.am
	simgear/scene/util/SGDebugDrawCallback.hxx
	simgear/scene/util/SGNodeMasks.hxx
	simgear/scene/util/SGStateAttributeVisitor.hxx
	simgear/scene/util/SGTextureStateAttributeVisitor.hxx
	simgear/scene/util/SGUpdateVisitor.hxx
Removed Files:
	simgear/screen/ssgEntityArray.cxx
	simgear/screen/ssgEntityArray.hxx
	simgear/structure/ssgSharedPtr.hxx
	Big BLOB on the way to OSG.
This commit is contained in:
frohlich
2006-10-29 19:27:08 +00:00
parent 7c410d36e3
commit 84dd54b33a
73 changed files with 4779 additions and 5368 deletions

View File

@@ -430,6 +430,7 @@ AC_CONFIG_FILES([ \
simgear/scene/model/Makefile \
simgear/scene/sky/Makefile \
simgear/scene/tgdb/Makefile \
simgear/scene/util/Makefile \
simgear/screen/Makefile \
simgear/serial/Makefile \
simgear/sound/Makefile \

View File

@@ -189,6 +189,8 @@ SGEnviro::SGEnviro() :
}
SGEnviro::~SGEnviro(void) {
// OSGFIXME
return;
list_of_lightning::iterator iLightning;
for( iLightning = lightnings.begin() ; iLightning != lightnings.end() ; iLightning++ ) {
delete (*iLightning);
@@ -197,6 +199,8 @@ SGEnviro::~SGEnviro(void) {
}
void SGEnviro::startOfFrame( sgVec3 p, sgVec3 up, double lon, double lat, double alt, double delta_time) {
// OSGFIXME
return;
view_in_cloud = false;
// ask the impostor cache to do some cleanup
if(SGNewCloud::cldCache)
@@ -319,6 +323,8 @@ void SGEnviro::set_lightning_enable_state(bool enable) {
}
void SGEnviro::setLight(sgVec4 adj_fog_color) {
// OSGFIXME
return;
sgCopyVec4( fog_color, adj_fog_color );
if( false ) {
// ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, l->scene_diffuse() );
@@ -326,6 +332,8 @@ void SGEnviro::setLight(sgVec4 adj_fog_color) {
}
void SGEnviro::callback_cloud(float heading, float alt, float radius, int family, float dist, int cloudId) {
// OSGFIXME
return;
// send data to wx radar
// compute turbulence
// draw precipitation
@@ -440,6 +448,8 @@ list_of_SGWxRadarEcho *SGEnviro::get_radar_echo(void) {
// precipitation rendering code
void SGEnviro::DrawCone2(float baseRadius, float height, int slices, bool down, double rain_norm, double speed) {
// OSGFIXME
return;
sgVec3 light;
sgAddVec3( light, fog_color, min_light );
float da = SG_PI * 2.0f / (float) slices;
@@ -488,6 +498,8 @@ void SGEnviro::DrawCone2(float baseRadius, float height, int slices, bool down,
}
void SGEnviro::drawRain(double pitch, double roll, double heading, double hspeed, double rain_norm) {
// OSGFIXME
return;
#if 0
static int debug_period = 0;
@@ -557,6 +569,8 @@ void SGEnviro::set_soundMgr(SGSoundMgr *mgr) {
}
void SGEnviro::drawPrecipitation(double rain_norm, double snow_norm, double hail_norm, double pitch, double roll, double heading, double hspeed) {
// OSGFIXME
return;
if( precipitation_enable_state && rain_norm > 0.0)
if( precipitation_max_alt >= last_alt )
drawRain(pitch, roll, heading, hspeed, rain_norm);
@@ -579,6 +593,8 @@ SGLightning::~SGLightning() {
// lightning rendering code
void SGLightning::lt_build_tree_branch(int tree_nr, Point3D &start, float energy, int nbseg, float segsize) {
// OSGFIXME
return;
sgVec3 dir, newdir;
int nseg = 0;
@@ -626,6 +642,8 @@ void SGLightning::lt_build_tree_branch(int tree_nr, Point3D &start, float energy
}
void SGLightning::lt_build(void) {
// OSGFIXME
return;
Point3D top;
nb_tree = 0;
top[PX] = 0 ;
@@ -651,6 +669,8 @@ void SGLightning::lt_build(void) {
void SGLightning::lt_Render(void) {
// OSGFIXME
return;
float flash = 0.5;
if( fmod(sgEnviro.elapsed_time*100.0, 100.0) > 50.0 )
flash = sg_random() * 0.75f + 0.25f;
@@ -675,10 +695,12 @@ void SGLightning::lt_Render(void) {
glDisable( GL_FOG );
glPushMatrix();
sgMat4 modelview, tmp;
ssgGetModelviewMatrix( modelview );
// OSGFIXME
// ssgGetModelviewMatrix( modelview );
sgCopyMat4( tmp, sgEnviro.transform );
sgPostMultMat4( tmp, modelview );
ssgLoadModelviewMatrix( tmp );
// OSGFIXME
// ssgLoadModelviewMatrix( tmp );
Point3D start( sgEnviro.last_lon*SG_DEGREES_TO_RADIANS, sgEnviro.last_lat*SG_DEGREES_TO_RADIANS, 0.0 );
Point3D dest( lon*SG_DEGREES_TO_RADIANS, lat*SG_DEGREES_TO_RADIANS, 0.0 );
@@ -736,6 +758,8 @@ void SGLightning::lt_Render(void) {
}
void SGEnviro::addLightning(double lon, double lat, double alt) {
// OSGFIXME
return;
if( lightnings.size() > 10)
return;
SGLightning *lt= new SGLightning(lon, lat, alt);
@@ -743,6 +767,8 @@ void SGEnviro::addLightning(double lon, double lat, double alt) {
}
void SGEnviro::drawLightning(void) {
// OSGFIXME
return;
list_of_lightning::iterator iLightning;
// play 'thunder' for lightning
if( snd_active )

View File

@@ -43,7 +43,7 @@ SGEphemeris::SGEphemeris( const string &path ) {
neptune = new Neptune;
nplanets = 7;
for ( int i = 0; i < nplanets; ++i ) {
sgdSetVec3( planets[i], 0.0, 0.0, 0.0 );
sgdSetVec3( planets[i].sg(), 0.0, 0.0, 0.0 );
}
stars = new SGStarData( SGPath(path) );
}

View File

@@ -83,7 +83,7 @@ class SGEphemeris {
// planets[i][1] = Declination
// planets[i][2] = Magnitude
int nplanets;
sgdVec3 planets[7];
SGVec3d planets[7];
SGStarData *stars;
@@ -155,7 +155,7 @@ public:
* the second is the declination, and the third is the magnitude.
* @return planets array
*/
inline sgdVec3 *getPlanets() { return planets; }
inline SGVec3d *getPlanets() { return planets; }
/** @return the numbers of defined stars. */
inline int getNumStars() const { return stars->getNumStars(); }
@@ -167,7 +167,7 @@ public:
* third is the magnitude.
* @returns star array
*/
inline sgdVec3 *getStars() { return stars->getStars(); }
inline SGVec3d *getStars() { return stars->getStars(); }
};

View File

@@ -56,7 +56,7 @@ bool SGStarData::load() {
// -dw- avoid local data > 32k error by dynamic allocation of the
// array, problem for some compilers
stars = new sgdVec3[SG_MAX_STARS];
stars = new SGVec3d[SG_MAX_STARS];
// build the full path name to the stars data base file
data_path.append( "stars" );
@@ -117,7 +117,7 @@ bool SGStarData::load() {
// cout << " star data = " << ra << " " << dec << " " << mag << endl;
sgdSetVec3( stars[nstars], ra, dec, mag );
sgdSetVec3( stars[nstars].sg(), ra, dec, mag );
++nstars;
}

View File

@@ -36,7 +36,7 @@
class SGStarData {
int nstars;
sgdVec3 *stars;
SGVec3d *stars;
SGPath data_path;
@@ -54,7 +54,7 @@ public:
// stars
inline int getNumStars() const { return nstars; }
inline sgdVec3 *getStars() { return stars; }
inline SGVec3d *getStars() { return stars; }
};

View File

@@ -574,8 +574,8 @@ toMatrixf(const SGMatrixd& m)
{
return SGMatrixf((float)m(0,0), (float)m(0,1), (float)m(0,2), (float)m(0,3),
(float)m(1,0), (float)m(1,1), (float)m(1,2), (float)m(1,3),
(float)m(3,0), (float)m(2,1), (float)m(2,2), (float)m(2,3),
(float)m(4,0), (float)m(4,1), (float)m(4,2), (float)m(4,3));
(float)m(2,0), (float)m(2,1), (float)m(2,2), (float)m(2,3),
(float)m(3,0), (float)m(3,1), (float)m(3,2), (float)m(3,3));
}
inline
@@ -584,8 +584,8 @@ toMatrixd(const SGMatrixf& m)
{
return SGMatrixd(m(0,0), m(0,1), m(0,2), m(0,3),
m(1,0), m(1,1), m(1,2), m(1,3),
m(3,0), m(2,1), m(2,2), m(2,3),
m(4,0), m(4,1), m(4,2), m(4,3));
m(2,0), m(2,1), m(2,2), m(2,3),
m(3,0), m(3,1), m(3,2), m(3,3));
}
#endif

View File

@@ -26,10 +26,42 @@
#undef max
#endif
#include <osg/Quat>
template<typename T>
struct SGQuatStorage {
/// Readonly raw storage interface
const T (&data(void) const)[4]
{ return _data; }
/// Readonly raw storage interface
T (&data(void))[4]
{ return _data; }
void osg() const
{ }
private:
T _data[4];
};
template<>
struct SGQuatStorage<double> : public osg::Quat {
/// Access raw data by index, the index is unchecked
const double (&data(void) const)[4]
{ return osg::Quat::_v; }
/// Access raw data by index, the index is unchecked
double (&data(void))[4]
{ return osg::Quat::_v; }
const osg::Quat& osg() const
{ return *this; }
osg::Quat& osg()
{ return *this; }
};
/// 3D Vector Class
template<typename T>
class SGQuat {
class SGQuat : protected SGQuatStorage<T> {
public:
typedef T value_type;
@@ -42,7 +74,7 @@ public:
/// uninitialized values in the debug build very fast ...
#ifndef NDEBUG
for (unsigned i = 0; i < 4; ++i)
_data[i] = SGLimits<T>::quiet_NaN();
data()[i] = SGLimits<T>::quiet_NaN();
#endif
}
/// Constructor. Initialize by the given values
@@ -51,7 +83,9 @@ public:
/// Constructor. Initialize by the content of a plain array,
/// make sure it has at least 4 elements
explicit SGQuat(const T* d)
{ _data[0] = d[0]; _data[1] = d[1]; _data[2] = d[2]; _data[3] = d[3]; }
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; }
explicit SGQuat(const osg::Quat& d)
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; }
/// Return a unit quaternion
static SGQuat unit(void)
@@ -236,67 +270,66 @@ public:
/// Access by index, the index is unchecked
const T& operator()(unsigned i) const
{ return _data[i]; }
{ return data()[i]; }
/// Access by index, the index is unchecked
T& operator()(unsigned i)
{ return _data[i]; }
{ return data()[i]; }
/// Access raw data by index, the index is unchecked
const T& operator[](unsigned i) const
{ return _data[i]; }
{ return data()[i]; }
/// Access raw data by index, the index is unchecked
T& operator[](unsigned i)
{ return _data[i]; }
{ return data()[i]; }
/// Access the x component
const T& x(void) const
{ return _data[0]; }
{ return data()[0]; }
/// Access the x component
T& x(void)
{ return _data[0]; }
{ return data()[0]; }
/// Access the y component
const T& y(void) const
{ return _data[1]; }
{ return data()[1]; }
/// Access the y component
T& y(void)
{ return _data[1]; }
{ return data()[1]; }
/// Access the z component
const T& z(void) const
{ return _data[2]; }
{ return data()[2]; }
/// Access the z component
T& z(void)
{ return _data[2]; }
{ return data()[2]; }
/// Access the w component
const T& w(void) const
{ return _data[3]; }
{ return data()[3]; }
/// Access the w component
T& w(void)
{ return _data[3]; }
{ return data()[3]; }
/// Get the data pointer, usefull for interfacing with plib's sg*Vec
const T* data(void) const
{ return _data; }
/// Get the data pointer, usefull for interfacing with plib's sg*Vec
T* data(void)
{ return _data; }
/// Get the data pointer
using SGQuatStorage<T>::data;
/// Readonly interface function to ssg's sgQuat/sgdQuat
const T (&sg(void) const)[4]
{ return _data; }
{ return data(); }
/// Interface function to ssg's sgQuat/sgdQuat
T (&sg(void))[4]
{ return _data; }
{ return data(); }
/// Interface function to osg's Quat*
using SGQuatStorage<T>::osg;
/// Inplace addition
SGQuat& operator+=(const SGQuat& v)
{ _data[0]+=v(0);_data[1]+=v(1);_data[2]+=v(2);_data[3]+=v(3);return *this; }
{ data()[0]+=v(0);data()[1]+=v(1);data()[2]+=v(2);data()[3]+=v(3);return *this; }
/// Inplace subtraction
SGQuat& operator-=(const SGQuat& v)
{ _data[0]-=v(0);_data[1]-=v(1);_data[2]-=v(2);_data[3]-=v(3);return *this; }
{ data()[0]-=v(0);data()[1]-=v(1);data()[2]-=v(2);data()[3]-=v(3);return *this; }
/// Inplace scalar multiplication
template<typename S>
SGQuat& operator*=(S s)
{ _data[0] *= s; _data[1] *= s; _data[2] *= s; _data[3] *= s; return *this; }
{ data()[0] *= s; data()[1] *= s; data()[2] *= s; data()[3] *= s; return *this; }
/// Inplace scalar multiplication by 1/s
template<typename S>
SGQuat& operator/=(S s)
@@ -343,10 +376,6 @@ public:
return deriv;
}
private:
/// The actual data
T _data[4];
};
/// Unary +, do nothing ...

View File

@@ -18,9 +18,58 @@
#ifndef SGVec3_H
#define SGVec3_H
#include <osg/Vec3f>
#include <osg/Vec3d>
template<typename T>
struct SGVec3Storage {
/// Readonly raw storage interface
const T (&data(void) const)[3]
{ return _data; }
/// Readonly raw storage interface
T (&data(void))[3]
{ return _data; }
void osg() const
{ }
private:
T _data[3];
};
template<>
struct SGVec3Storage<float> : public osg::Vec3f {
/// Access raw data by index, the index is unchecked
const float (&data(void) const)[3]
{ return osg::Vec3f::_v; }
/// Access raw data by index, the index is unchecked
float (&data(void))[3]
{ return osg::Vec3f::_v; }
const osg::Vec3f& osg() const
{ return *this; }
osg::Vec3f& osg()
{ return *this; }
};
template<>
struct SGVec3Storage<double> : public osg::Vec3d {
/// Access raw data by index, the index is unchecked
const double (&data(void) const)[3]
{ return osg::Vec3d::_v; }
/// Access raw data by index, the index is unchecked
double (&data(void))[3]
{ return osg::Vec3d::_v; }
const osg::Vec3d& osg() const
{ return *this; }
osg::Vec3d& osg()
{ return *this; }
};
/// 3D Vector Class
template<typename T>
class SGVec3 {
class SGVec3 : protected SGVec3Storage<T> {
public:
typedef T value_type;
@@ -33,74 +82,77 @@ public:
/// uninitialized values in the debug build very fast ...
#ifndef NDEBUG
for (unsigned i = 0; i < 3; ++i)
_data[i] = SGLimits<T>::quiet_NaN();
data()[i] = SGLimits<T>::quiet_NaN();
#endif
}
/// Constructor. Initialize by the given values
SGVec3(T x, T y, T z)
{ _data[0] = x; _data[1] = y; _data[2] = z; }
{ data()[0] = x; data()[1] = y; data()[2] = z; }
/// Constructor. Initialize by the content of a plain array,
/// make sure it has at least 3 elements
explicit SGVec3(const T* data)
{ _data[0] = data[0]; _data[1] = data[1]; _data[2] = data[2]; }
explicit SGVec3(const T* d)
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; }
explicit SGVec3(const osg::Vec3f& d)
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; }
explicit SGVec3(const osg::Vec3d& d)
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; }
/// Access by index, the index is unchecked
const T& operator()(unsigned i) const
{ return _data[i]; }
{ return data()[i]; }
/// Access by index, the index is unchecked
T& operator()(unsigned i)
{ return _data[i]; }
{ return data()[i]; }
/// Access raw data by index, the index is unchecked
const T& operator[](unsigned i) const
{ return _data[i]; }
{ return data()[i]; }
/// Access raw data by index, the index is unchecked
T& operator[](unsigned i)
{ return _data[i]; }
{ return data()[i]; }
/// Access the x component
const T& x(void) const
{ return _data[0]; }
{ return data()[0]; }
/// Access the x component
T& x(void)
{ return _data[0]; }
{ return data()[0]; }
/// Access the y component
const T& y(void) const
{ return _data[1]; }
{ return data()[1]; }
/// Access the y component
T& y(void)
{ return _data[1]; }
{ return data()[1]; }
/// Access the z component
const T& z(void) const
{ return _data[2]; }
{ return data()[2]; }
/// Access the z component
T& z(void)
{ return _data[2]; }
{ return data()[2]; }
/// Get the data pointer
const T* data(void) const
{ return _data; }
/// Get the data pointer
T* data(void)
{ return _data; }
using SGVec3Storage<T>::data;
/// Readonly interface function to ssg's sgVec3/sgdVec3
const T (&sg(void) const)[3]
{ return _data; }
{ return data(); }
/// Interface function to ssg's sgVec3/sgdVec3
T (&sg(void))[3]
{ return _data; }
{ return data(); }
/// Interface function to osg's Vec3*
using SGVec3Storage<T>::osg;
/// Inplace addition
SGVec3& operator+=(const SGVec3& v)
{ _data[0] += v(0); _data[1] += v(1); _data[2] += v(2); return *this; }
{ data()[0] += v(0); data()[1] += v(1); data()[2] += v(2); return *this; }
/// Inplace subtraction
SGVec3& operator-=(const SGVec3& v)
{ _data[0] -= v(0); _data[1] -= v(1); _data[2] -= v(2); return *this; }
{ data()[0] -= v(0); data()[1] -= v(1); data()[2] -= v(2); return *this; }
/// Inplace scalar multiplication
template<typename S>
SGVec3& operator*=(S s)
{ _data[0] *= s; _data[1] *= s; _data[2] *= s; return *this; }
{ data()[0] *= s; data()[1] *= s; data()[2] *= s; return *this; }
/// Inplace scalar multiplication by 1/s
template<typename S>
SGVec3& operator/=(S s)
@@ -123,10 +175,6 @@ public:
/// Constructor. Initialize by a geocentric coordinate
/// Note that this conversion is relatively expensive to compute
static SGVec3 fromGeoc(const SGGeoc& geoc);
private:
/// The actual data
T _data[3];
};
template<>

View File

@@ -18,9 +18,58 @@
#ifndef SGVec4_H
#define SGVec4_H
#include <osg/Vec4f>
#include <osg/Vec4d>
template<typename T>
struct SGVec4Storage {
/// Readonly raw storage interface
const T (&data(void) const)[4]
{ return _data; }
/// Readonly raw storage interface
T (&data(void))[4]
{ return _data; }
void osg() const
{ }
private:
T _data[4];
};
template<>
struct SGVec4Storage<float> : public osg::Vec4f {
/// Access raw data by index, the index is unchecked
const float (&data(void) const)[4]
{ return osg::Vec4f::_v; }
/// Access raw data by index, the index is unchecked
float (&data(void))[4]
{ return osg::Vec4f::_v; }
const osg::Vec4f& osg() const
{ return *this; }
osg::Vec4f& osg()
{ return *this; }
};
template<>
struct SGVec4Storage<double> : public osg::Vec4d {
/// Access raw data by index, the index is unchecked
const double (&data(void) const)[4]
{ return osg::Vec4d::_v; }
/// Access raw data by index, the index is unchecked
double (&data(void))[4]
{ return osg::Vec4d::_v; }
const osg::Vec4d& osg() const
{ return *this; }
osg::Vec4d& osg()
{ return *this; }
};
/// 4D Vector Class
template<typename T>
class SGVec4 {
class SGVec4 : protected SGVec4Storage<T> {
public:
typedef T value_type;
@@ -33,82 +82,84 @@ public:
/// uninitialized values in the debug build very fast ...
#ifndef NDEBUG
for (unsigned i = 0; i < 4; ++i)
_data[i] = SGLimits<T>::quiet_NaN();
data()[i] = SGLimits<T>::quiet_NaN();
#endif
}
/// Constructor. Initialize by the given values
SGVec4(T x, T y, T z, T w)
{ _data[0] = x; _data[1] = y; _data[2] = z; _data[3] = w; }
{ data()[0] = x; data()[1] = y; data()[2] = z; data()[3] = w; }
/// Constructor. Initialize by the content of a plain array,
/// make sure it has at least 3 elements
explicit SGVec4(const T* d)
{ _data[0] = d[0]; _data[1] = d[1]; _data[2] = d[2]; _data[3] = d[3]; }
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; }
explicit SGVec4(const osg::Vec4f& d)
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; }
explicit SGVec4(const osg::Vec4d& d)
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; }
/// Access by index, the index is unchecked
const T& operator()(unsigned i) const
{ return _data[i]; }
{ return data()[i]; }
/// Access by index, the index is unchecked
T& operator()(unsigned i)
{ return _data[i]; }
{ return data()[i]; }
/// Access raw data by index, the index is unchecked
const T& operator[](unsigned i) const
{ return _data[i]; }
{ return data()[i]; }
/// Access raw data by index, the index is unchecked
T& operator[](unsigned i)
{ return _data[i]; }
{ return data()[i]; }
/// Access the x component
const T& x(void) const
{ return _data[0]; }
{ return data()[0]; }
/// Access the x component
T& x(void)
{ return _data[0]; }
{ return data()[0]; }
/// Access the y component
const T& y(void) const
{ return _data[1]; }
{ return data()[1]; }
/// Access the y component
T& y(void)
{ return _data[1]; }
{ return data()[1]; }
/// Access the z component
const T& z(void) const
{ return _data[2]; }
{ return data()[2]; }
/// Access the z component
T& z(void)
{ return _data[2]; }
{ return data()[2]; }
/// Access the x component
const T& w(void) const
{ return _data[3]; }
{ return data()[3]; }
/// Access the x component
T& w(void)
{ return _data[3]; }
{ return data()[3]; }
/// Get the data pointer
using SGVec4Storage<T>::data;
/// Get the data pointer, usefull for interfacing with plib's sg*Vec
const T* data(void) const
{ return _data; }
/// Get the data pointer, usefull for interfacing with plib's sg*Vec
T* data(void)
{ return _data; }
/// Readonly interface function to ssg's sgVec3/sgdVec3
/// Readonly interface function to ssg's sgVec4/sgdVec4
const T (&sg(void) const)[4]
{ return _data; }
/// Interface function to ssg's sgVec3/sgdVec3
{ return data(); }
/// Interface function to ssg's sgVec4/sgdVec4
T (&sg(void))[4]
{ return _data; }
{ return data(); }
/// Interface function to osg's Vec4*
using SGVec4Storage<T>::osg;
/// Inplace addition
SGVec4& operator+=(const SGVec4& v)
{ _data[0]+=v(0);_data[1]+=v(1);_data[2]+=v(2);_data[3]+=v(3);return *this; }
{ data()[0]+=v(0);data()[1]+=v(1);data()[2]+=v(2);data()[3]+=v(3);return *this; }
/// Inplace subtraction
SGVec4& operator-=(const SGVec4& v)
{ _data[0]-=v(0);_data[1]-=v(1);_data[2]-=v(2);_data[3]-=v(3);return *this; }
{ data()[0]-=v(0);data()[1]-=v(1);data()[2]-=v(2);data()[3]-=v(3);return *this; }
/// Inplace scalar multiplication
template<typename S>
SGVec4& operator*=(S s)
{ _data[0] *= s; _data[1] *= s; _data[2] *= s; _data[3] *= s; return *this; }
{ data()[0] *= s; data()[1] *= s; data()[2] *= s; data()[3] *= s; return *this; }
/// Inplace scalar multiplication by 1/s
template<typename S>
SGVec4& operator/=(S s)
@@ -126,10 +177,6 @@ public:
{ return SGVec4(0, 0, 1, 0); }
static SGVec4 e4(void)
{ return SGVec4(0, 0, 0, 1); }
private:
/// The actual data
T _data[4];
};
/// Unary +, do nothing ...

View File

@@ -1,6 +1,6 @@
includedir = @includedir@/scene
SUBDIRS = material model sky tgdb
SUBDIRS = material model sky tgdb util
# lib_LIBRARIES = libsgscene.a

View File

@@ -37,14 +37,21 @@ SG_USING_STD(map);
# include <math.h>
#endif
#include <osg/CullFace>
#include <osg/Material>
#include <osg/ShadeModel>
#include <osg/TexEnv>
#include <osg/Texture2D>
#include <osgDB/ReadFile>
#include <simgear/debug/logstream.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/misc/sgstream.hxx>
#include <simgear/scene/model/model.hxx>
#include "mat.hxx"
static map<string, ssgTexture *> _tex_cache;
static map<string, ssgTexture *>::iterator _tex_cache_iter;
static map<string, osg::ref_ptr<osg::Texture2D> > _tex_cache;
////////////////////////////////////////////////////////////////////////
@@ -56,7 +63,7 @@ SGMaterial::SGMaterial( const string &fg_root, const SGPropertyNode *props, cons
{
init();
read_properties( fg_root, props, season );
build_ssg_state( false );
build_state( false );
}
SGMaterial::SGMaterial( const string &texpath )
@@ -66,13 +73,13 @@ SGMaterial::SGMaterial( const string &texpath )
_internal_state st( NULL, texpath, false );
_status.push_back( st );
build_ssg_state( true );
build_state( true );
}
SGMaterial::SGMaterial( ssgSimpleState *s )
SGMaterial::SGMaterial( osg::StateSet *s )
{
init();
set_ssg_state( s );
set_state( s );
}
SGMaterial::~SGMaterial (void)
@@ -225,7 +232,7 @@ SGMaterial::load_texture ( int n )
if ( !_status[i].texture_loaded ) {
SG_LOG( SG_GENERAL, SG_INFO, "Loading deferred texture "
<< _status[i].texture_path );
assignTexture(_status[i].state, _status[i].texture_path,
assignTexture(_status[i].state.get(), _status[i].texture_path,
wrapu, wrapv, mipmap );
_status[i].texture_loaded = true;
}
@@ -233,7 +240,7 @@ SGMaterial::load_texture ( int n )
return true;
}
ssgSimpleState *
osg::StateSet *
SGMaterial::get_state (int n) const
{
if (_status.size() == 0) {
@@ -241,80 +248,84 @@ SGMaterial::get_state (int n) const
return NULL;
}
ssgSimpleState *st = (n >= 0) ? _status[n].state
: _status[_current_ptr].state;
((SGMaterial *)this)->_current_ptr += 1;
osg::StateSet *st = (n >= 0) ? _status[n].state.get()
: _status[_current_ptr].state.get();
_current_ptr += 1;
if (_current_ptr >= _status.size())
((SGMaterial *)this)->_current_ptr = 0;
_current_ptr = 0;
return st;
}
void
SGMaterial::build_ssg_state( bool defer_tex_load )
SGMaterial::build_state( bool defer_tex_load )
{
GLenum shade_model = GL_SMOOTH;
for (unsigned int i = 0; i < _status.size(); i++)
{
ssgSimpleState *state = new ssgSimpleState();
osg::StateSet *stateSet = new osg::StateSet;
// Set up the textured state
state->setShadeModel( shade_model );
state->enable( GL_LIGHTING );
state->enable ( GL_CULL_FACE ) ;
state->enable( GL_TEXTURE_2D );
state->disable( GL_BLEND );
state->disable( GL_ALPHA_TEST );
osg::ShadeModel* shadeModel = new osg::ShadeModel;
shadeModel->setMode(osg::ShadeModel::SMOOTH);
stateSet->setAttributeAndModes(shadeModel, osg::StateAttribute::ON);
osg::CullFace* cullFace = new osg::CullFace;
cullFace->setMode(osg::CullFace::BACK);
stateSet->setAttributeAndModes(cullFace, osg::StateAttribute::ON);
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON);
stateSet->setMode(GL_BLEND, osg::StateAttribute::OFF);
stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::OFF);
if ( !defer_tex_load ) {
SG_LOG(SG_INPUT, SG_INFO, " " << _status[i].texture_path );
assignTexture( state, _status[i].texture_path, wrapu, wrapv );
assignTexture( stateSet, _status[i].texture_path, wrapu, wrapv );
_status[i].texture_loaded = true;
} else {
_status[i].texture_loaded = false;
}
state->enable( GL_COLOR_MATERIAL );
state->setMaterial ( GL_AMBIENT,
ambient[0], ambient[1],
ambient[2], ambient[3] ) ;
state->setMaterial ( GL_DIFFUSE,
diffuse[0], diffuse[1],
diffuse[2], diffuse[3] ) ;
state->setMaterial ( GL_SPECULAR,
specular[0], specular[1],
specular[2], specular[3] ) ;
state->setMaterial ( GL_EMISSION,
emission[0], emission[1],
emission[2], emission[3] ) ;
state->setShininess ( shininess );
osg::Material* material = new osg::Material;
material->setColorMode(osg::Material::DIFFUSE);
material->setAmbient(osg::Material::FRONT_AND_BACK, ambient.osg());
material->setDiffuse(osg::Material::FRONT_AND_BACK, diffuse.osg());
material->setSpecular(osg::Material::FRONT_AND_BACK, specular.osg());
material->setEmission(osg::Material::FRONT_AND_BACK, emission.osg());
material->setShininess(osg::Material::FRONT_AND_BACK, shininess );
stateSet->setAttribute(material);
// stateSet->setMode(GL_COLOR_MATERIAL, osg::StateAttribute::ON);
_status[i].state = state;
_status[i].state = stateSet;
}
}
void SGMaterial::set_ssg_state( ssgSimpleState *s )
void SGMaterial::set_state( osg::StateSet *s )
{
_status.push_back( _internal_state( s, "", true ) );
}
void SGMaterial::assignTexture( ssgSimpleState *state, string &fname,
void SGMaterial::assignTexture( osg::StateSet *state, const std::string &fname,
int _wrapu, int _wrapv, int _mipmap )
{
map<string, osg::ref_ptr<osg::Texture2D> >::iterator _tex_cache_iter;
_tex_cache_iter = _tex_cache.find(fname);
if (_tex_cache_iter == _tex_cache.end())
{
state->setTexture((char *)fname.c_str(), _wrapu, _wrapv, _mipmap);
_tex_cache[fname] = state->getTexture();
osg::Texture2D* texture = SGLoadTexture2D(fname, _wrapu, _wrapv,
mipmap ? -1 : 0);
state->setTextureAttributeAndModes(0, texture);
_tex_cache[fname] = texture;
}
else
{
state->setTexture(_tex_cache_iter->second);
state->setTextureAttributeAndModes(0, _tex_cache_iter->second.get());
// cout << "Cache hit: " << fname << endl;
}
osg::TexEnv* texEnv = new osg::TexEnv;
texEnv->setMode(osg::TexEnv::MODULATE);
state->setTextureAttributeAndModes(0, texEnv);
}
SGMaterialGlyph* SGMaterial::get_glyph (const string& name) const

View File

@@ -38,11 +38,10 @@
#include <simgear/math/SGMath.hxx>
#include <plib/sg.h>
#include <plib/ssg.h>
#include <osg/ref_ptr>
#include <osg/StateSet>
#include <simgear/props/props.hxx>
#include <simgear/structure/ssgSharedPtr.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
#include "matmodel.hxx"
@@ -93,15 +92,15 @@ public:
/**
* Construct a material around an existing SSG state.
* Construct a material around an existing state.
*
* This constructor allows the application to create a custom,
* low-level state for the scene graph and wrap a material around
* it. Note: the pointer ownership is transferred to the material.
*
* @param s The SSG state for this material.
* @param s The state for this material.
*/
SGMaterial( ssgSimpleState *s );
SGMaterial( osg::StateSet *s );
/**
* Destructor.
@@ -126,7 +125,7 @@ public:
/**
* Get the textured state.
*/
ssgSimpleState *get_state (int n = -1) const;
osg::StateSet *get_state (int n = -1) const;
/**
@@ -224,9 +223,9 @@ protected:
protected:
struct _internal_state {
_internal_state( ssgSimpleState *s, const string &t, bool l )
_internal_state( osg::StateSet *s, const string &t, bool l )
: state(s), texture_path(t), texture_loaded(l) {}
ssgSharedPtr<ssgSimpleState> state;
osg::ref_ptr<osg::StateSet> state;
string texture_path;
bool texture_loaded;
};
@@ -242,7 +241,7 @@ private:
vector<_internal_state> _status;
// Round-robin counter
unsigned int _current_ptr;
mutable unsigned int _current_ptr;
// texture size
double xsize, ysize;
@@ -291,10 +290,10 @@ private:
SGMaterial( const string &fg_root, const SGMaterial &mat ); // unimplemented
void read_properties( const string &fg_root, const SGPropertyNode *props, const char *season );
void build_ssg_state( bool defer_tex_load );
void set_ssg_state( ssgSimpleState *s );
void build_state( bool defer_tex_load );
void set_state( osg::StateSet *s );
void assignTexture( ssgSimpleState *state, string &fname, int _wrapu = TRUE, int _wrapv = TRUE, int _mipmap = TRUE );
void assignTexture( osg::StateSet *state, const std::string &fname, int _wrapu = TRUE, int _wrapv = TRUE, int _mipmap = TRUE );
};
@@ -311,7 +310,7 @@ protected:
double _right;
};
class SGMaterialUserData : public ssgBase {
class SGMaterialUserData : public osg::Referenced {
public:
SGMaterialUserData(const SGMaterial* material) :
mMaterial(material)

View File

@@ -33,8 +33,6 @@
# include <windows.h>
#endif
#include <plib/ssg.h>
#include <simgear/compiler.h>
#include <simgear/constants.h>
#include <simgear/structure/exception.hxx>
@@ -44,6 +42,20 @@
#include <string.h>
#include STL_STRING
#include <osg/AlphaFunc>
#include <osg/BlendFunc>
#include <osg/CullFace>
#include <osg/Material>
// #include <osg/Multisample>
#include <osg/Point>
#include <osg/PointSprite>
#include <osg/PolygonMode>
#include <osg/PolygonOffset>
#include <osg/StateSet>
#include <osg/TexEnv>
#include <osg/TexGen>
#include <osg/Texture2D>
#include <simgear/debug/logstream.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/misc/sgstream.hxx>
@@ -57,98 +69,26 @@
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 ) {
}
#if 0 // debugging infrastructure
static int gen_test_light_map() {
static const int env_tex_res = 32;
int half_res = env_tex_res / 2;
unsigned char env_map[env_tex_res][env_tex_res][4];
GLuint tex_name;
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; }
// cout << x << "," << y << " " << (int)(dist * 255) << ","
// << (int)((1.0 - dist) * 255) << endl;
env_map[i][j][0] = (int)(dist * 255);
env_map[i][j][1] = (int)((1.0 - dist) * 255);
env_map[i][j][2] = 0;
env_map[i][j][3] = 255;
}
}
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glGenTextures( 1, &tex_name );
glBindTexture( GL_TEXTURE_2D, tex_name );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, env_tex_res, env_tex_res, 0,
GL_RGBA, GL_UNSIGNED_BYTE, env_map);
return tex_name;
}
#endif
// generate a light sprite texture map
static int 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;
unsigned char env_map[env_tex_res][env_tex_res][4];
GLuint tex_name;
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; }
env_map[i][j][0] = r;
env_map[i][j][1] = g;
env_map[i][j][2] = b;
env_map[i][j][3] = (int)(bright * alpha);
}
}
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glGenTextures( 1, &tex_name );
glBindTexture( GL_TEXTURE_2D, tex_name );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, env_tex_res, env_tex_res, 0,
GL_RGBA, GL_UNSIGNED_BYTE, env_map);
return tex_name;
}
// generate standard colored directional light environment texture map
static int gen_standard_dir_light_map( int r, int g, int b, int alpha ) {
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;
unsigned char env_map[env_tex_res][env_tex_res][4];
GLuint tex_name;
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;
@@ -157,34 +97,30 @@ static int gen_standard_dir_light_map( int r, int g, int b, int alpha ) {
if ( dist > 1.0 ) { dist = 1.0; }
double bright = cos( dist * SGD_PI_2 );
if ( bright < 0.3 ) { bright = 0.3; }
env_map[i][j][0] = r;
env_map[i][j][1] = g;
env_map[i][j][2] = b;
env_map[i][j][3] = (int)(bright * alpha);
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);
}
}
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glGenTextures( 1, &tex_name );
glBindTexture( GL_TEXTURE_2D, tex_name );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, env_tex_res, env_tex_res, 0,
GL_RGBA, GL_UNSIGNED_BYTE, env_map);
osg::Texture2D* texture = new osg::Texture2D;
texture->setImage(image);
return tex_name;
return texture;
}
// generate standard colored directional light environment texture map
static int gen_taxiway_dir_light_map( int r, int g, int b, int alpha ) {
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;
unsigned char env_map[env_tex_res][env_tex_res][4];
GLuint tex_name;
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 ) {
@@ -195,25 +131,49 @@ static int gen_taxiway_dir_light_map( int r, int g, int b, int alpha ) {
if ( dist > 1.0 ) { dist = 1.0; }
double bright = sin( dist * SGD_PI_2 );
if ( bright < 0.2 ) { bright = 0.2; }
env_map[i][j][0] = r;
env_map[i][j][1] = g;
env_map[i][j][2] = b;
env_map[i][j][3] = (int)(bright * alpha);
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);
}
}
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glGenTextures( 1, &tex_name );
glBindTexture( GL_TEXTURE_2D, tex_name );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, env_tex_res, env_tex_res, 0,
GL_RGBA, GL_UNSIGNED_BYTE, env_map);
osg::Texture2D* texture = new osg::Texture2D;
texture->setImage(image);
return tex_name;
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;
}
@@ -254,41 +214,89 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
}
}
osg::ref_ptr<osg::StateSet> lightStateSet = new osg::StateSet;
{
// lightStateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
// lightStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
lightStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
// lightStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
lightStateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::OFF);
// lightStateSet->setAttribute(new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0));
// 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);
// lightStateSet->setMode(GL_COLOR_MATERIAL, osg::StateAttribute::OFF);
}
// hard coded ground light state
ssgSimpleState *gnd_lights = new ssgSimpleState;
gnd_lights->disable( GL_TEXTURE_2D );
gnd_lights->enable( GL_CULL_FACE );
gnd_lights->enable( GL_COLOR_MATERIAL );
gnd_lights->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
gnd_lights->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
gnd_lights->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
gnd_lights->enable( GL_BLEND );
gnd_lights->disable( GL_ALPHA_TEST );
gnd_lights->disable( GL_LIGHTING );
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;
GLuint tex_name;
// hard coded runway white light state
osg::Texture2D* texture;
if ( sprite_lighting ) {
tex_name = gen_standard_light_sprite( 235, 235, 195, 255 );
texture = gen_standard_light_sprite(235, 235, 195, 255);
} else {
tex_name = gen_standard_dir_light_map( 235, 235, 195, 255 );
texture = gen_standard_dir_light_map(235, 235, 195, 255);
}
ssgSimpleState *rwy_white_lights = new ssgSimpleState();
rwy_white_lights->disable( GL_LIGHTING );
rwy_white_lights->enable ( GL_CULL_FACE ) ;
rwy_white_lights->enable( GL_TEXTURE_2D );
rwy_white_lights->enable( GL_BLEND );
rwy_white_lights->enable( GL_ALPHA_TEST );
rwy_white_lights->enable( GL_COLOR_MATERIAL );
rwy_white_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
rwy_white_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
rwy_white_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
rwy_white_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
rwy_white_lights->setTexture( tex_name );
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;
@@ -301,242 +309,133 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
// hard coded runway medium intensity white light state
if ( sprite_lighting ) {
tex_name = gen_standard_light_sprite( 235, 235, 195, 205 );
texture = gen_standard_light_sprite( 235, 235, 195, 205 );
} else {
tex_name = gen_standard_dir_light_map( 235, 235, 195, 205 );
texture = gen_standard_dir_light_map( 235, 235, 195, 205 );
}
ssgSimpleState *rwy_white_medium_lights = new ssgSimpleState();
rwy_white_medium_lights->disable( GL_LIGHTING );
rwy_white_medium_lights->enable ( GL_CULL_FACE ) ;
rwy_white_medium_lights->enable( GL_TEXTURE_2D );
rwy_white_medium_lights->enable( GL_BLEND );
rwy_white_medium_lights->enable( GL_ALPHA_TEST );
rwy_white_medium_lights->enable( GL_COLOR_MATERIAL );
rwy_white_medium_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
rwy_white_medium_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
rwy_white_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
rwy_white_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
rwy_white_medium_lights->setTexture( tex_name );
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 ) {
tex_name = gen_standard_light_sprite( 235, 235, 195, 155 );
texture = gen_standard_light_sprite( 235, 235, 195, 155 );
} else {
tex_name = gen_standard_dir_light_map( 235, 235, 195, 155 );
texture = gen_standard_dir_light_map( 235, 235, 195, 155 );
}
ssgSimpleState *rwy_white_low_lights = new ssgSimpleState();
rwy_white_low_lights->disable( GL_LIGHTING );
rwy_white_low_lights->enable ( GL_CULL_FACE ) ;
rwy_white_low_lights->enable( GL_TEXTURE_2D );
rwy_white_low_lights->enable( GL_BLEND );
rwy_white_low_lights->enable( GL_ALPHA_TEST );
rwy_white_low_lights->enable( GL_COLOR_MATERIAL );
rwy_white_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
rwy_white_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
rwy_white_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
rwy_white_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
rwy_white_low_lights->setTexture( tex_name );
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 ) {
tex_name = gen_standard_light_sprite( 235, 215, 20, 255 );
texture = gen_standard_light_sprite( 235, 215, 20, 255 );
} else {
tex_name = gen_standard_dir_light_map( 235, 215, 20, 255 );
texture = gen_standard_dir_light_map( 235, 215, 20, 255 );
}
ssgSimpleState *rwy_yellow_lights = new ssgSimpleState();
rwy_yellow_lights->disable( GL_LIGHTING );
rwy_yellow_lights->enable ( GL_CULL_FACE ) ;
rwy_yellow_lights->enable( GL_TEXTURE_2D );
rwy_yellow_lights->enable( GL_BLEND );
rwy_yellow_lights->enable( GL_ALPHA_TEST );
rwy_yellow_lights->enable( GL_COLOR_MATERIAL );
rwy_yellow_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
rwy_yellow_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
rwy_yellow_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
rwy_yellow_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
rwy_yellow_lights->setTexture( tex_name );
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 ) {
tex_name = gen_standard_light_sprite( 235, 215, 20, 205 );
texture = gen_standard_light_sprite( 235, 215, 20, 205 );
} else {
tex_name = gen_standard_dir_light_map( 235, 215, 20, 205 );
texture = gen_standard_dir_light_map( 235, 215, 20, 205 );
}
ssgSimpleState *rwy_yellow_medium_lights = new ssgSimpleState();
rwy_yellow_medium_lights->disable( GL_LIGHTING );
rwy_yellow_medium_lights->enable ( GL_CULL_FACE ) ;
rwy_yellow_medium_lights->enable( GL_TEXTURE_2D );
rwy_yellow_medium_lights->enable( GL_BLEND );
rwy_yellow_medium_lights->enable( GL_ALPHA_TEST );
rwy_yellow_medium_lights->enable( GL_COLOR_MATERIAL );
rwy_yellow_medium_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
rwy_yellow_medium_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
rwy_yellow_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
rwy_yellow_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
rwy_yellow_medium_lights->setTexture( tex_name );
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 ) {
tex_name = gen_standard_light_sprite( 235, 215, 20, 155 );
texture = gen_standard_light_sprite( 235, 215, 20, 155 );
} else {
tex_name = gen_standard_dir_light_map( 235, 215, 20, 155 );
texture = gen_standard_dir_light_map( 235, 215, 20, 155 );
}
ssgSimpleState *rwy_yellow_low_lights = new ssgSimpleState();
rwy_yellow_low_lights->disable( GL_LIGHTING );
rwy_yellow_low_lights->enable ( GL_CULL_FACE ) ;
rwy_yellow_low_lights->enable( GL_TEXTURE_2D );
rwy_yellow_low_lights->enable( GL_BLEND );
rwy_yellow_low_lights->enable( GL_ALPHA_TEST );
rwy_yellow_low_lights->enable( GL_COLOR_MATERIAL );
rwy_yellow_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
rwy_yellow_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
rwy_yellow_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
rwy_yellow_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
rwy_yellow_low_lights->setTexture( tex_name );
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 ) {
tex_name = gen_standard_light_sprite( 235, 90, 90, 255 );
texture = gen_standard_light_sprite( 235, 90, 90, 255 );
} else {
tex_name = gen_standard_dir_light_map( 235, 90, 90, 255 );
texture = gen_standard_dir_light_map( 235, 90, 90, 255 );
}
ssgSimpleState *rwy_red_lights = new ssgSimpleState();
rwy_red_lights->disable( GL_LIGHTING );
rwy_red_lights->enable ( GL_CULL_FACE ) ;
rwy_red_lights->enable( GL_TEXTURE_2D );
rwy_red_lights->enable( GL_BLEND );
rwy_red_lights->enable( GL_ALPHA_TEST );
rwy_red_lights->enable( GL_COLOR_MATERIAL );
rwy_red_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
rwy_red_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
rwy_red_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
rwy_red_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
rwy_red_lights->setTexture( tex_name );
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 ) {
tex_name = gen_standard_light_sprite( 235, 90, 90, 205 );
texture = gen_standard_light_sprite( 235, 90, 90, 205 );
} else {
tex_name = gen_standard_dir_light_map( 235, 90, 90, 205 );
texture = gen_standard_dir_light_map( 235, 90, 90, 205 );
}
ssgSimpleState *rwy_red_medium_lights = new ssgSimpleState();
rwy_red_medium_lights->disable( GL_LIGHTING );
rwy_red_medium_lights->enable ( GL_CULL_FACE ) ;
rwy_red_medium_lights->enable( GL_TEXTURE_2D );
rwy_red_medium_lights->enable( GL_BLEND );
rwy_red_medium_lights->enable( GL_ALPHA_TEST );
rwy_red_medium_lights->enable( GL_COLOR_MATERIAL );
rwy_red_medium_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
rwy_red_medium_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
rwy_red_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
rwy_red_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
rwy_red_medium_lights->setTexture( tex_name );
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 ) {
tex_name = gen_standard_light_sprite( 235, 90, 90, 155 );
texture = gen_standard_light_sprite( 235, 90, 90, 155 );
} else {
tex_name = gen_standard_dir_light_map( 235, 90, 90, 155 );
texture = gen_standard_dir_light_map( 235, 90, 90, 155 );
}
ssgSimpleState *rwy_red_low_lights = new ssgSimpleState();
rwy_red_low_lights->disable( GL_LIGHTING );
rwy_red_low_lights->enable ( GL_CULL_FACE ) ;
rwy_red_low_lights->enable( GL_TEXTURE_2D );
rwy_red_low_lights->enable( GL_BLEND );
rwy_red_low_lights->enable( GL_ALPHA_TEST );
rwy_red_low_lights->enable( GL_COLOR_MATERIAL );
rwy_red_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
rwy_red_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
rwy_red_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
rwy_red_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
rwy_red_low_lights->setTexture( tex_name );
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 ) {
tex_name = gen_standard_light_sprite( 20, 235, 20, 255 );
texture = gen_standard_light_sprite( 20, 235, 20, 255 );
} else {
tex_name = gen_standard_dir_light_map( 20, 235, 20, 255 );
texture = gen_standard_dir_light_map( 20, 235, 20, 255 );
}
ssgSimpleState *rwy_green_lights = new ssgSimpleState();
rwy_green_lights->disable( GL_LIGHTING );
rwy_green_lights->enable ( GL_CULL_FACE ) ;
rwy_green_lights->enable( GL_TEXTURE_2D );
rwy_green_lights->enable( GL_BLEND );
rwy_green_lights->enable( GL_ALPHA_TEST );
rwy_green_lights->enable( GL_COLOR_MATERIAL );
rwy_green_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
rwy_green_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
rwy_green_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
rwy_green_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
rwy_green_lights->setTexture( tex_name );
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 ) {
tex_name = gen_standard_light_sprite( 20, 235, 20, 205 );
texture = gen_standard_light_sprite( 20, 235, 20, 205 );
} else {
tex_name = gen_standard_dir_light_map( 20, 235, 20, 205 );
texture = gen_standard_dir_light_map( 20, 235, 20, 205 );
}
ssgSimpleState *rwy_green_medium_lights = new ssgSimpleState();
rwy_green_medium_lights->disable( GL_LIGHTING );
rwy_green_medium_lights->enable ( GL_CULL_FACE ) ;
rwy_green_medium_lights->enable( GL_TEXTURE_2D );
rwy_green_medium_lights->enable( GL_BLEND );
rwy_green_medium_lights->enable( GL_ALPHA_TEST );
rwy_green_medium_lights->enable( GL_COLOR_MATERIAL );
rwy_green_medium_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
rwy_green_medium_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
rwy_green_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
rwy_green_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
rwy_green_medium_lights->setTexture( tex_name );
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 ) {
tex_name = gen_standard_light_sprite( 20, 235, 20, 155 );
texture = gen_standard_light_sprite( 20, 235, 20, 155 );
} else {
tex_name = gen_standard_dir_light_map( 20, 235, 20, 155 );
texture = gen_standard_dir_light_map( 20, 235, 20, 155 );
}
ssgSimpleState *rwy_green_low_lights = new ssgSimpleState();
rwy_green_low_lights->disable( GL_LIGHTING );
rwy_green_low_lights->enable ( GL_CULL_FACE ) ;
rwy_green_low_lights->enable( GL_TEXTURE_2D );
rwy_green_low_lights->enable( GL_BLEND );
rwy_green_low_lights->enable( GL_ALPHA_TEST );
rwy_green_low_lights->enable( GL_COLOR_MATERIAL );
rwy_green_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
rwy_green_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
rwy_green_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
rwy_green_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
rwy_green_low_lights->setTexture( tex_name );
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;
@@ -545,45 +444,34 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
// hard coded low intensity taxiway blue light state
if ( sprite_lighting ) {
tex_name = gen_standard_light_sprite( 90, 90, 235, 205 );
texture = gen_standard_light_sprite( 90, 90, 235, 205 );
} else {
tex_name = gen_taxiway_dir_light_map( 90, 90, 235, 205 );
texture = gen_taxiway_dir_light_map( 90, 90, 235, 205 );
}
ssgSimpleState *taxiway_blue_low_lights = new ssgSimpleState();
taxiway_blue_low_lights->disable( GL_LIGHTING );
taxiway_blue_low_lights->enable ( GL_CULL_FACE ) ;
taxiway_blue_low_lights->enable( GL_TEXTURE_2D );
taxiway_blue_low_lights->enable( GL_BLEND );
taxiway_blue_low_lights->enable( GL_ALPHA_TEST );
taxiway_blue_low_lights->enable( GL_COLOR_MATERIAL );
taxiway_blue_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
taxiway_blue_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
taxiway_blue_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
taxiway_blue_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
taxiway_blue_low_lights->setTexture( tex_name );
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 ) {
tex_name = gen_standard_light_sprite( 235, 235, 195, 255 );
texture = gen_standard_light_sprite( 235, 235, 195, 255 );
} else {
tex_name = gen_standard_dir_light_map( 235, 235, 195, 255 );
texture = gen_standard_dir_light_map( 235, 235, 195, 255 );
}
ssgSimpleState *rwy_vasi_lights = new ssgSimpleState();
rwy_vasi_lights->disable( GL_LIGHTING );
rwy_vasi_lights->enable ( GL_CULL_FACE ) ;
rwy_vasi_lights->enable( GL_TEXTURE_2D );
rwy_vasi_lights->enable( GL_BLEND );
rwy_vasi_lights->enable( GL_ALPHA_TEST );
rwy_vasi_lights->enable( GL_COLOR_MATERIAL );
rwy_vasi_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
rwy_vasi_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
rwy_vasi_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
rwy_vasi_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
// rwy_vasi_lights->setTexture( gen_vasi_light_map_old() );
rwy_vasi_lights->setTexture( tex_name );
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;
@@ -621,13 +509,13 @@ bool SGMaterialLib::add_item ( const string &mat_name, const string &full_path )
// Load a library of material properties
bool SGMaterialLib::add_item ( const string &mat_name, ssgSimpleState *state )
bool SGMaterialLib::add_item ( const string &mat_name, osg::StateSet *state )
{
matlib[mat_name] = new SGMaterial( state );
matlib[mat_name]->add_name(mat_name);
SG_LOG( SG_TERRAIN, SG_INFO, " Loading material given a premade "
<< "ssgSimpleState = " << mat_name );
<< "osg::StateSet = " << mat_name );
return true;
}
@@ -665,16 +553,17 @@ void SGMaterialLib::load_next_deferred() {
}
// Return the material from that given leaf
const SGMaterial* SGMaterialLib::findMaterial(/*const*/ssgLeaf* leaf) const
const SGMaterial* SGMaterialLib::findMaterial(const osg::Node* leaf) const
{
if (!leaf)
return 0;
ssgBase* base = leaf->getUserData();
const osg::Referenced* base = leaf->getUserData();
if (!base)
return 0;
SGMaterialUserData* matUserData = dynamic_cast<SGMaterialUserData*>(base);
const SGMaterialUserData* matUserData
= dynamic_cast<const SGMaterialUserData*>(base);
if (!matUserData)
return 0;

View File

@@ -37,8 +37,8 @@
#include <map> // STL associative "array"
#include <vector> // STL "array"
#include <plib/ssg.h> // plib include
#include <osg/Node>
#include <osg/StateSet>
class SGMaterial;
@@ -47,7 +47,6 @@ SG_USING_STD(map);
SG_USING_STD(vector);
SG_USING_STD(less);
// Material management class
class SGMaterialLib {
@@ -71,7 +70,7 @@ public:
// Add the named texture with default properties
bool add_item( const string &tex_path );
bool add_item( const string &mat_name, const string &tex_path );
bool add_item( const string &mat_name, ssgSimpleState *state );
bool add_item( const string &mat_name, osg::StateSet *state );
// find a material record by material name
SGMaterial *find( const string& material );
@@ -87,7 +86,7 @@ public:
material_map_iterator end() { return matlib.end(); }
const_material_map_iterator end() const { return matlib.end(); }
const SGMaterial* findMaterial(/*const*/ssgLeaf* leaf) const;
const SGMaterial* findMaterial(const osg::Node* leaf) const;
// Destructor
~SGMaterialLib ( void );

View File

@@ -30,7 +30,11 @@
#include <map>
SG_USING_STD(map);
#include <simgear/compiler.h>
#include <osg/AlphaFunc>
#include <osg/Group>
#include <osg/LOD>
#include <osg/StateSet>
#include <osg/Transform>
#ifdef SG_MATH_EXCEPTION_CLASH
# include <math.h>
@@ -120,22 +124,6 @@ SGMatModel::get_model_count( SGModelLib *modellib,
return _models.size();
}
static void
setAlphaClampToBranch( ssgBranch *b, float clamp )
{
int nb = b->getNumKids();
for (int i = 0; i<nb; i++) {
ssgEntity *e = b->getKid(i);
if (e->isAKindOf(ssgTypeLeaf())) {
ssgSimpleState*s = (ssgSimpleState*)((ssgLeaf*)e)->getState();
s->enable( GL_ALPHA_TEST );
s->setAlphaClamp( clamp );
} else if (e->isAKindOf(ssgTypeBranch())) {
setAlphaClampToBranch( (ssgBranch*)e, clamp );
}
}
}
inline void
SGMatModel::load_models ( SGModelLib *modellib,
const string &fg_root,
@@ -145,7 +133,7 @@ SGMatModel::load_models ( SGModelLib *modellib,
// Load model only on demand
if (!_models_loaded) {
for (unsigned int i = 0; i < _paths.size(); i++) {
ssgEntity *entity = modellib->load_model( fg_root, _paths[i],
osg::Node *entity = modellib->load_model( fg_root, _paths[i],
prop_root, sim_time_sec,
/*cache_object*/ true );
if (entity != 0) {
@@ -153,23 +141,29 @@ SGMatModel::load_models ( SGModelLib *modellib,
// in the XML wrapper as well (at least,
// the billboarding should be handled
// there).
float ranges[] = {0, _range_m};
ssgRangeSelector * lod = new ssgRangeSelector;
lod->setRanges(ranges, 2);
osg::LOD * lod = new osg::LOD;
lod->setName("Model LOD");
lod->setRangeMode(osg::LOD::DISTANCE_FROM_EYE_POINT);
lod->setRange(0, 0, _range_m);
if (_heading_type == HEADING_BILLBOARD) {
// if the model is a billboard, it is likely :
// 1. a branch with only leaves,
// 2. a tree or a non rectangular shape faked by transparency
// We add alpha clamp then
if ( entity->isAKindOf(ssgTypeBranch()) ) {
ssgBranch *b = (ssgBranch *)entity;
setAlphaClampToBranch( b, 0.01f );
}
ssgCutout * cutout = new ssgCutout(false);
cutout->addKid(entity);
lod->addKid(cutout);
osg::StateSet* stateSet = entity->getOrCreateStateSet();
osg::AlphaFunc* alphaFunc =
new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.01f);
stateSet->setAttributeAndModes(alphaFunc,
osg::StateAttribute::OVERRIDE);
stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
osg::Transform* transform = new osg::Transform;
transform->setName("Model Billboard Transform");
transform->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
transform->addChild(entity);
lod->addChild(transform);
} else {
lod->addKid(entity);
lod->addChild(entity);
}
_models.push_back(lod);
} else {
@@ -180,7 +174,7 @@ SGMatModel::load_models ( SGModelLib *modellib,
_models_loaded = true;
}
ssgEntity *
osg::Node*
SGMatModel::get_model( int index,
SGModelLib *modellib,
const string &fg_root,
@@ -188,10 +182,10 @@ SGMatModel::get_model( int index,
double sim_time_sec )
{
load_models( modellib, fg_root, prop_root, sim_time_sec ); // comment this out if preloading models
return _models[index];
return _models[index].get();
}
ssgEntity *
osg::Node*
SGMatModel::get_random_model( SGModelLib *modellib,
const string &fg_root,
SGPropertyNode *prop_root,
@@ -202,7 +196,7 @@ SGMatModel::get_random_model( SGModelLib *modellib,
int index = int(sg_random() * nModels);
if (index >= nModels)
index = 0;
return _models[index];
return _models[index].get();
}
double

View File

@@ -32,12 +32,11 @@
#include STL_STRING // Standard C++ string library
#include <plib/sg.h>
#include <plib/ssg.h>
#include <osg/ref_ptr>
#include <osg/Node>
#include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/structure/ssgSharedPtr.hxx>
#include <simgear/props/props.hxx>
SG_USING_STD(string);
@@ -86,7 +85,7 @@ public:
* @param index The index of the model.
* @return The model.
*/
ssgEntity *get_model( int index,
osg::Node *get_model( int index,
SGModelLib *modellib,
const string &fg_root,
SGPropertyNode *prop_root,
@@ -98,7 +97,7 @@ public:
*
* @return A randomly select model from the variants.
*/
ssgEntity *get_random_model( SGModelLib *modellib,
osg::Node *get_random_model( SGModelLib *modellib,
const string &fg_root,
SGPropertyNode *prop_root,
double sim_time_sec );
@@ -141,7 +140,7 @@ private:
double sim_time_sec );
vector<string> _paths;
mutable vector<ssgSharedPtr<ssgEntity> > _models;
mutable vector<osg::ref_ptr<osg::Node> > _models;
mutable bool _models_loaded;
double _coverage_m2;
double _range_m;
@@ -198,7 +197,6 @@ private:
double _range_m;
vector<SGSharedPtr<SGMatModel> > _objects;
};

View File

@@ -6,19 +6,16 @@ noinst_HEADERS =
include_HEADERS = \
animation.hxx \
custtrans.hxx \
location.hxx \
model.hxx \
modellib.hxx \
personality.hxx \
persparam.hxx \
placement.hxx \
placementtrans.hxx \
shadowvolume.hxx
placementtrans.hxx
libsgmodel_a_SOURCES = \
animation.cxx \
custtrans.cxx \
location.cxx \
model.cxx \
modellib.cxx \
@@ -26,7 +23,6 @@ libsgmodel_a_SOURCES = \
persparam.cxx \
placement.cxx \
placementtrans.cxx \
shadowvolume.cxx \
shadanim.cxx
INCLUDES = -I$(top_srcdir)

File diff suppressed because it is too large Load Diff

View File

@@ -14,25 +14,35 @@
#include <vector>
#include <map>
#include <plib/sg.h>
#include <plib/ssg.h>
#include <osg/Vec3>
#include <osg/Vec4>
#include <osg/ref_ptr>
#include <osg/AlphaFunc>
#include <osg/ColorMatrix>
#include <osg/Group>
#include <osg/Material>
#include <osg/Node>
#include <osg/NodeCallback>
#include <osg/NodeVisitor>
#include <osg/StateSet>
#include <osg/Texture2D>
#include <osg/TexMat>
#include <simgear/math/point3d.hxx>
#include <simgear/props/props.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/scene/model/persparam.hxx>
#include <simgear/scene/util/SGNodeMasks.hxx>
SG_USING_STD(vector);
SG_USING_STD(map);
// Don't pull in the headers, since we don't need them here.
class SGInterpTable;
class SGCondition;
class SGPersonalityBranch;
// Has anyone done anything *really* stupid, like making min and max macros?
#ifdef min
#undef min
@@ -50,7 +60,7 @@ class SGPersonalityBranch;
/**
* Abstract base class for all animations.
*/
class SGAnimation : public ssgBase
class SGAnimation : public osg::NodeCallback
{
public:
enum PersonalityVar { INIT_SPIN, LAST_TIME_SEC_SPIN, FACTOR_SPIN,
@@ -62,14 +72,14 @@ public:
INIT_SCALE, X_FACTOR_SCALE, Y_FACTOR_SCALE, Z_FACTOR_SCALE,
X_OFFSET_SCALE, Y_OFFSET_SCALE, Z_OFFSET_SCALE };
SGAnimation (SGPropertyNode_ptr props, ssgBranch * branch);
SGAnimation (SGPropertyNode_ptr props, osg::Group * branch);
virtual ~SGAnimation ();
/**
* Get the SSG branch holding the animation.
*/
virtual ssgBranch * getBranch () { return _branch; }
virtual osg::Group * getBranch () { return _branch; }
/**
* Initialize the animation, after children have been added.
@@ -79,6 +89,14 @@ public:
/**
* Update the animation.
*/
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{
// note, callback is responsible for scenegraph traversal so
// should always include call traverse(node,nv) to ensure
// that the rest of cullbacks and the scene graph are traversed.
update();
traverse(node, nv);
}
virtual int update();
/**
@@ -104,7 +122,7 @@ protected:
static double sim_time_sec;
ssgBranch * _branch;
osg::Group* _branch;
int animation_type;
};
@@ -162,7 +180,7 @@ public:
SGSelectAnimation( SGPropertyNode *prop_root,
SGPropertyNode_ptr props );
virtual ~SGSelectAnimation ();
virtual int update();
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
private:
SGCondition * _condition;
};
@@ -187,9 +205,8 @@ private:
SGPersonalityParameter<double> _factor;
SGPersonalityParameter<double> _position_deg;
double _last_time_sec;
sgMat4 _matrix;
sgVec3 _center;
sgVec3 _axis;
osg::Vec3 _center;
osg::Vec3 _axis;
SGCondition * _condition;
};
@@ -209,7 +226,7 @@ private:
double _duration_sec;
double _last_time_sec;
double _total_duration_sec;
int _step;
unsigned _step;
struct DurationSpec {
DurationSpec( double m = 0.0 ) : _min(m), _max(m) {}
DurationSpec( double m1, double m2 ) : _min(m1), _max(m2) {}
@@ -241,9 +258,8 @@ private:
bool _has_max;
double _max_deg;
double _position_deg;
sgMat4 _matrix;
sgVec3 _center;
sgVec3 _axis;
osg::Vec3 _center;
osg::Vec3 _axis;
SGCondition * _condition;
};
@@ -269,8 +285,7 @@ private:
bool _has_max;
double _max_m;
double _position_m;
sgMat4 _matrix;
sgVec3 _axis;
osg::Vec3 _axis;
SGCondition * _condition;
};
@@ -295,6 +310,7 @@ private:
double _min;
bool _has_max;
double _max;
osg::ref_ptr<osg::ColorMatrix> _colorMatrix;
};
/**
@@ -332,7 +348,6 @@ private:
double _x_scale;
double _y_scale;
double _z_scale;
sgMat4 _matrix;
};
/**
@@ -356,10 +371,10 @@ private:
bool _has_max;
double _max_deg;
double _position_deg;
sgMat4 _matrix;
sgVec3 _center;
sgVec3 _axis;
osg::Vec3 _center;
osg::Vec3 _axis;
SGCondition * _condition;
osg::ref_ptr<osg::TexMat> _texMat;
};
@@ -385,9 +400,9 @@ private:
bool _has_max;
double _max;
double _position;
sgMat4 _matrix;
sgVec3 _axis;
osg::Vec3 _axis;
SGCondition * _condition;
osg::ref_ptr<osg::TexMat> _texMat;
};
@@ -419,13 +434,13 @@ private:
bool has_max;
double max;
double position;
sgMat4 matrix;
sgVec3 center;
sgVec3 axis;
osg::Vec3 center;
osg::Vec3 axis;
};
SGPropertyNode_ptr _prop;
TexTransform* _transform;
int _num_transforms;
osg::ref_ptr<osg::TexMat> _texMat;
};
@@ -439,7 +454,6 @@ public:
virtual ~SGAlphaTestAnimation ();
virtual void init();
private:
void setAlphaClampToBranch(ssgBranch *b, float clamp);
float _alpha_clamp;
};
@@ -475,7 +489,7 @@ private:
SGPropertyNode_ptr blue_prop;
SGPropertyNode_ptr factor_prop;
SGPropertyNode_ptr offset_prop;
sgVec4 v;
osg::Vec4 v;
inline bool dirty() {
return red >= 0.0 || green >= 0.0 || blue >= 0.0;
}
@@ -487,7 +501,7 @@ private:
return red != a.red || green != a.green || blue != a.blue
|| factor != a.factor || offset != a.offset;
}
sgVec4 &rgba() {
osg::Vec4 &rgba() {
v[0] = clamp(red * factor + offset);
v[1] = clamp(green * factor + offset);
v[2] = clamp(blue * factor + offset);
@@ -520,8 +534,6 @@ private:
SGPath _texture_base;
SGPath _texture;
string _texture_str;
ssgSimpleState* _cached_material;
ssgSimpleState* _cloned_material;
unsigned _read;
unsigned _update;
unsigned _static_update;
@@ -538,9 +550,12 @@ private:
SGPropertyNode_ptr _shi_prop;
SGPropertyNode_ptr _thresh_prop;
SGPropertyNode_ptr _tex_prop;
std::vector<osg::Material*> _materialList;
osg::ref_ptr<osg::AlphaFunc> _alphaFunc;
osg::ref_ptr<osg::Texture2D> _texture2D;
void cloneMaterials(ssgBranch *b);
void setMaterialBranch(ssgBranch *b);
void cloneMaterials(osg::Group *b);
void setMaterialBranch(osg::Group *b);
void initColorGroup(SGPropertyNode_ptr, ColorSpec *, int flag);
void updateColorGroup(ColorSpec *, int flag);
inline float clamp(float val, float min = 0.0, float max = 1.0) {
@@ -561,14 +576,6 @@ class SGFlashAnimation : public SGAnimation
public:
SGFlashAnimation(SGPropertyNode_ptr props);
virtual ~SGFlashAnimation ();
static void flashCallback( sgMat4 r, sgFrustum *f, sgMat4 m, void *d );
void flashCallback( sgMat4 r, sgFrustum *f, sgMat4 m );
private:
sgVec3 _axis, _center;
float _power, _factor, _offset, _min_v, _max_v;
bool _two_sides;
};
@@ -581,15 +588,6 @@ class SGDistScaleAnimation : public SGAnimation
public:
SGDistScaleAnimation(SGPropertyNode_ptr props);
virtual ~SGDistScaleAnimation ();
static void distScaleCallback( sgMat4 r, sgFrustum *f, sgMat4 m, void *d );
void distScaleCallback( sgMat4 r, sgFrustum *f, sgMat4 m );
private:
sgVec3 _center;
float _factor, _offset, _min_v, _max_v;
bool _has_min, _has_max;
SGInterpTable * _table;
};
/**
@@ -618,24 +616,25 @@ public:
SGPropertyNode_ptr props );
virtual ~SGShaderAnimation ();
virtual void init();
virtual int update();
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
bool get_condition_value(void);
private:
SGCondition * _condition;
bool _condition_value;
int _shader_type;
float _param_1;
sgVec4 _param_color;
osg::Vec4 _param_color;
public:
bool _depth_test;
float _factor;
SGPropertyNode_ptr _factor_prop;
float _speed;
float totalTime;
SGPropertyNode_ptr _speed_prop;
ssgTexture *_effectTexture;
osg::ref_ptr<osg::Texture2D> _effectTexture;
unsigned char *_textureData;
GLint _texWidth, _texHeight;
sgVec4 _envColor;
osg::Vec4 _envColor;
};

View File

@@ -5,8 +5,6 @@
#ifndef _SG_CUSTOM_TRANSFORM_HXX
#define _SG_CUSTOM_TRANSFORM_HXX 1
#include "plib/ssg.h"
class SGCustomTransform : public ssgBranch
{
public:

View File

@@ -9,12 +9,22 @@
#include <string.h> // for strcmp()
#include <vector>
#include <set>
#include <osg/observer_ptr>
#include <osg/ref_ptr>
#include <osg/Group>
#include <osg/NodeCallback>
#include <osg/Switch>
#include <osg/MatrixTransform>
#include <osgDB/Archive>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/ReadFile>
#include <osgDB/Registry>
#include <osgDB/SharedStateManager>
#include <osgUtil/Optimizer>
#include <plib/sg.h>
#include <plib/ssg.h>
#include <plib/ul.h>
#include <simgear/scene/util/SGStateAttributeVisitor.hxx>
#include <simgear/scene/util/SGTextureStateAttributeVisitor.hxx>
#include <simgear/structure/exception.hxx>
#include <simgear/props/props.hxx>
@@ -27,121 +37,362 @@
SG_USING_STD(vector);
SG_USING_STD(set);
bool sgUseDisplayList = true;
////////////////////////////////////////////////////////////////////////
// Global state
////////////////////////////////////////////////////////////////////////
static bool
model_filter = true;
////////////////////////////////////////////////////////////////////////
// Static utility functions.
////////////////////////////////////////////////////////////////////////
static int
model_filter_callback (ssgEntity * entity, int mask)
static inline
int nMipMaps(int s)
{
return model_filter ? 1 : 0;
s = s >> 2;
int n = 0;
do {
++n;
s = s >> 1;
} while(s);
return n;
}
/**
* Callback to update an animation.
*/
static int
animation_callback (ssgEntity * entity, int mask)
{
return ((SGAnimation *)entity->getUserData())->update();
}
/**
* Callback to restore the state after an animation.
*/
static int
restore_callback (ssgEntity * entity, int mask)
{
((SGAnimation *)entity->getUserData())->restore();
return 1;
}
/**
* Callback and userData class for conditional rendering.
*/
class SGConditionalRender : public ssgBase {
// Little helper class that holds an extra reference to a
// loaded 3d model.
// Since we clone all structural nodes from our 3d models,
// the database pager will only see one single reference to
// top node of the model and expire it relatively fast.
// We attach that extra reference to every model cloned from
// a base model in the pager. When that cloned model is deleted
// this extra reference is deleted too. So if there are no
// cloned models left the model will expire.
class SGDatabaseReference : public osg::Observer {
public:
SGConditionalRender(SGCondition *c) : _condition(c) {}
bool test() { return _condition->test(); }
SGDatabaseReference(osg::Referenced* referenced) :
mReferenced(referenced)
{ }
virtual void objectDeleted(void*)
{
mReferenced = 0;
}
private:
SGCondition *_condition;
osg::ref_ptr<osg::Referenced> mReferenced;
};
static int
model_condition_callback (ssgEntity * entity, int mask)
class SGTexCompressionVisitor : public SGTextureStateAttributeVisitor {
public:
SGTexCompressionVisitor(osg::Texture::InternalFormatMode formatMode) :
mFormatMode(formatMode)
{ }
virtual void apply(int, osg::StateSet::RefAttributePair& refAttr)
{
osg::Texture2D* texture = dynamic_cast<osg::Texture2D*>(refAttr.first.get());
if (!texture)
return;
osg::Image* image = texture->getImage(0);
if (!image)
return;
int s = image->s();
int t = image->t();
int mipmaplevels = 0;
if (s < t) {
mipmaplevels = nMipMaps(s);
} else {
mipmaplevels = nMipMaps(t);
}
texture->setNumMipmapLevels(mipmaplevels);
if (s <= t && 32 <= s) {
texture->setInternalFormatMode(mFormatMode);
} else if (t < s && 32 <= t) {
texture->setInternalFormatMode(mFormatMode);
}
}
private:
osg::Texture::InternalFormatMode mFormatMode;
};
class SGAcMaterialCrippleVisitor : public SGStateAttributeVisitor {
public:
virtual void apply(osg::StateSet::RefAttributePair& refAttr)
{
osg::Material* material = dynamic_cast<osg::Material*>(refAttr.first.get());
if (!material)
return;
material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
}
};
class SGReadFileCallback :
public osgDB::Registry::ReadFileCallback {
public:
virtual osgDB::ReaderWriter::ReadResult
readImage(const std::string& fileName, const osgDB::ReaderWriter::Options* opt)
{
std::string absFileName = osgDB::findDataFile(fileName);
if (!osgDB::fileExists(absFileName)) {
SG_LOG(SG_IO, SG_ALERT, "Cannot find image file \""
<< fileName << "\"");
return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND;
}
osgDB::Registry* registry = osgDB::Registry::instance();
osgDB::ReaderWriter::ReadResult res = registry->readImageImplementation(absFileName, opt);
if (res.loadedFromCache())
SG_LOG(SG_IO, SG_INFO, "Returning cached image \""
<< res.getImage()->getFileName() << "\"");
else
SG_LOG(SG_IO, SG_INFO, "Reading image \""
<< res.getImage()->getFileName() << "\"");
return res;
}
virtual osgDB::ReaderWriter::ReadResult
readNode(const std::string& fileName, const osgDB::ReaderWriter::Options* opt)
{
std::string absFileName = osgDB::findDataFile(fileName);
if (!osgDB::fileExists(absFileName)) {
SG_LOG(SG_IO, SG_ALERT, "Cannot find model file \""
<< fileName << "\"");
return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND;
}
osgDB::Registry* registry = osgDB::Registry::instance();
osgDB::ReaderWriter::ReadResult res;
res = registry->readNodeImplementation(absFileName, opt);
if (!res.validNode())
return res;
if (res.loadedFromCache()) {
SG_LOG(SG_IO, SG_INFO, "Returning cached model \""
<< absFileName << "\"");
} else {
SG_LOG(SG_IO, SG_INFO, "Reading model \""
<< absFileName << "\"");
if (osgDB::getLowerCaseFileExtension(absFileName) == "ac") {
osg::Matrix m(1, 0, 0, 0,
0, 0, 1, 0,
0, -1, 0, 0,
0, 0, 0, 1);
osg::ref_ptr<osg::Group> root = new osg::Group;
osg::MatrixTransform* transform = new osg::MatrixTransform;
root->addChild(transform);
transform->setDataVariance(osg::Object::STATIC);
transform->setMatrix(m);
transform->addChild(res.getNode());
res = osgDB::ReaderWriter::ReadResult(0);
osgUtil::Optimizer optimizer;
unsigned opts = osgUtil::Optimizer::FLATTEN_STATIC_TRANSFORMS;
optimizer.optimize(root.get(), opts);
// Ok, this step is questionable.
// It is there to have the same visual appearance of ac objects for the
// first cut. Osg's ac3d loader will correctly set materials from the
// ac file. But the old plib loader used GL_AMBIENT_AND_DIFFUSE for the
// materials that in effect igored the ambient part specified in the
// file. We emulate that for the first cut here by changing all ac models
// here. But in the long term we should use the unchanged model and fix
// the input files instead ...
SGAcMaterialCrippleVisitor matCriple;
root->accept(matCriple);
res = osgDB::ReaderWriter::ReadResult(root.get());
}
osgUtil::Optimizer optimizer;
unsigned opts = 0;
// Don't use this one. It will break animation names ...
// opts |= osgUtil::Optimizer::REMOVE_REDUNDANT_NODES;
// opts |= osgUtil::Optimizer::REMOVE_LOADED_PROXY_NODES;
// opts |= osgUtil::Optimizer::COMBINE_ADJACENT_LODS;
// opts |= osgUtil::Optimizer::SHARE_DUPLICATE_STATE;
opts |= osgUtil::Optimizer::MERGE_GEOMETRY;
// opts |= osgUtil::Optimizer::CHECK_GEOMETRY;
// opts |= osgUtil::Optimizer::SPATIALIZE_GROUPS;
// opts |= osgUtil::Optimizer::COPY_SHARED_NODES;
opts |= osgUtil::Optimizer::TRISTRIP_GEOMETRY;
// opts |= osgUtil::Optimizer::TESSELATE_GEOMETRY;
// opts |= osgUtil::Optimizer::OPTIMIZE_TEXTURE_SETTINGS;
optimizer.optimize(res.getNode(), opts);
// OSGFIXME
registry->getSharedStateManager()->share(res.getNode());
// OSGFIXME: guard that with a flag
// OSGFIXME: in the long term it is unclear if we have an OpenGL context here...
osg::Texture::Extensions* e = osg::Texture::getExtensions(0, true);
if (e->isTextureCompressionARBSupported()) {
SGTexCompressionVisitor texComp(osg::Texture::USE_ARB_COMPRESSION);
res.getNode()->accept(texComp);
} else if (e->isTextureCompressionS3TCSupported()) {
SGTexCompressionVisitor texComp(osg::Texture::USE_S3TC_DXT5_COMPRESSION);
res.getNode()->accept(texComp);
}
}
// Add an extra reference to the model stored in the database.
// That it to avoid expiring the object from the cache even if it is still
// in use. Note that the object cache will think that a model is unused if the
// reference count is 1. If we clone all structural nodes here we need that extra
// reference to the original object
SGDatabaseReference* databaseReference = new SGDatabaseReference(res.getNode());
osg::CopyOp::CopyFlags flags = osg::CopyOp::DEEP_COPY_ALL;
flags &= ~osg::CopyOp::DEEP_COPY_TEXTURES;
flags &= ~osg::CopyOp::DEEP_COPY_IMAGES;
flags &= ~osg::CopyOp::DEEP_COPY_ARRAYS;
flags &= ~osg::CopyOp::DEEP_COPY_PRIMITIVES;
// This will safe display lists ...
flags &= ~osg::CopyOp::DEEP_COPY_DRAWABLES;
flags &= ~osg::CopyOp::DEEP_COPY_SHAPES;
res = osgDB::ReaderWriter::ReadResult(osg::CopyOp(flags)(res.getNode()));
res.getNode()->addObserver(databaseReference);
return res;
}
};
class SGReadCallbackInstaller {
public:
SGReadCallbackInstaller()
{
osg::Referenced::setThreadSafeReferenceCounting(true);
osgDB::Registry* registry = osgDB::Registry::instance();
osgDB::ReaderWriter::Options* options = new osgDB::ReaderWriter::Options;
options->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_ALL);
registry->setOptions(options);
registry->getOrCreateSharedStateManager()->setShareMode(osgDB::SharedStateManager::SHARE_TEXTURES);
registry->setReadFileCallback(new SGReadFileCallback);
}
};
static SGReadCallbackInstaller readCallbackInstaller;
osg::Texture2D*
SGLoadTexture2D(const std::string& path, bool wrapu, bool wrapv,
int mipmaplevels)
{
return ((SGConditionalRender *)entity->getUserData())->test();
osg::Image* image = osgDB::readImageFile(path);
osg::Texture2D* texture = new osg::Texture2D;
texture->setImage(image);
if (wrapu)
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
else
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP);
if (wrapv)
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
else
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP);
if (image) {
int s = image->s();
int t = image->t();
if (mipmaplevels < 0) {
if (s < t) {
mipmaplevels = nMipMaps(s);
} else {
mipmaplevels = nMipMaps(t);
}
}
texture->setNumMipmapLevels(mipmaplevels);
// OSGFIXME: guard with a flag
if (osg::Texture::getExtensions(0, true)->isTextureCompressionARBSupported()) {
if (s <= t && 32 <= s) {
texture->setInternalFormatMode(osg::Texture::USE_ARB_COMPRESSION);
} else if (t < s && 32 <= t) {
texture->setInternalFormatMode(osg::Texture::USE_ARB_COMPRESSION);
}
} else if (osg::Texture::getExtensions(0, true)->isTextureCompressionS3TCSupported()) {
if (s <= t && 32 <= s) {
texture->setInternalFormatMode(osg::Texture::USE_S3TC_DXT5_COMPRESSION);
} else if (t < s && 32 <= t) {
texture->setInternalFormatMode(osg::Texture::USE_S3TC_DXT5_COMPRESSION);
}
}
}
return texture;
}
class SGSwitchUpdateCallback : public osg::NodeCallback {
public:
SGSwitchUpdateCallback(SGCondition* condition) :
mCondition(condition) {}
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{
assert(dynamic_cast<osg::Switch*>(node));
osg::Switch* s = static_cast<osg::Switch*>(node);
if (mCondition && mCondition->test()) {
s->setAllChildrenOn();
// note, callback is responsible for scenegraph traversal so
// should always include call traverse(node,nv) to ensure
// that the rest of cullbacks and the scene graph are traversed.
traverse(node, nv);
} else
s->setAllChildrenOff();
}
private:
SGCondition* mCondition;
};
/**
* Locate a named SSG node in a branch.
* Locate a named node in a branch.
*/
static ssgEntity *
find_named_node (ssgEntity * node, const char * name)
{
char * node_name = node->getName();
if (node_name != 0 && !strcmp(name, node_name))
return node;
else if (node->isAKindOf(ssgTypeBranch())) {
int nKids = node->getNumKids();
for (int i = 0; i < nKids; i++) {
ssgEntity * result =
find_named_node(((ssgBranch*)node)->getKid(i), name);
if (result != 0)
return result;
class NodeFinder : public osg::NodeVisitor {
public:
NodeFinder(const std::string& nameToFind) :
osg::NodeVisitor(osg::NodeVisitor::NODE_VISITOR,
osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
mName(nameToFind),
mNode(0)
{ }
virtual void apply(osg::Node& node)
{
if (mNode)
return;
if (mName == node.getName()) {
mNode = &node;
return;
}
}
return 0;
}
traverse(node);
}
osg::Node* getNode() const
{ return mNode; }
private:
std::string mName;
osg::Node* mNode;
};
/**
* Splice a branch in between all child nodes and their parents.
*/
static void
splice_branch (ssgBranch * branch, ssgEntity * child)
splice_branch(osg::Group* group, osg::Node* child)
{
int nParents = child->getNumParents();
branch->addKid(child);
for (int i = 0; i < nParents; i++) {
ssgBranch * parent = child->getParent(i);
parent->replaceKid(child, branch);
}
osg::Node::ParentList parents = child->getParents();
group->addChild(child);
osg::Node::ParentList::iterator i;
for (i = parents.begin(); i != parents.end(); ++i)
(*i)->replaceChild(child, group);
}
/**
* Make an offset matrix from rotations and position offset.
*/
void
sgMakeOffsetsMatrix( sgMat4 * result, double h_rot, double p_rot, double r_rot,
double x_off, double y_off, double z_off )
{
sgMat4 rot_matrix;
sgMat4 pos_matrix;
sgMakeRotMat4(rot_matrix, h_rot, p_rot, r_rot);
sgMakeTransMat4(pos_matrix, x_off, y_off, z_off);
sgMultMat4(*result, pos_matrix, rot_matrix);
}
void
sgMakeAnimation( ssgBranch * model,
sgMakeAnimation( osg::Node * model,
const char * name,
vector<SGPropertyNode_ptr> &name_nodes,
SGPropertyNode *prop_root,
SGPropertyNode_ptr node,
double sim_time_sec,
SGPath &texture_path,
set<ssgBranch *> &ignore_branches )
set<osg::Node*> &ignore_branches )
{
bool ignore = false;
SGAnimation * animation = 0;
@@ -191,14 +442,16 @@ sgMakeAnimation( ssgBranch * model,
}
if (name != 0)
animation->setName((char *)name);
animation->setName(name);
ssgEntity * object;
if (name_nodes.size() > 0) {
object = find_named_node(model, name_nodes[0]->getStringValue());
osg::Node * object = 0;
if (!name_nodes.empty()) {
const char * name = name_nodes[0]->getStringValue();
NodeFinder nodeFinder(name);
model->accept(nodeFinder);
object = nodeFinder.getNode();
if (object == 0) {
SG_LOG(SG_INPUT, SG_ALERT, "Object " << name_nodes[0]->getStringValue()
<< " not found");
SG_LOG(SG_INPUT, SG_ALERT, "Object " << name << " not found");
delete animation;
animation = 0;
}
@@ -208,70 +461,48 @@ sgMakeAnimation( ssgBranch * model,
if ( animation == 0 )
return;
ssgBranch * branch = animation->getBranch();
osg::Group* branch = animation->getBranch();
splice_branch(branch, object);
for (unsigned int i = 1; i < name_nodes.size(); i++) {
const char * name = name_nodes[i]->getStringValue();
object = find_named_node(model, name);
NodeFinder nodeFinder(name);
model->accept(nodeFinder);
object = nodeFinder.getNode();
if (object == 0) {
SG_LOG(SG_INPUT, SG_ALERT, "Object " << name << " not found");
delete animation;
animation = 0;
} else {
ssgBranch * oldParent = object->getParent(0);
branch->addKid(object);
oldParent->removeKid(object);
osg::Group* oldParent = object->getParent(0);
branch->addChild(object);
oldParent->removeChild(object);
}
}
if ( animation != 0 ) {
animation->init();
branch->setUserData(animation);
branch->setTravCallback(SSG_CALLBACK_PRETRAV, animation_callback);
branch->setTravCallback(SSG_CALLBACK_POSTTRAV, restore_callback);
branch->setUpdateCallback(animation);
if ( ignore ) {
ignore_branches.insert( branch );
}
}
}
static void makeDList( ssgBranch *b, const set<ssgBranch *> &ignore )
{
int nb = b->getNumKids();
for (int i = 0; i<nb; i++) {
ssgEntity *e = b->getKid(i);
if (e->isAKindOf(ssgTypeLeaf())) {
if( ((ssgLeaf*)e)->getNumVertices() > 0)
((ssgLeaf*)e)->makeDList();
} else if (e->isAKindOf(ssgTypeBranch()) && ignore.find((ssgBranch *)e) == ignore.end()) {
makeDList( (ssgBranch*)e, ignore );
}
}
}
class SGLoaderOptions : public ssgLoaderOptions {
public:
SGLoaderOptions() { ssgSetCurrentOptions( this ); } // Install our own loader options at startup
void endLoad() {} // Avoid clearing the texture cache after every model load
};
static SGLoaderOptions loaderOptions;
////////////////////////////////////////////////////////////////////////
// Global functions.
////////////////////////////////////////////////////////////////////////
ssgBranch *
osg::Node *
sgLoad3DModel( const string &fg_root, const string &path,
SGPropertyNode *prop_root,
double sim_time_sec, ssgEntity *(*load_panel)(SGPropertyNode *),
SGModelData *data )
double sim_time_sec, osg::Node *(*load_panel)(SGPropertyNode *),
SGModelData *data,
const SGPath& externalTexturePath )
{
ssgBranch * model = 0;
osg::Switch* model = 0;
SGPropertyNode props;
// Load the 3D aircraft object itself
@@ -294,36 +525,48 @@ sgLoad3DModel( const string &fg_root, const string &path,
}
} else {
if (model == 0)
model = new ssgBranch;
model = new osg::Switch;
}
}
osgDB::FilePathList pathList = osgDB::getDataFilePathList();
osgDB::Registry::instance()->initFilePathLists();
// Assume that textures are in
// the same location as the XML file.
if (model == 0) {
if (texturepath.extension() != "")
texturepath = texturepath.dir();
ssgTexturePath((char *)texturepath.c_str());
model = (ssgBranch *)ssgLoad((char *)modelpath.c_str());
if (model == 0)
osgDB::Registry::instance()->getDataFilePathList().push_front(texturepath.str());
osg::Node* node = osgDB::readNodeFile(modelpath.str());
if (node == 0)
throw sg_io_exception("Failed to load 3D model",
sg_location(modelpath.str()));
sg_location(modelpath.str()));
model = new osg::Switch;
model->addChild(node, true);
}
osgDB::Registry::instance()->getDataFilePathList().push_front(externalTexturePath.str());
// Set up the alignment node
ssgTransform * alignmainmodel = new ssgTransform;
if ( load_panel == 0 )
alignmainmodel->setTravCallback( SSG_CALLBACK_PRETRAV, model_filter_callback );
alignmainmodel->addKid(model);
sgMat4 res_matrix;
sgMakeOffsetsMatrix(&res_matrix,
props.getFloatValue("/offsets/heading-deg", 0.0),
props.getFloatValue("/offsets/roll-deg", 0.0),
props.getFloatValue("/offsets/pitch-deg", 0.0),
props.getFloatValue("/offsets/x-m", 0.0),
props.getFloatValue("/offsets/y-m", 0.0),
props.getFloatValue("/offsets/z-m", 0.0));
alignmainmodel->setTransform(res_matrix);
osg::MatrixTransform* alignmainmodel = new osg::MatrixTransform;
alignmainmodel->addChild(model);
osg::Matrix res_matrix;
res_matrix.makeRotate(
props.getFloatValue("/offsets/heading-deg", 0.0)*SG_DEGREES_TO_RADIANS,
osg::Vec3(0, 0, 1),
props.getFloatValue("/offsets/roll-deg", 0.0)*SG_DEGREES_TO_RADIANS,
osg::Vec3(1, 0, 0),
props.getFloatValue("/offsets/pitch-deg", 0.0)*SG_DEGREES_TO_RADIANS,
osg::Vec3(0, 1, 0));
osg::Matrix tmat;
tmat.makeTranslate(props.getFloatValue("/offsets/x-m", 0.0),
props.getFloatValue("/offsets/y-m", 0.0),
props.getFloatValue("/offsets/z-m", 0.0));
alignmainmodel->setMatrix(res_matrix*tmat);
unsigned int i;
@@ -331,18 +574,23 @@ sgLoad3DModel( const string &fg_root, const string &path,
vector<SGPropertyNode_ptr> model_nodes = props.getChildren("model");
for (i = 0; i < model_nodes.size(); i++) {
SGPropertyNode_ptr node = model_nodes[i];
ssgTransform * align = new ssgTransform;
sgMat4 res_matrix;
sgMakeOffsetsMatrix(&res_matrix,
node->getFloatValue("offsets/heading-deg", 0.0),
node->getFloatValue("offsets/roll-deg", 0.0),
node->getFloatValue("offsets/pitch-deg", 0.0),
node->getFloatValue("offsets/x-m", 0.0),
node->getFloatValue("offsets/y-m", 0.0),
node->getFloatValue("offsets/z-m", 0.0));
align->setTransform(res_matrix);
osg::MatrixTransform* align = new osg::MatrixTransform;
res_matrix.makeIdentity();
res_matrix.makeRotate(
node->getFloatValue("offsets/heading-deg", 0.0)*SG_DEGREES_TO_RADIANS,
osg::Vec3(0, 0, 1),
node->getFloatValue("offsets/roll-deg", 0.0)*SG_DEGREES_TO_RADIANS,
osg::Vec3(1, 0, 0),
node->getFloatValue("offsets/pitch-deg", 0.0)*SG_DEGREES_TO_RADIANS,
osg::Vec3(0, 1, 0));
tmat.makeIdentity();
tmat.makeTranslate(node->getFloatValue("offsets/x-m", 0.0),
node->getFloatValue("offsets/y-m", 0.0),
node->getFloatValue("offsets/z-m", 0.0));
align->setMatrix(res_matrix*tmat);
ssgBranch * kid;
osg::Node* kid;
const char * submodel = node->getStringValue("path");
try {
kid = sgLoad3DModel( fg_root, submodel, prop_root, sim_time_sec, load_panel );
@@ -351,27 +599,28 @@ sgLoad3DModel( const string &fg_root, const string &path,
SG_LOG(SG_INPUT, SG_ALERT, "Failed to load submodel: " << t.getFormattedMessage());
throw;
}
align->addChild(kid);
align->setName(node->getStringValue("name", ""));
model->addChild(align);
SGPropertyNode *cond = node->getNode("condition", false);
if (cond) {
align->setUserData(new SGConditionalRender(sgReadCondition(prop_root, cond)));
align->setTravCallback(SSG_CALLBACK_PRETRAV, model_condition_callback);
}
align->addKid(kid);
align->setName(node->getStringValue("name", ""));
model->addKid(align);
if (cond)
model->setUpdateCallback(new SGSwitchUpdateCallback(sgReadCondition(prop_root, cond)));
}
// restore old path list
osgDB::setDataFilePathList(pathList);
if ( load_panel ) {
// Load panels
vector<SGPropertyNode_ptr> panel_nodes = props.getChildren("panel");
for (i = 0; i < panel_nodes.size(); i++) {
SG_LOG(SG_INPUT, SG_DEBUG, "Loading a panel");
ssgEntity * panel = load_panel(panel_nodes[i]);
osg::Node * panel = load_panel(panel_nodes[i]);
if (panel_nodes[i]->hasValue("name"))
panel->setName((char *)panel_nodes[i]->getStringValue("name"));
model->addKid(panel);
model->addChild(panel);
}
}
@@ -380,7 +629,7 @@ sgLoad3DModel( const string &fg_root, const string &path,
data->modelLoaded(path, &props, alignmainmodel);
}
// Load animations
set<ssgBranch *> ignore_branches;
set<osg::Node*> ignore_branches;
vector<SGPropertyNode_ptr> animation_nodes = props.getChildren("animation");
for (i = 0; i < animation_nodes.size(); i++) {
const char * name = animation_nodes[i]->getStringValue("name", 0);
@@ -390,31 +639,7 @@ sgLoad3DModel( const string &fg_root, const string &path,
sim_time_sec, texturepath, ignore_branches);
}
#if PLIB_VERSION > 183
if ( model != 0 && sgUseDisplayList ) {
makeDList( model, ignore_branches );
}
#endif
int m = props.getIntValue("dump", 0);
if (m > 0)
model->print(stderr, "", m - 1);
return alignmainmodel;
}
bool
sgSetModelFilter( bool filter )
{
bool old = model_filter;
model_filter = filter;
return old;
}
bool
sgCheckAnimationBranch (ssgEntity * entity)
{
return entity->getTravCallback(SSG_CALLBACK_PRETRAV) == animation_callback;
}
// end of model.cxx

View File

@@ -18,8 +18,8 @@
SG_USING_STD(vector);
SG_USING_STD(set);
#include <plib/sg.h>
#include <plib/ssg.h>
#include <osg/Node>
#include <osg/Texture2D>
#include <simgear/misc/sg_path.hxx>
#include <simgear/props/props.hxx>
@@ -39,11 +39,11 @@ SG_USING_STD(set);
* called by sgLoad3DModel() after the model was loaded, and the destructor
* when the branch is removed from the graph.
*/
class SGModelData : public ssgBase {
class SGModelData : public osg::Referenced {
public:
virtual ~SGModelData() {}
virtual void modelLoaded( const string& path, SGPropertyNode *prop,
ssgBranch *branch) {}
osg::Node*branch) = 0;
};
@@ -59,48 +59,37 @@ public:
* Subsystems should not normally invoke this function directly;
* instead, they should use the FGModelLoader declared in loader.hxx.
*/
ssgBranch *
osg::Node*
sgLoad3DModel( const string& fg_root, const string &path,
SGPropertyNode *prop_root, double sim_time_sec,
ssgEntity *(*load_panel)(SGPropertyNode *) = 0,
SGModelData *data = 0 );
SGPropertyNode *prop_root, double sim_time_sec,
osg::Node *(*load_panel)(SGPropertyNode *) = 0,
SGModelData *data = 0,
const SGPath& texturePath = SGPath() );
/**
* Make an offset matrix from rotations and position offset.
*/
void
sgMakeOffsetsMatrix( sgMat4 * result, double h_rot, double p_rot, double r_rot,
double x_off, double y_off, double z_off );
/**
* Make the animation
*/
void
sgMakeAnimation( ssgBranch * model,
sgMakeAnimation( osg::Node* model,
const char * name,
vector<SGPropertyNode_ptr> &name_nodes,
SGPropertyNode *prop_root,
SGPropertyNode_ptr node,
double sim_time_sec,
SGPath &texture_path,
set<ssgBranch *> &ignore_branches );
set<osg::Node*> &ignore_branches );
/**
* Set the filter state on models
*/
bool
sgSetModelFilter( bool filter );
/**
* Check if the ssg node contains an animation
*/
bool
sgCheckAnimationBranch (ssgEntity * entity);
osg::Texture2D*
SGLoadTexture2D(const std::string& path, bool wrapu = true,
bool wrapv = true, int mipmaplevels = -1);
/**
* Enable or disable Display list usage
*/
extern bool sgUseDisplayList;
inline osg::Texture2D*
SGLoadTexture2D(const SGPath& path, bool wrapu = true, bool wrapv = true,
int mipmaplevels = -1)
{
return SGLoadTexture2D(path.str(), wrapu, wrapv, mipmaplevels);
}
#endif // __MODEL_HXX

View File

@@ -6,6 +6,7 @@
#include <simgear/compiler.h>
#include <simgear/props/props.hxx>
#include <simgear/scene/util/SGNodeMasks.hxx>
#include "model.hxx"
#include "animation.hxx"
@@ -48,11 +49,11 @@ SGModelLib::flush1()
return;
map<string, ssgSharedPtr<ssgEntity> >::iterator it = _table.begin();
map<string, osg::ref_ptr<osg::Node> >::iterator it = _table.begin();
while (it != _table.end()) {
// If there is only one reference, it's
// ours; no one else is using the item.
if (!it->second.isShared()) {
if (it->second->referenceCount() <= 1) {
string key = it->first;
_table.erase(it);
it = _table.upper_bound(key);
@@ -61,7 +62,7 @@ SGModelLib::flush1()
}
}
ssgEntity *
osg::Node*
SGModelLib::load_model( const string &fg_root,
const string &path,
SGPropertyNode *prop_root,
@@ -69,21 +70,24 @@ SGModelLib::load_model( const string &fg_root,
bool cache_object,
SGModelData *data )
{
ssgBranch *personality_branch = new SGPersonalityBranch;
osg::Group *personality_branch = new SGPersonalityBranch;
personality_branch->setName("Model Personality Group");
// FIXME: normalize path to
// avoid duplicates.
map<string, ssgSharedPtr<ssgEntity> >::iterator it = _table.find(path);
map<string, osg::ref_ptr<osg::Node> >::iterator it = _table.find(path);
if (!cache_object || it == _table.end()) {
ssgSharedPtr<ssgEntity> model = sgLoad3DModel(fg_root, path, prop_root,
osg::ref_ptr<osg::Node> model = sgLoad3DModel(fg_root, path, prop_root,
sim_time_sec, 0, data );
model->setName("Loaded model node");
if (cache_object)
_table[path] = model; // add one reference to keep it around
personality_branch->addKid( model );
personality_branch->addChild( model.get() );
} else {
personality_branch->addKid( it->second );
personality_branch->addChild( it->second.get() );
}
return personality_branch;
}

View File

@@ -12,9 +12,9 @@
#include <map>
#include STL_STRING
#include <plib/ssg.h>
#include <osg/ref_ptr>
#include <osg/Node>
#include <simgear/structure/ssgSharedPtr.hxx>
#include <simgear/props/props.hxx>
#include "model.hxx"
@@ -34,7 +34,7 @@ public:
virtual ~SGModelLib ();
virtual void flush1();
virtual ssgEntity *load_model( const string &fg_root,
virtual osg::Node *load_model( const string &fg_root,
const string &path,
SGPropertyNode *prop_root,
double sim_time_sec,
@@ -42,7 +42,7 @@ public:
SGModelData *data = 0 );
protected:
map<string,ssgSharedPtr<ssgEntity> > _table;
map<string, osg::ref_ptr<osg::Node> > _table;
};

View File

@@ -9,26 +9,20 @@
#include "personality.hxx"
#include "animation.hxx"
static int
personality_pretrav_callback(ssgEntity * entity, int mask)
class SGPersonalityBranchCallback : public osg::NodeCallback
{
((SGPersonalityBranch *)entity)->_old_current = SGAnimation::current_object;
SGAnimation::current_object = (SGPersonalityBranch *)entity;
return 1;
}
static int
personality_posttrav_callback(ssgEntity * entity, int mask)
{
SGAnimation::current_object = ((SGPersonalityBranch *)entity)->_old_current;
((SGPersonalityBranch *)entity)->_old_current = 0;
return 1;
}
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{
SGPersonalityBranch* old_current = SGAnimation::current_object;
SGAnimation::current_object = static_cast<SGPersonalityBranch*>(node);
traverse(node, nv);
SGAnimation::current_object = old_current;
}
};
SGPersonalityBranch::SGPersonalityBranch()
{
setTravCallback(SSG_CALLBACK_PRETRAV, personality_pretrav_callback);
setTravCallback(SSG_CALLBACK_POSTTRAV, personality_posttrav_callback);
setUpdateCallback(new SGPersonalityBranchCallback);
}
void SGPersonalityBranch::setDoubleValue( double value, SGAnimation *anim, int var_id, int var_num )

View File

@@ -6,7 +6,7 @@
#define _SG_PERSONALITY_HXX 1
#include <simgear/compiler.h>
#include <plib/ssg.h>
#include <osg/Group>
#include <map>
@@ -14,7 +14,8 @@ SG_USING_STD(map);
class SGAnimation;
class SGPersonalityBranch : public ssgBranch {
// OSGFIXME avoid personality with cloning the structural trees.
class SGPersonalityBranch : public osg::Group {
public:
SGPersonalityBranch();
void setDoubleValue( double value, SGAnimation *anim, int var_id, int var_num = 0 );
@@ -22,8 +23,6 @@ public:
double getDoubleValue( SGAnimation *anim, int var_id, int var_num = 0 ) const;
int getIntValue( SGAnimation *anim, int var_id, int var_num = 0 ) const;
SGPersonalityBranch *_old_current;
private:
struct Key {
Key( SGAnimation *a, int i, int n = 0 ) : anim(a), var_id(i), var_num(n) {}

View File

@@ -11,8 +11,6 @@
#include <string.h> // for strcmp()
#include <plib/sg.h>
#include <plib/ssg.h>
#include <plib/ul.h>
#include "location.hxx"
@@ -33,8 +31,8 @@ SGModelPlacement::SGModelPlacement ()
_roll_deg(0),
_pitch_deg(0),
_heading_deg(0),
_selector(new ssgSelector),
_position(new ssgPlacementTransform),
_selector(new osg::Switch),
_position(new SGPlacementTransform),
_location(new SGLocation)
{
}
@@ -45,13 +43,14 @@ SGModelPlacement::~SGModelPlacement ()
}
void
SGModelPlacement::init( ssgBranch * model )
SGModelPlacement::init( osg::Node * model )
{
if (model != 0) {
_position->addKid(model);
_position->addChild(model);
}
_selector->addKid(_position);
_selector->clrTraversalMaskBits(SSGTRAV_HOT);
_selector->addChild(_position.get());
// _selector->setNodeMask(_selector->getNodeMask() & ~SG_HOT_TRAVERSAL_BIT);
_selector->setValue(0, 1);
}
void
@@ -60,21 +59,25 @@ SGModelPlacement::update()
_location->setPosition( _lon_deg, _lat_deg, _elev_ft );
_location->setOrientation( _roll_deg, _pitch_deg, _heading_deg );
sgMat4 rotation;
sgCopyMat4( rotation, _location->getTransformMatrix() );
_position->setTransform(_location->get_absolute_view_pos(), rotation);
const sgVec4 *t = _location->getTransformMatrix();
SGMatrixd rotation;
for (unsigned i = 0; i < 4; ++i)
for (unsigned j = 0; j < 4; ++j)
rotation(i, j) = t[j][i];
SGVec3d pos(_location->get_absolute_view_pos());
_position->setTransform(pos, rotation);
}
bool
SGModelPlacement::getVisible () const
{
return (_selector->getSelect() != 0);
return _selector->getValue(0);
}
void
SGModelPlacement::setVisible (bool visible)
{
_selector->select(visible);
_selector->setValue(0, visible);
}
void

View File

@@ -11,17 +11,16 @@
# error This library requires C++
#endif
#include <plib/sg.h>
#include <plib/ssg.h>
#include <osg/ref_ptr>
#include <osg/Node>
#include <osg/Switch>
#include <simgear/math/point3d.hxx>
#include <simgear/props/props.hxx>
#include <simgear/structure/ssgSharedPtr.hxx>
#include "placementtrans.hxx"
// Don't pull in the headers, since we don't need them here.
class SGLocation;
class ssgPlacementTransform;
// Has anyone done anything *really* stupid, like making min and max macros?
@@ -47,11 +46,11 @@ public:
SGModelPlacement ();
virtual ~SGModelPlacement ();
virtual void init( ssgBranch * model );
virtual void init( osg::Node* model );
virtual void update();
virtual ssgEntity * getSceneGraph () { return (ssgEntity *)_selector; }
virtual osg::Node* getSceneGraph () { return _selector.get(); }
virtual SGLocation * getSGLocation () { return _location; }
@@ -79,8 +78,8 @@ public:
double heading_deg);
void setOrientation(const SGQuatd& orientation);
ssgPlacementTransform * getTransform(void)
{ return _position; }
SGPlacementTransform * getTransform(void)
{ return _position.get(); }
private:
@@ -94,8 +93,8 @@ private:
double _pitch_deg;
double _heading_deg;
ssgSharedPtr<ssgSelector> _selector;
ssgSharedPtr<ssgPlacementTransform> _position;
osg::ref_ptr<osg::Switch> _selector;
osg::ref_ptr<SGPlacementTransform> _position;
// Location
SGLocation * _location;

View File

@@ -27,74 +27,57 @@
#include <simgear/compiler.h>
#include <simgear/constants.h>
#include <plib/sg.h>
#include <plib/ssg.h>
#include "placementtrans.hxx"
ssgPlacementTransform::ssgPlacementTransform(void)
{
sgdSetVec3(_placement_offset, 0, 0, 0);
sgdSetVec3(_scenery_center, 0, 0, 0);
}
ssgPlacementTransform::~ssgPlacementTransform(void)
SGPlacementTransform::SGPlacementTransform(void) :
_placement_offset(0, 0, 0),
_scenery_center(0, 0, 0),
_rotation(1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1)
{
}
ssgBase *ssgPlacementTransform::clone(int clone_flags)
SGPlacementTransform::~SGPlacementTransform(void)
{
ssgPlacementTransform *b = new ssgPlacementTransform;
b->copy_from(this, clone_flags);
return b;
}
void
ssgPlacementTransform::copy_from(ssgPlacementTransform *src, int clone_flags)
bool
SGPlacementTransform::computeLocalToWorldMatrix(osg::Matrix& matrix,
osg::NodeVisitor*) const
{
ssgBaseTransform::copy_from(src, clone_flags);
sgdCopyVec3(_placement_offset, src->_placement_offset);
sgdCopyVec3(_scenery_center, src->_scenery_center);
osg::Matrix t;
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
t(j, i) = _rotation(i, j);
}
t(3, i) = _placement_offset(i) - _scenery_center(i);
}
if (_referenceFrame == RELATIVE_RF)
matrix.preMult(t);
else
matrix = t;
return true;
}
void ssgPlacementTransform::setTransform(sgdVec3 off)
bool
SGPlacementTransform::computeWorldToLocalMatrix(osg::Matrix& matrix,
osg::NodeVisitor*) const
{
sgdCopyVec3(_placement_offset, off);
sgdVec3 tmp;
sgdSubVec3(tmp, _placement_offset, _scenery_center);
sgMat4 tmat;
sgZeroVec4(tmat[0]);
tmat[0][0] = 1;
sgZeroVec4(tmat[1]);
tmat[1][1] = 1;
sgZeroVec4(tmat[2]);
tmat[2][2] = 1;
sgSetVec3(tmat[3], tmp);
tmat[3][3] = 1;
ssgTransform::setTransform(tmat);
}
osg::Matrix t;
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
t(j, i) = _rotation(i, j);
}
t(3, i) = _placement_offset(i) - _scenery_center(i);
}
t = osg::Matrix::inverse(t);
void ssgPlacementTransform::setTransform(sgdVec3 off, sgMat4 rot)
{
sgdCopyVec3(_placement_offset, off);
sgdVec3 tmp;
sgdSubVec3(tmp, _placement_offset, _scenery_center);
sgMat4 tmat;
sgCopyVec4(tmat[0], rot[0]);
sgCopyVec4(tmat[1], rot[1]);
sgCopyVec4(tmat[2], rot[2]);
sgSetVec3(tmat[3], tmp);
tmat[3][3] = 1;
ssgTransform::setTransform(tmat);
}
void ssgPlacementTransform::setSceneryCenter(sgdVec3 xyz)
{
sgdCopyVec3(_scenery_center, xyz);
sgdVec3 tmp;
sgdSubVec3(tmp, _placement_offset, _scenery_center);
sgMat4 tmat;
getTransform(tmat);
sgSetVec3(tmat[3], tmp);
ssgTransform::setTransform(tmat);
if (_referenceFrame == RELATIVE_RF)
matrix.postMult(t);
else
matrix = t;
return true;
}

View File

@@ -29,33 +29,28 @@
#include <simgear/compiler.h>
#include <simgear/constants.h>
#include <simgear/math/SGMath.hxx>
#include <plib/sg.h>
#include <plib/ssg.h>
#include <osg/Transform>
class ssgPlacementTransform : public ssgTransform
class SGPlacementTransform : public osg::Transform
{
public:
ssgPlacementTransform(void);
virtual ~ssgPlacementTransform(void);
SGPlacementTransform(void);
virtual ~SGPlacementTransform(void);
// using ssgTransform::addKid(ssgEntity*);
virtual ssgBase *clone(int clone_flags);
protected:
void copy_from(ssgPlacementTransform *src, int clone_flags);
private:
// virtual void setTransform(sgVec3 xyz);
// virtual void setTransform(sgCoord *xform);
// virtual void setTransform(sgCoord *xform, float sx, float sy, float sz);
// virtual void setTransform(sgMat4 xform);
public:
void setTransform(sgdVec3 off);
void setTransform(sgdVec3 off, sgMat4 rot);
void setSceneryCenter(sgdVec3 xyz);
void setTransform(const SGVec3d& off)
{ _placement_offset = off; dirtyBound(); }
void setTransform(const SGVec3d& off, const SGMatrixd& rot)
{ _placement_offset = off; _rotation = rot; dirtyBound(); }
void setSceneryCenter(const SGVec3d& center)
{ _scenery_center = center; dirtyBound(); }
virtual bool computeLocalToWorldMatrix(osg::Matrix&,osg::NodeVisitor*) const;
virtual bool computeWorldToLocalMatrix(osg::Matrix&,osg::NodeVisitor*) const;
private:
@@ -63,9 +58,9 @@ private:
// private data //
//////////////////////////////////////////////////////////////////
sgdVec3 _placement_offset;
sgdVec3 _scenery_center;
SGVec3d _placement_offset;
SGVec3d _scenery_center;
SGMatrixd _rotation;
};
#endif // _SG_LOCATION_HXX

File diff suppressed because it is too large Load Diff

View File

@@ -24,12 +24,8 @@
#define _SHADOWVOLUME_HXX
#include <simgear/compiler.h>
#include <simgear/structure/ssgSharedPtr.hxx>
#include <simgear/props/props.hxx>
#include <plib/ssg.h>
#include <plib/sg.h>
#include <vector>
#include <map>

File diff suppressed because it is too large Load Diff

View File

@@ -29,22 +29,25 @@
#include <simgear/compiler.h>
#include <simgear/misc/sg_path.hxx>
#include <plib/ssg.h>
#include <simgear/math/SGMath.hxx>
#include <simgear/structure/SGReferenced.hxx>
#include STL_STRING
SG_USING_STD(string);
// #include <iostream>
// SG_USING_STD(cout);
// SG_USING_STD(endl);
#include <osg/ref_ptr>
#include <osg/Array>
#include <osg/Geode>
#include <osg/Group>
#include <osg/MatrixTransform>
#include <osg/Switch>
class SGCloudField;
/**
* A class layer to model a single cloud layer
*/
class SGCloudLayer {
class SGCloudLayer : public SGReferenced {
public:
/**
@@ -163,7 +166,7 @@ public:
* repaint the cloud colors based on the specified fog_color
* @param fog_color the fog color
*/
bool repaint( sgVec3 fog_color );
bool repaint( const SGVec3f& fog_color );
/**
* reposition the cloud layer at the specified origin and
@@ -176,42 +179,30 @@ public:
* (and orients the sunrise/set effects)
* @param dt the time elapsed since the last call
*/
bool reposition( sgVec3 p, sgVec3 up, double lon, double lat, double alt,
bool reposition( const SGVec3f& p, const SGVec3f& up,
double lon, double lat, double alt,
double dt = 0.0 );
/** draw the cloud layer */
void draw( bool top );
osg::Switch* getNode() { return layer_root.get(); }
static bool enable_bump_mapping;
/** return the 3D layer cloud associated with this 2D layer */
SGCloudField *get_layer3D(void) { return layer3D; }
/** return the 3D layer cloud associated with this 2D layer */
SGCloudField *get_layer3D(void) { return layer3D; }
private:
struct CloudVertex {
sgVec3 position;
sgVec2 texCoord;
sgVec3 tangentSpLight;
sgVec3 sTangent;
sgVec3 tTangent;
sgVec3 normal;
sgVec4 color;
};
CloudVertex *vertices;
unsigned int *indices;
ssgRoot *layer_root;
ssgTransform *layer_transform;
ssgLeaf *layer[4];
ssgStateSelector *state_sel;
osg::ref_ptr<osg::Switch> layer_root;
osg::ref_ptr<osg::Group> group_top, group_bottom;
osg::ref_ptr<osg::MatrixTransform> layer_transform;
osg::ref_ptr<osg::Geode> layer[4];
float cloud_alpha; // 1.0 = drawn fully, 0.0 faded out completely
ssgColourArray *cl[4];
ssgVertexArray *vl[4];
ssgTexCoordArray *tl[4];
osg::ref_ptr<osg::Vec4Array> cl[4];
osg::ref_ptr<osg::Vec3Array> vl[4];
osg::ref_ptr<osg::Vec2Array> tl[4];
osg::ref_ptr<osg::Vec3Array> tl2[4];
// height above sea level (meters)
SGPath texture_path;
@@ -230,12 +221,9 @@ private:
// double xoff, yoff;
double last_lon, last_lat, last_course;
SGCloudField *layer3D;
osg::Vec2 base;
SGCloudField *layer3D;
};
// make an ssgSimpleState for a cloud layer given the named texture
ssgSimpleState *sgCloudMakeState( const string &path );
#endif // _SG_CLOUD_HXX_

View File

@@ -78,10 +78,14 @@ static int cacheResolution = 64;
static sgVec3 last_sunlight={0.0f, 0.0f, 0.0f};
int SGCloudField::get_CacheResolution(void) {
#if 0
return cacheResolution;
#endif
return 0;
}
void SGCloudField::set_CacheResolution(int resolutionPixels) {
#if 0
if(cacheResolution == resolutionPixels)
return;
cacheResolution = resolutionPixels;
@@ -91,13 +95,18 @@ void SGCloudField::set_CacheResolution(int resolutionPixels) {
count = 1;
SGNewCloud::cldCache->setCacheSize(count, cacheResolution);
}
#endif
}
int SGCloudField::get_CacheSize(void) {
#if 0
return SGNewCloud::cldCache->queryCacheSize();
#endif
return 0;
}
void SGCloudField::set_CacheSize(int sizeKb) {
#if 0
// apply in rendering option dialog
if(last_cache_size == sizeKb)
return;
@@ -111,15 +120,21 @@ void SGCloudField::set_CacheSize(int sizeKb) {
count = 1;
SGNewCloud::cldCache->setCacheSize(count, cacheResolution);
}
#endif
}
void SGCloudField::set_CloudVis(float distance) {
#if 0
if( distance <= fieldSize )
SGCloudField::CloudVis = distance;
#endif
}
void SGCloudField::set_density(float density) {
#if 0
SGCloudField::density = density;
#endif
}
void SGCloudField::set_enable3dClouds(bool enable) {
#if 0
if(enable3D == enable)
return;
enable3D = enable;
@@ -131,10 +146,12 @@ void SGCloudField::set_enable3dClouds(bool enable) {
} else {
SGNewCloud::cldCache->setCacheSize(0);
}
#endif
}
// reposition the cloud layer at the specified origin and orientation
void SGCloudField::reposition( sgVec3 p, sgVec3 up, double lon, double lat, double alt, double dt, float direction, float speed) {
#if 0
sgMat4 T1, LON, LAT;
sgVec3 axis;
@@ -211,6 +228,7 @@ void SGCloudField::reposition( sgVec3 p, sgVec3 up, double lon, double lat, doub
frustum.setFOV( w, h );
frustum.setNearFar(1.0, CloudVis);
timer_dt = dt;
#endif
}
SGCloudField::SGCloudField() :
@@ -220,22 +238,29 @@ SGCloudField::SGCloudField() :
last_density(0.0),
draw_in_3d(true)
{
#if 0
sgSetVec3( relative_position, 0,0,0);
theField.reserve(200);
inViewClouds.reserve(200);
sg_srandom_time_10();
#else
draw_in_3d = false;
#endif
}
SGCloudField::~SGCloudField() {
#if 0
list_of_Cloud::iterator iCloud;
for( iCloud = theField.begin() ; iCloud != theField.end() ; iCloud++ ) {
delete iCloud->aCloud;
}
theField.clear();
#endif
}
void SGCloudField::clear(void) {
#if 0
list_of_Cloud::iterator iCloud;
for( iCloud = theField.begin() ; iCloud != theField.end() ; iCloud++ ) {
delete iCloud->aCloud;
@@ -245,6 +270,7 @@ void SGCloudField::clear(void) {
last_density = 0.0;
// true to come back in set density after layer is built
draw_in_3d = true;
#endif
}
// use a table or else we see poping when moving the slider...
@@ -264,6 +290,7 @@ static int densTable[][10] = {
// set the visible flag depending on density
void SGCloudField::applyDensity(void) {
#if 0
int row = (int) (density / 10.0);
int col = 0;
sgBox fieldBox;
@@ -286,16 +313,19 @@ void SGCloudField::applyDensity(void) {
center[1] = 0.0f;
field_sphere.setCenter( center );
field_sphere.setRadius( fieldSize * 0.5f * 1.414f );
#endif
}
// add one cloud, data is not copied, ownership given
void SGCloudField::addCloud( sgVec3 pos, SGNewCloud *cloud) {
#if 0
Cloud cl;
cl.aCloud = cloud;
cl.visible = true;
cloud->SetPos( pos );
sgCopyVec3( cl.pos, *cloud->getCenter() );
theField.push_back( cl );
#endif
}
@@ -306,7 +336,7 @@ static float Rnd(float n) {
// for debug only
// build a field of cloud of size 25x25 km, its a grid of 11x11 clouds
void SGCloudField::buildTestLayer(void) {
#if 0
const float s = 2250.0f;
for( int z = -5 ; z <= 5 ; z++) {
@@ -318,10 +348,12 @@ void SGCloudField::buildTestLayer(void) {
}
}
applyDensity();
#endif
}
// cull all clouds of a tiled field
void SGCloudField::cullClouds(sgVec3 eyePos, sgMat4 mat) {
#if 0
list_of_Cloud::iterator iCloud;
sgSphere tile_sphere;
@@ -357,7 +389,7 @@ void SGCloudField::cullClouds(sgVec3 eyePos, sgMat4 mat) {
sgEnviro.set_view_in_cloud(true);
}
}
#endif
}
@@ -366,6 +398,7 @@ void SGCloudField::cullClouds(sgVec3 eyePos, sgMat4 mat) {
// we draw this field and adjacent fields.
// adjacent fields are not real, its the same field displaced by some offset
void SGCloudField::Render(void) {
#if 0
sgVec3 eyePos;
double relx, rely;
@@ -493,6 +526,5 @@ void SGCloudField::Render(void) {
ssgLoadModelviewMatrix( modelview );
glPopMatrix();
#endif
}

View File

@@ -34,10 +34,15 @@
#include <simgear/compiler.h>
#include SG_GL_H
#include <plib/sg.h>
#include <osg/Array>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Node>
#include <osg/MatrixTransform>
#include <osg/Material>
#include <osg/ShadeModel>
#include <simgear/scene/util/SGDebugDrawCallback.hxx>
#include <simgear/debug/logstream.hxx>
#include "dome.hxx"
@@ -64,37 +69,9 @@ static const float bottom_radius = 0.8;
static const float bottom_elev = -0.1;
// Set up dome rendering callbacks
static int sgSkyDomePreDraw( ssgEntity *e ) {
/* cout << endl << "Dome Pre Draw" << endl << "----------------"
<< endl << endl; */
ssgLeaf *f = (ssgLeaf *)e;
if ( f -> hasState () ) f->getState()->apply() ;
glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_FOG_BIT );
// cout << "push error = " << glGetError() << endl;
glDisable( GL_DEPTH_TEST );
glDisable( GL_FOG );
return true;
}
static int sgSkyDomePostDraw( ssgEntity *e ) {
/* cout << endl << "Dome Post Draw" << endl << "----------------"
<< endl << endl; */
glPopAttrib();
// cout << "pop error = " << glGetError() << endl;
return true;
}
// Constructor
SGSkyDome::SGSkyDome( void ) {
asl = 0.0f;
asl = 0;
}
@@ -104,181 +81,176 @@ SGSkyDome::~SGSkyDome( void ) {
// initialize the sky object and connect it into our scene graph
ssgBranch * SGSkyDome::build( double hscale, double vscale ) {
sgVec4 color;
osg::Node*
SGSkyDome::build( double hscale, double vscale ) {
double theta;
int i;
osg::Geode* geode = new osg::Geode;
// set up the state
dome_state = new ssgSimpleState();
dome_state->setShadeModel( GL_SMOOTH );
dome_state->disable( GL_LIGHTING );
dome_state->disable( GL_CULL_FACE );
dome_state->disable( GL_TEXTURE_2D );
dome_state->enable( GL_COLOR_MATERIAL );
dome_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
dome_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
dome_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
dome_state->disable( GL_BLEND );
dome_state->disable( GL_ALPHA_TEST );
osg::StateSet* stateSet = geode->getOrCreateStateSet();
stateSet->setRenderBinDetails(-10, "RenderBin");
osg::ShadeModel* shadeModel = new osg::ShadeModel;
shadeModel->setMode(osg::ShadeModel::SMOOTH);
stateSet->setAttributeAndModes(shadeModel);
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
stateSet->setMode(GL_BLEND, osg::StateAttribute::OFF);
stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::OFF);
osg::Material* material = new osg::Material;
// material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
// material->setEmission(osg::Material::FRONT_AND_BACK,
// osg::Vec4(0, 0, 0, 1));
// material->setSpecular(osg::Material::FRONT_AND_BACK,
// osg::Vec4(0, 0, 0, 1));
// material->setShininess(osg::Material::FRONT_AND_BACK, 0);
stateSet->setAttribute(material);
// stateSet->setMode(GL_COLOR_MATERIAL, osg::StateAttribute::OFF);
// initialize arrays
center_disk_vl = new ssgVertexArray( 14 );
center_disk_cl = new ssgColourArray( 14 );
upper_ring_vl = new ssgVertexArray( 26 );
upper_ring_cl = new ssgColourArray( 26 );
middle_ring_vl = new ssgVertexArray( 26 );
middle_ring_cl = new ssgColourArray( 26 );
lower_ring_vl = new ssgVertexArray( 26 );
lower_ring_cl = new ssgColourArray( 26 );
// initially seed to all blue
sgSetVec4( color, 0.0, 0.0, 1.0, 1.0 );
center_disk_vl = new osg::Vec3Array;
center_disk_cl = new osg::Vec3Array;
center_disk_cl->assign(14, osg::Vec3(0, 0, 1));
upper_ring_vl = new osg::Vec3Array;
upper_ring_cl = new osg::Vec3Array;
upper_ring_cl->assign(26, osg::Vec3(0, 0, 1));
middle_ring_vl = new osg::Vec3Array;
middle_ring_cl = new osg::Vec3Array;
middle_ring_cl->assign(26, osg::Vec3(0, 0, 1));
lower_ring_vl = new osg::Vec3Array;
lower_ring_cl = new osg::Vec3Array;
lower_ring_cl->assign(26, osg::Vec3(0, 0, 1));
// generate the raw vertex data
sgVec3 center_vertex;
sgVec3 upper_vertex[12];
sgVec3 middle_vertex[12];
sgVec3 lower_vertex[12];
sgVec3 bottom_vertex[12];
osg::Vec3 center_vertex(0.0, 0.0, center_elev*vscale);
osg::Vec3 upper_vertex[12];
osg::Vec3 middle_vertex[12];
osg::Vec3 lower_vertex[12];
osg::Vec3 bottom_vertex[12];
sgSetVec3( center_vertex, 0.0, 0.0, center_elev * vscale );
for ( int i = 0; i < 12; ++i ) {
double theta = (i * 30) * SGD_DEGREES_TO_RADIANS;
double sTheta = hscale*sin(theta);
double cTheta = hscale*cos(theta);
for ( i = 0; i < 12; i++ ) {
theta = (i * 30.0) * SGD_DEGREES_TO_RADIANS;
upper_vertex[i] = osg::Vec3(cTheta * upper_radius,
sTheta * upper_radius,
upper_elev * vscale);
sgSetVec3( upper_vertex[i],
cos(theta) * upper_radius * hscale,
sin(theta) * upper_radius * hscale,
upper_elev * vscale );
middle_vertex[i] = osg::Vec3(cTheta * middle_radius,
sTheta * middle_radius,
middle_elev * vscale);
sgSetVec3( middle_vertex[i],
cos(theta) * middle_radius * hscale,
sin(theta) * middle_radius * hscale,
middle_elev * vscale );
lower_vertex[i] = osg::Vec3(cTheta * lower_radius,
sTheta * lower_radius,
lower_elev * vscale);
sgSetVec3( lower_vertex[i],
cos(theta) * lower_radius * hscale,
sin(theta) * lower_radius * hscale,
lower_elev * vscale );
sgSetVec3( bottom_vertex[i],
cos(theta) * bottom_radius * hscale,
sin(theta) * bottom_radius * hscale,
bottom_elev * vscale );
bottom_vertex[i] = osg::Vec3(cTheta * bottom_radius,
sTheta * bottom_radius,
bottom_elev * vscale);
}
// generate the center disk vertex/color arrays
center_disk_vl->add( center_vertex );
center_disk_cl->add( color );
for ( i = 11; i >= 0; i-- ) {
center_disk_vl->add( upper_vertex[i] );
center_disk_cl->add( color );
}
center_disk_vl->add( upper_vertex[11] );
center_disk_cl->add( color );
center_disk_vl->push_back(center_vertex);
for ( int i = 11; i >= 0; --i )
center_disk_vl->push_back(upper_vertex[i]);
center_disk_vl->push_back(upper_vertex[11]);
// generate the upper ring
for ( i = 0; i < 12; i++ ) {
upper_ring_vl->add( middle_vertex[i] );
upper_ring_cl->add( color );
upper_ring_vl->add( upper_vertex[i] );
upper_ring_cl->add( color );
for ( int i = 0; i < 12; ++i ) {
upper_ring_vl->push_back( middle_vertex[i] );
upper_ring_vl->push_back( upper_vertex[i] );
}
upper_ring_vl->add( middle_vertex[0] );
upper_ring_cl->add( color );
upper_ring_vl->add( upper_vertex[0] );
upper_ring_cl->add( color );
upper_ring_vl->push_back( middle_vertex[0] );
upper_ring_vl->push_back( upper_vertex[0] );
// generate middle ring
for ( i = 0; i < 12; i++ ) {
middle_ring_vl->add( lower_vertex[i] );
middle_ring_cl->add( color );
middle_ring_vl->add( middle_vertex[i] );
middle_ring_cl->add( color );
for ( int i = 0; i < 12; i++ ) {
middle_ring_vl->push_back( lower_vertex[i] );
middle_ring_vl->push_back( middle_vertex[i] );
}
middle_ring_vl->add( lower_vertex[0] );
middle_ring_cl->add( color );
middle_ring_vl->add( middle_vertex[0] );
middle_ring_cl->add( color );
middle_ring_vl->push_back( lower_vertex[0] );
middle_ring_vl->push_back( middle_vertex[0] );
// generate lower ring
for ( i = 0; i < 12; i++ ) {
lower_ring_vl->add( bottom_vertex[i] );
lower_ring_cl->add( color );
lower_ring_vl->add( lower_vertex[i] );
lower_ring_cl->add( color );
for ( int i = 0; i < 12; i++ ) {
lower_ring_vl->push_back( bottom_vertex[i] );
lower_ring_vl->push_back( lower_vertex[i] );
}
lower_ring_vl->add( bottom_vertex[0] );
lower_ring_cl->add( color );
lower_ring_vl->add( lower_vertex[0] );
lower_ring_cl->add( color );
lower_ring_vl->push_back( bottom_vertex[0] );
lower_ring_vl->push_back( lower_vertex[0] );
// force a repaint of the sky colors with ugly defaults
sgVec4 fog_color;
sgSetVec4( fog_color, 1.0, 1.0, 1.0, 1.0 );
repaint( color, fog_color, 0.0, 5000.0 );
repaint(SGVec3f(1, 1, 1), SGVec3f(1, 1, 1), 0.0, 5000.0 );
// build the ssg scene graph sub tree for the sky and connected
// into the provide scene graph branch
ssgVtxTable *center_disk, *upper_ring, *middle_ring, *lower_ring;
osg::Geometry* geometry = new osg::Geometry;
geometry->setName("Dome Center");
// geometry->setDrawCallback(new SGDebugDrawCallback);
geometry->setUseDisplayList(false);
geometry->setVertexArray(center_disk_vl.get());
geometry->setColorArray(center_disk_cl.get());
geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
geometry->setNormalBinding(osg::Geometry::BIND_OFF);
geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_FAN, 0, 14));
geode->addDrawable(geometry);
center_disk = new ssgVtxTable( GL_TRIANGLE_FAN,
center_disk_vl, NULL, NULL, center_disk_cl );
geometry = new osg::Geometry;
geometry->setName("Dome Upper Ring");
// geometry->setDrawCallback(new SGDebugDrawCallback);
geometry->setUseDisplayList(false);
geometry->setVertexArray(upper_ring_vl.get());
geometry->setColorArray(upper_ring_cl.get());
geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
geometry->setNormalBinding(osg::Geometry::BIND_OFF);
geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, 26));
geode->addDrawable(geometry);
upper_ring = new ssgVtxTable( GL_TRIANGLE_STRIP,
upper_ring_vl, NULL, NULL, upper_ring_cl );
geometry = new osg::Geometry;
geometry->setName("Dome Middle Ring");
// geometry->setDrawCallback(new SGDebugDrawCallback);
geometry->setUseDisplayList(false);
geometry->setVertexArray(middle_ring_vl.get());
geometry->setColorArray(middle_ring_cl.get());
geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
geometry->setNormalBinding(osg::Geometry::BIND_OFF);
geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, 26));
geode->addDrawable(geometry);
middle_ring = new ssgVtxTable( GL_TRIANGLE_STRIP,
middle_ring_vl, NULL, NULL, middle_ring_cl );
geometry = new osg::Geometry;
geometry->setName("Dome Lower Ring");
// geometry->setDrawCallback(new SGDebugDrawCallback);
geometry->setUseDisplayList(false);
geometry->setVertexArray(lower_ring_vl.get());
geometry->setColorArray(lower_ring_cl.get());
geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
geometry->setNormalBinding(osg::Geometry::BIND_OFF);
geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, 26));
geode->addDrawable(geometry);
lower_ring = new ssgVtxTable( GL_TRIANGLE_STRIP,
lower_ring_vl, NULL, NULL, lower_ring_cl );
dome_transform = new osg::MatrixTransform;
dome_transform->addChild(geode);
center_disk->setState( dome_state );
upper_ring->setState( dome_state );
middle_ring->setState( dome_state );
lower_ring->setState( dome_state );
dome_transform = new ssgTransform;
dome_transform->addKid( center_disk );
dome_transform->addKid( upper_ring );
dome_transform->addKid( middle_ring );
dome_transform->addKid( lower_ring );
// not entirely satisfying. We are depending here that the first
// thing we add to a parent is the first drawn
center_disk->setCallback( SSG_CALLBACK_PREDRAW, sgSkyDomePreDraw );
center_disk->setCallback( SSG_CALLBACK_POSTDRAW, sgSkyDomePostDraw );
upper_ring->setCallback( SSG_CALLBACK_PREDRAW, sgSkyDomePreDraw );
upper_ring->setCallback( SSG_CALLBACK_POSTDRAW, sgSkyDomePostDraw );
middle_ring->setCallback( SSG_CALLBACK_PREDRAW, sgSkyDomePreDraw );
middle_ring->setCallback( SSG_CALLBACK_POSTDRAW, sgSkyDomePostDraw );
lower_ring->setCallback( SSG_CALLBACK_PREDRAW, sgSkyDomePreDraw );
lower_ring->setCallback( SSG_CALLBACK_POSTDRAW, sgSkyDomePostDraw );
return dome_transform;
return dome_transform.get();
}
static void fade_to_black( sgVec4 sky_color[], float asl, int count) {
static void fade_to_black(osg::Vec3 sky_color[], float asl, int count) {
const float ref_asl = 10000.0f;
const sgVec3 space_color = {0.0f, 0.0f, 0.0f};
float d = exp( - asl / ref_asl );
for(int i = 0; i < count ; i++)
sgLerpVec3( sky_color[i], sky_color[i], space_color, 1.0 - d);
for(int i = 0; i < count ; i++) {
float f = 1 - d;
sky_color[i][0] = sky_color[i][0] - f * sky_color[i][0] ;
sky_color[i][1] = sky_color[i][1] - f * sky_color[i][1] ;
sky_color[i][2] = sky_color[i][2] - f * sky_color[i][2] ;
}
}
// repaint the sky colors based on current value of sun_angle, sky,
@@ -287,59 +259,50 @@ static void fade_to_black( sgVec4 sky_color[], float asl, int count) {
// 0 degrees = high noon
// 90 degrees = sun rise/set
// 180 degrees = darkest midnight
bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle,
double vis )
bool
SGSkyDome::repaint( const SGVec3f& sky_color, const SGVec3f& fog_color,
double sun_angle, double vis )
{
double diff, prev_sun_angle = 999.0;
sgVec3 outer_param, outer_amt, outer_diff;
sgVec3 middle_param, middle_amt, middle_diff;
int i, j;
if (prev_sun_angle == sun_angle)
return true;
prev_sun_angle = sun_angle;
SGVec3f outer_param, outer_diff;
SGVec3f middle_param, middle_diff;
// Check for sunrise/sunset condition
if (sun_angle > 80.0) // && (sun_angle < 100.0) )
if (sun_angle > 80)
{
// 0.0 - 0.4
sgSetVec3( outer_param,
(10.0 - fabs(90.0 - sun_angle)) / 20.0,
(10.0 - fabs(90.0 - sun_angle)) / 40.0,
-(10.0 - fabs(90.0 - sun_angle)) / 30.0 );
outer_param[0] = (10.0 - fabs(90.0 - sun_angle)) / 20.0;
outer_param[1] = (10.0 - fabs(90.0 - sun_angle)) / 40.0;
outer_param[2] = -(10.0 - fabs(90.0 - sun_angle)) / 30.0;
sgSetVec3( middle_param,
(10.0 - fabs(90.0 - sun_angle)) / 40.0,
(10.0 - fabs(90.0 - sun_angle)) / 80.0,
0.0 );
middle_param[0] = (10.0 - fabs(90.0 - sun_angle)) / 40.0;
middle_param[1] = (10.0 - fabs(90.0 - sun_angle)) / 80.0;
middle_param[2] = 0.0;
sgScaleVec3( outer_diff, outer_param, 1.0 / 6.0 );
sgScaleVec3( middle_diff, middle_param, 1.0 / 6.0 );
outer_diff = (1.0 / 6.0) * outer_param;
middle_diff = (1.0 / 6.0) * middle_param;
} else {
sgSetVec3( outer_param, 0.0, 0.0, 0.0 );
sgSetVec3( middle_param, 0.0, 0.0, 0.0 );
outer_param = SGVec3f(0, 0, 0);
middle_param = SGVec3f(0, 0, 0);
sgSetVec3( outer_diff, 0.0, 0.0, 0.0 );
sgSetVec3( middle_diff, 0.0, 0.0, 0.0 );
outer_diff = SGVec3f(0, 0, 0);
middle_diff = SGVec3f(0, 0, 0);
}
// printf(" outer_red_param = %.2f outer_red_diff = %.2f\n",
// outer_red_param, outer_red_diff);
// calculate transition colors between sky and fog
sgCopyVec3( outer_amt, outer_param );
sgCopyVec3( middle_amt, middle_param );
SGVec3f outer_amt = outer_param;
SGVec3f middle_amt = middle_param;
//
// First, recalulate the basic colors
//
sgVec4 center_color;
sgVec4 upper_color[12];
sgVec4 middle_color[12];
sgVec4 lower_color[12];
sgVec4 bottom_color[12];
osg::Vec3 center_color;
osg::Vec3 upper_color[12];
osg::Vec3 middle_color[12];
osg::Vec3 lower_color[12];
osg::Vec3 bottom_color[12];
double vis_factor, cvf = vis;
@@ -353,25 +316,21 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle,
vis_factor = 1.0;
}
for ( j = 0; j < 3; j++ ) {
diff = sky_color[j] - fog_color[j];
center_color[j] = sky_color[j]; // - diff * ( 1.0 - vis_factor );
}
center_color[3] = 1.0;
center_color = sky_color.osg();
for ( i = 0; i < 6; i++ ) {
for ( j = 0; j < 3; j++ ) {
for ( int i = 0; i < 6; i++ ) {
for ( int j = 0; j < 3; j++ ) {
double saif = sun_angle/SG_PI;
diff = (sky_color[j] - fog_color[j]) * (0.8 + j * 0.2) * (0.8 + saif - ((6-i)/10));
double diff = (sky_color[j] - fog_color[j])
* (0.8 + j * 0.2) * (0.8 + saif - ((6-i)/10));
// printf("sky = %.2f fog = %.2f diff = %.2f\n",
// l->sky_color[j], l->fog_color[j], diff);
upper_color[i][j] = sky_color[j] - diff *
( 1.0 - vis_factor * (0.7 + 0.3 * cvf/45000) );
( 1.0 - vis_factor * (0.7 + 0.3 * cvf/45000) );
middle_color[i][j] = sky_color[j] - diff *
( 1.0 - vis_factor * (0.1 + 0.85 * cvf/45000) )
+ middle_amt[j];
( 1.0 - vis_factor * (0.1 + 0.85 * cvf/45000) ) + middle_amt[j];
lower_color[i][j] = fog_color[j] + outer_amt[j];
if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; }
@@ -381,12 +340,9 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle,
if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; }
if ( lower_color[i][j] < 0.0 ) { lower_color[i][j] = 0.0; }
}
upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = 1.0;
for ( j = 0; j < 3; j++ ) {
outer_amt[j] -= outer_diff[j];
middle_amt[j] -= middle_diff[j];
}
outer_amt -= outer_diff;
middle_amt -= middle_diff;
/*
printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0],
@@ -400,22 +356,22 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle,
*/
}
sgSetVec3( outer_amt, 0.0, 0.0, 0.0 );
sgSetVec3( middle_amt, 0.0, 0.0, 0.0 );
outer_amt = SGVec3f(0, 0, 0);
middle_amt = SGVec3f(0, 0, 0);
for ( i = 6; i < 12; i++ ) {
for ( j = 0; j < 3; j++ ) {
double saif = sun_angle/SG_PI;
diff = (sky_color[j] - fog_color[j]) * (0.8 + j * 0.2) * (0.8 + saif - ((-i+12)/10));
for ( int i = 6; i < 12; i++ ) {
for ( int j = 0; j < 3; j++ ) {
double saif = sun_angle/SGD_PI;
double diff = (sky_color[j] - fog_color[j])
* (0.8 + j * 0.2) * (0.8 + saif - ((-i+12)/10));
// printf("sky = %.2f fog = %.2f diff = %.2f\n",
// sky_color[j], fog_color[j], diff);
upper_color[i][j] = sky_color[j] - diff *
( 1.0 - vis_factor * (0.7 + 0.3 * cvf/45000) );
( 1.0 - vis_factor * (0.7 + 0.3 * cvf/45000) );
middle_color[i][j] = sky_color[j] - diff *
( 1.0 - vis_factor * (0.1 + 0.85 * cvf/45000) )
+ middle_amt[j];
( 1.0 - vis_factor * (0.1 + 0.85 * cvf/45000) ) + middle_amt[j];
lower_color[i][j] = fog_color[j] + outer_amt[j];
if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; }
@@ -425,12 +381,9 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle,
if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; }
if ( lower_color[i][j] < 0.0 ) { lower_color[i][j] = 0.0; }
}
upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = 1.0;
for ( j = 0; j < 3; j++ ) {
outer_amt[j] += outer_diff[j];
middle_amt[j] += middle_diff[j];
}
outer_amt += outer_diff;
middle_amt += middle_diff;
/*
printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0],
@@ -444,79 +397,56 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle,
*/
}
fade_to_black( (sgVec4 *) center_color, asl * center_elev, 1);
fade_to_black( &center_color, asl * center_elev, 1);
fade_to_black( upper_color, (asl+0.05f) * upper_elev, 12);
fade_to_black( middle_color, (asl+0.05f) * middle_elev, 12);
fade_to_black( lower_color, (asl+0.05f) * lower_elev, 12);
for ( i = 0; i < 12; i++ ) {
sgCopyVec4( bottom_color[i], fog_color );
}
for ( int i = 0; i < 12; i++ )
bottom_color[i] = fog_color.osg();
//
// Second, assign the basic colors to the object color arrays
//
float *slot;
int counter;
// update the center disk color arrays
counter = 0;
slot = center_disk_cl->get( counter++ );
// sgVec4 red;
// sgSetVec4( red, 1.0, 0.0, 0.0, 1.0 );
sgCopyVec4( slot, center_color );
for ( i = 11; i >= 0; i-- ) {
slot = center_disk_cl->get( counter++ );
sgCopyVec4( slot, upper_color[i] );
int counter = 0;
(*center_disk_cl)[counter++] = center_color;
for ( int i = 11; i >= 0; i-- ) {
(*center_disk_cl)[counter++] = upper_color[i];
}
slot = center_disk_cl->get( counter++ );
sgCopyVec4( slot, upper_color[11] );
(*center_disk_cl)[counter++] = upper_color[11];
center_disk_cl->dirty();
// generate the upper ring
counter = 0;
for ( i = 0; i < 12; i++ ) {
slot = upper_ring_cl->get( counter++ );
sgCopyVec4( slot, middle_color[i] );
slot = upper_ring_cl->get( counter++ );
sgCopyVec4( slot, upper_color[i] );
for ( int i = 0; i < 12; i++ ) {
(*upper_ring_cl)[counter++] = middle_color[i];
(*upper_ring_cl)[counter++] = upper_color[i];
}
slot = upper_ring_cl->get( counter++ );
sgCopyVec4( slot, middle_color[0] );
slot = upper_ring_cl->get( counter++ );
sgCopyVec4( slot, upper_color[0] );
(*upper_ring_cl)[counter++] = middle_color[0];
(*upper_ring_cl)[counter++] = upper_color[0];
upper_ring_cl->dirty();
// generate middle ring
counter = 0;
for ( i = 0; i < 12; i++ ) {
slot = middle_ring_cl->get( counter++ );
sgCopyVec4( slot, lower_color[i] );
slot = middle_ring_cl->get( counter++ );
sgCopyVec4( slot, middle_color[i] );
for ( int i = 0; i < 12; i++ ) {
(*middle_ring_cl)[counter++] = lower_color[i];
(*middle_ring_cl)[counter++] = middle_color[i];
}
slot = middle_ring_cl->get( counter++ );
sgCopyVec4( slot, lower_color[0] );
slot = middle_ring_cl->get( counter++ );
sgCopyVec4( slot, middle_color[0] );
(*middle_ring_cl)[counter++] = lower_color[0];
(*middle_ring_cl)[counter++] = middle_color[0];
middle_ring_cl->dirty();
// generate lower ring
counter = 0;
for ( i = 0; i < 12; i++ ) {
slot = lower_ring_cl->get( counter++ );
sgCopyVec4( slot, bottom_color[i] );
slot = lower_ring_cl->get( counter++ );
sgCopyVec4( slot, lower_color[i] );
for ( int i = 0; i < 12; i++ ) {
(*lower_ring_cl)[counter++] = bottom_color[i];
(*lower_ring_cl)[counter++] = lower_color[i];
}
slot = lower_ring_cl->get( counter++ );
sgCopyVec4( slot, bottom_color[0] );
slot = lower_ring_cl->get( counter++ );
sgCopyVec4( slot, lower_color[0] );
(*lower_ring_cl)[counter++] = bottom_color[0];
(*lower_ring_cl)[counter++] = lower_color[0];
lower_ring_cl->dirty();
return true;
}
@@ -527,14 +457,17 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle,
// lat specifies a rotation about the new Y axis
// spin specifies a rotation about the new Z axis (and orients the
// sunrise/set effects
bool SGSkyDome::reposition( sgVec3 p, double lon, double lat, double spin ) {
sgMat4 T, LON, LAT, SPIN;
sgVec3 axis;
bool
SGSkyDome::reposition( const SGVec3f& p, double _asl,
double lon, double lat, double spin ) {
asl = _asl;
osg::Matrix T, LON, LAT, SPIN;
// Translate to view position
// Point3D zero_elev = current_view.get_cur_zero_elev();
// xglTranslatef( zero_elev.x(), zero_elev.y(), zero_elev.z() );
sgMakeTransMat4( T, p );
T.makeTranslate( p.osg() );
// printf(" Translated to %.2f %.2f %.2f\n",
// zero_elev.x, zero_elev.y, zero_elev.z );
@@ -544,29 +477,15 @@ bool SGSkyDome::reposition( sgVec3 p, double lon, double lat, double spin ) {
// lon * SGD_RADIANS_TO_DEGREES,
// lat * SGD_RADIANS_TO_DEGREES);
// xglRotatef( lon * SGD_RADIANS_TO_DEGREES, 0.0, 0.0, 1.0 );
sgSetVec3( axis, 0.0, 0.0, 1.0 );
sgMakeRotMat4( LON, lon * SGD_RADIANS_TO_DEGREES, axis );
LON.makeRotate(lon, osg::Vec3(0, 0, 1));
// xglRotatef( 90.0 - f->get_Latitude() * SGD_RADIANS_TO_DEGREES,
// 0.0, 1.0, 0.0 );
sgSetVec3( axis, 0.0, 1.0, 0.0 );
sgMakeRotMat4( LAT, 90.0 - lat * SGD_RADIANS_TO_DEGREES, axis );
LAT.makeRotate(90.0 * SGD_DEGREES_TO_RADIANS - lat, osg::Vec3(0, 1, 0));
// xglRotatef( l->sun_rotation * SGD_RADIANS_TO_DEGREES, 0.0, 0.0, 1.0 );
sgSetVec3( axis, 0.0, 0.0, 1.0 );
sgMakeRotMat4( SPIN, spin * SGD_RADIANS_TO_DEGREES, axis );
SPIN.makeRotate(spin, osg::Vec3(0, 0, 1));
sgMat4 TRANSFORM;
sgCopyMat4( TRANSFORM, T );
sgPreMultMat4( TRANSFORM, LON );
sgPreMultMat4( TRANSFORM, LAT );
sgPreMultMat4( TRANSFORM, SPIN );
sgCoord skypos;
sgSetCoord( &skypos, TRANSFORM );
dome_transform->setTransform( &skypos );
asl = - skypos.xyz[2];
dome_transform->setMatrix( SPIN*LAT*LON*T );
return true;
}

View File

@@ -30,27 +30,29 @@
# error This library requires C++
#endif
#include <osg/ref_ptr>
#include <osg/Array>
#include <osg/MatrixTransform>
#include <plib/ssg.h> // plib include
#include <simgear/structure/SGReferenced.hxx>
#include <simgear/math/SGMath.hxx>
class SGSkyDome : public SGReferenced {
osg::ref_ptr<osg::MatrixTransform> dome_transform;
class SGSkyDome {
ssgTransform *dome_transform;
ssgSimpleState *dome_state;
osg::ref_ptr<osg::Vec3Array> center_disk_vl;
osg::ref_ptr<osg::Vec3Array> center_disk_cl;
ssgVertexArray *center_disk_vl;
ssgColourArray *center_disk_cl;
osg::ref_ptr<osg::Vec3Array> upper_ring_vl;
osg::ref_ptr<osg::Vec3Array> upper_ring_cl;
ssgVertexArray *upper_ring_vl;
ssgColourArray *upper_ring_cl;
osg::ref_ptr<osg::Vec3Array> middle_ring_vl;
osg::ref_ptr<osg::Vec3Array> middle_ring_cl;
ssgVertexArray *middle_ring_vl;
ssgColourArray *middle_ring_cl;
osg::ref_ptr<osg::Vec3Array> lower_ring_vl;
osg::ref_ptr<osg::Vec3Array> lower_ring_cl;
ssgVertexArray *lower_ring_vl;
ssgColourArray *lower_ring_cl;
float asl;
double asl;
public:
@@ -62,7 +64,7 @@ public:
// initialize the sky object and connect it into our scene graph
// root
ssgBranch *build( double hscale = 80000.0, double vscale = 80000.0 );
osg::Node *build( double hscale = 80000.0, double vscale = 80000.0 );
// repaint the sky colors based on current value of sun_angle,
// sky, and fog colors. This updates the color arrays for
@@ -71,15 +73,16 @@ public:
// 0 degrees = high noon
// 90 degrees = sun rise/set
// 180 degrees = darkest midnight
bool repaint( sgVec3 sky_color, sgVec3 fog_color, double sun_angle,
double vis );
bool repaint( const SGVec3f& sky_color, const SGVec3f& fog_color,
double sun_angle, double vis );
// reposition the sky at the specified origin and orientation
// lon specifies a rotation about the Z axis
// lat specifies a rotation about the new Y axis
// spin specifies a rotation about the new Z axis (and orients the
// sunrise/set effects
bool reposition( sgVec3 p, double lon, double lat, double spin );
bool reposition( const SGVec3f& p, double asl,
double lon, double lat, double spin );
};

View File

@@ -32,80 +32,24 @@
#include <stdio.h>
#include STL_IOSTREAM
#include <plib/sg.h>
#include <plib/ssg.h>
#include <osg/Array>
#include <osg/AlphaFunc>
#include <osg/BlendFunc>
#include <osg/CullFace>
#include <osg/Geometry>
#include <osg/Geode>
#include <osg/Node>
#include <osg/ShadeModel>
#include <osg/TexEnv>
#include <osg/Texture2D>
#include <simgear/constants.h>
#include <simgear/screen/colors.hxx>
#include <simgear/scene/model/model.hxx>
#include "sphere.hxx"
#include "moon.hxx"
// Set up moon rendering call backs
static int sgMoonOrbPreDraw( ssgEntity *e ) {
/* cout << endl << "Moon orb pre draw" << endl << "----------------"
<< endl << endl; */
ssgLeaf *f = (ssgLeaf *)e;
if ( f -> hasState () ) f->getState()->apply() ;
glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT );
// cout << "push error = " << glGetError() << endl;
glDisable( GL_DEPTH_TEST );
glDisable( GL_FOG );
glBlendFunc ( GL_SRC_ALPHA, GL_ONE ) ;
return true;
}
static int sgMoonOrbPostDraw( ssgEntity *e ) {
/* cout << endl << "Moon orb post draw" << endl << "----------------"
<< endl << endl; */
// Some drivers don't properly reset glBendFunc with a
// glPopAttrib() so we reset it to the 'default' here.
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
glPopAttrib();
// cout << "pop error = " << glGetError() << endl;
return true;
}
#if 0
static int sgMoonHaloPreDraw( ssgEntity *e ) {
/* cout << endl << "Moon halo pre draw" << endl << "----------------"
<< endl << endl; */
ssgLeaf *f = (ssgLeaf *)e;
if ( f -> hasState () ) f->getState()->apply() ;
glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_FOG_BIT | GL_COLOR_BUFFER_BIT);
// cout << "push error = " << glGetError() << endl;
glDisable( GL_DEPTH_TEST );
glDisable( GL_FOG );
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
return true;
}
static int sgMoonHaloPostDraw( ssgEntity *e ) {
/* cout << endl << "Moon halo post draw" << endl << "----------------"
<< endl << endl; */
glPopAttrib();
// cout << "pop error = " << glGetError() << endl;
return true;
}
#endif
// Constructor
SGMoon::SGMoon( void ) :
prev_moon_angle(-1)
@@ -119,99 +63,64 @@ SGMoon::~SGMoon( void ) {
// build the moon object
ssgBranch * SGMoon::build( SGPath path, double moon_size ) {
osg::Node*
SGMoon::build( SGPath path, double moon_size ) {
osg::Node* orb = SGMakeSphere(moon_size, 15, 15);
osg::StateSet* stateSet = orb->getOrCreateStateSet();
stateSet->setRenderBinDetails(-5, "RenderBin");
// set up the orb state
path.append( "moon.rgba" );
orb_state = new ssgSimpleState();
orb_state->setTexture( (char *)path.c_str() );
orb_state->setShadeModel( GL_SMOOTH );
orb_state->enable( GL_LIGHTING );
orb_state->enable( GL_CULL_FACE );
orb_state->enable( GL_TEXTURE_2D );
orb_state->enable( GL_COLOR_MATERIAL );
orb_state->setColourMaterial( GL_DIFFUSE );
orb_state->setMaterial( GL_AMBIENT, 0, 0, 0, 1.0 );
orb_state->setMaterial( GL_EMISSION, 0.0, 0.0, 0.0, 1 );
orb_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
orb_state->enable( GL_BLEND );
orb_state->enable( GL_ALPHA_TEST );
orb_state->setAlphaClamp( 0.01 );
cl = new ssgColourArray( 1 );
sgVec4 color;
sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
cl->add( color );
osg::Texture2D* texture = SGLoadTexture2D(path);
stateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
osg::TexEnv* texEnv = new osg::TexEnv;
texEnv->setMode(osg::TexEnv::MODULATE);
stateSet->setTextureAttribute(0, texEnv, osg::StateAttribute::ON);
ssgBranch *orb = ssgMakeSphere( orb_state, cl, moon_size, 15, 15,
sgMoonOrbPreDraw, sgMoonOrbPostDraw );
orb_material = new osg::Material;
orb_material->setColorMode(osg::Material::DIFFUSE);
orb_material->setDiffuse(osg::Material::FRONT_AND_BACK,
osg::Vec4(1, 1, 1, 1));
orb_material->setAmbient(osg::Material::FRONT_AND_BACK,
osg::Vec4(0, 0, 0, 1));
orb_material->setEmission(osg::Material::FRONT_AND_BACK,
osg::Vec4(0, 0, 0, 1));
orb_material->setSpecular(osg::Material::FRONT_AND_BACK,
osg::Vec4(0, 0, 0, 1));
orb_material->setShininess(osg::Material::FRONT_AND_BACK, 0);
stateSet->setAttributeAndModes(orb_material.get());
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON);
stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
osg::ShadeModel* shadeModel = new osg::ShadeModel;
shadeModel->setMode(osg::ShadeModel::SMOOTH);
stateSet->setAttributeAndModes(shadeModel);
osg::CullFace* cullFace = new osg::CullFace;
cullFace->setMode(osg::CullFace::BACK);
stateSet->setAttributeAndModes(cullFace);
osg::BlendFunc* blendFunc = new osg::BlendFunc;
blendFunc->setFunction(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE);
stateSet->setAttributeAndModes(blendFunc);
// osg::AlphaFunc* alphaFunc = new osg::AlphaFunc;
// alphaFunc->setFunction(osg::AlphaFunc::GREATER);
// alphaFunc->setReferenceValue(0.01);
// stateSet->setAttributeAndModes(alphaFunc);
stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::OFF);
// force a repaint of the moon colors with arbitrary defaults
repaint( 0.0 );
// build the halo
// moon_texbuf = new GLubyte[64*64*3];
// moon_texid = makeHalo( moon_texbuf, 64 );
// my_glWritePPMFile("moonhalo.ppm", moon_texbuf, 64, 64, RGB);
#if 0
// set up the halo state
halo_state = new ssgSimpleState();
halo_state->setTexture( "halo.rgb" );
// halo_state->setTexture( moon_texid );
halo_state->enable( GL_TEXTURE_2D );
halo_state->disable( GL_LIGHTING );
halo_state->setShadeModel( GL_SMOOTH );
halo_state->disable( GL_CULL_FACE );
halo_state->disable( GL_COLOR_MATERIAL );
halo_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
halo_state->setMaterial ( GL_AMBIENT_AND_DIFFUSE, 1, 1, 1, 1 ) ;
halo_state->setMaterial ( GL_EMISSION, 0, 0, 0, 1 ) ;
halo_state->setMaterial ( GL_SPECULAR, 0, 0, 0, 1 ) ;
// halo_state -> setShininess ( 0 ) ;
halo_state->enable( GL_ALPHA_TEST );
halo_state->setAlphaClamp(0.01);
halo_state->enable ( GL_BLEND ) ;
// Build ssg structure
double size = moon_size * 10.0;
sgVec3 v3;
halo_vl = new ssgVertexArray;
sgSetVec3( v3, -size, 0.0, -size );
halo_vl->add( v3 );
sgSetVec3( v3, size, 0.0, -size );
halo_vl->add( v3 );
sgSetVec3( v3, -size, 0.0, size );
halo_vl->add( v3 );
sgSetVec3( v3, size, 0.0, size );
halo_vl->add( v3 );
sgVec2 v2;
halo_tl = new ssgTexCoordArray;
sgSetVec2( v2, 0.0f, 0.0f );
halo_tl->add( v2 );
sgSetVec2( v2, 1.0, 0.0 );
halo_tl->add( v2 );
sgSetVec2( v2, 0.0, 1.0 );
halo_tl->add( v2 );
sgSetVec2( v2, 1.0, 1.0 );
halo_tl->add( v2 );
ssgLeaf *halo =
new ssgVtxTable ( GL_TRIANGLE_STRIP, halo_vl, NULL, halo_tl, cl );
halo->setState( halo_state );
#endif
// build the ssg scene graph sub tree for the sky and connected
// into the provide scene graph branch
moon_transform = new ssgTransform;
moon_transform = new osg::MatrixTransform;
// moon_transform->addKid( halo );
moon_transform->addKid( orb );
moon_transform->addChild( orb );
return moon_transform;
return moon_transform.get();
}
@@ -222,31 +131,27 @@ ssgBranch * SGMoon::build( SGPath path, double moon_size ) {
// 180 degrees = darkest midnight
bool SGMoon::repaint( double moon_angle ) {
if (prev_moon_angle != moon_angle) {
prev_moon_angle = moon_angle;
if (prev_moon_angle == moon_angle)
return true;
float moon_factor = 4*cos(moon_angle);
prev_moon_angle = moon_angle;
if (moon_factor > 1) moon_factor = 1.0;
if (moon_factor < -1) moon_factor = -1.0;
moon_factor = moon_factor/2 + 0.5;
float moon_factor = 4*cos(moon_angle);
if (moon_factor > 1) moon_factor = 1.0;
if (moon_factor < -1) moon_factor = -1.0;
moon_factor = moon_factor/2 + 0.5;
osg::Vec4 color;
color[1] = sqrt(moon_factor);
color[0] = sqrt(color[1]);
color[2] = moon_factor * moon_factor;
color[2] *= color[2];
color[3] = 1.0;
gamma_correct_rgb( color._v );
sgVec4 color;
color[1] = sqrt(moon_factor);
color[0] = sqrt(color[1]);
color[2] = moon_factor * moon_factor;
color[2] *= color[2];
color[3] = 1.0;
gamma_correct_rgb( color );
// cout << "color = " << color[0] << " " << color[1] << " "
// << color[2] << endl;
float *ptr;
ptr = cl->get( 0 );
sgCopyVec4( ptr, color );
}
orb_material->setDiffuse(osg::Material::FRONT_AND_BACK, color);
return true;
}
@@ -256,43 +161,28 @@ bool SGMoon::repaint( double moon_angle ) {
// declination, offset by our current position (p) so that it appears
// fixed at a great distance from the viewer. Also add in an optional
// rotation (i.e. for the current time of day.)
bool SGMoon::reposition( sgVec3 p, double angle,
bool SGMoon::reposition( const SGVec3f& p, double angle,
double rightAscension, double declination,
double moon_dist )
{
sgMat4 T1, T2, GST, RA, DEC;
sgVec3 axis;
sgVec3 v;
osg::Matrix T1, T2, GST, RA, DEC;
sgMakeTransMat4( T1, p );
T1.makeTranslate(p.osg());
sgSetVec3( axis, 0.0, 0.0, -1.0 );
sgMakeRotMat4( GST, angle, axis );
GST.makeRotate(SGD_DEGREES_TO_RADIANS*angle, osg::Vec3(0, 0, -1));
// xglRotatef( ((SGD_RADIANS_TO_DEGREES * rightAscension)- 90.0),
// 0.0, 0.0, 1.0);
sgSetVec3( axis, 0.0, 0.0, 1.0 );
sgMakeRotMat4( RA, (rightAscension * SGD_RADIANS_TO_DEGREES) - 90.0, axis );
RA.makeRotate(rightAscension - 90.0 * SGD_DEGREES_TO_RADIANS,
osg::Vec3(0, 0, 1));
// xglRotatef((SGD_RADIANS_TO_DEGREES * declination), 1.0, 0.0, 0.0);
sgSetVec3( axis, 1.0, 0.0, 0.0 );
sgMakeRotMat4( DEC, declination * SGD_RADIANS_TO_DEGREES, axis );
DEC.makeRotate(declination, osg::Vec3(1, 0, 0));
// xglTranslatef(0,moon_dist);
sgSetVec3( v, 0.0, moon_dist, 0.0 );
sgMakeTransMat4( T2, v );
T2.makeTranslate(osg::Vec3(0, moon_dist, 0));
sgMat4 TRANSFORM;
sgCopyMat4( TRANSFORM, T1 );
sgPreMultMat4( TRANSFORM, GST );
sgPreMultMat4( TRANSFORM, RA );
sgPreMultMat4( TRANSFORM, DEC );
sgPreMultMat4( TRANSFORM, T2 );
sgCoord skypos;
sgSetCoord( &skypos, TRANSFORM );
moon_transform->setTransform( &skypos );
moon_transform->setMatrix(T2*DEC*RA*GST*T1);
return true;
}

View File

@@ -29,21 +29,20 @@
#define _SG_MOON_HXX_
#include <plib/ssg.h>
#include <osg/ref_ptr>
#include <osg/MatrixTransform>
#include <osg/Material>
#include <simgear/math/SGMath.hxx>
#include <simgear/structure/SGReferenced.hxx>
#include <simgear/misc/sg_path.hxx>
class SGMoon {
class SGMoon : public SGReferenced {
ssgTransform *moon_transform;
ssgSimpleState *orb_state;
ssgSimpleState *halo_state;
ssgColourArray *cl;
ssgVertexArray *halo_vl;
ssgTexCoordArray *halo_tl;
osg::ref_ptr<osg::MatrixTransform> moon_transform;
osg::ref_ptr<osg::Material> orb_material;
double prev_moon_angle;
@@ -56,7 +55,7 @@ public:
~SGMoon( void );
// build the moon object
ssgBranch *build( SGPath path, double moon_size );
osg::Node *build( SGPath path, double moon_size );
// repaint the moon colors based on current value of moon_anglein
// degrees relative to verticle
@@ -69,7 +68,7 @@ public:
// declination, offset by our current position (p) so that it
// appears fixed at a great distance from the viewer. Also add in
// an optional rotation (i.e. for the current time of day.)
bool reposition( sgVec3 p, double angle,
bool reposition( const SGVec3f& p, double angle,
double rightAscension, double declination,
double moon_dist );
};

View File

@@ -24,13 +24,14 @@
# include <simgear_config.h>
#endif
#include <osg/ref_ptr>
#include <osg/Texture2D>
#include <simgear/compiler.h>
#include <plib/sg.h>
#include <plib/ssg.h>
#include <simgear/math/sg_random.h>
#include <simgear/misc/sg_path.hxx>
#include <simgear/structure/ssgSharedPtr.hxx>
#include STL_ALGORITHM
#include SG_GLU_H
@@ -42,7 +43,7 @@
/*
*/
static ssgSharedPtr<ssgTexture> cloudTextures[SGNewCloud::CLTexture_max];
static osg::ref_ptr<osg::Texture2D> cloudTextures[SGNewCloud::CLTexture_max];
bool SGNewCloud::useAnisotropic = true;
@@ -129,11 +130,15 @@ void SGNewCloud::loadTextures(const string &tex_path) {
cloud_path.set(tex_path);
cloud_path.append("cl_cumulus.rgb");
cloudTextures[ CLTexture_cumulus ] = new ssgTexture( cloud_path.str().c_str(), false, false, false );
// OSGFIXME
// cloudTextures[ CLTexture_cumulus ] = new osg::Texture2D( cloud_path.str().c_str(), false, false, false );
cloudTextures[ CLTexture_cumulus ] = new osg::Texture2D;
cloud_path.set(tex_path);
cloud_path.append("cl_stratus.rgb");
cloudTextures[ CLTexture_stratus ] = new ssgTexture( cloud_path.str().c_str(), false, false, false );
// OSGFIXME
// cloudTextures[ CLTexture_stratus ] = new ssgTexture( cloud_path.str().c_str(), false, false, false );
cloudTextures[ CLTexture_stratus ] = new osg::Texture2D;
}
@@ -486,7 +491,8 @@ void SGNewCloud::Render3Dcloud( bool drawBB, sgVec3 FakeEyePos, sgVec3 deltaPos,
// in practice there is no texture switch (atm)
if( previousTexture != thisTexture ) {
previousTexture = thisTexture;
glBindTexture(GL_TEXTURE_2D, cloudTextures[thisTexture]->getHandle());
// OSGFIXME
// glBindTexture(GL_TEXTURE_2D, cloudTextures[thisTexture]->getHandle());
}
sgVec3 translate;

View File

@@ -30,78 +30,21 @@
#include <simgear/compiler.h>
#include <plib/sg.h>
#include <plib/ssg.h>
// define the following to enable a cheesy lens flare effect for the sun
// #define FG_TEST_CHEESY_LENS_FLARE
#ifdef FG_TEST_CHEESY_LENS_FLARE
# include <plib/ssgaLensFlare.h>
#endif
#include <osg/AlphaFunc>
#include <osg/BlendFunc>
#include <osg/Fog>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Material>
#include <osg/ShadeModel>
#include <osg/TexEnv>
#include <osg/Texture2D>
#include <osgDB/ReadFile>
#include <simgear/screen/colors.hxx>
#include <simgear/scene/model/model.hxx>
#include "oursun.hxx"
static double sun_exp2_punch_through;
// Set up sun rendering call backs
static int sgSunPreDraw( ssgEntity *e ) {
/* cout << endl << "Sun orb pre draw" << endl << "----------------"
<< endl << endl; */
ssgLeaf *f = (ssgLeaf *)e;
if ( f -> hasState () ) f->getState()->apply() ;
glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_FOG_BIT );
// cout << "push error = " << glGetError() << endl;
glDisable( GL_DEPTH_TEST );
glDisable( GL_FOG );
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
return true;
}
static int sgSunPostDraw( ssgEntity *e ) {
/* cout << endl << "Sun orb post draw" << endl << "----------------"
<< endl << endl; */
glPopAttrib();
// cout << "pop error = " << glGetError() << endl;
return true;
}
static int sgSunHaloPreDraw( ssgEntity *e ) {
/* cout << endl << "Sun halo pre draw" << endl << "----------------"
<< endl << endl; */
ssgLeaf *f = (ssgLeaf *)e;
if ( f -> hasState () ) f->getState()->apply() ;
glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_FOG_BIT );
// cout << "push error = " << glGetError() << endl;
glDisable( GL_DEPTH_TEST );
// glDisable( GL_FOG );
glFogf (GL_FOG_DENSITY, sun_exp2_punch_through);
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
return true;
}
static int sgSunHaloPostDraw( ssgEntity *e ) {
/* cout << endl << "Sun halo post draw" << endl << "----------------"
<< endl << endl; */
glPopAttrib();
// cout << "pop error = " << glGetError() << endl;
return true;
}
// Constructor
SGSun::SGSun( void ) {
prev_sun_angle = -9999.0;
@@ -114,308 +57,170 @@ SGSun::~SGSun( void ) {
}
#if 0
// this might be nice to keep, just as an example of how to generate a
// texture on the fly ...
static GLuint makeHalo( GLubyte *sun_texbuf, int width ) {
int texSize;
GLuint texid;
GLubyte *p;
int i,j;
double radius;
// create a texture id
#ifdef GL_VERSION_1_1
glGenTextures(1, &texid);
glBindTexture(GL_TEXTURE_2D, texid);
#elif GL_EXT_texture_object
glGenTexturesEXT(1, &texid);
glBindTextureEXT(GL_TEXTURE_2D, texid);
#else
# error port me
#endif
glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ;
// create the actual texture contents
texSize = width * width;
if ( !sun_texbuf ) {
SG_LOG( SG_EVENT, SG_ALERT,
"Could not allocate memroy for the sun texture");
exit(-1); // Ugly!
}
p = sun_texbuf;
radius = (double)(width / 2);
GLubyte value;
double x, y, d;
for ( i = 0; i < width; i++ ) {
for ( j = 0; j < width; j++ ) {
x = fabs((double)(i - (width / 2)));
y = fabs((double)(j - (width / 2)));
d = sqrt((x * x) + (y * y));
if (d < radius) {
// t is 1.0 at center, 0.0 at edge
double t = 1.0 - (d / radius);
// inverse square looks nice
value = (int)((double) 0xff * (t*t));
} else {
value = 0x00;
}
*p = value;
*(p+1) = value;
*(p+2) = value;
// *(p+3) = value;
p += 3;
}
}
/* glTexImage2D( GL_TEXTURE_2D,
0,
GL_RGBA,
width, width,
0,
GL_RGBA, GL_UNSIGNED_BYTE,
sun_texbuf ); */
return texid;
}
#define RGB 3 // 3 bytes of color info per pixel
#define RGBA 4 // 4 bytes of color+alpha info
void my_glWritePPMFile(const char *filename, GLubyte *buffer, int win_width, int win_height, int mode)
{
int i, j, k, q;
unsigned char *ibuffer;
FILE *fp;
int pixelSize = mode==GL_RGBA?4:3;
ibuffer = (unsigned char *) malloc(win_width*win_height*RGB);
fp = fopen(filename, "wb");
fprintf(fp, "P6\n# CREATOR: glReadPixel()\n%d %d\n%d\n",
win_width, win_height, UCHAR_MAX);
q = 0;
for (i = 0; i < win_height; i++) {
for (j = 0; j < win_width; j++) {
for (k = 0; k < RGB; k++) {
ibuffer[q++] = (unsigned char)
*(buffer + (pixelSize*((win_height-1-i)*win_width+j)+k));
}
}
}
// *(buffer + (pixelSize*((win_height-1-i)*win_width+j)+k));
fwrite(ibuffer, sizeof(unsigned char), RGB*win_width*win_height, fp);
fclose(fp);
free(ibuffer);
printf("wrote file (%d x %d pixels, %d bytes)\n",
win_width, win_height, RGB*win_width*win_height);
}
#endif
// initialize the sun object and connect it into our scene graph root
ssgBranch * SGSun::build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node ) {
osg::Node*
SGSun::build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node ) {
env_node = property_tree_Node;
SGPath ihalopath = path, ohalopath = path;
sgVec4 color;
sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
// build the ssg scene graph sub tree for the sky and connected
// into the provide scene graph branch
sun_transform = new osg::MatrixTransform;
osg::StateSet* stateSet = sun_transform->getOrCreateStateSet();
sun_cl = new ssgColourArray( 1 );
sun_cl->add( color );
osg::TexEnv* texEnv = new osg::TexEnv;
texEnv->setMode(osg::TexEnv::MODULATE);
stateSet->setTextureAttribute(0, texEnv, osg::StateAttribute::ON);
osg::Material* material = new osg::Material;
material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
material->setEmission(osg::Material::FRONT_AND_BACK,
osg::Vec4(0, 0, 0, 1));
material->setSpecular(osg::Material::FRONT_AND_BACK,
osg::Vec4(0, 0, 0, 1));
stateSet->setAttributeAndModes(material);
ihalo_cl = new ssgColourArray( 1 );
ihalo_cl->add( color );
osg::ShadeModel* shadeModel = new osg::ShadeModel;
shadeModel->setMode(osg::ShadeModel::FLAT);
stateSet->setAttributeAndModes(shadeModel);
ohalo_cl = new ssgColourArray( 1 );
ohalo_cl->add( color );
osg::AlphaFunc* alphaFunc = new osg::AlphaFunc;
alphaFunc->setFunction(osg::AlphaFunc::GREATER);
alphaFunc->setReferenceValue(0.01);
stateSet->setAttributeAndModes(alphaFunc);
// force a repaint of the sun colors with arbitrary defaults
repaint( 0.0, 1.0 );
osg::BlendFunc* blendFunc = new osg::BlendFunc;
blendFunc->setSource(osg::BlendFunc::SRC_ALPHA);
blendFunc->setDestination(osg::BlendFunc::ONE_MINUS_SRC_ALPHA);
stateSet->setAttributeAndModes(blendFunc);
stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
osg::Geode* geode = new osg::Geode;
stateSet = geode->getOrCreateStateSet();
stateSet->setRenderBinDetails(-8, "RenderBin");
// set up the sun-state
path.append( "sun.rgba" );
sun_state = new ssgSimpleState();
sun_state->setShadeModel( GL_SMOOTH );
sun_state->disable( GL_LIGHTING );
sun_state->disable( GL_CULL_FACE );
sun_state->setTexture( (char *)path.c_str() );
sun_state->enable( GL_TEXTURE_2D );
sun_state->enable( GL_COLOR_MATERIAL );
sun_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
sun_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
sun_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
sun_state->enable( GL_BLEND );
sun_state->setAlphaClamp( 0.01 );
sun_state->enable( GL_ALPHA_TEST );
osg::Texture2D* texture = SGLoadTexture2D(path);
stateSet->setTextureAttributeAndModes(0, texture);
// Build ssg structure
sgVec3 va;
sun_vl = new ssgVertexArray;
sgSetVec3( va, -sun_size, 0.0, -sun_size );
sun_vl->add( va );
sgSetVec3( va, sun_size, 0.0, -sun_size );
sun_vl->add( va );
sgSetVec3( va, -sun_size, 0.0, sun_size );
sun_vl->add( va );
sgSetVec3( va, sun_size, 0.0, sun_size );
sun_vl->add( va );
// Build scenegraph
sun_cl = new osg::Vec4Array;
sun_cl->push_back(osg::Vec4(1, 1, 1, 1));
sgVec2 vb;
sun_tl = new ssgTexCoordArray;
sgSetVec2( vb, 0.0f, 0.0f );
sun_tl->add( vb );
sgSetVec2( vb, 1.0, 0.0 );
sun_tl->add( vb );
sgSetVec2( vb, 0.0, 1.0 );
sun_tl->add( vb );
sgSetVec2( vb, 1.0, 1.0 );
sun_tl->add( vb );
osg::Vec3Array* sun_vl = new osg::Vec3Array;
sun_vl->push_back(osg::Vec3(-sun_size, 0, -sun_size));
sun_vl->push_back(osg::Vec3(sun_size, 0, -sun_size));
sun_vl->push_back(osg::Vec3(-sun_size, 0, sun_size));
sun_vl->push_back(osg::Vec3(sun_size, 0, sun_size));
osg::Vec2Array* sun_tl = new osg::Vec2Array;
sun_tl->push_back(osg::Vec2(0, 0));
sun_tl->push_back(osg::Vec2(1, 0));
sun_tl->push_back(osg::Vec2(0, 1));
sun_tl->push_back(osg::Vec2(1, 1));
ssgLeaf *sun =
new ssgVtxTable ( GL_TRIANGLE_STRIP, sun_vl, NULL, sun_tl, sun_cl );
sun->setState( sun_state );
osg::Geometry* geometry = new osg::Geometry;
geometry->setUseDisplayList(false);
geometry->setVertexArray(sun_vl);
geometry->setColorArray(sun_cl.get());
geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
geometry->setTexCoordArray(0, sun_tl);
geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, 4));
geode->addDrawable(geometry);
sun->setCallback( SSG_CALLBACK_PREDRAW, sgSunPreDraw );
sun->setCallback( SSG_CALLBACK_POSTDRAW, sgSunPostDraw );
sun_transform->addChild( geode );
// build the halo
// sun_texbuf = new GLubyte[64*64*3];
// sun_texid = makeHalo( sun_texbuf, 64 );
// my_glWritePPMFile("sunhalo.ppm", sun_texbuf, 64, 64, RGB);
// set up the inner-halo state
ihalopath.append( "inner_halo.rgba" );
ihalo_state = new ssgSimpleState();
ihalo_state->setTexture( (char *)ihalopath.c_str() );
ihalo_state->enable( GL_TEXTURE_2D );
ihalo_state->disable( GL_LIGHTING );
ihalo_state->setShadeModel( GL_SMOOTH );
ihalo_state->disable( GL_CULL_FACE );
ihalo_state->enable( GL_COLOR_MATERIAL );
ihalo_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
ihalo_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
ihalo_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
ihalo_state->enable( GL_ALPHA_TEST );
ihalo_state->setAlphaClamp(0.01);
ihalo_state->enable ( GL_BLEND ) ;
geode = new osg::Geode;
stateSet = geode->getOrCreateStateSet();
stateSet->setRenderBinDetails(-7, "RenderBin");
ihalopath.append( "inner_halo.rgba" );
texture = SGLoadTexture2D(path);
stateSet->setTextureAttributeAndModes(0, texture);
// Build ssg structure
double ihalo_size = sun_size * 2.0;
sgVec3 vc;
ihalo_vl = new ssgVertexArray;
sgSetVec3( vc, -ihalo_size, 0.0, -ihalo_size );
ihalo_vl->add( vc );
sgSetVec3( vc, ihalo_size, 0.0, -ihalo_size );
ihalo_vl->add( vc );
sgSetVec3( vc, -ihalo_size, 0.0, ihalo_size );
ihalo_vl->add( vc );
sgSetVec3( vc, ihalo_size, 0.0, ihalo_size );
ihalo_vl->add( vc );
ihalo_cl = new osg::Vec4Array;
ihalo_cl->push_back(osg::Vec4(1, 1, 1, 1));
sgVec2 vd;
ihalo_tl = new ssgTexCoordArray;
sgSetVec2( vd, 0.0f, 0.0f );
ihalo_tl->add( vd );
sgSetVec2( vd, 1.0, 0.0 );
ihalo_tl->add( vd );
sgSetVec2( vd, 0.0, 1.0 );
ihalo_tl->add( vd );
sgSetVec2( vd, 1.0, 1.0 );
ihalo_tl->add( vd );
float ihalo_size = sun_size * 2.0;
osg::Vec3Array* ihalo_vl = new osg::Vec3Array;
ihalo_vl->push_back(osg::Vec3(-ihalo_size, 0, -ihalo_size));
ihalo_vl->push_back(osg::Vec3(ihalo_size, 0, -ihalo_size));
ihalo_vl->push_back(osg::Vec3(-ihalo_size, 0, ihalo_size));
ihalo_vl->push_back(osg::Vec3(ihalo_size, 0, ihalo_size));
ssgLeaf *ihalo =
new ssgVtxTable ( GL_TRIANGLE_STRIP, ihalo_vl, NULL, ihalo_tl, ihalo_cl );
ihalo->setState( ihalo_state );
osg::Vec2Array* ihalo_tl = new osg::Vec2Array;
ihalo_tl->push_back(osg::Vec2(0, 0));
ihalo_tl->push_back(osg::Vec2(1, 0));
ihalo_tl->push_back(osg::Vec2(0, 1));
ihalo_tl->push_back(osg::Vec2(1, 1));
geometry = new osg::Geometry;
geometry->setUseDisplayList(false);
geometry->setVertexArray(ihalo_vl);
geometry->setColorArray(ihalo_cl.get());
geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
geometry->setTexCoordArray(0, ihalo_tl);
geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, 4));
geode->addDrawable(geometry);
sun_transform->addChild( geode );
// set up the outer halo state
geode = new osg::Geode;
stateSet = geode->getOrCreateStateSet();
stateSet->setRenderBinDetails(-6, "RenderBin");
ohalopath.append( "outer_halo.rgba" );
ohalo_state = new ssgSimpleState();
ohalo_state->setTexture( (char *)ohalopath.c_str() );
ohalo_state->enable( GL_TEXTURE_2D );
ohalo_state->disable( GL_LIGHTING );
ohalo_state->setShadeModel( GL_SMOOTH );
ohalo_state->disable( GL_CULL_FACE );
ohalo_state->enable( GL_COLOR_MATERIAL );
ohalo_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
ohalo_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
ohalo_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
ohalo_state->enable( GL_ALPHA_TEST );
ohalo_state->setAlphaClamp(0.01);
ohalo_state->enable ( GL_BLEND ) ;
texture = SGLoadTexture2D(path);
stateSet->setTextureAttributeAndModes(0, texture);
// Build ssg structure
ohalo_cl = new osg::Vec4Array;
ohalo_cl->push_back(osg::Vec4(1, 1, 1, 1));
double ohalo_size = sun_size * 7.0;
sgVec3 ve;
ohalo_vl = new ssgVertexArray;
sgSetVec3( ve, -ohalo_size, 0.0, -ohalo_size );
ohalo_vl->add( ve );
sgSetVec3( ve, ohalo_size, 0.0, -ohalo_size );
ohalo_vl->add( ve );
sgSetVec3( ve, -ohalo_size, 0.0, ohalo_size );
ohalo_vl->add( ve );
sgSetVec3( ve, ohalo_size, 0.0, ohalo_size );
ohalo_vl->add( ve );
osg::Vec3Array* ohalo_vl = new osg::Vec3Array;
ohalo_vl->push_back(osg::Vec3(-ohalo_size, 0, -ohalo_size));
ohalo_vl->push_back(osg::Vec3(ohalo_size, 0, -ohalo_size));
ohalo_vl->push_back(osg::Vec3(-ohalo_size, 0, ohalo_size));
ohalo_vl->push_back(osg::Vec3(ohalo_size, 0, ohalo_size));
sgVec2 vf;
ohalo_tl = new ssgTexCoordArray;
sgSetVec2( vf, 0.0f, 0.0f );
ohalo_tl->add( vf );
sgSetVec2( vf, 1.0, 0.0 );
ohalo_tl->add( vf );
sgSetVec2( vf, 0.0, 1.0 );
ohalo_tl->add( vf );
sgSetVec2( vf, 1.0, 1.0 );
ohalo_tl->add( vf );
osg::Vec2Array* ohalo_tl = new osg::Vec2Array;
ohalo_tl->push_back(osg::Vec2(0, 0));
ohalo_tl->push_back(osg::Vec2(1, 0));
ohalo_tl->push_back(osg::Vec2(0, 1));
ohalo_tl->push_back(osg::Vec2(1, 1));
ssgLeaf *ohalo =
new ssgVtxTable ( GL_TRIANGLE_STRIP, ohalo_vl, NULL, ohalo_tl, ohalo_cl );
ohalo->setState( ohalo_state );
geometry = new osg::Geometry;
geometry->setUseDisplayList(false);
geometry->setVertexArray(ihalo_vl);
geometry->setColorArray(ihalo_cl.get());
geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
geometry->setTexCoordArray(0, ihalo_tl);
geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, 4));
geode->addDrawable(geometry);
sun_transform->addChild( geode );
// build the ssg scene graph sub tree for the sky and connected
// into the provide scene graph branch
sun_transform = new ssgTransform;
// force a repaint of the sun colors with arbitrary defaults
repaint( 0.0, 1.0 );
ihalo->setCallback( SSG_CALLBACK_PREDRAW, sgSunHaloPreDraw );
ihalo->setCallback( SSG_CALLBACK_POSTDRAW, sgSunHaloPostDraw );
ohalo->setCallback( SSG_CALLBACK_PREDRAW, sgSunHaloPreDraw );
ohalo->setCallback( SSG_CALLBACK_POSTDRAW, sgSunHaloPostDraw );
sun_transform->addKid( ohalo );
sun_transform->addKid( ihalo );
sun_transform->addKid( sun );
#ifdef FG_TEST_CHEESY_LENS_FLARE
// cheesy lens flair
sun_transform->addKid( new ssgaLensFlare );
#endif
return sun_transform;
return sun_transform.get();
}
@@ -460,7 +265,7 @@ bool SGSun::repaint( double sun_angle, double new_visibility ) {
}
// ok, now let's go and generate the sun color
sgVec4 i_halo_color, o_halo_color, sun_color;
osg::Vec4 i_halo_color, o_halo_color, sun_color;
// Some comments:
// When the sunangle changes, light has to travel a longer distance through the atmosphere.
@@ -536,18 +341,16 @@ bool SGSun::repaint( double sun_angle, double new_visibility ) {
else if ( o_halo_color[3] > 1) o_halo_color[3] = 1;
gamma_correct_rgb( i_halo_color );
gamma_correct_rgb( o_halo_color );
gamma_correct_rgb( sun_color );
gamma_correct_rgb( i_halo_color._v );
gamma_correct_rgb( o_halo_color._v );
gamma_correct_rgb( sun_color._v );
float *ptr;
ptr = sun_cl->get( 0 );
sgCopyVec4( ptr, sun_color );
ptr = ihalo_cl->get( 0 );
sgCopyVec4( ptr, i_halo_color );
ptr = ohalo_cl->get( 0 );
sgCopyVec4( ptr, o_halo_color );
(*sun_cl)[0] = sun_color;
sun_cl->dirty();
(*ihalo_cl)[0] = i_halo_color;
ihalo_cl->dirty();
(*ohalo_cl)[0] = o_halo_color;
ohalo_cl->dirty();
}
return true;
@@ -559,43 +362,27 @@ bool SGSun::repaint( double sun_angle, double new_visibility ) {
// fixed at a great distance from the viewer. Also add in an optional
// rotation (i.e. for the current time of day.)
// Then calculate stuff needed for the sun-coloring
bool SGSun::reposition( sgVec3 p, double angle,
bool SGSun::reposition( const SGVec3f& p, double angle,
double rightAscension, double declination,
double sun_dist, double lat, double alt_asl, double sun_angle)
{
// GST - GMT sidereal time
sgMat4 T1, T2, GST, RA, DEC;
sgVec3 axis;
sgVec3 v;
osg::Matrix T1, T2, GST, RA, DEC;
sgMakeTransMat4( T1, p );
sgSetVec3( axis, 0.0, 0.0, -1.0 );
sgMakeRotMat4( GST, angle, axis );
T1.makeTranslate(p.osg());
GST.makeRotate(SGD_DEGREES_TO_RADIANS*angle, osg::Vec3(0, 0, -1));
// xglRotatef( ((SGD_RADIANS_TO_DEGREES * rightAscension)- 90.0),
// 0.0, 0.0, 1.0);
sgSetVec3( axis, 0.0, 0.0, 1.0 );
sgMakeRotMat4( RA, (rightAscension * SGD_RADIANS_TO_DEGREES) - 90.0, axis );
RA.makeRotate(rightAscension - 90*SGD_DEGREES_TO_RADIANS, osg::Vec3(0, 0, 1));
// xglRotatef((SGD_RADIANS_TO_DEGREES * declination), 1.0, 0.0, 0.0);
sgSetVec3( axis, 1.0, 0.0, 0.0 );
sgMakeRotMat4( DEC, declination * SGD_RADIANS_TO_DEGREES, axis );
DEC.makeRotate(declination, osg::Vec3(1, 0, 0));
// xglTranslatef(0,sun_dist);
sgSetVec3( v, 0.0, sun_dist, 0.0 );
sgMakeTransMat4( T2, v );
T2.makeTranslate(osg::Vec3(0, sun_dist, 0));
sgMat4 TRANSFORM;
sgCopyMat4( TRANSFORM, T1 );
sgPreMultMat4( TRANSFORM, GST );
sgPreMultMat4( TRANSFORM, RA );
sgPreMultMat4( TRANSFORM, DEC );
sgPreMultMat4( TRANSFORM, T2 );
sgCoord skypos;
sgSetCoord( &skypos, TRANSFORM );
sun_transform->setTransform( &skypos );
sun_transform->setMatrix(T2*DEC*RA*GST*T1);
// Suncolor related things:
if ( prev_sun_angle != sun_angle ) {
@@ -631,3 +418,9 @@ bool SGSun::reposition( sgVec3 p, double angle,
return true;
}
SGVec4f
SGSun::get_color()
{
return SGVec4f((*sun_cl)[0][0], (*sun_cl)[0][1], (*sun_cl)[0][2], (*sun_cl)[0][3]);
}

View File

@@ -28,40 +28,30 @@
#ifndef _SG_SUN_HXX_
#define _SG_SUN_HXX_
#include <osg/Array>
#include <osg/Node>
#include <osg/MatrixTransform>
#include <plib/ssg.h>
#include <simgear/structure/SGReferenced.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/props/props.hxx>
class SGSun {
class SGSun : public SGReferenced {
ssgTransform *sun_transform;
ssgSimpleState *sun_state;
ssgSimpleState *ihalo_state;
ssgSimpleState *ohalo_state;
osg::ref_ptr<osg::MatrixTransform> sun_transform;
ssgColourArray *sun_cl;
ssgColourArray *ihalo_cl;
ssgColourArray *ohalo_cl;
ssgVertexArray *sun_vl;
ssgVertexArray *ihalo_vl;
ssgVertexArray *ohalo_vl;
ssgTexCoordArray *sun_tl;
ssgTexCoordArray *ihalo_tl;
ssgTexCoordArray *ohalo_tl;
GLuint sun_texid;
GLubyte *sun_texbuf;
osg::ref_ptr<osg::Vec4Array> sun_cl;
osg::ref_ptr<osg::Vec4Array> ihalo_cl;
osg::ref_ptr<osg::Vec4Array> ohalo_cl;
double visibility;
double prev_sun_angle;
// distance of light traveling through the atmosphere
double path_distance;
double sun_exp2_punch_through;
SGPropertyNode *env_node;
SGPropertyNode_ptr env_node;
public:
@@ -72,7 +62,7 @@ public:
~SGSun( void );
// return the sun object
ssgBranch *build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node );
osg::Node* build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node );
// repaint the sun colors based on current value of sun_anglein
// degrees relative to verticle
@@ -85,15 +75,12 @@ public:
// declination, offset by our current position (p) so that it
// appears fixed at a great distance from the viewer. Also add in
// an optional rotation (i.e. for the current time of day.)
bool reposition( sgVec3 p, double angle,
bool reposition( const SGVec3f& p, double angle,
double rightAscension, double declination,
double sun_dist, double lat, double alt_asl, double sun_angle );
// retrun the current color of the sun
inline float *get_color() { return ohalo_cl->get( 0 ); }
// return the texture id of the sun halo texture
inline GLuint get_texture_id() { return ohalo_state->getTextureHandle(); }
SGVec4f get_color();
};

View File

@@ -25,9 +25,6 @@
# include <simgear_config.h>
#endif
#include <plib/sg.h>
#include <plib/ssg.h>
#include <simgear/math/sg_random.h>
#include "sky.hxx"
@@ -43,18 +40,24 @@ SGSky::SGSky( void ) {
puff_progression = 0;
ramp_up = 0.15;
ramp_down = 0.15;
// ramp_up = 4.0;
// ramp_down = 4.0;
in_cloud = -1;
pre_root = new osg::Group;
post_root = new osg::Group;
cloud_root = new osg::Group;
pre_selector = new osg::Switch;
post_selector = new osg::Switch;
pre_transform = new osg::MatrixTransform;
post_transform = new osg::MatrixTransform;
}
// Destructor
SGSky::~SGSky( void )
{
for (unsigned int i = 0; i < cloud_layers.size(); i++)
delete cloud_layers[i];
}
@@ -62,41 +65,30 @@ SGSky::~SGSky( void )
// the provided branch
void SGSky::build( double h_radius_m, double v_radius_m,
double sun_size, double moon_size,
int nplanets, sgdVec3 *planet_data,
int nstars, sgdVec3 *star_data, SGPropertyNode *property_tree_node )
int nplanets, SGVec3d planet_data[7],
int nstars, SGVec3d star_data[], SGPropertyNode *property_tree_node )
{
pre_root = new ssgRoot;
post_root = new ssgRoot;
pre_selector = new ssgSelector;
post_selector = new ssgSelector;
pre_transform = new ssgTransform;
post_transform = new ssgTransform;
dome = new SGSkyDome;
pre_transform -> addKid( dome->build( h_radius_m, v_radius_m ) );
pre_transform->addChild( dome->build( h_radius_m, v_radius_m ) );
planets = new SGStars;
pre_transform -> addKid(planets->build(nplanets, planet_data, h_radius_m));
pre_transform->addChild(planets->build(nplanets, planet_data, h_radius_m));
stars = new SGStars;
pre_transform -> addKid( stars->build(nstars, star_data, h_radius_m) );
pre_transform->addChild( stars->build(nstars, star_data, h_radius_m) );
moon = new SGMoon;
pre_transform -> addKid( moon->build(tex_path, moon_size) );
pre_transform->addChild( moon->build(tex_path, moon_size) );
oursun = new SGSun;
pre_transform -> addKid( oursun->build(tex_path, sun_size, property_tree_node ) );
pre_transform->addChild( oursun->build(tex_path, sun_size, property_tree_node ) );
pre_selector->addKid( pre_transform );
pre_selector->clrTraversalMaskBits( SSGTRAV_HOT );
pre_selector->addChild( pre_transform.get() );
post_selector->addKid( post_transform );
post_selector->clrTraversalMaskBits( SSGTRAV_HOT );
post_selector->addChild( post_transform.get() );
pre_root->addKid( pre_selector );
post_root->addKid( post_selector );
pre_root->addChild( pre_selector.get() );
post_root->addChild( post_selector.get() );
}
@@ -119,7 +111,7 @@ bool SGSky::repaint( const SGSkyColor &sc )
oursun->repaint( sc.sun_angle, effective_visibility );
moon->repaint( sc.moon_angle );
for ( int i = 0; i < (int)cloud_layers.size(); ++i ) {
for ( unsigned i = 0; i < cloud_layers.size(); ++i ) {
if (cloud_layers[i]->getCoverage() != SGCloudLayer::SG_CLOUD_CLEAR){
cloud_layers[i]->repaint( sc.cloud_color );
}
@@ -145,7 +137,7 @@ bool SGSky::reposition( SGSkyState &st, double dt )
double angle = st.gst * 15; // degrees
dome->reposition( st.zero_elev, st.lon, st.lat, st.spin );
dome->reposition( st.zero_elev, st.alt, st.lon, st.lat, st.spin );
stars->reposition( st.view_pos, angle );
planets->reposition( st.view_pos, angle );
@@ -156,87 +148,22 @@ bool SGSky::reposition( SGSkyState &st, double dt )
moon->reposition( st.view_pos, angle,
st.moon_ra, st.moon_dec, st.moon_dist );
for ( int i = 0; i < (int)cloud_layers.size(); ++i ) {
for ( unsigned i = 0; i < cloud_layers.size(); ++i ) {
if ( cloud_layers[i]->getCoverage() != SGCloudLayer::SG_CLOUD_CLEAR ) {
cloud_layers[i]->reposition( st.zero_elev, st.view_up,
st.lon, st.lat, st.alt, dt );
}
} else
cloud_layers[i]->getNode()->setAllChildrenOff();
}
return true;
}
// draw background portions of the sky ... do this before you draw the
// rest of your scene.
void SGSky::preDraw( float alt, float fog_exp2_density ) {
ssgCullAndDraw( pre_root );
// if we are closer than this to a cloud layer, don't draw clouds
static const float slop = 5.0;
int i;
// check where we are relative to the cloud layers
in_cloud = -1;
for ( i = 0; i < (int)cloud_layers.size(); ++i ) {
float asl = cloud_layers[i]->getElevation_m();
float thickness = cloud_layers[i]->getThickness_m();
if ( alt < asl - slop ) {
// below cloud layer
} else if ( alt < asl + thickness + slop ) {
// in cloud layer
// bail now and don't draw any clouds
if( cloud_layers[i]->get_layer3D()->is3D() && SGCloudField::enable3D )
continue;
in_cloud = i;
} else {
// above cloud layer
}
}
// determine rendering order
cur_layer_pos = 0;
while ( cur_layer_pos < (int)cloud_layers.size() &&
alt > cloud_layers[cur_layer_pos]->getElevation_m() )
{
++cur_layer_pos;
}
// FIXME: This should not be needed, but at this time (08/15/2003)
// certain NVidia drivers don't seem to implement
// glPushAttrib(FG_FOG_BIT) properly. The result is that
// there is not fog when looking at the sun.
glFogf ( GL_FOG_DENSITY, fog_exp2_density );
}
void SGSky::drawUpperClouds( ) {
// draw the cloud layers that are above us, top to bottom
for ( int i = (int)cloud_layers.size() - 1; i >= cur_layer_pos; --i ) {
if ( i != in_cloud ) {
cloud_layers[i]->draw( false );
}
}
}
// draw translucent clouds ... do this after you've drawn all the
// oapaque elements of your scene.
void SGSky::drawLowerClouds() {
// draw the cloud layers that are below us, bottom to top
for ( int i = 0; i < cur_layer_pos; ++i ) {
if ( i != in_cloud ) {
cloud_layers[i]->draw( true );
}
}
}
void
SGSky::add_cloud_layer( SGCloudLayer * layer )
{
cloud_layers.push_back(layer);
cloud_root->addChild(layer->getNode());
}
const SGCloudLayer *

View File

@@ -33,15 +33,17 @@
# error This library requires C++
#endif
#include <plib/ssg.h> // plib include
#include <simgear/compiler.h>
#include <simgear/misc/sg_path.hxx>
#include <simgear/props/props.hxx>
#include <vector>
#include <osg/ref_ptr>
#include <osg/MatrixTransform>
#include <osg/Node>
#include <osg/Switch>
#include <simgear/scene/sky/cloud.hxx>
#include <simgear/scene/sky/dome.hxx>
#include <simgear/scene/sky/moon.hxx>
@@ -51,12 +53,8 @@
SG_USING_STD(vector);
typedef vector < SGCloudLayer* > layer_list_type;
typedef layer_list_type::iterator layer_list_iterator;
typedef layer_list_type::const_iterator layer_list_const_iterator;
typedef struct {
float *view_pos, *zero_elev, *view_up;
SGVec3f view_pos, zero_elev, view_up;
double lon, lat, alt, spin;
double gst;
double sun_ra, sun_dec, sun_dist;
@@ -65,10 +63,12 @@ typedef struct {
} SGSkyState;
typedef struct {
float *sky_color, *fog_color, *cloud_color;
SGVec3f sky_color, fog_color;
SGVec3f cloud_color;
double sun_angle, moon_angle;
int nplanets, nstars;
sgdVec3 *planet_data, *star_data;
SGVec3d *planet_data;
SGVec3d *star_data;
} SGSkyColor;
/**
@@ -205,19 +205,21 @@ typedef struct {
class SGSky {
private:
typedef std::vector<SGSharedPtr<SGCloudLayer> > layer_list_type;
typedef layer_list_type::iterator layer_list_iterator;
typedef layer_list_type::const_iterator layer_list_const_iterator;
// components of the sky
SGSkyDome *dome;
SGSun *oursun;
SGMoon *moon;
SGStars *planets;
SGStars *stars;
SGSharedPtr<SGSkyDome> dome;
SGSharedPtr<SGSun> oursun;
SGSharedPtr<SGMoon> moon;
SGSharedPtr<SGStars> planets;
SGSharedPtr<SGStars> stars;
layer_list_type cloud_layers;
ssgRoot *pre_root, *post_root;
ssgSelector *pre_selector, *post_selector;
ssgTransform *pre_transform, *post_transform;
osg::ref_ptr<osg::Group> pre_root, post_root, cloud_root;
osg::ref_ptr<osg::Switch> pre_selector, post_selector;
osg::ref_ptr<osg::MatrixTransform> pre_transform, post_transform;
SGPath tex_path;
@@ -260,8 +262,8 @@ public:
*/
void build( double h_radius_m, double v_radius_m,
double sun_size, double moon_size,
int nplanets, sgdVec3 *planet_data,
int nstars, sgdVec3 *star_data, SGPropertyNode *property_tree_node );
int nplanets, SGVec3d planet_data[7],
int nstars, SGVec3d star_data[], SGPropertyNode *property_tree_node );
/**
* Repaint the sky components based on current value of sun_angle,
@@ -329,28 +331,9 @@ public:
*/
void modify_vis( float alt, float time_factor );
/**
* Draw background portions of the sky ... do this before you draw
* the rest of your scene. See discussion in detailed
* class description.
* @param alt current altitude
*/
void preDraw( float alt, float fog_exp2_density );
/**
* Draw upper translucent clouds ... do this before you've drawn
* all the translucent elements of your scene. See discussion in
* detailed class description.
* @param fog_exp2_density fog density of the current cloud layer
*/
void drawUpperClouds();
/**
* Draw lower translucent clouds ... do this after you've drawn
* all the opaque elements of your scene. See discussion in detailed
* class description.
*/
void drawLowerClouds();
osg::Node* getPreRoot() { return pre_root.get(); }
osg::Node* getPostRoot() { return post_root.get(); }
osg::Node* getCloudRoot() { return cloud_root.get(); }
/**
* Specify the texture path (optional, defaults to current directory)
@@ -362,8 +345,8 @@ public:
/** Enable drawing of the sky. */
inline void enable() {
pre_selector->select( 1 );
post_selector->select( 1 );
pre_selector->setValue(0, 1);
post_selector->setValue(0, 1);
}
/**
@@ -371,21 +354,14 @@ public:
* there, how ever it won't be traversed on by ssgCullandRender()
*/
inline void disable() {
pre_selector->select( 0 );
post_selector->select( 0 );
pre_selector->setValue(0, 0);
post_selector->setValue(0, 0);
}
/**
* Get the current sun color
*/
inline float *get_sun_color() { return oursun->get_color(); }
/**
* Get the sun halo texture handle
*/
inline GLuint get_sun_texture_id() { return oursun->get_texture_id(); }
inline SGVec4f get_sun_color() { return oursun->get_color(); }
/**
* Add a cloud layer.

View File

@@ -28,23 +28,21 @@
#include STL_IOSTREAM
#include <plib/sg.h>
#include <plib/ssg.h>
#include <osg/Node>
#include <osg/Geometry>
#include <osg/Geode>
#include <osg/Array>
// return a sphere object as an ssgBranch
ssgBranch *ssgMakeSphere( ssgSimpleState *state, ssgColourArray *cl,
double radius, int slices, int stacks,
ssgCallback predraw, ssgCallback postdraw )
osg::Node*
SGMakeSphere(double radius, int slices, int stacks)
{
float rho, drho, theta, dtheta;
float x, y, z;
float rho, drho, dtheta;
float s, t, ds, dt;
int i, j, imin, imax;
float nsign = 1.0;
ssgBranch *sphere = new ssgBranch;
sgVec2 vec2;
sgVec3 vec3;
osg::Geode* geode = new osg::Geode;
drho = SGD_PI / (float) stacks;
dtheta = SGD_2PI / (float) slices;
@@ -62,69 +60,67 @@ ssgBranch *ssgMakeSphere( ssgSimpleState *state, ssgColourArray *cl,
/* build slices as quad strips */
for ( i = imin; i < imax; i++ ) {
ssgVertexArray *vl = new ssgVertexArray();
ssgNormalArray *nl = new ssgNormalArray();
ssgTexCoordArray *tl = new ssgTexCoordArray();
osg::Geometry* geometry = new osg::Geometry;
osg::Vec3Array* vl = new osg::Vec3Array;
osg::Vec3Array* nl = new osg::Vec3Array;
osg::Vec2Array* tl = new osg::Vec2Array;
rho = i * drho;
s = 0.0;
for ( j = 0; j <= slices; j++ ) {
theta = (j == slices) ? 0.0 : j * dtheta;
x = -sin(theta) * sin(rho);
y = cos(theta) * sin(rho);
z = nsign * cos(rho);
double theta = (j == slices) ? 0.0 : j * dtheta;
double x = -sin(theta) * sin(rho);
double y = cos(theta) * sin(rho);
double z = nsign * cos(rho);
// glNormal3f( x*nsign, y*nsign, z*nsign );
sgSetVec3( vec3, x*nsign, y*nsign, z*nsign );
sgNormalizeVec3( vec3 );
nl->add( vec3 );
osg::Vec3 normal(x*nsign, y*nsign, z*nsign);
normal.normalize();
nl->push_back(normal);
// glTexCoord2f(s,t);
sgSetVec2( vec2, s, t );
tl->add( vec2 );
tl->push_back(osg::Vec2(s, t));
// glVertex3f( x*radius, y*radius, z*radius );
sgSetVec3( vec3, x*radius, y*radius, z*radius );
vl->add( vec3 );
vl->push_back(osg::Vec3(x*radius, y*radius, z*radius));
x = -sin(theta) * sin(rho+drho);
y = cos(theta) * sin(rho+drho);
z = nsign * cos(rho+drho);
// glNormal3f( x*nsign, y*nsign, z*nsign );
sgSetVec3( vec3, x*nsign, y*nsign, z*nsign );
sgNormalizeVec3( vec3 );
nl->add( vec3 );
normal = osg::Vec3(x*nsign, y*nsign, z*nsign);
normal.normalize();
nl->push_back(normal);
// glTexCoord2f(s,t-dt);
sgSetVec2( vec2, s, t-dt );
tl->add( vec2 );
tl->push_back(osg::Vec2(s, t-dt));
s += ds;
// glVertex3f( x*radius, y*radius, z*radius );
sgSetVec3( vec3, x*radius, y*radius, z*radius );
vl->add( vec3 );
vl->push_back(osg::Vec3(x*radius, y*radius, z*radius));
}
ssgLeaf *slice =
new ssgVtxTable ( GL_TRIANGLE_STRIP, vl, nl, tl, cl );
if ( vl->getNum() != nl->getNum() ) {
if ( vl->size() != nl->size() ) {
SG_LOG( SG_EVENT, SG_ALERT, "bad sphere1");
exit(-1);
}
if ( vl->getNum() != tl->getNum() ) {
if ( vl->size() != tl->size() ) {
SG_LOG( SG_EVENT, SG_ALERT, "bad sphere2");
exit(-1);
}
slice->setState( state );
slice->setCallback( SSG_CALLBACK_PREDRAW, predraw );
slice->setCallback( SSG_CALLBACK_POSTDRAW, postdraw );
sphere->addKid( slice );
geometry->setUseDisplayList(false);
geometry->setVertexArray(vl);
geometry->setNormalArray(nl);
geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
geometry->setTexCoordArray(0, tl);
geometry->setColorBinding(osg::Geometry::BIND_OFF);
geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, vl->size()));
geode->addDrawable(geometry);
t -= dt;
}
return sphere;
return geode;
}

View File

@@ -22,13 +22,10 @@
// $Id$
#include <plib/ssg.h>
#include <osg/Node>
// return a sphere object as an ssgBranch (and connect in the
// specified ssgSimpleState
ssgBranch *ssgMakeSphere( ssgSimpleState *state, ssgColourArray *cl,
double radius, int slices, int stacks,
ssgCallback predraw, ssgCallback postdraw );
osg::Node* SGMakeSphere(double radius, int slices, int stacks);

View File

@@ -31,39 +31,17 @@
#include <stdio.h>
#include STL_IOSTREAM
#include <plib/sg.h>
#include <plib/ssg.h>
#include <osg/AlphaFunc>
#include <osg/BlendFunc>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Image>
#include <osg/Material>
#include <osg/Point>
#include <osg/ShadeModel>
#include "stars.hxx"
// Set up star rendering call backs
static int sgStarPreDraw( ssgEntity *e ) {
/* cout << endl << "Star pre draw" << endl << "----------------"
<< endl << endl; */
ssgLeaf *f = (ssgLeaf *)e;
if ( f -> hasState () ) f->getState()->apply() ;
glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_FOG_BIT | GL_COLOR_BUFFER_BIT );
glDisable( GL_DEPTH_TEST );
glDisable( GL_FOG );
// glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
return true;
}
static int sgStarPostDraw( ssgEntity *e ) {
/* cout << endl << "Star post draw" << endl << "----------------"
<< endl << endl; */
glPopAttrib();
return true;
}
// Constructor
SGStars::SGStars( void ) :
old_phase(-1)
@@ -77,64 +55,76 @@ SGStars::~SGStars( void ) {
// initialize the stars object and connect it into our scene graph root
ssgBranch * SGStars::build( int num, sgdVec3 *star_data, double star_dist ) {
sgVec4 color;
if ( star_data == NULL )
SG_LOG( SG_EVENT, SG_WARN, "null star data passed to SGStars::build()");
// set up the orb state
state = new ssgSimpleState();
state->disable( GL_LIGHTING );
state->disable( GL_CULL_FACE );
state->disable( GL_TEXTURE_2D );
state->enable( GL_COLOR_MATERIAL );
state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
state->enable( GL_BLEND );
state->disable( GL_ALPHA_TEST );
vl = new ssgVertexArray( num );
cl = new ssgColourArray( num );
// cl = new ssgColourArray( 1 );
// sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
// cl->add( color );
// Build ssg structure
sgVec3 p;
for ( int i = 0; i < num; ++i ) {
// position seeded to arbitrary values
sgSetVec3( p,
star_dist * cos( star_data[i][0] )
* cos( star_data[i][1] ),
star_dist * sin( star_data[i][0] )
* cos( star_data[i][1] ),
star_dist * sin( star_data[i][1] )
);
vl->add( p );
// color (magnitude)
sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
cl->add( color );
}
ssgLeaf *stars_obj =
new ssgVtxTable ( GL_POINTS, vl, NULL, NULL, cl );
stars_obj->setState( state );
stars_obj->setCallback( SSG_CALLBACK_PREDRAW, sgStarPreDraw );
stars_obj->setCallback( SSG_CALLBACK_POSTDRAW, sgStarPostDraw );
osg::Node*
SGStars::build( int num, const SGVec3d star_data[], double star_dist ) {
// build the ssg scene graph sub tree for the sky and connected
// into the provide scene graph branch
stars_transform = new ssgTransform;
stars_transform = new osg::MatrixTransform;
stars_transform->addKid( stars_obj );
osg::Geode* geode = new osg::Geode;
osg::StateSet* stateSet = geode->getOrCreateStateSet();
stateSet->setRenderBinDetails(-9, "RenderBin");
SG_LOG( SG_EVENT, SG_INFO, "stars = " << stars_transform);
// set up the star state
return stars_transform;
// Ok, the old implementation did have a color material set.
// But with lighting off, I don't see how this should change the result
osg::Material* material = new osg::Material;
// material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
// material->setEmission(osg::Material::FRONT_AND_BACK,
// osg::Vec4(0, 0, 0, 1));
// material->setSpecular(osg::Material::FRONT_AND_BACK,
// osg::Vec4(0, 0, 0, 1));
stateSet->setAttribute(material);
// stateSet->setMode(GL_COLOR_MATERIAL, osg::StateAttribute::OFF);
osg::BlendFunc* blendFunc = new osg::BlendFunc;
blendFunc->setFunction(osg::BlendFunc::SRC_ALPHA,
osg::BlendFunc::ONE_MINUS_SRC_ALPHA);
stateSet->setAttributeAndModes(blendFunc);
// osg::Point* point = new osg::Point;
// point->setSize(5);
// stateSet->setAttributeAndModes(point);
stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::OFF);
// Build scenegraph structure
cl = new osg::Vec4Array;
osg::Vec3Array* vl = new osg::Vec3Array;
// Build scenegraph structure
for ( int i = 0; i < num; ++i ) {
// position seeded to arbitrary values
vl->push_back(osg::Vec3(star_dist * cos( star_data[i][0])
* cos( star_data[i][1] ),
star_dist * sin( star_data[i][0])
* cos( star_data[i][1] ),
star_dist * sin( star_data[i][1])));
// color (magnitude)
cl->push_back(osg::Vec4(1, 1, 1, 1));
}
osg::Geometry* geometry = new osg::Geometry;
geometry->setUseDisplayList(false);
geometry->setVertexArray(vl);
geometry->setColorArray(cl.get());
geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
geometry->setNormalBinding(osg::Geometry::BIND_OFF);
geometry->addPrimitiveSet(new osg::DrawArrays(GL_POINTS, 0, vl->size()));
geode->addDrawable(geometry);
stars_transform->addChild(geode);
SG_LOG( SG_EVENT, SG_INFO, "stars = " << stars_transform.get());
return stars_transform.get();
}
@@ -143,12 +133,11 @@ ssgBranch * SGStars::build( int num, sgdVec3 *star_data, double star_dist ) {
// 0 degrees = high noon
// 90 degrees = sun rise/set
// 180 degrees = darkest midnight
bool SGStars::repaint( double sun_angle, int num, sgdVec3 *star_data ) {
bool SGStars::repaint( double sun_angle, int num, const SGVec3d star_data[] ) {
// cout << "repainting stars" << endl;
// double min = 100;
// double max = -100;
double mag, nmag, alpha, factor, cutoff;
float *color;
int phase;
@@ -217,10 +206,10 @@ bool SGStars::repaint( double sun_angle, int num, sgdVec3 *star_data ) {
if (alpha > 1.0) { alpha = 1.0; }
if (alpha < 0.0) { alpha = 0.0; }
color = cl->get( i );
sgSetVec4( color, 1.0, 1.0, 1.0, alpha );
(*cl)[i] = osg::Vec4(1, 1, 1, alpha);
// cout << "alpha[" << i << "] = " << alpha << endl;
}
cl->dirty();
} else {
// cout << " no phase change, skipping" << endl;
}
@@ -235,24 +224,15 @@ bool SGStars::repaint( double sun_angle, int num, sgdVec3 *star_data ) {
// reposition the stars for the specified time (GST rotation),
// offset by our current position (p) so that it appears fixed at a
// great distance from the viewer.
bool SGStars::reposition( sgVec3 p, double angle )
bool
SGStars::reposition( const SGVec3f& p, double angle )
{
sgMat4 T1, GST;
sgVec3 axis;
osg::Matrix T1, GST;
T1.makeTranslate(p.osg());
sgMakeTransMat4( T1, p );
GST.makeRotate(angle*SGD_DEGREES_TO_RADIANS, osg::Vec3(0, 0, -1));
sgSetVec3( axis, 0.0, 0.0, -1.0 );
sgMakeRotMat4( GST, angle, axis );
sgMat4 TRANSFORM;
sgCopyMat4( TRANSFORM, T1 );
sgPreMultMat4( TRANSFORM, GST );
sgCoord skypos;
sgSetCoord( &skypos, TRANSFORM );
stars_transform->setTransform( &skypos );
stars_transform->setMatrix(GST*T1);
return true;
}

View File

@@ -29,16 +29,18 @@
#define _SG_STARS_HXX_
#include <plib/ssg.h>
#include <osg/Array>
#include <osg/Node>
#include <osg/MatrixTransform>
#include <simgear/math/SGMath.hxx>
#include <simgear/structure/SGReferenced.hxx>
class SGStars {
class SGStars : public SGReferenced {
ssgTransform *stars_transform;
ssgSimpleState *state;
ssgColourArray *cl;
ssgVertexArray *vl;
osg::ref_ptr<osg::MatrixTransform> stars_transform;
osg::ref_ptr<osg::Vec4Array> cl;
int old_phase; // data for optimization
@@ -51,7 +53,7 @@ public:
~SGStars( void );
// initialize the stars structure
ssgBranch *build( int num, sgdVec3 *star_data, double star_dist );
osg::Node* build( int num, const SGVec3d star_data[], double star_dist );
// repaint the planet magnitudes based on current value of
// sun_angle in degrees relative to verticle (so we can make them
@@ -59,12 +61,12 @@ public:
// 0 degrees = high noon
// 90 degrees = sun rise/set
// 180 degrees = darkest midnight
bool repaint( double sun_angle, int num, sgdVec3 *star_data );
bool repaint( double sun_angle, int num, const SGVec3d star_data[] );
// reposition the stars for the specified time (GST rotation),
// offset by our current position (p) so that it appears fixed at
// a great distance from the viewer.
bool reposition( sgVec3 p, double angle );
bool reposition( const SGVec3f& p, double angle );
};

View File

@@ -26,6 +26,11 @@
#include <vector>
#include <osg/StateSet>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Group>
#include <simgear/debug/logstream.hxx>
#include <simgear/math/sg_types.hxx>
#include <simgear/scene/tgdb/leaf.hxx>
@@ -41,14 +46,14 @@ SG_USING_STD(vector);
// for temporary storage of sign elements
struct element_info {
element_info(SGMaterial *m, ssgSimpleState *s, SGMaterialGlyph *g, double h)
element_info(SGMaterial *m, osg::StateSet *s, SGMaterialGlyph *g, double h)
: material(m), state(s), glyph(g), height(h)
{
scale = h * m->get_xsize()
/ (m->get_ysize() < 0.001 ? 1.0 : m->get_ysize());
}
SGMaterial *material;
ssgSimpleState *state;
osg::StateSet *state;
SGMaterialGlyph *glyph;
double height;
double scale;
@@ -82,7 +87,8 @@ struct pair {
// see $FG_ROOT/Docs/README.scenery
//
ssgBranch *sgMakeSign(SGMaterialLib *matlib, const string path, const string content)
osg::Node*
SGMakeSign(SGMaterialLib *matlib, const string& path, const string& content)
{
double sign_height = 1.0; // meter
bool lighted = true;
@@ -95,12 +101,12 @@ ssgBranch *sgMakeSign(SGMaterialLib *matlib, const string path, const string con
int size = -1;
char oldtype = 0, newtype = 0;
ssgBranch *object = new ssgBranch();
object->setName((char *)content.c_str());
osg::Group* object = new osg::Group;
object->setName(content);
SGMaterial *material;
ssgSimpleState *lighted_state;
ssgSimpleState *unlighted_state;
osg::StateSet *lighted_state;
osg::StateSet *unlighted_state;
// Part I: parse & measure
for (const char *s = content.data(); *s; s++) {
@@ -239,7 +245,7 @@ ssgBranch *sgMakeSign(SGMaterialLib *matlib, const string path, const string con
}
// in managed mode push frame stop and frame start first
ssgSimpleState *state = lighted ? lighted_state : unlighted_state;
osg::StateSet *state = lighted ? lighted_state : unlighted_state;
element_info *e;
if (newtype && newtype != oldtype) {
if (close) {
@@ -276,12 +282,6 @@ ssgBranch *sgMakeSign(SGMaterialLib *matlib, const string path, const string con
double hpos = -total_width / 2;
const double dist = 0.25; // hard-code distance from surface for now
sgVec3 normal;
sgSetVec3(normal, 0, -1, 0);
sgVec4 color;
sgSetVec4(color, 1.0, 1.0, 1.0, 1.0);
for (unsigned int i = 0; i < elements.size(); i++) {
element_info *element = elements[i];
@@ -291,51 +291,67 @@ ssgBranch *sgMakeSign(SGMaterialLib *matlib, const string path, const string con
double abswidth = width * element->scale;
// vertices
ssgVertexArray *vl = new ssgVertexArray(4);
vl->add(0, hpos, dist);
vl->add(0, hpos + abswidth, dist);
vl->add(0, hpos, dist + height);
vl->add(0, hpos + abswidth, dist + height);
osg::Vec3Array* vl = new osg::Vec3Array;
vl->push_back(osg::Vec3(0, hpos, dist));
vl->push_back(osg::Vec3(0, hpos + abswidth, dist));
vl->push_back(osg::Vec3(0, hpos, dist + height));
vl->push_back(osg::Vec3(0, hpos + abswidth, dist + height));
// texture coordinates
ssgTexCoordArray *tl = new ssgTexCoordArray(4);
tl->add(xoffset, 0);
tl->add(xoffset + width, 0);
tl->add(xoffset, 1);
tl->add(xoffset + width, 1);
osg::Vec2Array* tl = new osg::Vec2Array;
tl->push_back(osg::Vec2(xoffset, 0));
tl->push_back(osg::Vec2(xoffset + width, 0));
tl->push_back(osg::Vec2(xoffset, 1));
tl->push_back(osg::Vec2(xoffset + width, 1));
// normals
ssgNormalArray *nl = new ssgNormalArray(1);
nl->add(normal);
osg::Vec3Array* nl = new osg::Vec3Array;
nl->push_back(osg::Vec3(0, -1, 0));
// colors
ssgColourArray *cl = new ssgColourArray(1);
cl->add(color);
osg::Vec4Array* cl = new osg::Vec4Array;
cl->push_back(osg::Vec4(1, 1, 1, 1));
ssgLeaf *leaf = new ssgVtxTable(GL_TRIANGLE_STRIP, vl, nl, tl, cl);
leaf->setState(element->state);
osg::Geometry* geometry = new osg::Geometry;
// geometry->setUseDisplayList(false);
geometry->setVertexArray(vl);
geometry->setNormalArray(nl);
geometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
geometry->setColorArray(cl);
geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
geometry->setTexCoordArray(0, tl);
geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, vl->size()));
osg::Geode* geode = new osg::Geode;
geode->addDrawable(geometry);
geode->setStateSet(element->state);
object->addKid(leaf);
object->addChild(geode);
hpos += abswidth;
delete element;
}
// minimalistic backside
ssgVertexArray *vl = new ssgVertexArray(4);
vl->add(0, hpos, dist);
vl->add(0, hpos - total_width, dist);
vl->add(0, hpos, dist + sign_height);
vl->add(0, hpos - total_width, dist + sign_height);
osg::Vec3Array* vl = new osg::Vec3Array;
vl->push_back(osg::Vec3(0, hpos, dist));
vl->push_back(osg::Vec3(0, hpos - total_width, dist));
vl->push_back(osg::Vec3(0, hpos, dist + sign_height));
vl->push_back(osg::Vec3(0, hpos - total_width, dist + sign_height));
ssgNormalArray *nl = new ssgNormalArray(1);
nl->add(0, 1, 0);
osg::Vec3Array* nl = new osg::Vec3Array;
nl->push_back(osg::Vec3(0, 1, 0));
ssgLeaf *leaf = new ssgVtxTable(GL_TRIANGLE_STRIP, vl, nl, 0, 0);
osg::Geometry* geometry = new osg::Geometry;
geometry->setVertexArray(vl);
geometry->setNormalArray(nl);
geometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, vl->size()));
osg::Geode* geode = new osg::Geode;
geode->addDrawable(geometry);
SGMaterial *mat = matlib->find("BlackSign");
if (mat)
leaf->setState(mat->get_state());
object->addKid(leaf);
geode->setStateSet(mat->get_state());
object->addChild(geode);
return object;
}
@@ -344,14 +360,14 @@ ssgBranch *sgMakeSign(SGMaterialLib *matlib, const string path, const string con
ssgBranch *sgMakeRunwaySign( SGMaterialLib *matlib,
const string path, const string name )
osg::Node*
SGMakeRunwaySign(SGMaterialLib *matlib, const string& path, const string& name)
{
// for demo purposes we assume each element (letter) is 1x1 meter.
// Sign is placed 0.25 meters above the ground
ssgBranch *object = new ssgBranch();
object->setName( (char *)name.c_str() );
osg::Group *object = new osg::Group;
object->setName(name);
double width = name.length() / 3.0;
@@ -391,12 +407,12 @@ ssgBranch *sgMakeRunwaySign( SGMaterialLib *matlib,
tex_index.push_back( 2 );
tex_index.push_back( 3 );
ssgLeaf *leaf = sgMakeLeaf( path, GL_TRIANGLE_STRIP, matlib, material,
nodes, normals, texcoords,
vertex_index, normal_index, tex_index,
false, NULL );
osg::Node* leaf = SGMakeLeaf( path, GL_TRIANGLE_STRIP, matlib, material,
nodes, normals, texcoords,
vertex_index, normal_index, tex_index,
false, NULL );
object->addKid( leaf );
object->addChild(leaf);
return object;
}

View File

@@ -34,7 +34,7 @@
#include STL_STRING
#include <plib/ssg.h> // plib include
#include <osg/Node>
class SGMaterialLib; // forward declaration
@@ -42,13 +42,13 @@ SG_USING_STD(string);
// Generate a generic sign
ssgBranch *sgMakeSign( SGMaterialLib *matlib,
const string path, const string content );
osg::Node* SGMakeSign( SGMaterialLib *matlib,
const string& path, const string& content );
// Generate a runway sign
ssgBranch *sgMakeRunwaySign( SGMaterialLib *matlib,
const string path, const string name );
osg::Node* SGMakeRunwaySign( SGMaterialLib *matlib,
const string& path, const string& name );
#endif // _SG_APT_SIGNS_HXX

View File

@@ -33,10 +33,17 @@
#include STL_STRING
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Group>
#include <osg/StateSet>
#include <osg/TriangleFunctor>
#include <simgear/debug/logstream.hxx>
#include <simgear/math/sg_random.h>
#include <simgear/scene/material/mat.hxx>
#include <simgear/scene/material/matlib.hxx>
// #include <simgear/scene/util/SGDebugDrawCallback.hxx>
#include "leaf.hxx"
@@ -49,8 +56,9 @@ typedef int_list::iterator int_list_iterator;
typedef int_list::const_iterator int_point_list_iterator;
static void random_pt_inside_tri( float *res,
float *n1, float *n2, float *n3 )
static inline
osg::Vec3 random_pt_inside_tri(const osg::Vec3& n1, const osg::Vec3& n2,
const osg::Vec3& n3 )
{
double a = sg_random();
double b = sg_random();
@@ -60,60 +68,45 @@ static void random_pt_inside_tri( float *res,
}
double c = 1 - a - b;
res[0] = n1[0]*a + n2[0]*b + n3[0]*c;
res[1] = n1[1]*a + n2[1]*b + n3[1]*c;
res[2] = n1[2]*a + n2[2]*b + n3[2]*c;
return n1*a + n2*b + n3*c;
}
/// class to implement the TrinagleFunctor class
struct SGRandomSurfacePointsFill {
osg::Vec3Array* lights;
float factor;
void sgGenRandomSurfacePoints( ssgLeaf *leaf, double factor,
ssgVertexArray *lights )
{
int tris = leaf->getNumTriangles();
if ( tris > 0 ) {
short int n1, n2, n3;
float *p1, *p2, *p3;
sgVec3 result;
// generate a repeatable random seed
p1 = leaf->getVertex( 0 );
unsigned int seed = (unsigned int)(fabs(p1[0]*100));
sg_srandom( seed );
for ( int i = 0; i < tris; ++i ) {
leaf->getTriangle( i, &n1, &n2, &n3 );
p1 = leaf->getVertex(n1);
p2 = leaf->getVertex(n2);
p3 = leaf->getVertex(n3);
double area = sgTriArea( p1, p2, p3 );
double num = area / factor;
// generate a light point for each unit of area
while ( num > 1.0 ) {
random_pt_inside_tri( result, p1, p2, p3 );
lights->add( result );
num -= 1.0;
}
// for partial units of area, use a zombie door method to
// create the proper random chance of a light being created
// for this triangle
if ( num > 0.0 ) {
if ( sg_random() <= num ) {
// a zombie made it through our door
random_pt_inside_tri( result, p1, p2, p3 );
lights->add( result );
}
}
}
void operator () (const osg::Vec3& v1, const osg::Vec3& v2,
const osg::Vec3& v3, bool)
{
// Compute the area
float area = 0.5*((v1 - v2)^(v3 - v2)).length();
float num = area / factor;
// generate a light point for each unit of area
while ( num > 1.0 ) {
lights->push_back(random_pt_inside_tri( v1, v2, v3 ));
num -= 1.0;
}
}
// for partial units of area, use a zombie door method to
// create the proper random chance of a light being created
// for this triangle
if ( num > 0.0 ) {
if ( sg_random() <= num ) {
// a zombie made it through our door
lights->push_back(random_pt_inside_tri( v1, v2, v3 ));
}
}
}
};
ssgVertexArray *sgGenRandomSurfacePoints( ssgLeaf *leaf, double factor ) {
ssgVertexArray *result = new ssgVertexArray();
sgGenRandomSurfacePoints( leaf, factor, result );
return result;
static void SGGenRandomSurfacePoints( osg::Geometry *leaf, double factor,
osg::Vec3Array *lights )
{
osg::TriangleFunctor<SGRandomSurfacePointsFill> triangleFunctor;
triangleFunctor.lights = lights;
triangleFunctor.factor = factor;
leaf->accept(triangleFunctor);
}
@@ -121,7 +114,7 @@ ssgVertexArray *sgGenRandomSurfacePoints( ssgLeaf *leaf, double factor ) {
// Scenery loaders.
////////////////////////////////////////////////////////////////////////
ssgLeaf *sgMakeLeaf( const string& path,
osg::Node* SGMakeLeaf( const string& path,
const GLenum ty,
SGMaterialLib *matlib, const string& material,
const point_list& nodes, const point_list& normals,
@@ -129,10 +122,10 @@ ssgLeaf *sgMakeLeaf( const string& path,
const int_list& node_index,
const int_list& normal_index,
const int_list& tex_index,
const bool calc_lights, ssgVertexArray *lights )
const bool calc_lights, osg::Vec3Array *lights )
{
double tex_width = 1000.0, tex_height = 1000.0;
ssgSimpleState *state = NULL;
osg::StateSet *state = 0;
float coverage = -1;
SGMaterial *mat = matlib->find( material );
@@ -173,9 +166,6 @@ ssgLeaf *sgMakeLeaf( const string& path,
coverage = -1;
}
sgVec2 tmp2;
sgVec3 tmp3;
sgVec4 tmp4;
int i;
// vertices
@@ -184,74 +174,81 @@ ssgLeaf *sgMakeLeaf( const string& path,
SG_LOG( SG_TERRAIN, SG_ALERT, "Woh! node list size < 1" );
exit(-1);
}
ssgVertexArray *vl = new ssgVertexArray( size );
Point3D node;
osg::Vec3Array* vl = new osg::Vec3Array;
vl->reserve(size);
for ( i = 0; i < size; ++i ) {
node = nodes[ node_index[i] ];
sgSetVec3( tmp3, node[0], node[1], node[2] );
vl -> add( tmp3 );
Point3D node = nodes[ node_index[i] ];
vl->push_back(osg::Vec3(node[0], node[1], node[2]));
}
// normals
Point3D normal;
ssgNormalArray *nl = new ssgNormalArray( size );
osg::Vec3Array* nl = new osg::Vec3Array;
nl->reserve(size);
if ( normal_index.size() ) {
// object file specifies normal indices (i.e. normal indices
// aren't 'implied'
for ( i = 0; i < size; ++i ) {
normal = normals[ normal_index[i] ];
sgSetVec3( tmp3, normal[0], normal[1], normal[2] );
nl -> add( tmp3 );
Point3D normal = normals[ normal_index[i] ];
nl->push_back(osg::Vec3(normal[0], normal[1], normal[2]));
}
} else {
// use implied normal indices. normal index = vertex index.
for ( i = 0; i < size; ++i ) {
normal = normals[ node_index[i] ];
sgSetVec3( tmp3, normal[0], normal[1], normal[2] );
nl -> add( tmp3 );
Point3D normal = normals[ node_index[i] ];
nl->push_back(osg::Vec3(normal[0], normal[1], normal[2]));
}
}
// colors
ssgColourArray *cl = new ssgColourArray( 1 );
sgSetVec4( tmp4, 1.0, 1.0, 1.0, 1.0 );
cl->add( tmp4 );
osg::Vec4Array* cl = new osg::Vec4Array;
cl->push_back(osg::Vec4(1, 1, 1, 1));
// texture coordinates
size = tex_index.size();
Point3D texcoord;
ssgTexCoordArray *tl = new ssgTexCoordArray( size );
osg::Vec2Array* tl = new osg::Vec2Array;
tl->reserve(size);
if ( size == 1 ) {
texcoord = texcoords[ tex_index[0] ];
sgSetVec2( tmp2, texcoord[0], texcoord[1] );
//sgSetVec2( tmp2, texcoord[0], texcoord[1] );
Point3D texcoord = texcoords[ tex_index[0] ];
osg::Vec2 tmp2(texcoord[0], texcoord[1]);
if ( tex_width > 0 ) {
tmp2[0] *= (1000.0 / tex_width);
}
if ( tex_height > 0 ) {
tmp2[1] *= (1000.0 / tex_height);
}
tl -> add( tmp2 );
tl -> push_back( tmp2 );
} else if ( size > 1 ) {
for ( i = 0; i < size; ++i ) {
texcoord = texcoords[ tex_index[i] ];
sgSetVec2( tmp2, texcoord[0], texcoord[1] );
Point3D texcoord = texcoords[ tex_index[i] ];
osg::Vec2 tmp2(texcoord[0], texcoord[1]);
if ( tex_width > 0 ) {
tmp2[0] *= (1000.0 / tex_width);
}
if ( tex_height > 0 ) {
tmp2[1] *= (1000.0 / tex_height);
}
tl -> add( tmp2 );
tl -> push_back( tmp2 );
}
}
ssgLeaf *leaf = new ssgVtxTable ( ty, vl, nl, tl, cl );
osg::Geometry* geometry = new osg::Geometry;
// geometry->setUseDisplayList(false);
// geometry->setDrawCallback(new SGDebugDrawCallback);
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);
geometry->addPrimitiveSet(new osg::DrawArrays(ty, 0, vl->size()));
osg::Geode* geode = new osg::Geode;
geode->addDrawable(geometry);
// lookup the state record
leaf->setUserData( new SGMaterialUserData(mat) );
leaf->setState( state );
geode->setStateSet(state);
geode->setUserData( new SGMaterialUserData(mat) );
if ( calc_lights ) {
if ( coverage > 0.0 ) {
@@ -260,9 +257,9 @@ ssgLeaf *sgMakeLeaf( const string& path,
<< coverage << ", pushing up to 10000");
coverage = 10000;
}
sgGenRandomSurfacePoints(leaf, coverage, lights );
SGGenRandomSurfacePoints(geometry, coverage, lights );
}
}
return leaf;
return geode;
}

View File

@@ -34,7 +34,8 @@
#include STL_STRING
#include <plib/ssg.h> // plib include
#include <osg/Array>
#include <osg/Node>
#include <simgear/math/sg_types.hxx>
@@ -45,7 +46,7 @@ class SGMaterialLib; // forward declaration.
// Create a ssg leaf
ssgLeaf *sgMakeLeaf( const string& path,
osg::Node* SGMakeLeaf( const string& path,
const GLenum ty,
SGMaterialLib *matlib, const string& material,
const point_list& nodes, const point_list& normals,
@@ -53,17 +54,6 @@ ssgLeaf *sgMakeLeaf( const string& path,
const int_list& node_index,
const int_list& normal_index,
const int_list& tex_index,
const bool calc_lights, ssgVertexArray *lights );
// return a newly created list of points randomly spread across the
// specified leaf. "factor" specifies density ... on average there
// will be one object per the area specified by "factor" in m^2 A
// larger factor will mean fewer objects.
ssgVertexArray *sgGenRandomSurfacePoints( ssgLeaf *leaf, double factor );
// Another varient of the same routine.
void sgGenRandomSurfacePoints( ssgLeaf *leaf, double factor,
ssgVertexArray *lights );
const bool calc_lights, osg::Vec3Array *lights );
#endif // _SG_LEAF_HXX

View File

@@ -32,6 +32,12 @@
#include STL_STRING
#include <osg/StateSet>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Group>
#include <osg/LOD>
#include <simgear/bucket/newbucket.hxx>
#include <simgear/io/sg_binobj.hxx>
#include <simgear/math/sg_geodesy.hxx>
@@ -55,13 +61,11 @@ struct Leaf {
// Generate an ocean tile
bool sgGenTile( const string& path, SGBucket b,
bool SGGenTile( const string& path, SGBucket b,
Point3D *center, double *bounding_radius,
SGMaterialLib *matlib, ssgBranch* geometry )
SGMaterialLib *matlib, osg::Group* group )
{
ssgSimpleState *state = NULL;
geometry->setName( (char *)path.c_str() );
osg::StateSet *state = 0;
double tex_width = 1000.0;
// double tex_height;
@@ -142,43 +146,30 @@ bool sgGenTile( const string& path, SGBucket b,
1000.0 / tex_width );
// Allocate ssg structure
ssgVertexArray *vl = new ssgVertexArray( 4 );
ssgNormalArray *nl = new ssgNormalArray( 4 );
ssgTexCoordArray *tl = new ssgTexCoordArray( 4 );
ssgColourArray *cl = new ssgColourArray( 1 );
osg::Vec3Array *vl = new osg::Vec3Array;
osg::Vec3Array *nl = new osg::Vec3Array;
osg::Vec2Array *tl = new osg::Vec2Array;
sgVec4 color;
sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
cl->add( color );
// sgVec3 *vtlist = new sgVec3 [ 4 ];
// t->vec3_ptrs.push_back( vtlist );
// sgVec3 *vnlist = new sgVec3 [ 4 ];
// t->vec3_ptrs.push_back( vnlist );
// sgVec2 *tclist = new sgVec2 [ 4 ];
// t->vec2_ptrs.push_back( tclist );
sgVec2 tmp2;
sgVec3 tmp3;
for ( i = 0; i < 4; ++i ) {
sgSetVec3( tmp3,
rel[i].x(), rel[i].y(), rel[i].z() );
vl->add( tmp3 );
sgSetVec3( tmp3,
normals[i].x(), normals[i].y(), normals[i].z() );
nl->add( tmp3 );
sgSetVec2( tmp2, texs[i].x(), texs[i].y());
tl->add( tmp2 );
vl->push_back(osg::Vec3(rel[i].x(), rel[i].y(), rel[i].z()));
nl->push_back(osg::Vec3(normals[i].x(), normals[i].y(), normals[i].z()));
tl->push_back(osg::Vec2(texs[i].x(), texs[i].y()));
}
ssgLeaf *leaf =
new ssgVtxTable ( GL_TRIANGLE_FAN, vl, nl, tl, cl );
leaf->setUserData( new SGMaterialUserData(mat) );
leaf->setState( state );
geometry->addKid( leaf );
osg::Geometry* geometry = new osg::Geometry;
geometry->setVertexArray(vl);
geometry->setNormalArray(nl);
geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
geometry->setColorBinding(osg::Geometry::BIND_OFF);
geometry->setTexCoordArray(0, tl);
geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_FAN, 0, vl->size()));
osg::Geode* geode = new osg::Geode;
geode->setName(path);
geode->addDrawable(geometry);
geode->setStateSet(state);
group->addChild(geode);
return true;
}
@@ -197,22 +188,22 @@ bool sgGenTile( const string& path, SGBucket b,
* @param mask The entity's traversal mask (not used).
* @return Always 1, to allow traversal and culling to continue.
*/
static int
leaf_in_range_callback (ssgEntity * entity, int mask)
{
SGLeafUserData * data = (SGLeafUserData *)entity->getUserData();
// static int
// leaf_in_range_callback (ssgEntity * entity, int mask)
// {
// SGLeafUserData * data = (SGLeafUserData *)entity->getUserData();
if (!data->is_filled_in) {
// Iterate through all the triangles
// and populate them.
int num_tris = data->leaf->getNumTriangles();
for ( int i = 0; i < num_tris; ++i ) {
data->setup_triangle(i);
}
data->is_filled_in = true;
}
return 1;
}
// if (!data->is_filled_in) {
// // Iterate through all the triangles
// // and populate them.
// int num_tris = data->leaf->getNumTriangles();
// for ( int i = 0; i < num_tris; ++i ) {
// data->setup_triangle(i);
// }
// data->is_filled_in = true;
// }
// return 1;
// }
/**
@@ -227,16 +218,16 @@ leaf_in_range_callback (ssgEntity * entity, int mask)
* @param mask The entity's traversal mask (not used).
* @return Always 0, to prevent any further traversal or culling.
*/
static int
leaf_out_of_range_callback (ssgEntity * entity, int mask)
{
SGLeafUserData * data = (SGLeafUserData *)entity->getUserData();
if (data->is_filled_in) {
data->branch->removeAllKids();
data->is_filled_in = false;
}
return 0;
}
// static int
// leaf_out_of_range_callback (ssgEntity * entity, int mask)
// {
// SGLeafUserData * data = (SGLeafUserData *)entity->getUserData();
// if (data->is_filled_in) {
// data->branch->removeAllKids();
// data->is_filled_in = false;
// }
// return 0;
// }
/**
@@ -255,11 +246,13 @@ leaf_out_of_range_callback (ssgEntity * entity, int mask)
* @param material_name The name of the surface's material.
*/
static void
gen_random_surface_objects (ssgLeaf *leaf,
ssgBranch *branch,
gen_random_surface_objects (osg::Node *leaf,
osg::Group *branch,
Point3D *center,
SGMaterial *mat )
{
// OSGFIXME
#if 0
// If the surface has no triangles, return
// now.
int num_tris = leaf->getNumTriangles();
@@ -280,17 +273,15 @@ gen_random_surface_objects (ssgLeaf *leaf,
// LOD for the leaf
// max random object range: 20000m
float ranges[] = { 0, 20000, 1000000 };
ssgRangeSelector * lod = new ssgRangeSelector;
lod->setRanges(ranges, 3);
branch->addKid(lod);
osg::LOD * lod = new osg::LOD;
branch->addChild(lod);
// Create the in-range and out-of-range
// branches.
ssgBranch * in_range = new ssgBranch;
ssgBranch * out_of_range = new ssgBranch;
lod->addKid(in_range);
lod->addKid(out_of_range);
osg::Group * in_range = new osg::Group;
// osg::Group * out_of_range = new osg::Group;
lod->addChild(in_range, 0, 20000 /*OSGFIXME hardcoded visibility ???*/);
// lod->addChild(out_of_range, 20000, 1e30);
SGLeafUserData * data = new SGLeafUserData;
data->is_filled_in = false;
@@ -303,12 +294,16 @@ gen_random_surface_objects (ssgLeaf *leaf,
data->cos_lon = cos(lon_rad);
in_range->setUserData(data);
in_range->setTravCallback(SSG_CALLBACK_PRETRAV, leaf_in_range_callback);
out_of_range->setUserData(data);
out_of_range->setTravCallback(SSG_CALLBACK_PRETRAV,
leaf_out_of_range_callback);
out_of_range
->addKid(new SGDummyBSphereEntity(leaf->getBSphere()->getRadius()));
// OSGFIXME: implement random objects to be loaded when in sight
// in_range->setTravCallback(SSG_CALLBACK_PRETRAV, leaf_in_range_callback);
// OSGFIXME: implement deletion of tiles that are no longer used
// out_of_range->setUserData(data);
// out_of_range->setTravCallback(SSG_CALLBACK_PRETRAV,
// leaf_out_of_range_callback);
// out_of_range
// ->addChild(new SGDummyBSphereEntity(leaf->getBSphere()->getRadius()));
#endif
}
@@ -318,16 +313,16 @@ gen_random_surface_objects (ssgLeaf *leaf,
////////////////////////////////////////////////////////////////////////
// Load an Binary obj file
bool sgBinObjLoad( const string& path, const bool is_base,
bool SGBinObjLoad( const string& path, const bool is_base,
Point3D *center,
double *bounding_radius,
SGMaterialLib *matlib,
bool use_random_objects,
ssgBranch *geometry,
ssgBranch *vasi_lights,
ssgBranch *rwy_lights,
ssgBranch *taxi_lights,
ssgVertexArray *ground_lights )
osg::Group *geometry,
osg::Group *vasi_lights,
osg::Group *rwy_lights,
osg::Group *taxi_lights,
osg::Vec3Array *ground_lights )
{
SGBinObject obj;
@@ -335,11 +330,11 @@ bool sgBinObjLoad( const string& path, const bool is_base,
return false;
}
ssgBranch *local_terrain = new ssgBranch;
osg::Group *local_terrain = new osg::Group;
local_terrain->setName( "LocalTerrain" );
geometry->addKid( local_terrain );
geometry->addChild( local_terrain );
geometry->setName( (char *)path.c_str() );
geometry->setName(path);
// reference point (center offset/bounding sphere)
*center = obj.get_gbs_center();
@@ -363,45 +358,43 @@ bool sgBinObjLoad( const string& path, const bool is_base,
// cout << "pts_v.size() = " << pts_v.size() << endl;
if ( pt_materials[i].substr(0, 3) == "RWY" ) {
// airport environment lighting
sgdVec3 up;
sgdSetVec3( up, center->x(), center->y(), center->z() );
SGVec3d up(center->x(), center->y(), center->z());
// returns a transform -> lod -> leaf structure
ssgBranch *branch = sgMakeDirectionalLights( nodes, normals,
osg::Node *branch = SGMakeDirectionalLights( nodes, normals,
pts_v[i], pts_n[i],
matlib,
pt_materials[i], up );
if ( pt_materials[i] == "RWY_VASI_LIGHTS" ) {
vasi_lights->addKid( branch );
vasi_lights->addChild( branch );
} else if ( pt_materials[i] == "RWY_BLUE_TAXIWAY_LIGHTS"
|| pt_materials[i] == "RWY_GREEN_TAXIWAY_LIGHTS" )
{
taxi_lights->addKid( branch );
taxi_lights->addChild( branch );
} else {
rwy_lights->addKid( branch );
rwy_lights->addChild( branch );
}
} else {
// other geometry
material = pt_materials[i];
tex_index.clear();
ssgLeaf *leaf = sgMakeLeaf( path, GL_POINTS, matlib, material,
osg::Node *leaf = SGMakeLeaf( path, GL_POINTS, matlib, material,
nodes, normals, texcoords,
pts_v[i], pts_n[i], tex_index,
false, ground_lights );
local_terrain->addKid( leaf );
local_terrain->addChild( leaf );
}
}
// Put all randomly-placed objects under a separate branch
// (actually an ssgRangeSelector) named "random-models".
ssgBranch * random_object_branch = 0;
osg::Group * random_object_branch = 0;
if (use_random_objects) {
float ranges[] = { 0, 20000 }; // Maximum 20km range for random objects
ssgRangeSelector * object_lod = new ssgRangeSelector;
object_lod->setRanges(ranges, 2);
osg::LOD* object_lod = new osg::LOD;
object_lod->setName("random-models");
geometry->addKid(object_lod);
random_object_branch = new ssgBranch;
object_lod->addKid(random_object_branch);
geometry->addChild(object_lod);
random_object_branch = new osg::Group;
// Maximum 20km range for random objects
object_lod->addChild(random_object_branch, 0, 20000);
}
typedef map<string,list<Leaf> > LeafMap;
@@ -443,7 +436,7 @@ bool sgBinObjLoad( const string& path, const bool is_base,
Leaf &leaf = *li;
int ind = leaf.index;
if ( leaf.type == GL_TRIANGLES ) {
ssgLeaf *leaf = sgMakeLeaf( path, GL_TRIANGLES, matlib,
osg::Node *leaf = SGMakeLeaf( path, GL_TRIANGLES, matlib,
tri_materials[ind],
nodes, normals, texcoords,
tris_v[ind], tris_n[ind], tris_tc[ind],
@@ -459,9 +452,9 @@ bool sgBinObjLoad( const string& path, const bool is_base,
center, mat );
}
}
local_terrain->addKid( leaf );
local_terrain->addChild( leaf );
} else if ( leaf.type == GL_TRIANGLE_STRIP ) {
ssgLeaf *leaf = sgMakeLeaf( path, GL_TRIANGLE_STRIP,
osg::Node *leaf = SGMakeLeaf( path, GL_TRIANGLE_STRIP,
matlib, strip_materials[ind],
nodes, normals, texcoords,
strips_v[ind], strips_n[ind], strips_tc[ind],
@@ -477,9 +470,9 @@ bool sgBinObjLoad( const string& path, const bool is_base,
center, mat );
}
}
local_terrain->addKid( leaf );
local_terrain->addChild( leaf );
} else {
ssgLeaf *leaf = sgMakeLeaf( path, GL_TRIANGLE_FAN,
osg::Node *leaf = SGMakeLeaf( path, GL_TRIANGLE_FAN,
matlib, fan_materials[ind],
nodes, normals, texcoords,
fans_v[ind], fans_n[ind], fans_tc[ind],
@@ -495,7 +488,7 @@ bool sgBinObjLoad( const string& path, const bool is_base,
center, mat );
}
}
local_terrain->addKid( leaf );
local_terrain->addChild( leaf );
}
++li;
}

View File

@@ -35,7 +35,8 @@
#include STL_STRING
#include <plib/ssg.h> // plib include
#include <osg/Array>
#include <osg/Group>
#include <simgear/math/point3d.hxx>
@@ -46,21 +47,21 @@ class SGMaterialLib;
// Load a Binary obj file
bool sgBinObjLoad( const string& path, const bool is_base,
bool SGBinObjLoad( const string& path, const bool is_base,
Point3D *center,
double *bounding_radius,
SGMaterialLib *matlib,
bool use_random_objects,
ssgBranch *geometry,
ssgBranch *vasi_lights,
ssgBranch *rwy_lights,
ssgBranch *taxi_lights,
ssgVertexArray *ground_lights );
osg::Group *geometry,
osg::Group *vasi_lights,
osg::Group *rwy_lights,
osg::Group *taxi_lights,
osg::Vec3Array *ground_lights );
// Generate an ocean tile
bool sgGenTile( const string& path, SGBucket b,
bool SGGenTile( const string& path, SGBucket b,
Point3D *center, double *bounding_radius,
SGMaterialLib *matlib, ssgBranch *geometry );
SGMaterialLib *matlib, osg::Group *geometry );
#endif // _SG_OBJ_HXX

File diff suppressed because it is too large Load Diff

View File

@@ -35,9 +35,6 @@
#include STL_STRING
#include <vector> // STL
#include <plib/sg.h>
#include <plib/ssg.h> // plib include
#include <simgear/math/sg_types.hxx>
#include <simgear/scene/material/matlib.hxx>
@@ -79,21 +76,18 @@ typedef int_list::const_iterator int_point_list_iterator;
// Yes this get's to be long and convoluted. If you can suggest a
// simpler way, please do! :-)
ssgLeaf *sgMakeDirectionalLight( sgVec3 pt, sgVec3 dir, sgVec3 up );
ssgBranch *sgMakeDirectionalLights( const point_list &nodes,
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,
sgdVec3 dup );
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,
void SGConfigureDirectionalLights( bool use_point_sprites,
bool enhanced_lighting,
bool distance_attenuation );

View File

@@ -25,9 +25,6 @@
# include <simgear_config.h>
#endif
#include <plib/sg.h>
#include <plib/ssg.h>
#include <simgear/sg_inlines.h>
#include <simgear/math/point3d.hxx>
#include <simgear/math/sg_geodesy.hxx>
@@ -120,6 +117,8 @@ void SGTriUserData::add_object_to_triangle (SGMatModel * object)
if (object->get_heading_type() == SGMatModel::HEADING_RANDOM)
hdg_deg = sg_random() * 360;
#if 0
// OSGFIXME
sgMat4 mat;
makeWorldMatrix(mat, hdg_deg);
@@ -132,45 +131,47 @@ void SGTriUserData::add_object_to_triangle (SGMatModel * object)
root_props, sim_time_sec )
);
branch->addKid(pos);
#endif
}
void SGTriUserData::makeWorldMatrix (sgMat4 mat, double hdg_deg )
{
if (hdg_deg == 0) {
mat[0][0] = leafData->sin_lat * leafData->cos_lon;
mat[0][1] = leafData->sin_lat * leafData->sin_lon;
mat[0][2] = -leafData->cos_lat;
mat[0][3] = SG_ZERO;
// OSGFIXME
// if (hdg_deg == 0) {
// mat[0][0] = leafData->sin_lat * leafData->cos_lon;
// mat[0][1] = leafData->sin_lat * leafData->sin_lon;
// mat[0][2] = -leafData->cos_lat;
// mat[0][3] = SG_ZERO;
mat[1][0] = -leafData->sin_lon;
mat[1][1] = leafData->cos_lon;
mat[1][2] = SG_ZERO;
mat[1][3] = SG_ZERO;
} else {
float sin_hdg = sin( hdg_deg * SGD_DEGREES_TO_RADIANS ) ;
float cos_hdg = cos( hdg_deg * SGD_DEGREES_TO_RADIANS ) ;
mat[0][0] = cos_hdg * leafData->sin_lat * leafData->cos_lon - sin_hdg * leafData->sin_lon;
mat[0][1] = cos_hdg * leafData->sin_lat * leafData->sin_lon + sin_hdg * leafData->cos_lon;
mat[0][2] = -cos_hdg * leafData->cos_lat;
mat[0][3] = SG_ZERO;
// mat[1][0] = -leafData->sin_lon;
// mat[1][1] = leafData->cos_lon;
// mat[1][2] = SG_ZERO;
// mat[1][3] = SG_ZERO;
// } else {
// float sin_hdg = sin( hdg_deg * SGD_DEGREES_TO_RADIANS ) ;
// float cos_hdg = cos( hdg_deg * SGD_DEGREES_TO_RADIANS ) ;
// mat[0][0] = cos_hdg * leafData->sin_lat * leafData->cos_lon - sin_hdg * leafData->sin_lon;
// mat[0][1] = cos_hdg * leafData->sin_lat * leafData->sin_lon + sin_hdg * leafData->cos_lon;
// mat[0][2] = -cos_hdg * leafData->cos_lat;
// mat[0][3] = SG_ZERO;
mat[1][0] = -sin_hdg * leafData->sin_lat * leafData->cos_lon - cos_hdg * leafData->sin_lon;
mat[1][1] = -sin_hdg * leafData->sin_lat * leafData->sin_lon + cos_hdg * leafData->cos_lon;
mat[1][2] = sin_hdg * leafData->cos_lat;
mat[1][3] = SG_ZERO;
}
// mat[1][0] = -sin_hdg * leafData->sin_lat * leafData->cos_lon - cos_hdg * leafData->sin_lon;
// mat[1][1] = -sin_hdg * leafData->sin_lat * leafData->sin_lon + cos_hdg * leafData->cos_lon;
// mat[1][2] = sin_hdg * leafData->cos_lat;
// mat[1][3] = SG_ZERO;
// }
mat[2][0] = leafData->cos_lat * leafData->cos_lon;
mat[2][1] = leafData->cos_lat * leafData->sin_lon;
mat[2][2] = leafData->sin_lat;
mat[2][3] = SG_ZERO;
// mat[2][0] = leafData->cos_lat * leafData->cos_lon;
// mat[2][1] = leafData->cos_lat * leafData->sin_lon;
// mat[2][2] = leafData->sin_lat;
// mat[2][3] = SG_ZERO;
// translate to random point in triangle
sgVec3 result;
random_pt_inside_tri(result, p1, p2, p3);
sgSubVec3(mat[3], result, center);
// // translate to random point in triangle
// sgVec3 result;
// random_pt_inside_tri(result, p1, p2, p3);
// sgSubVec3(mat[3], result, center);
mat[3][3] = SG_ONE ;
// mat[3][3] = SG_ONE ;
}
/**
@@ -185,16 +186,16 @@ void SGTriUserData::makeWorldMatrix (sgMat4 mat, double hdg_deg )
* @param mask The entity's traversal mask (not used).
* @return Always 1, to allow traversal and culling to continue.
*/
static int
tri_in_range_callback (ssgEntity * entity, int mask)
{
SGTriUserData * data = (SGTriUserData *)entity->getUserData();
if (!data->is_filled_in) {
data->fill_in_triangle();
data->is_filled_in = true;
}
return 1;
}
// static int
// tri_in_range_callback (ssgEntity * entity, int mask)
// {
// SGTriUserData * data = (SGTriUserData *)entity->getUserData();
// if (!data->is_filled_in) {
// data->fill_in_triangle();
// data->is_filled_in = true;
// }
// return 1;
// }
/**
@@ -209,16 +210,16 @@ tri_in_range_callback (ssgEntity * entity, int mask)
* @param mask The entity's traversal mask (not used).
* @return Always 0, to prevent any further traversal or culling.
*/
static int
tri_out_of_range_callback (ssgEntity * entity, int mask)
{
SGTriUserData * data = (SGTriUserData *)entity->getUserData();
if (data->is_filled_in) {
data->branch->removeAllKids();
data->is_filled_in = false;
}
return 0;
}
// static int
// tri_out_of_range_callback (ssgEntity * entity, int mask)
// {
// SGTriUserData * data = (SGTriUserData *)entity->getUserData();
// if (data->is_filled_in) {
// data->branch->removeAllKids();
// data->is_filled_in = false;
// }
// return 0;
// }
/**
@@ -230,13 +231,13 @@ tri_out_of_range_callback (ssgEntity * entity, int mask)
* @param p3 The third point in the triangle.
* @return The greatest distance any point lies from the center.
*/
static inline float
get_bounding_radius( sgVec3 center, float *p1, float *p2, float *p3)
{
return sqrt( SG_MAX3( sgDistanceSquaredVec3(center, p1),
sgDistanceSquaredVec3(center, p2),
sgDistanceSquaredVec3(center, p3) ) );
}
// static inline float
// get_bounding_radius( sgVec3 center, float *p1, float *p2, float *p3)
// {
// return sqrt( SG_MAX3( sgDistanceSquaredVec3(center, p1),
// sgDistanceSquaredVec3(center, p2),
// sgDistanceSquaredVec3(center, p3) ) );
// }
/**
@@ -248,81 +249,81 @@ get_bounding_radius( sgVec3 center, float *p1, float *p2, float *p3)
void SGLeafUserData::setup_triangle (int i )
{
short n1, n2, n3;
leaf->getTriangle(i, &n1, &n2, &n3);
// short n1, n2, n3;
// leaf->getTriangle(i, &n1, &n2, &n3);
float * p1 = leaf->getVertex(n1);
float * p2 = leaf->getVertex(n2);
float * p3 = leaf->getVertex(n3);
// float * p1 = leaf->getVertex(n1);
// float * p2 = leaf->getVertex(n2);
// float * p3 = leaf->getVertex(n3);
// Set up a single center point for LOD
sgVec3 center;
sgSetVec3(center,
(p1[0] + p2[0] + p3[0]) / 3.0,
(p1[1] + p2[1] + p3[1]) / 3.0,
(p1[2] + p2[2] + p3[2]) / 3.0);
double area = sgTriArea(p1, p2, p3);
// // Set up a single center point for LOD
// sgVec3 center;
// sgSetVec3(center,
// (p1[0] + p2[0] + p3[0]) / 3.0,
// (p1[1] + p2[1] + p3[1]) / 3.0,
// (p1[2] + p2[2] + p3[2]) / 3.0);
// double area = sgTriArea(p1, p2, p3);
// maximum radius of an object from center.
double bounding_radius = get_bounding_radius(center, p1, p2, p3);
// // maximum radius of an object from center.
// double bounding_radius = get_bounding_radius(center, p1, p2, p3);
// Set up a transformation to the center
// point, so that everything else can
// be specified relative to it.
ssgTransform * location = new ssgTransform;
sgMat4 TRANS;
sgMakeTransMat4(TRANS, center);
location->setTransform(TRANS);
branch->addKid(location);
// // Set up a transformation to the center
// // point, so that everything else can
// // be specified relative to it.
// ssgTransform * location = new ssgTransform;
// sgMat4 TRANS;
// sgMakeTransMat4(TRANS, center);
// location->setTransform(TRANS);
// branch->addKid(location);
// Iterate through all the object types.
int num_groups = mat->get_object_group_count();
for (int j = 0; j < num_groups; j++) {
// Look up the random object.
SGMatModelGroup * group = mat->get_object_group(j);
// // Iterate through all the object types.
// int num_groups = mat->get_object_group_count();
// for (int j = 0; j < num_groups; j++) {
// // Look up the random object.
// SGMatModelGroup * group = mat->get_object_group(j);
// Set up the range selector for the entire
// triangle; note that we use the object
// range plus the bounding radius here, to
// allow for objects far from the center.
float ranges[] = { 0,
group->get_range_m() + bounding_radius,
SG_MAX };
ssgRangeSelector * lod = new ssgRangeSelector;
lod->setRanges(ranges, 3);
location->addKid(lod);
// // Set up the range selector for the entire
// // triangle; note that we use the object
// // range plus the bounding radius here, to
// // allow for objects far from the center.
// float ranges[] = { 0,
// group->get_range_m() + bounding_radius,
// SG_MAX };
// ssgRangeSelector * lod = new ssgRangeSelector;
// lod->setRanges(ranges, 3);
// location->addKid(lod);
// Create the in-range and out-of-range
// branches.
ssgBranch * in_range = new ssgBranch;
ssgBranch * out_of_range = new ssgBranch;
// // Create the in-range and out-of-range
// // branches.
// ssgBranch * in_range = new ssgBranch;
// ssgBranch * out_of_range = new ssgBranch;
// Set up the user data for if/when
// the random objects in this triangle
// are filled in.
SGTriUserData * data = new SGTriUserData;
data->is_filled_in = false;
data->p1 = p1;
data->p2 = p2;
data->p3 = p3;
sgCopyVec3 (data->center, center);
data->area = area;
data->object_group = group;
data->branch = in_range;
data->leafData = this;
data->seed = (unsigned int)(p1[0] * j);
// // Set up the user data for if/when
// // the random objects in this triangle
// // are filled in.
// SGTriUserData * data = new SGTriUserData;
// data->is_filled_in = false;
// data->p1 = p1;
// data->p2 = p2;
// data->p3 = p3;
// sgCopyVec3 (data->center, center);
// data->area = area;
// data->object_group = group;
// data->branch = in_range;
// data->leafData = this;
// data->seed = (unsigned int)(p1[0] * j);
// Set up the in-range node.
in_range->setUserData(data);
in_range->setTravCallback(SSG_CALLBACK_PRETRAV,
tri_in_range_callback);
lod->addKid(in_range);
// // Set up the in-range node.
// in_range->setUserData(data);
// in_range->setTravCallback(SSG_CALLBACK_PRETRAV,
// tri_in_range_callback);
// lod->addKid(in_range);
// Set up the out-of-range node.
out_of_range->setUserData(data);
out_of_range->setTravCallback(SSG_CALLBACK_PRETRAV,
tri_out_of_range_callback);
out_of_range->addKid(new SGDummyBSphereEntity(bounding_radius));
lod->addKid(out_of_range);
}
// // Set up the out-of-range node.
// out_of_range->setUserData(data);
// out_of_range->setTravCallback(SSG_CALLBACK_PRETRAV,
// tri_out_of_range_callback);
// out_of_range->addKid(new SGDummyBSphereEntity(bounding_radius));
// lod->addKid(out_of_range);
// }
}

View File

@@ -29,7 +29,11 @@
#include STL_STRING
#include <plib/ssg.h>
#include <plib/sg.h>
#include <osg/Referenced>
#include <osg/Geometry>
#include <osg/Group>
SG_USING_STD(string);
@@ -52,13 +56,13 @@ void sgUserDataInit( SGModelLib *m, const string &r,
/**
* User data for populating leaves when they come in range.
*/
class SGLeafUserData : public ssgBase
class SGLeafUserData : public osg::Referenced
{
public:
bool is_filled_in;
ssgLeaf *leaf;
osg::Geometry *leaf;
SGMaterial *mat;
ssgBranch *branch;
osg::Group *branch;
float sin_lat;
float cos_lat;
float sin_lon;
@@ -71,17 +75,17 @@ public:
/**
* User data for populating triangles when they come in range.
*/
class SGTriUserData : public ssgBase
class SGTriUserData : public osg::Referenced
{
public:
bool is_filled_in;
float * p1;
float * p2;
float * p3;
sgVec3 center;
osg::Vec3 center;
double area;
SGMatModelGroup * object_group;
ssgBranch * branch;
osg::Group * branch;
SGLeafUserData * leafData;
unsigned int seed;
@@ -90,26 +94,4 @@ public:
void makeWorldMatrix (sgMat4 ROT, double hdg_deg );
};
/**
* ssgEntity with a dummy bounding sphere, to fool culling.
*
* This forces the in-range and out-of-range branches to be visited
* when appropriate, even if they have no children. It's ugly, but
* it works and seems fairly efficient (since branches can still
* be culled when they're out of the view frustum).
*/
class SGDummyBSphereEntity : public ssgBranch
{
public:
SGDummyBSphereEntity (float radius)
{
bsphere.setCenter(0, 0, 0);
bsphere.setRadius(radius);
}
virtual ~SGDummyBSphereEntity () {}
virtual void recalcBSphere () { bsphere_is_invalid = false; }
};
#endif // _SG_USERDATA_HXX

View File

@@ -24,159 +24,174 @@
#ifndef _SG_VASI_HXX
#define _SG_VASI_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#include <simgear/compiler.h>
#include STL_STRING
SG_USING_STD(string);
#include <osg/io_utils>
#include <osg/ref_ptr>
#include <osg/Array>
#include <osg/NodeCallback>
#include <osg/NodeVisitor>
#include <osg/Vec3>
#include <plib/ssg.h> // plib include
/// 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);
#include <simgear/math/sg_geodesy.hxx>
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);
}
class SGVASIUserData : public ssgBase
{
// 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:
sgdVec3 abs_pos;
double alt_m;
ssgLeaf *leaf;
public:
SGVASIUserData( sgdVec3 pos_cart, ssgLeaf *l ) {
sgdCopyVec3( abs_pos, pos_cart );
double lat, lon;
sgCartToGeod( abs_pos, &lat, &lon, &alt_m );
leaf = l;
}
~SGVASIUserData() {}
double get_alt_m() { return alt_m; }
double *get_abs_pos() { return abs_pos; }
int i;
// color the vasi/papi correctly based on angle
void set_color( float angle_deg ) {
int count = leaf->getNumColours();
double trans = 0.05;
double color = 1.0;
double ref;
float *entry;
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 ( i = 0; i < 3; ++i ) {
entry = leaf->getColour( i );
entry[1] = color;
entry[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 ( i = 3; i < 6; ++i ) {
entry = leaf->getColour( i );
entry[1] = color;
entry[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 ( i = 6; i < 9; ++i ) {
entry = leaf->getColour( i );
entry[1] = color;
entry[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 ( i = 9; i < 12; ++i ) {
entry = leaf->getColour( i );
entry[1] = color;
entry[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 ( int i = 0; i < 18; ++i ) {
entry = leaf->getColour( i );
entry[1] = color;
entry[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 ( int i = 18; i < 36; ++i ) {
entry = leaf->getColour( i );
entry[1] = color;
entry[2] = color;
}
} else {
// fail safe
cout << "unknown vasi/papi configuration, count = " << count << endl;
for ( int i = 0; i < count; ++i ) {
entry = leaf->getColour( i );
entry[1] = color;
entry[2] = color;
}
}
}
osg::ref_ptr<osg::Vec4Array> mVasiColorArray;
osg::Vec3 mReferencePoint;
osg::Vec3 mGlideSlopeUp;
osg::Vec3 mGlideSlopeDir;
};
#endif // _SG_VASI_HXX

View File

@@ -0,0 +1,16 @@
includedir = @includedir@/scene/util
lib_LIBRARIES = libsgutil.a
noinst_HEADERS =
include_HEADERS = \
SGNodeMasks.hxx \
SGUpdateVisitor.hxx \
SGDebugDrawCallback.hxx \
SGStateAttributeVisitor.hxx \
SGTextureStateAttributeVisitor.hxx
libsgutil_a_SOURCES =
INCLUDES = -I$(top_srcdir)

View File

@@ -0,0 +1,164 @@
/* -*-c++-*-
*
* Copyright (C) 2006 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_DEBUGDRAWCALLBACK_HXX
#define SG_SCENE_DEBUGDRAWCALLBACK_HXX
#include <iostream>
#include <GL/gl.h>
#include <osg/Drawable>
#include <osg/State>
struct SGDebugDrawCallback : public osg::Drawable::DrawCallback {
virtual void drawImplementation(osg::State& state,
const osg::Drawable* drawable) const
{
// state.dirtyColorPointer();
printState(std::cout, drawable);
drawable->drawImplementation(state);
printState(std::cout, drawable);
// state.dirtyColorPointer();
}
void printState(std::ostream& stream, const osg::Drawable* drawable) const
{
stream << "Drawable \"" << drawable->getName() << "\"";
#ifdef ERROR_CHECK
#undef ERROR_CHECK
#endif
#define ERROR_CHECK(msg) \
do { \
GLenum errorNo = glGetError(); \
if (errorNo != GL_NO_ERROR) \
stream << msg; \
} while(0)
#ifdef PRINT_STATE
#undef PRINT_STATE
#endif
#define PRINT_STATE(flag) \
do { \
if (glIsEnabled(flag)) \
stream << " " #flag; \
ERROR_CHECK(" ERROR " #flag); \
} while(0)
PRINT_STATE(GL_COLOR_ARRAY);
PRINT_STATE(GL_EDGE_FLAG_ARRAY);
PRINT_STATE(GL_INDEX_ARRAY);
PRINT_STATE(GL_NORMAL_ARRAY);
PRINT_STATE(GL_TEXTURE_COORD_ARRAY);
PRINT_STATE(GL_VERTEX_ARRAY);
PRINT_STATE(GL_ALPHA_TEST);
PRINT_STATE(GL_AUTO_NORMAL);
PRINT_STATE(GL_BLEND);
PRINT_STATE(GL_CLIP_PLANE0);
PRINT_STATE(GL_CLIP_PLANE1);
PRINT_STATE(GL_CLIP_PLANE2);
PRINT_STATE(GL_CLIP_PLANE3);
PRINT_STATE(GL_CLIP_PLANE4);
PRINT_STATE(GL_CLIP_PLANE5);
PRINT_STATE(GL_COLOR_LOGIC_OP);
// PRINT_STATE(GL_COLOR_TABLE);
// PRINT_STATE(GL_CONVOLUTION_1D);
// PRINT_STATE(GL_CONVOLUTION_2D);
PRINT_STATE(GL_CULL_FACE);
PRINT_STATE(GL_DEPTH_TEST);
PRINT_STATE(GL_DITHER);
PRINT_STATE(GL_FOG);
// PRINT_STATE(GL_HISTOGRAM);
PRINT_STATE(GL_INDEX_LOGIC_OP);
PRINT_STATE(GL_LIGHT0);
PRINT_STATE(GL_LIGHT1);
PRINT_STATE(GL_LIGHT2);
PRINT_STATE(GL_LIGHT3);
PRINT_STATE(GL_LIGHT4);
PRINT_STATE(GL_LIGHT5);
PRINT_STATE(GL_LIGHT6);
PRINT_STATE(GL_LIGHT7);
PRINT_STATE(GL_LIGHTING);
PRINT_STATE(GL_LINE_SMOOTH);
PRINT_STATE(GL_LINE_STIPPLE);
PRINT_STATE(GL_MAP1_COLOR_4);
PRINT_STATE(GL_MAP1_INDEX);
PRINT_STATE(GL_MAP1_NORMAL);
PRINT_STATE(GL_MAP1_TEXTURE_COORD_1);
PRINT_STATE(GL_MAP1_TEXTURE_COORD_2);
PRINT_STATE(GL_MAP1_TEXTURE_COORD_3);
PRINT_STATE(GL_MAP1_TEXTURE_COORD_4);
PRINT_STATE(GL_MAP2_COLOR_4);
PRINT_STATE(GL_MAP2_INDEX);
PRINT_STATE(GL_MAP2_NORMAL);
PRINT_STATE(GL_MAP2_TEXTURE_COORD_1);
PRINT_STATE(GL_MAP2_TEXTURE_COORD_2);
PRINT_STATE(GL_MAP2_TEXTURE_COORD_3);
PRINT_STATE(GL_MAP2_TEXTURE_COORD_4);
PRINT_STATE(GL_MAP2_VERTEX_3);
PRINT_STATE(GL_MAP2_VERTEX_4);
// PRINT_STATE(GL_MINMAX);
PRINT_STATE(GL_NORMALIZE);
PRINT_STATE(GL_POINT_SMOOTH);
PRINT_STATE(GL_POLYGON_SMOOTH);
PRINT_STATE(GL_POLYGON_OFFSET_FILL);
PRINT_STATE(GL_POLYGON_OFFSET_LINE);
PRINT_STATE(GL_POLYGON_OFFSET_POINT);
PRINT_STATE(GL_POLYGON_STIPPLE);
// PRINT_STATE(GL_POST_COLOR_MATRIX_COLOR_TABLE);
// PRINT_STATE(GL_POST_CONVOLUTION_COLOR_TABLE);
PRINT_STATE(GL_RESCALE_NORMAL);
PRINT_STATE(GL_SCISSOR_TEST);
// PRINT_STATE(GL_SEPARABLE_2D);
PRINT_STATE(GL_STENCIL_TEST);
PRINT_STATE(GL_TEXTURE_1D);
PRINT_STATE(GL_TEXTURE_2D);
PRINT_STATE(GL_TEXTURE_3D);
PRINT_STATE(GL_TEXTURE_GEN_Q);
PRINT_STATE(GL_TEXTURE_GEN_R);
PRINT_STATE(GL_TEXTURE_GEN_S);
PRINT_STATE(GL_TEXTURE_GEN_T);
#undef PRINT_STATE
#undef ERROR_CHECK
if (glIsEnabled(GL_COLOR_MATERIAL)) {
stream << " GL_COLOR_MATERIAL(";
GLint value;
glGetIntegerv(GL_COLOR_MATERIAL_PARAMETER, &value);
if (value == GL_DIFFUSE)
stream << "GL_DIFFUSE";
if (value == GL_AMBIENT)
stream << "GL_AMBIENT";
if (value == GL_AMBIENT_AND_DIFFUSE)
stream << "GL_AMBIENT_AND_DIFFUSE";
if (value == GL_EMISSION)
stream << "GL_EMISSION";
if (value == GL_SPECULAR)
stream << "GL_SPECULAR";
stream << ")";
}
stream << "\n";
}
};
#endif

View File

@@ -0,0 +1,28 @@
/* -*-c++-*-
*
* Copyright (C) 2006 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_NODEMASKS_HXX
#define SG_SCENE_NODEMASKS_HXX
#define SG_NODEMASK_TERRAIN_BIT (2<<10)
#define SG_NODEMASK_SHADOW_BIT (2<<11)
#endif

View File

@@ -0,0 +1,65 @@
/* -*-c++-*-
*
* Copyright (C) 2006 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_STATEATTRIBUTEVISITOR_HXX
#define SG_SCENE_STATEATTRIBUTEVISITOR_HXX
class SGStateAttributeVisitor : public osg::NodeVisitor {
public:
SGStateAttributeVisitor() :
osg::NodeVisitor(osg::NodeVisitor::NODE_VISITOR,
osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
{ }
virtual void apply(osg::StateSet::RefAttributePair&)
{ }
virtual void apply(osg::StateSet::AttributeList& attrList)
{
osg::StateSet::AttributeList::iterator i;
i = attrList.begin();
while (i != attrList.end()) {
apply(i->second);
++i;
}
}
virtual void apply(osg::StateSet* stateSet)
{
if (!stateSet)
return;
apply(stateSet->getAttributeList());
}
virtual void apply(osg::Node& node)
{
apply(node.getStateSet());
traverse(node);
}
virtual void apply(osg::Geode& node)
{
unsigned nDrawables = node.getNumDrawables();
for (unsigned i = 0; i < nDrawables; ++i)
apply(node.getDrawable(i)->getStateSet());
apply(node.getStateSet());
traverse(node);
}
};
#endif

View File

@@ -0,0 +1,70 @@
/* -*-c++-*-
*
* Copyright (C) 2006 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_TEXTURESTATEATTRIBUTEVISITOR_HXX
#define SG_SCENE_TEXTURESTATEATTRIBUTEVISITOR_HXX
class SGTextureStateAttributeVisitor : public osg::NodeVisitor {
public:
SGTextureStateAttributeVisitor() :
osg::NodeVisitor(osg::NodeVisitor::NODE_VISITOR,
osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
{ }
virtual void apply(int textureUnit, osg::StateSet::RefAttributePair& refAttr)
{ }
virtual void apply(int textureUnit, osg::StateSet::AttributeList& attrList)
{
osg::StateSet::AttributeList::iterator i;
i = attrList.begin();
while (i != attrList.end()) {
apply(textureUnit, i->second);
++i;
}
}
virtual void apply(osg::StateSet::TextureAttributeList& attrList)
{
for (unsigned i = 0; i < attrList.size(); ++i)
apply(i, attrList[i]);
}
virtual void apply(osg::StateSet* stateSet)
{
if (!stateSet)
return;
apply(stateSet->getTextureAttributeList());
}
virtual void apply(osg::Node& node)
{
apply(node.getStateSet());
traverse(node);
}
virtual void apply(osg::Geode& node)
{
unsigned nDrawables = node.getNumDrawables();
for (unsigned i = 0; i < nDrawables; ++i)
apply(node.getDrawable(i)->getStateSet());
apply(node.getStateSet());
traverse(node);
}
};
#endif

View File

@@ -0,0 +1,66 @@
/* -*-c++-*-
*
* Copyright (C) 2006 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_UPDATEVISITOR_HXX
#define SG_SCENE_UPDATEVISITOR_HXX
#include <osg/NodeVisitor>
#include <osgUtil/UpdateVisitor>
#include <osg/io_utils>
class SGUpdateVisitor : public osgUtil::UpdateVisitor {
public:
SGUpdateVisitor()
{
// setTraversalMode(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN);
}
// virtual void apply(osg::Transform& transform)
// {
// osg::Matrix matrix = mModelViewMatrix;
// transform.computeLocalToWorldMatrix(mModelViewMatrix, this);
// handle_callbacks_and_traverse(transform);
// mModelViewMatrix = matrix;
// }
// virtual osg::Vec3 getEyePoint() const
// {
// osg::Matrix matrix;
// matrix.invert(mModelViewMatrix);
// return matrix.preMult(osg::Vec3(0, 0, 0));
// }
// protected:
// osg::Matrix mModelViewMatrix;
};
// #include <osg/NodeCallback>
// class SGNodeCallback : public osg::NodeCallback {
// public:
// virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
// {
// }
// };
#endif

View File

@@ -25,8 +25,6 @@
# include <windows.h>
#endif
#include <plib/ssg.h>
#include "jpgfactory.hxx"
@@ -42,6 +40,7 @@ static boolean empty_output_buffer (j_compress_ptr cinfo);
}
#endif
// OSGFIME: offscreenrendering on osg - completely new context ...
typedef struct {
struct jpeg_destination_mgr pub; /* public fields */
@@ -238,7 +237,8 @@ int trJpgFactory::render()
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
sgFrustum *frustum = ssgGetFrustum();
// OSGFIXME
// sgFrustum *frustum = ssgGetFrustum();
trFrustum(tr,
frustum->getLeft(), frustum->getRight(),
frustum->getBot(), frustum->getTop(),

View File

@@ -1,362 +0,0 @@
/*
PLIB - A Suite of Portable Game Libraries
Copyright (C) 1998,2002 Steve Baker
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library 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.
For further information visit http://plib.sourceforge.net
$Id$
*/
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include "ssgEntityArray.hxx"
// Forward declaration of internal ssg stuff (for hot/isec/los/etc.)
void _ssgPushPath ( ssgEntity *l ) ;
void _ssgPopPath () ;
void ssgEntityArray::copy_from ( ssgEntityArray *src, int clone_flags )
{
ssgEntity::copy_from ( src, clone_flags ) ;
ssgEntity *k = src -> getModel ( ) ;
if ( k != NULL && ( clone_flags & SSG_CLONE_RECURSIVE ) )
setModel ( (ssgEntity *)( k -> clone ( clone_flags )) ) ;
else
setModel ( k ) ;
ssgTransform *t = src -> getPosTransform();
if ( t != NULL && ( clone_flags & SSG_CLONE_RECURSIVE ) )
pos = (ssgTransform *)( t -> clone ( clone_flags ) );
else
pos = t;
ssgVertexArray *v = src -> getLocations();
if ( v != NULL && ( clone_flags & SSG_CLONE_RECURSIVE ) )
locations = (ssgVertexArray *)( v -> clone ( clone_flags ) );
else
locations = v;
v = src -> getOrientations();
if ( v != NULL && ( clone_flags & SSG_CLONE_RECURSIVE ) )
orientations = (ssgVertexArray *)( v -> clone ( clone_flags ) );
else
orientations = v;
}
ssgBase *ssgEntityArray::clone ( int clone_flags )
{
ssgEntityArray *b = new ssgEntityArray ;
b -> copy_from ( this, clone_flags ) ;
return b ;
}
ssgEntityArray::ssgEntityArray (void)
{
type = ssgTypeBranch () ;
pos = new ssgTransform;
locations = new ssgVertexArray();
orientations = new ssgVertexArray();
}
ssgEntityArray::~ssgEntityArray (void)
{
removeModel() ;
ssgDeRefDelete( pos );
locations->removeAll();
orientations->removeAll();
delete orientations;
delete locations;
delete pos;
}
void ssgEntityArray::zeroSpareRecursive ()
{
zeroSpare () ;
model -> zeroSpareRecursive () ;
pos -> zeroSpareRecursive () ;
locations -> zeroSpareRecursive () ;
orientations -> zeroSpareRecursive () ;
}
void ssgEntityArray::recalcBSphere (void)
{
emptyBSphere () ;
pos->removeAllKids();
pos->addKid( model );
for ( int i = 0; i < locations->getNum(); ++i ) {
sgCoord c;
sgSetCoord( &c, locations->get(i), orientations->get(i) );
pos->setTransform( &c );
extendBSphere( pos->getBSphere() );
}
pos->removeAllKids();
/* FIXME: Traverse placement list
for ( ssgEntity *k = getKid ( 0 ) ; k != NULL ; k = getNextKid () )
extendBSphere ( k -> getBSphere () ) ;
*/
bsphere_is_invalid = FALSE ;
}
void ssgEntityArray::removeModel ()
{
model->deadBeefCheck () ;
ssgDeRefDelete ( model ) ;
}
void ssgEntityArray::replaceModel ( ssgEntity *new_entity )
{
removeModel();
setModel( new_entity );
}
void ssgEntityArray::addPlacement ( sgVec3 loc, sgVec3 orient )
{
locations->add( loc ) ;
orientations->add( orient ) ;
dirtyBSphere () ;
}
void ssgEntityArray::removeAllPlacements()
{
locations->removeAll();
orientations->removeAll();
dirtyBSphere () ;
}
void ssgEntityArray::print ( FILE *fd, char *indent, int how_much )
{
ssgEntity::print ( fd, indent, how_much ) ;
fprintf ( fd, "%s Num Kids=%d\n", indent, getNumKids() ) ;
if ( getNumParents() != getRef() )
ulSetError ( UL_WARNING, "Ref count doesn't tally with parent count" ) ;
if ( how_much > 1 )
{ if ( bsphere.isEmpty() )
fprintf ( fd, "%s BSphere is Empty.\n", indent ) ;
else
fprintf ( fd, "%s BSphere R=%g, C=(%g,%g,%g)\n", indent,
bsphere.getRadius(), bsphere.getCenter()[0], bsphere.getCenter()[1], bsphere.getCenter()[2] ) ;
}
char in [ 100 ] ;
sprintf ( in, "%s ", indent ) ;
model -> print ( fd, in, how_much ) ;
}
#ifdef HAVE_PLIB_PSL
void ssgEntityArray::getStats ( int *num_branches, int *num_leaves, int *num_tris, int *num_verts )
{
int nb, nl, nt, nv ;
*num_branches = 1 ; /* this! */
*num_leaves = 0 ;
*num_tris = 0 ;
*num_verts = 0 ;
model -> getStats ( & nb, & nl, & nt, & nv ) ;
*num_branches += nb * locations->getNum() ;
*num_leaves += nl * locations->getNum() ;
*num_tris += nt * locations->getNum() ;
*num_verts += nv * locations->getNum() ;
}
#endif
void ssgEntityArray::cull ( sgFrustum *f, sgMat4 m, int test_needed )
{
if ( ! preTravTests ( &test_needed, SSGTRAV_CULL ) )
return ;
int cull_result = cull_test ( f, m, test_needed ) ;
if ( cull_result == SSG_OUTSIDE )
return ;
pos->removeAllKids();
pos->addKid( model );
for ( int i = 0; i < locations->getNum(); ++i ) {
sgCoord c;
sgSetCoord( &c, locations->get(i), orientations->get(i) );
pos->setTransform( &c );
pos->cull( f, m, cull_result != SSG_INSIDE );
}
pos->removeAllKids();
postTravTests ( SSGTRAV_CULL ) ;
}
void ssgEntityArray::hot ( sgVec3 s, sgMat4 m, int test_needed )
{
if ( ! preTravTests ( &test_needed, SSGTRAV_HOT ) )
return ;
int hot_result = hot_test ( s, m, test_needed ) ;
if ( hot_result == SSG_OUTSIDE )
return ;
_ssgPushPath ( this ) ;
pos->removeAllKids();
pos->addKid( model );
for ( int i = 0; i < locations->getNum(); ++i ) {
sgCoord c;
sgSetCoord( &c, locations->get(i), orientations->get(i) );
pos->setTransform( &c );
pos->hot ( s, m, hot_result != SSG_INSIDE );
}
pos->removeAllKids();
_ssgPopPath () ;
postTravTests ( SSGTRAV_HOT ) ;
}
void ssgEntityArray::los ( sgVec3 s, sgMat4 m, int test_needed )
{
if ( ! preTravTests ( &test_needed, SSGTRAV_LOS ) )
return ;
int los_result = los_test ( s, m, test_needed ) ;
if ( los_result == SSG_OUTSIDE )
return ;
_ssgPushPath ( this ) ;
pos->removeAllKids();
pos->addKid( model );
for ( int i = 0; i < locations->getNum(); ++i ) {
sgCoord c;
sgSetCoord( &c, locations->get(i), orientations->get(i) );
pos->setTransform( &c );
pos->los ( s, m, los_result != SSG_INSIDE ) ;
}
pos->removeAllKids();
_ssgPopPath () ;
postTravTests ( SSGTRAV_LOS) ;
}
void ssgEntityArray::isect ( sgSphere *s, sgMat4 m, int test_needed )
{
if ( ! preTravTests ( &test_needed, SSGTRAV_ISECT ) )
return ;
int isect_result = isect_test ( s, m, test_needed ) ;
if ( isect_result == SSG_OUTSIDE )
return ;
_ssgPushPath ( this ) ;
pos->removeAllKids();
pos->addKid( model );
for ( int i = 0; i < locations->getNum(); ++i ) {
sgCoord c;
sgSetCoord( &c, locations->get(i), orientations->get(i) );
pos->setTransform( &c );
pos->isect ( s, m, isect_result != SSG_INSIDE ) ;
}
pos->removeAllKids();
_ssgPopPath () ;
postTravTests ( SSGTRAV_ISECT ) ;
}
#if 0
int ssgEntityArray::load ( FILE *fd )
{
int nkids ;
_ssgReadInt ( fd, & nkids ) ;
if ( ! ssgEntity::load ( fd ) )
return FALSE ;
for ( int i = 0 ; i < nkids ; i++ )
{
ssgEntity *kid ;
if ( ! _ssgLoadObject ( fd, (ssgBase **) &kid, ssgTypeEntity () ) )
return FALSE ;
addKid ( kid ) ;
}
return TRUE ;
}
int ssgEntityArray::save ( FILE *fd )
{
_ssgWriteInt ( fd, getNumKids() ) ;
if ( ! ssgEntity::save ( fd ) )
return FALSE ;
for ( int i = 0 ; i < getNumKids() ; i++ )
{
if ( ! _ssgSaveObject ( fd, getKid ( i ) ) )
return FALSE ;
}
return TRUE ;
}
#endif

View File

@@ -1,66 +0,0 @@
#ifndef _SSG_ENTITY_ARRAY_HXX
#define _SSG_ENTITY_ARRAY_HXX
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <plib/ssg.h>
class ssgEntityArray : public ssgEntity
{
// The replicated child
ssgEntity *model ;
// The one transformation node
ssgTransform *pos;
// The list of locations and orientations
ssgVertexArray *locations;
ssgVertexArray *orientations;
protected:
virtual void copy_from ( ssgEntityArray *src, int clone_flags ) ;
public:
virtual void zeroSpareRecursive ();
virtual ssgBase *clone ( int clone_flags = 0 ) ;
ssgEntityArray (void) ;
virtual ~ssgEntityArray (void) ;
ssgEntity *getModel () const { return model ; }
void setModel ( ssgEntity *entity ) { model = entity; }
void removeModel () ;
void replaceModel ( ssgEntity *new_entity ) ;
ssgVertexArray *getLocations () const { return locations; }
ssgVertexArray *getOrientations () const { return orientations; }
float *getLocation ( int i ) const { return locations->get( i ); }
float *getOrientation ( int i ) const { return orientations->get( i ); }
void addPlacement ( sgVec3 loc, sgVec3 orient );
virtual int getNumPlacements() const { return locations->getNum(); }
void removeAllPlacements();
ssgTransform *getPosTransform() { return pos; }
virtual const char *getTypeName(void) ;
virtual void cull ( sgFrustum *f, sgMat4 m, int test_needed ) ;
virtual void isect ( sgSphere *s, sgMat4 m, int test_needed ) ;
virtual void hot ( sgVec3 s, sgMat4 m, int test_needed ) ;
virtual void los ( sgVec3 s, sgMat4 m, int test_needed ) ;
virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
#ifdef HAVE_PLIB_PSL
virtual void getStats ( int *num_branches, int *num_leaves, int *num_tris, int *num_vertices ) ;
#endif
virtual int load ( FILE *fd ) ;
virtual int save ( FILE *fd ) ;
virtual void recalcBSphere () ;
} ;
#endif // _SSG_ENTITY_ARRAY_HXX

View File

@@ -2,7 +2,65 @@
/*
* $Log$
* Revision 1.3 2006/02/21 10:47:21 ehofman
* Revision 1.4 2006/10/29 19:27:11 frohlich
* Modified Files:
* configure.ac simgear/environment/visual_enviro.cxx
* simgear/ephemeris/ephemeris.cxx
* simgear/ephemeris/ephemeris.hxx simgear/ephemeris/stardata.cxx
* simgear/ephemeris/stardata.hxx simgear/math/SGMatrix.hxx
* simgear/math/SGQuat.hxx simgear/math/SGVec3.hxx
* simgear/math/SGVec4.hxx simgear/scene/Makefile.am
* simgear/scene/material/mat.cxx simgear/scene/material/mat.hxx
* simgear/scene/material/matlib.cxx
* simgear/scene/material/matlib.hxx
* simgear/scene/material/matmodel.cxx
* simgear/scene/material/matmodel.hxx
* simgear/scene/model/Makefile.am
* simgear/scene/model/animation.cxx
* simgear/scene/model/animation.hxx
* simgear/scene/model/custtrans.hxx
* simgear/scene/model/model.cxx simgear/scene/model/model.hxx
* simgear/scene/model/modellib.cxx
* simgear/scene/model/modellib.hxx
* simgear/scene/model/personality.cxx
* simgear/scene/model/personality.hxx
* simgear/scene/model/placement.cxx
* simgear/scene/model/placement.hxx
* simgear/scene/model/placementtrans.cxx
* simgear/scene/model/placementtrans.hxx
* simgear/scene/model/shadanim.cxx
* simgear/scene/model/shadowvolume.hxx
* simgear/scene/sky/cloud.cxx simgear/scene/sky/cloud.hxx
* simgear/scene/sky/cloudfield.cxx simgear/scene/sky/dome.cxx
* simgear/scene/sky/dome.hxx simgear/scene/sky/moon.cxx
* simgear/scene/sky/moon.hxx simgear/scene/sky/newcloud.cxx
* simgear/scene/sky/oursun.cxx simgear/scene/sky/oursun.hxx
* simgear/scene/sky/sky.cxx simgear/scene/sky/sky.hxx
* simgear/scene/sky/sphere.cxx simgear/scene/sky/sphere.hxx
* simgear/scene/sky/stars.cxx simgear/scene/sky/stars.hxx
* simgear/scene/tgdb/apt_signs.cxx
* simgear/scene/tgdb/apt_signs.hxx simgear/scene/tgdb/leaf.cxx
* simgear/scene/tgdb/leaf.hxx simgear/scene/tgdb/obj.cxx
* simgear/scene/tgdb/obj.hxx simgear/scene/tgdb/pt_lights.cxx
* simgear/scene/tgdb/pt_lights.hxx
* simgear/scene/tgdb/userdata.cxx
* simgear/scene/tgdb/userdata.hxx simgear/scene/tgdb/vasi.hxx
* simgear/screen/jpgfactory.cxx simgear/screen/tr.cxx
* simgear/structure/Makefile.am simgear/threads/SGThread.hxx
* Added Files:
* simgear/scene/util/Makefile.am
* simgear/scene/util/SGDebugDrawCallback.hxx
* simgear/scene/util/SGNodeMasks.hxx
* simgear/scene/util/SGStateAttributeVisitor.hxx
* simgear/scene/util/SGTextureStateAttributeVisitor.hxx
* simgear/scene/util/SGUpdateVisitor.hxx
* Removed Files:
* simgear/screen/ssgEntityArray.cxx
* simgear/screen/ssgEntityArray.hxx
* simgear/structure/ssgSharedPtr.hxx
* Big BLOB on the way to OSG.
*
* Revision 1.3 2006-02-21 10:47:21 ehofman
* Back out the previous patch.
*
* Revision 1.2 2004/11/18 19:10:34 curt
@@ -73,7 +131,6 @@
#include SG_GLU_H
#include <plib/ssg.h>
#include "tr.h"
@@ -395,7 +452,8 @@ void trBeginTile(TRcontext *tr)
* (tr->CurrentRow * tr->TileHeightNB - border) / tr->ImageHeight;
top = bottom + (tr->Top - tr->Bottom) * tileHeight / tr->ImageHeight;
ssgSetFrustum ( left, right, bottom, top, tr->Near, tr->Far );
// OSGFIXME
// ssgSetFrustum ( left, right, bottom, top, tr->Near, tr->Far );
/* restore user's matrix mode */
glMatrixMode( (GLenum)matrixMode );

View File

@@ -7,7 +7,6 @@ include_HEADERS = \
commands.hxx \
exception.hxx \
event_mgr.hxx \
ssgSharedPtr.hxx \
subsystem_mgr.hxx \
SGReferenced.hxx \
SGSharedPtr.hxx

View File

@@ -1,94 +0,0 @@
/* -*-c++-*-
*
* Copyright (C) 2005-2006 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 ssgSharedPtr_HXX
#define ssgSharedPtr_HXX
/// This class is a pointer proxy doing reference counting on the object
/// it is pointing to.
/// It is very similar to the SGSharedPtr class but is made to work together
/// with reference counting of plib's ssg reference counters
/// For notes on usage see SGSharedPtr.
template<typename T>
class ssgSharedPtr {
public:
ssgSharedPtr(void) : _ptr(0)
{}
ssgSharedPtr(T* ptr) : _ptr(ptr)
{ get(_ptr); }
ssgSharedPtr(const ssgSharedPtr& p) : _ptr(p.ptr())
{ get(_ptr); }
template<typename U>
ssgSharedPtr(const ssgSharedPtr<U>& p) : _ptr(p.ptr())
{ get(_ptr); }
~ssgSharedPtr(void)
{ put(); }
ssgSharedPtr& operator=(const ssgSharedPtr& p)
{ assign(p.ptr()); return *this; }
template<typename U>
ssgSharedPtr& operator=(const ssgSharedPtr<U>& p)
{ assign(p.ptr()); return *this; }
template<typename U>
ssgSharedPtr& operator=(U* p)
{ assign(p); return *this; }
T* operator->(void) const
{ return _ptr; }
T& operator*(void) const
{ return *_ptr; }
operator T*(void) const
{ return _ptr; }
T* ptr(void) const
{ return _ptr; }
bool isShared(void) const
{ if (_ptr) return 1 < _ptr->getRef(); else return false; }
unsigned getNumRefs(void) const
{ if (_ptr) return _ptr->getRef(); else return 0; }
bool valid(void) const
{ return _ptr; }
private:
void assign(T* p)
{ get(p); put(); _ptr = p; }
static void get(T* p)
{ if (p) p->ref(); }
void put(void)
{
if (!_ptr)
return;
assert(0 < _ptr->getRef());
_ptr->deRef();
if (_ptr->getRef() == 0) {
delete _ptr;
_ptr = 0;
}
}
// The reference itself.
T* _ptr;
};
#endif

View File

@@ -136,6 +136,7 @@ SGThread::start( unsigned cpu )
{
int status = pthread_create( &tid, 0, start_handler, this );
assert( status == 0 );
(void)status;
#if defined( sgi )
if ( !status && !cpu )
pthread_setrunon_np( cpu );
@@ -148,6 +149,7 @@ SGThread::join()
{
int status = pthread_join( tid, 0 );
assert( status == 0 );
(void)status;
}
inline void
@@ -155,6 +157,7 @@ SGThread::cancel()
{
int status = pthread_cancel( tid );
assert( status == 0 );
(void)status;
}
/**
@@ -219,24 +222,28 @@ inline SGMutex::SGMutex()
{
int status = pthread_mutex_init( &mutex, 0 );
assert( status == 0 );
(void)status;
}
inline SGMutex::~SGMutex()
{
int status = pthread_mutex_destroy( &mutex );
assert( status == 0 );
(void)status;
}
inline void SGMutex::lock()
{
int status = pthread_mutex_lock( &mutex );
assert( status == 0 );
(void)status;
}
inline void SGMutex::unlock()
{
int status = pthread_mutex_unlock( &mutex );
assert( status == 0 );
(void)status;
}
/**
@@ -307,30 +314,35 @@ inline SGPthreadCond::SGPthreadCond()
{
int status = pthread_cond_init( &cond, 0 );
assert( status == 0 );
(void)status;
}
inline SGPthreadCond::~SGPthreadCond()
{
int status = pthread_cond_destroy( &cond );
assert( status == 0 );
(void)status;
}
inline void SGPthreadCond::signal()
{
int status = pthread_cond_signal( &cond );
assert( status == 0 );
(void)status;
}
inline void SGPthreadCond::broadcast()
{
int status = pthread_cond_broadcast( &cond );
assert( status == 0 );
(void)status;
}
inline void SGPthreadCond::wait( SGMutex& mutex )
{
int status = pthread_cond_wait( &cond, &mutex.mutex );
assert( status == 0 );
(void)status;
}
#endif /* SGTHREAD_HXX_INCLUDED */