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:
@@ -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 \
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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) );
|
||||
}
|
||||
|
||||
@@ -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(); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ...
|
||||
|
||||
@@ -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<>
|
||||
|
||||
@@ -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 ...
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
includedir = @includedir@/scene
|
||||
|
||||
SUBDIRS = material model sky tgdb
|
||||
SUBDIRS = material model sky tgdb util
|
||||
|
||||
# lib_LIBRARIES = libsgscene.a
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
#ifndef _SG_CUSTOM_TRANSFORM_HXX
|
||||
#define _SG_CUSTOM_TRANSFORM_HXX 1
|
||||
|
||||
#include "plib/ssg.h"
|
||||
|
||||
class SGCustomTransform : public ssgBranch
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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) {}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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_
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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( ¢er_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;
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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 *
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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 );
|
||||
|
||||
|
||||
@@ -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);
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
16
simgear/scene/util/Makefile.am
Normal file
16
simgear/scene/util/Makefile.am
Normal 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)
|
||||
164
simgear/scene/util/SGDebugDrawCallback.hxx
Normal file
164
simgear/scene/util/SGDebugDrawCallback.hxx
Normal 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
|
||||
28
simgear/scene/util/SGNodeMasks.hxx
Normal file
28
simgear/scene/util/SGNodeMasks.hxx
Normal 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
|
||||
65
simgear/scene/util/SGStateAttributeVisitor.hxx
Normal file
65
simgear/scene/util/SGStateAttributeVisitor.hxx
Normal 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
|
||||
70
simgear/scene/util/SGTextureStateAttributeVisitor.hxx
Normal file
70
simgear/scene/util/SGTextureStateAttributeVisitor.hxx
Normal 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
|
||||
66
simgear/scene/util/SGUpdateVisitor.hxx
Normal file
66
simgear/scene/util/SGUpdateVisitor.hxx
Normal 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
|
||||
@@ -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(),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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 );
|
||||
|
||||
@@ -7,7 +7,6 @@ include_HEADERS = \
|
||||
commands.hxx \
|
||||
exception.hxx \
|
||||
event_mgr.hxx \
|
||||
ssgSharedPtr.hxx \
|
||||
subsystem_mgr.hxx \
|
||||
SGReferenced.hxx \
|
||||
SGSharedPtr.hxx
|
||||
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user