From: frohlich Date: Sun, 29 Oct 2006 19:27:08 +0000 (+0000) Subject: Modified Files: X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=84dd54b33a6d8b35e57c32194b025f79245f35c4;p=simgear.git 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. --- diff --git a/configure.ac b/configure.ac index b59695a8..fcc326d7 100644 --- a/configure.ac +++ b/configure.ac @@ -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 \ diff --git a/simgear/environment/visual_enviro.cxx b/simgear/environment/visual_enviro.cxx index 1f8d3acf..9371503e 100644 --- a/simgear/environment/visual_enviro.cxx +++ b/simgear/environment/visual_enviro.cxx @@ -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 ) diff --git a/simgear/ephemeris/ephemeris.cxx b/simgear/ephemeris/ephemeris.cxx index 46c7df2c..7f14dd6f 100644 --- a/simgear/ephemeris/ephemeris.cxx +++ b/simgear/ephemeris/ephemeris.cxx @@ -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) ); } diff --git a/simgear/ephemeris/ephemeris.hxx b/simgear/ephemeris/ephemeris.hxx index e8fd02cf..7554391f 100644 --- a/simgear/ephemeris/ephemeris.hxx +++ b/simgear/ephemeris/ephemeris.hxx @@ -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(); } }; diff --git a/simgear/ephemeris/stardata.cxx b/simgear/ephemeris/stardata.cxx index 4c703cf9..7f04b8b2 100644 --- a/simgear/ephemeris/stardata.cxx +++ b/simgear/ephemeris/stardata.cxx @@ -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; } diff --git a/simgear/ephemeris/stardata.hxx b/simgear/ephemeris/stardata.hxx index 7f207888..5ac685b3 100644 --- a/simgear/ephemeris/stardata.hxx +++ b/simgear/ephemeris/stardata.hxx @@ -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; } }; diff --git a/simgear/math/SGMatrix.hxx b/simgear/math/SGMatrix.hxx index 9f0edce9..ed146038 100644 --- a/simgear/math/SGMatrix.hxx +++ b/simgear/math/SGMatrix.hxx @@ -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 diff --git a/simgear/math/SGQuat.hxx b/simgear/math/SGQuat.hxx index c50f185d..f05568e0 100644 --- a/simgear/math/SGQuat.hxx +++ b/simgear/math/SGQuat.hxx @@ -26,10 +26,42 @@ #undef max #endif +#include + +template +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 : 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 -class SGQuat { +class SGQuat : protected SGQuatStorage { 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::quiet_NaN(); + data()[i] = SGLimits::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::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::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 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 SGQuat& operator/=(S s) @@ -343,10 +376,6 @@ public: return deriv; } - -private: - /// The actual data - T _data[4]; }; /// Unary +, do nothing ... diff --git a/simgear/math/SGVec3.hxx b/simgear/math/SGVec3.hxx index c6f99657..ee75415c 100644 --- a/simgear/math/SGVec3.hxx +++ b/simgear/math/SGVec3.hxx @@ -18,9 +18,58 @@ #ifndef SGVec3_H #define SGVec3_H +#include +#include + +template +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 : 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 : 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 -class SGVec3 { +class SGVec3 : protected SGVec3Storage { 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::quiet_NaN(); + data()[i] = SGLimits::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::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::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 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 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<> diff --git a/simgear/math/SGVec4.hxx b/simgear/math/SGVec4.hxx index feee964b..50b138c9 100644 --- a/simgear/math/SGVec4.hxx +++ b/simgear/math/SGVec4.hxx @@ -18,9 +18,58 @@ #ifndef SGVec4_H #define SGVec4_H +#include +#include + +template +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 : 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 : 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 -class SGVec4 { +class SGVec4 : protected SGVec4Storage { 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::quiet_NaN(); + data()[i] = SGLimits::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, 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 SGVec4Storage::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::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 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 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 ... diff --git a/simgear/scene/Makefile.am b/simgear/scene/Makefile.am index c6aed399..ff99d550 100644 --- a/simgear/scene/Makefile.am +++ b/simgear/scene/Makefile.am @@ -1,6 +1,6 @@ includedir = @includedir@/scene -SUBDIRS = material model sky tgdb +SUBDIRS = material model sky tgdb util # lib_LIBRARIES = libsgscene.a diff --git a/simgear/scene/material/mat.cxx b/simgear/scene/material/mat.cxx index b8af8091..b9d4fa6d 100644 --- a/simgear/scene/material/mat.cxx +++ b/simgear/scene/material/mat.cxx @@ -37,14 +37,21 @@ SG_USING_STD(map); # include #endif +#include +#include +#include +#include +#include +#include + #include #include #include +#include #include "mat.hxx" -static map _tex_cache; -static map::iterator _tex_cache_iter; +static map > _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 ); - - _status[i].state = state; + 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 = 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 >::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 diff --git a/simgear/scene/material/mat.hxx b/simgear/scene/material/mat.hxx index e3e38a13..a55ddd73 100644 --- a/simgear/scene/material/mat.hxx +++ b/simgear/scene/material/mat.hxx @@ -38,11 +38,10 @@ #include -#include -#include +#include +#include #include -#include #include #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 state; + osg::ref_ptr 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) diff --git a/simgear/scene/material/matlib.cxx b/simgear/scene/material/matlib.cxx index b3f702cc..07a20b11 100644 --- a/simgear/scene/material/matlib.cxx +++ b/simgear/scene/material/matlib.cxx @@ -33,8 +33,6 @@ # include #endif -#include - #include #include #include @@ -44,6 +42,20 @@ #include #include STL_STRING +#include +#include +#include +#include +// #include +#include +#include +#include +#include +#include +#include +#include +#include + #include #include #include @@ -57,62 +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 ) { +// generate standard colored directional light environment texture map +static osg::Texture2D* +gen_standard_dir_light_map( int r, int g, int b, int alpha ) { const int env_tex_res = 32; int half_res = env_tex_res / 2; - 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; @@ -120,100 +96,84 @@ static int gen_standard_light_sprite( int r, int g, int b, int alpha ) { 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); + if ( bright < 0.3 ) { bright = 0.3; } + unsigned char* env_map = image->data(i, j); + env_map[0] = r; + env_map[1] = g; + env_map[2] = b; + env_map[3] = (int)(bright * alpha); } } - 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; + + osg::Texture2D* texture = new osg::Texture2D; + texture->setImage(image); + + return texture; } // 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_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 ) { double x = (i - half_res) / (double)half_res; double y = (j - half_res) / (double)half_res; - double dist = sqrt(x*x + y*y); + double tmp = sqrt(x*x + y*y); + double dist = tmp * tmp; 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); + double bright = sin( dist * SGD_PI_2 ); + if ( bright < 0.2 ) { bright = 0.2; } + unsigned char* env_map = image->data(i, j); + env_map[0] = r; + env_map[1] = g; + env_map[2] = b; + env_map[3] = (int)(bright * alpha); } } - 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; -} + osg::Texture2D* texture = new osg::Texture2D; + texture->setImage(image); + 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_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; + + osg::Image* image = new osg::Image; + image->allocateImage(env_tex_res, env_tex_res, 1, + GL_RGBA, GL_UNSIGNED_BYTE); for ( int i = 0; i < env_tex_res; ++i ) { for ( int j = 0; j < env_tex_res; ++j ) { double x = (i - half_res) / (double)half_res; double y = (j - half_res) / (double)half_res; - double tmp = sqrt(x*x + y*y); - double dist = tmp * tmp; + double dist = sqrt(x*x + y*y); 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); + 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); } } - 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; + 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 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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(base); + const SGMaterialUserData* matUserData + = dynamic_cast(base); if (!matUserData) return 0; diff --git a/simgear/scene/material/matlib.hxx b/simgear/scene/material/matlib.hxx index 057c4220..14a0a8d1 100644 --- a/simgear/scene/material/matlib.hxx +++ b/simgear/scene/material/matlib.hxx @@ -37,8 +37,8 @@ #include // STL associative "array" #include // STL "array" -#include // plib include - +#include +#include 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 ); diff --git a/simgear/scene/material/matmodel.cxx b/simgear/scene/material/matmodel.cxx index 314f1403..789f29ee 100644 --- a/simgear/scene/material/matmodel.cxx +++ b/simgear/scene/material/matmodel.cxx @@ -30,7 +30,11 @@ #include SG_USING_STD(map); -#include +#include +#include +#include +#include +#include #ifdef SG_MATH_EXCEPTION_CLASH # include @@ -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; igetKid(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 diff --git a/simgear/scene/material/matmodel.hxx b/simgear/scene/material/matmodel.hxx index 8802ad2b..85363e80 100644 --- a/simgear/scene/material/matmodel.hxx +++ b/simgear/scene/material/matmodel.hxx @@ -32,12 +32,11 @@ #include STL_STRING // Standard C++ string library -#include -#include +#include +#include #include #include -#include #include 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 _paths; - mutable vector > _models; + mutable vector > _models; mutable bool _models_loaded; double _coverage_m2; double _range_m; @@ -198,7 +197,6 @@ private: double _range_m; vector > _objects; - }; diff --git a/simgear/scene/model/Makefile.am b/simgear/scene/model/Makefile.am index acdd4716..ac2b8e81 100644 --- a/simgear/scene/model/Makefile.am +++ b/simgear/scene/model/Makefile.am @@ -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) diff --git a/simgear/scene/model/animation.cxx b/simgear/scene/model/animation.cxx index 36ae1e50..d99d846c 100644 --- a/simgear/scene/model/animation.cxx +++ b/simgear/scene/model/animation.cxx @@ -10,18 +10,26 @@ #include // for strcmp() #include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include +#include #include "animation.hxx" -#include "custtrans.hxx" #include "personality.hxx" +#include "model.hxx" //////////////////////////////////////////////////////////////////////// @@ -32,8 +40,8 @@ * Set up the transform matrix for a spin or rotation. */ static void -set_rotation (sgMat4 &matrix, double position_deg, - sgVec3 ¢er, sgVec3 &axis) +set_rotation (osg::Matrix &matrix, double position_deg, + const osg::Vec3 ¢er, const osg::Vec3 &axis) { float temp_angle = -position_deg * SG_DEGREES_TO_RADIANS ; @@ -47,80 +55,55 @@ set_rotation (sgMat4 &matrix, double position_deg, float y = axis[1]; float z = axis[2]; - matrix[0][0] = t * x * x + c ; - matrix[0][1] = t * y * x - s * z ; - matrix[0][2] = t * z * x + s * y ; - matrix[0][3] = SG_ZERO; + matrix(0, 0) = t * x * x + c ; + matrix(0, 1) = t * y * x - s * z ; + matrix(0, 2) = t * z * x + s * y ; + matrix(0, 3) = SG_ZERO; - matrix[1][0] = t * x * y + s * z ; - matrix[1][1] = t * y * y + c ; - matrix[1][2] = t * z * y - s * x ; - matrix[1][3] = SG_ZERO; + matrix(1, 0) = t * x * y + s * z ; + matrix(1, 1) = t * y * y + c ; + matrix(1, 2) = t * z * y - s * x ; + matrix(1, 3) = SG_ZERO; - matrix[2][0] = t * x * z - s * y ; - matrix[2][1] = t * y * z + s * x ; - matrix[2][2] = t * z * z + c ; - matrix[2][3] = SG_ZERO; + matrix(2, 0) = t * x * z - s * y ; + matrix(2, 1) = t * y * z + s * x ; + matrix(2, 2) = t * z * z + c ; + matrix(2, 3) = SG_ZERO; // hint to the compiler to put these into FP registers x = center[0]; y = center[1]; z = center[2]; - matrix[3][0] = x - x*matrix[0][0] - y*matrix[1][0] - z*matrix[2][0]; - matrix[3][1] = y - x*matrix[0][1] - y*matrix[1][1] - z*matrix[2][1]; - matrix[3][2] = z - x*matrix[0][2] - y*matrix[1][2] - z*matrix[2][2]; - matrix[3][3] = SG_ONE; + matrix(3, 0) = x - x*matrix(0, 0) - y*matrix(1, 0) - z*matrix(2, 0); + matrix(3, 1) = y - x*matrix(0, 1) - y*matrix(1, 1) - z*matrix(2, 1); + matrix(3, 2) = z - x*matrix(0, 2) - y*matrix(1, 2) - z*matrix(2, 2); + matrix(3, 3) = SG_ONE; } /** * Set up the transform matrix for a translation. */ static void -set_translation (sgMat4 &matrix, double position_m, sgVec3 &axis) +set_translation (osg::Matrix &matrix, double position_m, const osg::Vec3 &axis) { - sgVec3 xyz; - sgScaleVec3(xyz, axis, position_m); - sgMakeTransMat4(matrix, xyz); + osg::Vec3 xyz = axis * position_m; + matrix.makeIdentity(); + matrix(3, 0) = xyz[0]; + matrix(3, 1) = xyz[1]; + matrix(3, 2) = xyz[2]; } /** * Set up the transform matrix for a scale operation. */ static void -set_scale (sgMat4 &matrix, double x, double y, double z) +set_scale (osg::Matrix &matrix, double x, double y, double z) { - sgMakeIdentMat4( matrix ); - matrix[0][0] = x; - matrix[1][1] = y; - matrix[2][2] = z; -} - -/** - * Recursively process all kids to change the alpha values - */ -static void -change_alpha( ssgBase *_branch, float _blend ) -{ - int i; - - for (i = 0; i < ((ssgBranch *)_branch)->getNumKids(); i++) - change_alpha( ((ssgBranch *)_branch)->getKid(i), _blend ); - - if ( !_branch->isAKindOf(ssgTypeLeaf()) - && !_branch->isAKindOf(ssgTypeVtxTable()) - && !_branch->isAKindOf(ssgTypeVTable()) ) - return; - - int num_colors = ((ssgLeaf *)_branch)->getNumColours(); -// unsigned int select_ = (_blend == 1.0) ? false : true; - - for (i = 0; i < num_colors; i++) - { -// ((ssgSelector *)_branch)->select( select_ ); - float *color = ((ssgLeaf *)_branch)->getColour(i); - color[3] = _blend; - } + matrix.makeIdentity(); + matrix(0, 0) = x; + matrix(1, 1) = y; + matrix(2, 2) = z; } /** @@ -181,15 +164,15 @@ read_interpolation_table (SGPropertyNode_ptr props) double SGAnimation::sim_time_sec = 0.0; SGPersonalityBranch *SGAnimation::current_object = 0; -SGAnimation::SGAnimation (SGPropertyNode_ptr props, ssgBranch * branch) +SGAnimation::SGAnimation (SGPropertyNode_ptr props, osg::Group * branch) : _branch(branch), animation_type(0) { - _branch->setName(props->getStringValue("name", 0)); + _branch->setName(props->getStringValue("name", "Animation")); if ( props->getBoolValue( "enable-hot", true ) ) { - _branch->setTraversalMaskBits( SSGTRAV_HOT ); + _branch->setNodeMask(SG_NODEMASK_TERRAIN_BIT|_branch->getNodeMask()); } else { - _branch->clrTraversalMaskBits( SSGTRAV_HOT ); + _branch->setNodeMask(~SG_NODEMASK_TERRAIN_BIT&_branch->getNodeMask()); } } @@ -220,7 +203,7 @@ SGAnimation::restore() //////////////////////////////////////////////////////////////////////// SGNullAnimation::SGNullAnimation (SGPropertyNode_ptr props) - : SGAnimation(props, new ssgBranch) + : SGAnimation(props, new osg::Group) { } @@ -236,7 +219,7 @@ SGNullAnimation::~SGNullAnimation () SGRangeAnimation::SGRangeAnimation (SGPropertyNode *prop_root, SGPropertyNode_ptr props) - : SGAnimation(props, new ssgRangeSelector), + : SGAnimation(props, new osg::LOD), _min(0.0), _max(0.0), _min_factor(1.0), _max_factor(1.0), _condition(0) { @@ -270,7 +253,7 @@ SGRangeAnimation::SGRangeAnimation (SGPropertyNode *prop_root, _max = props->getFloatValue("max-m", 0); ranges[1] = _max * _max_factor; } - ((ssgRangeSelector *)_branch)->setRanges(ranges, 2); + static_cast(_branch)->setRange(0, ranges[0], ranges[1]); } SGRangeAnimation::~SGRangeAnimation () @@ -296,7 +279,7 @@ SGRangeAnimation::update() ranges[0] = 0.f; ranges[1] = 1000000000.f; } - ((ssgRangeSelector *)_branch)->setRanges(ranges, 2); + static_cast(_branch)->setRange(0, ranges[0], ranges[1]); return 2; } @@ -307,8 +290,18 @@ SGRangeAnimation::update() //////////////////////////////////////////////////////////////////////// SGBillboardAnimation::SGBillboardAnimation (SGPropertyNode_ptr props) - : SGAnimation(props, new ssgCutout(props->getBoolValue("spherical", true))) + : SGAnimation(props, new osg::AutoTransform) { +//OSGFIXME: verify + bool spherical = props->getBoolValue("spherical", true); + osg::AutoTransform* autoTrans = static_cast(_branch); + if (spherical) { + autoTrans->setAutoRotateMode(osg::AutoTransform::ROTATE_TO_SCREEN); + } else { + autoTrans->setAutoRotateMode(osg::AutoTransform::NO_ROTATION); + autoTrans->setReferenceFrame(osg::Transform::ABSOLUTE_RF); + } + autoTrans->setAutoScaleToScreen(false); } SGBillboardAnimation::~SGBillboardAnimation () @@ -323,7 +316,7 @@ SGBillboardAnimation::~SGBillboardAnimation () SGSelectAnimation::SGSelectAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props ) - : SGAnimation(props, new ssgSelector), + : SGAnimation(props, new osg::Switch), _condition(0) { SGPropertyNode_ptr node = props->getChild("condition"); @@ -336,17 +329,16 @@ SGSelectAnimation::~SGSelectAnimation () delete _condition; } -int -SGSelectAnimation::update() -{ - if (_condition != 0 && _condition->test()) - ((ssgSelector *)_branch)->select(0xffff); +void +SGSelectAnimation::operator()(osg::Node* node, osg::NodeVisitor* nv) +{ + if (_condition != 0 && _condition->test()) + static_cast(_branch)->setAllChildrenOn(); else - ((ssgSelector *)_branch)->select(0x0000); - return 2; + static_cast(_branch)->setAllChildrenOff(); + traverse(node, nv); } - //////////////////////////////////////////////////////////////////////// // Implementation of SGSpinAnimation @@ -355,13 +347,13 @@ SGSelectAnimation::update() SGSpinAnimation::SGSpinAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props, double sim_time_sec ) - : SGAnimation(props, new ssgTransform), + : SGAnimation(props, new osg::MatrixTransform), _use_personality( props->getBoolValue("use-personality",false) ), _prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)), - _last_time_sec( sim_time_sec ), - _condition(0), _factor( props, "factor", 1.0 ), - _position_deg( props, "starting-position-deg", 0.0 ) + _position_deg( props, "starting-position-deg", 0.0 ), + _last_time_sec( sim_time_sec ), + _condition(0) { SGPropertyNode_ptr node = props->getChild("condition"); if (node != 0) @@ -395,7 +387,8 @@ SGSpinAnimation::SGSpinAnimation( SGPropertyNode *prop_root, _center[1] = props->getFloatValue("center/y-m", 0); _center[2] = props->getFloatValue("center/z-m", 0); } - sgNormalizeVec3(_axis); + + _axis.normalize(); } SGSpinAnimation::~SGSpinAnimation () @@ -427,10 +420,7 @@ SGSpinAnimation::update() velocity_rpms = (_prop->getDoubleValue() * _factor / 60.0); _position_deg += (dt * velocity_rpms * 360); - while (_position_deg < 0) - _position_deg += 360.0; - while (_position_deg >= 360.0) - _position_deg -= 360.0; + _position_deg -= 360*floor(_position_deg/360); key->setDoubleValue( _position_deg, this, POSITION_DEG_SPIN ); } else { dt = sim_time_sec - _last_time_sec; @@ -438,14 +428,12 @@ SGSpinAnimation::update() velocity_rpms = (_prop->getDoubleValue() * _factor / 60.0); _position_deg += (dt * velocity_rpms * 360); - while (_position_deg < 0) - _position_deg += 360.0; - while (_position_deg >= 360.0) - _position_deg -= 360.0; + _position_deg -= 360*floor(_position_deg/360); } + osg::Matrix _matrix; set_rotation(_matrix, _position_deg, _center, _axis); - ((ssgTransform *)_branch)->setTransform(_matrix); + static_cast(_branch)->setMatrix(_matrix); } return 1; } @@ -457,7 +445,7 @@ SGSpinAnimation::update() //////////////////////////////////////////////////////////////////////// SGTimedAnimation::SGTimedAnimation (SGPropertyNode_ptr props) - : SGAnimation(props, new ssgSelector), + : SGAnimation(props, new osg::Switch), _use_personality( props->getBoolValue("use-personality",false) ), _duration_sec(props->getDoubleValue("duration-sec", 1.0)), _last_time_sec( sim_time_sec ), @@ -490,9 +478,9 @@ void SGTimedAnimation::init() { if ( !_use_personality ) { - for ( int i = 0; i < getBranch()->getNumKids(); i++ ) { + for ( unsigned i = 0; i < getBranch()->getNumChildren(); i++ ) { double v; - if ( i < (int)_branch_duration_specs.size() ) { + if ( i < _branch_duration_specs.size() ) { DurationSpec &sp = _branch_duration_specs[ i ]; v = sp._min + sg_random() * ( sp._max - sp._min ); } else { @@ -501,12 +489,14 @@ SGTimedAnimation::init() _branch_duration_sec.push_back( v ); _total_duration_sec += v; } - // Sanity check : total duration shouldn't equal zero - if ( _total_duration_sec < 0.01 ) { - _total_duration_sec = 0.01; - } } - ((ssgSelector *)getBranch())->selectStep(_step); + // Sanity check : total duration shouldn't equal zero + if (_duration_sec < 0.01) + _duration_sec = 0.01; + if ( _total_duration_sec < 0.01 ) + _total_duration_sec = 0.01; + + static_cast(getBranch())->setSingleChildOn(_step); } int @@ -539,36 +529,32 @@ SGTimedAnimation::update() _step = key->getIntValue( this, STEP_TIMED ); _last_time_sec = key->getDoubleValue( this, LAST_TIME_SEC_TIMED ); _total_duration_sec = key->getDoubleValue( this, TOTAL_DURATION_SEC_TIMED ); - while ( ( sim_time_sec - _last_time_sec ) >= _total_duration_sec ) { - _last_time_sec += _total_duration_sec; - } + _last_time_sec -= _total_duration_sec*floor((sim_time_sec - _last_time_sec)/_total_duration_sec); double duration = _duration_sec; - if ( _step < (int)_branch_duration_specs.size() ) { + if ( _step < _branch_duration_specs.size() ) { duration = key->getDoubleValue( this, BRANCH_DURATION_SEC_TIMED, _step ); } if ( ( sim_time_sec - _last_time_sec ) >= duration ) { _last_time_sec += duration; _step += 1; - if ( _step >= getBranch()->getNumKids() ) + if ( _step >= getBranch()->getNumChildren() ) _step = 0; } - ((ssgSelector *)getBranch())->selectStep( _step ); + static_cast(getBranch())->setSingleChildOn(_step); key->setDoubleValue( _last_time_sec, this, LAST_TIME_SEC_TIMED ); key->setIntValue( _step, this, STEP_TIMED ); } else { - while ( ( sim_time_sec - _last_time_sec ) >= _total_duration_sec ) { - _last_time_sec += _total_duration_sec; - } + _last_time_sec -= _total_duration_sec*floor((sim_time_sec - _last_time_sec)/_total_duration_sec); double duration = _duration_sec; - if ( _step < (int)_branch_duration_sec.size() ) { + if ( _step < _branch_duration_sec.size() ) { duration = _branch_duration_sec[ _step ]; } if ( ( sim_time_sec - _last_time_sec ) >= duration ) { _last_time_sec += duration; _step += 1; - if ( _step >= getBranch()->getNumKids() ) + if ( _step >= getBranch()->getNumChildren() ) _step = 0; - ((ssgSelector *)getBranch())->selectStep( _step ); + static_cast(getBranch())->setSingleChildOn(_step); } } return 1; @@ -582,7 +568,7 @@ SGTimedAnimation::update() SGRotateAnimation::SGRotateAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props ) - : SGAnimation(props, new ssgTransform), + : SGAnimation(props, new osg::MatrixTransform), _prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)), _offset_deg(props->getDoubleValue("offset-deg", 0.0)), _factor(props->getDoubleValue("factor", 1.0)), @@ -627,7 +613,7 @@ SGRotateAnimation::SGRotateAnimation( SGPropertyNode *prop_root, _center[1] = props->getFloatValue("center/y-m", 0); _center[2] = props->getFloatValue("center/z-m", 0); } - sgNormalizeVec3(_axis); + _axis.normalize(); } SGRotateAnimation::~SGRotateAnimation () @@ -648,8 +634,9 @@ SGRotateAnimation::update() } else { _position_deg = _table->interpolate(_prop->getDoubleValue()); } + osg::Matrix _matrix; set_rotation(_matrix, _position_deg, _center, _axis); - ((ssgTransform *)_branch)->setTransform(_matrix); + static_cast(_branch)->setMatrix(_matrix); } return 2; } @@ -661,7 +648,7 @@ SGRotateAnimation::update() SGBlendAnimation::SGBlendAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props ) - : SGAnimation(props, new ssgTransform), + : SGAnimation(props, new osg::Group), _use_personality( props->getBoolValue("use-personality",false) ), _prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)), _table(read_interpolation_table(props)), @@ -673,6 +660,12 @@ SGBlendAnimation::SGBlendAnimation( SGPropertyNode *prop_root, _has_max(props->hasValue("max")), _max(props->getDoubleValue("max", 1.0)) { + // OSGFIXME: does ot work like that!!! + // depends on a not so wide available extension + + _colorMatrix = new osg::ColorMatrix; + osg::StateSet* stateSet = _branch->getOrCreateStateSet(); + stateSet->setAttribute(_colorMatrix.get()); } SGBlendAnimation::~SGBlendAnimation () @@ -711,7 +704,7 @@ SGBlendAnimation::update() if (_blend != _prev_value) { _prev_value = _blend; - change_alpha( _branch, _blend ); + _colorMatrix->getMatrix()(3, 3) = _blend; } return 1; } @@ -724,18 +717,18 @@ SGBlendAnimation::update() SGTranslateAnimation::SGTranslateAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props ) - : SGAnimation(props, new ssgTransform), + : SGAnimation(props, new osg::MatrixTransform), _use_personality( props->getBoolValue("use-personality",false) ), _prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)), + _offset_m( props, "offset-m", 0.0 ), + _factor( props, "factor", 1.0 ), _table(read_interpolation_table(props)), _has_min(props->hasValue("min-m")), _min_m(props->getDoubleValue("min-m")), _has_max(props->hasValue("max-m")), _max_m(props->getDoubleValue("max-m")), _position_m(props->getDoubleValue("starting-position-m", 0)), - _condition(0), - _factor( props, "factor", 1.0 ), - _offset_m( props, "offset-m", 0.0 ) + _condition(0) { SGPropertyNode_ptr node = props->getChild("condition"); if (node != 0) @@ -744,7 +737,7 @@ SGTranslateAnimation::SGTranslateAnimation( SGPropertyNode *prop_root, _axis[0] = props->getFloatValue("axis/x", 0); _axis[1] = props->getFloatValue("axis/y", 0); _axis[2] = props->getFloatValue("axis/z", 0); - sgNormalizeVec3(_axis); + _axis.normalize(); } SGTranslateAnimation::~SGTranslateAnimation () @@ -779,8 +772,9 @@ SGTranslateAnimation::update() _position_m = _table->interpolate(_prop->getDoubleValue()); } + osg::Matrix _matrix; set_translation(_matrix, _position_m, _axis); - ((ssgTransform *)_branch)->setTransform(_matrix); + static_cast(_branch)->setMatrix(_matrix); } return 2; } @@ -793,7 +787,7 @@ SGTranslateAnimation::update() SGScaleAnimation::SGScaleAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props ) - : SGAnimation(props, new ssgTransform), + : SGAnimation(props, new osg::MatrixTransform), _use_personality( props->getBoolValue("use-personality",false) ), _prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)), _x_factor(props,"x-factor",1.0), @@ -877,8 +871,9 @@ SGScaleAnimation::update() _z_scale = _table->interpolate(_prop->getDoubleValue()); } + osg::Matrix _matrix; set_scale(_matrix, _x_scale, _y_scale, _z_scale ); - ((ssgTransform *)_branch)->setTransform(_matrix); + static_cast(_branch)->setMatrix(_matrix); return 2; } @@ -889,7 +884,7 @@ SGScaleAnimation::update() SGTexRotateAnimation::SGTexRotateAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props ) - : SGAnimation(props, new ssgTexTrans), + : SGAnimation(props, new osg::Group), _prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)), _offset_deg(props->getDoubleValue("offset-deg", 0.0)), _factor(props->getDoubleValue("factor", 1.0)), @@ -911,7 +906,11 @@ SGTexRotateAnimation::SGTexRotateAnimation( SGPropertyNode *prop_root, _axis[0] = props->getFloatValue("axis/x", 0); _axis[1] = props->getFloatValue("axis/y", 0); _axis[2] = props->getFloatValue("axis/z", 0); - sgNormalizeVec3(_axis); + _axis.normalize(); + + osg::StateSet* stateSet = _branch->getOrCreateStateSet(); + _texMat = new osg::TexMat; + stateSet->setTextureAttribute(0, _texMat.get()); } SGTexRotateAnimation::~SGTexRotateAnimation () @@ -934,8 +933,9 @@ SGTexRotateAnimation::update() } else { _position_deg = _table->interpolate(_prop->getDoubleValue()); } + osg::Matrix _matrix; set_rotation(_matrix, _position_deg, _center, _axis); - ((ssgTexTrans *)_branch)->setTransform(_matrix); + _texMat->setMatrix(_matrix); return 2; } @@ -946,7 +946,7 @@ SGTexRotateAnimation::update() SGTexTranslateAnimation::SGTexTranslateAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props ) - : SGAnimation(props, new ssgTexTrans), + : SGAnimation(props, new osg::Group), _prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)), _offset(props->getDoubleValue("offset", 0.0)), _factor(props->getDoubleValue("factor", 1.0)), @@ -967,7 +967,11 @@ SGTexTranslateAnimation::SGTexTranslateAnimation( SGPropertyNode *prop_root, _axis[0] = props->getFloatValue("axis/x", 0); _axis[1] = props->getFloatValue("axis/y", 0); _axis[2] = props->getFloatValue("axis/z", 0); - sgNormalizeVec3(_axis); + _axis.normalize(); + + osg::StateSet* stateSet = _branch->getOrCreateStateSet(); + _texMat = new osg::TexMat; + stateSet->setTextureAttribute(0, _texMat.get()); } SGTexTranslateAnimation::~SGTexTranslateAnimation () @@ -990,8 +994,9 @@ SGTexTranslateAnimation::update() } else { _position = _table->interpolate(apply_mods(_prop->getDoubleValue(), _step, _scroll)); } + osg::Matrix _matrix; set_translation(_matrix, _position, _axis); - ((ssgTexTrans *)_branch)->setTransform(_matrix); + _texMat->setMatrix(_matrix); return 2; } @@ -1002,7 +1007,7 @@ SGTexTranslateAnimation::update() SGTexMultipleAnimation::SGTexMultipleAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props ) - : SGAnimation(props, new ssgTexTrans), + : SGAnimation(props, new osg::Group), _prop((SGPropertyNode *)prop_root->getNode(props->getStringValue("property", "/null"), true)) { unsigned int i; @@ -1034,7 +1039,7 @@ SGTexMultipleAnimation::SGTexMultipleAnimation( SGPropertyNode *prop_root, _transform[i].axis[0] = transform_props->getFloatValue("axis/x", 0); _transform[i].axis[1] = transform_props->getFloatValue("axis/y", 0); _transform[i].axis[2] = transform_props->getFloatValue("axis/z", 0); - sgNormalizeVec3(_transform[i].axis); + _transform[i].axis.normalize(); _num_transforms++; } else if (!strcmp("texrotate",transform_nodes[i]->getStringValue("subtype", 0))) { @@ -1057,10 +1062,13 @@ SGTexMultipleAnimation::SGTexMultipleAnimation( SGPropertyNode *prop_root, _transform[i].axis[0] = transform_props->getFloatValue("axis/x", 0); _transform[i].axis[1] = transform_props->getFloatValue("axis/y", 0); _transform[i].axis[2] = transform_props->getFloatValue("axis/z", 0); - sgNormalizeVec3(_transform[i].axis); + _transform[i].axis.normalize(); _num_transforms++; } } + osg::StateSet* stateSet = _branch->getOrCreateStateSet(); + _texMat = new osg::TexMat; + stateSet->setTextureAttribute(0, _texMat.get()); } SGTexMultipleAnimation::~SGTexMultipleAnimation () @@ -1072,8 +1080,8 @@ int SGTexMultipleAnimation::update() { int i; - sgMat4 tmatrix; - sgMakeIdentMat4(tmatrix); + osg::Matrix tmatrix; + tmatrix.makeIdentity(); for (i = 0; i < _num_transforms; i++) { if(_transform[i].subtype == 0) { @@ -1088,8 +1096,9 @@ SGTexMultipleAnimation::update() } else { _transform[i].position = _transform[i].table->interpolate(apply_mods(_transform[i].prop->getDoubleValue(), _transform[i].step,_transform[i].scroll)); } - set_translation(_transform[i].matrix, _transform[i].position, _transform[i].axis); - sgPreMultMat4(tmatrix, _transform[i].matrix); + osg::Matrix matrix; + set_translation(matrix, _transform[i].position, _transform[i].axis); + tmatrix = matrix*tmatrix; } else if (_transform[i].subtype == 1) { @@ -1104,11 +1113,13 @@ SGTexMultipleAnimation::update() } else { _transform[i].position = _transform[i].table->interpolate(_transform[i].prop->getDoubleValue()); } - set_rotation(_transform[i].matrix, _transform[i].position, _transform[i].center, _transform[i].axis); - sgPreMultMat4(tmatrix, _transform[i].matrix); + + osg::Matrix matrix; + set_rotation(matrix, _transform[i].position, _transform[i].center, _transform[i].axis); + tmatrix = matrix*tmatrix; } } - ((ssgTexTrans *)_branch)->setTransform(tmatrix); + _texMat->setMatrix(tmatrix); return 2; } @@ -1119,7 +1130,7 @@ SGTexMultipleAnimation::update() //////////////////////////////////////////////////////////////////////// SGAlphaTestAnimation::SGAlphaTestAnimation(SGPropertyNode_ptr props) - : SGAnimation(props, new ssgBranch) + : SGAnimation(props, new osg::Group) { _alpha_clamp = props->getFloatValue("alpha-factor", 0.0); } @@ -1130,22 +1141,13 @@ SGAlphaTestAnimation::~SGAlphaTestAnimation () void SGAlphaTestAnimation::init() { - setAlphaClampToBranch(_branch,_alpha_clamp); -} - -void SGAlphaTestAnimation::setAlphaClampToBranch(ssgBranch *b, float clamp) -{ - int nb = b->getNumKids(); - for (int i = 0; igetKid(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 ); - } - } + osg::StateSet* stateSet = _branch->getOrCreateStateSet(); + osg::AlphaFunc* alphaFunc = new osg::AlphaFunc; + alphaFunc->setFunction(osg::AlphaFunc::GREATER); + alphaFunc->setReferenceValue(_alpha_clamp); + stateSet->setAttribute(alphaFunc); + stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON); + stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); } @@ -1156,13 +1158,11 @@ void SGAlphaTestAnimation::setAlphaClampToBranch(ssgBranch *b, float clamp) SGMaterialAnimation::SGMaterialAnimation( SGPropertyNode *prop_root, SGPropertyNode_ptr props, const SGPath &texture_path) - : SGAnimation(props, new ssgBranch), + : SGAnimation(props, new osg::Group), _last_condition(false), _prop_root(prop_root), _prop_base(""), _texture_base(texture_path), - _cached_material(0), - _cloned_material(0), _read(0), _update(0), _global(props->getBoolValue("global", false)) @@ -1229,6 +1229,9 @@ SGMaterialAnimation::SGMaterialAnimation( SGPropertyNode *prop_root, _tex_prop = n ? _prop_root->getNode(path(n->getStringValue()), true) : 0; _static_update = _update; + + _alphaFunc = new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0); + _texture2D = SGLoadTexture2D(_texture); } void SGMaterialAnimation::initColorGroup(SGPropertyNode_ptr group, ColorSpec *col, int flag) @@ -1263,6 +1266,17 @@ void SGMaterialAnimation::init() { if (!_global) cloneMaterials(_branch); + + // OSGFIXME + osg::StateSet* stateSet = _branch->getOrCreateStateSet(); + if (_update & THRESHOLD) { + stateSet->setAttribute(_alphaFunc.get(), osg::StateAttribute::OVERRIDE); + stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); + } + if (_update & TEXTURE) { + stateSet->setTextureAttribute(0, _texture2D.get(), osg::StateAttribute::OVERRIDE); + stateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); + } } int SGMaterialAnimation::update() @@ -1343,79 +1357,124 @@ void SGMaterialAnimation::updateColorGroup(ColorSpec *col, int flag) _update |= flag; } -void SGMaterialAnimation::cloneMaterials(ssgBranch *b) -{ - for (int i = 0; i < b->getNumKids(); i++) - cloneMaterials((ssgBranch *)b->getKid(i)); - - if (!b->isAKindOf(ssgTypeLeaf()) || !((ssgLeaf *)b)->hasState()) - return; - - ssgSimpleState *s = (ssgSimpleState *)((ssgLeaf *)b)->getState(); - if (!_cached_material || _cached_material != s) { - _cached_material = s; - _cloned_material = (ssgSimpleState *)s->clone(SSG_CLONE_STATE); +class SGMaterialAnimationCloneVisitor : public osg::NodeVisitor { +public: + SGMaterialAnimationCloneVisitor() : + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) + { + setVisitorType(osg::NodeVisitor::NODE_VISITOR); + } + virtual void apply(osg::Node& node) + { + traverse(node); + osg::StateSet* stateSet = node.getStateSet(); + if (!stateSet) + return; + if (1 < stateSet->referenceCount()) { + osg::CopyOp copyOp(osg::CopyOp::DEEP_COPY_STATESETS); + osg::Object* object = stateSet->clone(copyOp); + stateSet = static_cast(object); + node.setStateSet(stateSet); } - ((ssgLeaf *)b)->setState(_cloned_material); -} + cloneMaterial(stateSet); + } + virtual void apply(osg::Geode& node) + { + apply((osg::Node&)node); + traverse(node); + unsigned nDrawables = node.getNumDrawables(); + for (unsigned i = 0; i < nDrawables; ++i) { + osg::Drawable* drawable = node.getDrawable(i); + osg::StateSet* stateSet = drawable->getStateSet(); + if (!stateSet) + continue; + if (1 < stateSet->referenceCount()) { + osg::CopyOp copyOp(osg::CopyOp::DEEP_COPY_STATESETS); + osg::Object* object = stateSet->clone(copyOp); + stateSet = static_cast(object); + drawable->setStateSet(stateSet); + } + cloneMaterial(stateSet); + } + } + void cloneMaterial(osg::StateSet* stateSet) + { + + osg::StateAttribute* stateAttr; + stateAttr = stateSet->getAttribute(osg::StateAttribute::MATERIAL); + if (!stateAttr) + return; + osg::CopyOp copyOp(osg::CopyOp::DEEP_COPY_STATEATTRIBUTES); + osg::Object* object = stateAttr->clone(copyOp); + osg::Material* material = static_cast(object); + materialList.push_back(material); + while (stateSet->getAttribute(osg::StateAttribute::MATERIAL)) { + stateSet->removeAttribute(osg::StateAttribute::MATERIAL); + } + stateSet->setAttribute(material); + } + std::vector materialList; +}; -void SGMaterialAnimation::setMaterialBranch(ssgBranch *b) +void SGMaterialAnimation::cloneMaterials(osg::Group *b) { - for (int i = 0; i < b->getNumKids(); i++) - setMaterialBranch((ssgBranch *)b->getKid(i)); - - if (!b->isAKindOf(ssgTypeLeaf()) || !((ssgLeaf *)b)->hasState()) - return; - - ssgSimpleState *s = (ssgSimpleState *)((ssgLeaf *)b)->getState(); + SGMaterialAnimationCloneVisitor cloneVisitor; + b->accept(cloneVisitor); + _materialList.swap(cloneVisitor.materialList); +} +void SGMaterialAnimation::setMaterialBranch(osg::Group *b) +{ + std::vector::iterator i; + for (i = _materialList.begin(); i != _materialList.end(); ++i) { + osg::Material* material = *i; if (_update & DIFFUSE) { - float *v = _diff.rgba(); - SGfloat alpha = s->getMaterial(GL_DIFFUSE)[3]; - s->setColourMaterial(GL_DIFFUSE); - s->enable(GL_COLOR_MATERIAL); - s->setMaterial(GL_DIFFUSE, v[0], v[1], v[2], alpha); - s->disable(GL_COLOR_MATERIAL); + osg::Vec4 v = _diff.rgba(); + float alpha = material->getDiffuse(osg::Material::FRONT_AND_BACK)[3]; + material->setColorMode(osg::Material::DIFFUSE); + material->setDiffuse(osg::Material::FRONT_AND_BACK, + osg::Vec4(v[0], v[1], v[2], alpha)); } if (_update & AMBIENT) { - s->setColourMaterial(GL_AMBIENT); - s->enable(GL_COLOR_MATERIAL); - s->setMaterial(GL_AMBIENT, _amb.rgba()); - s->disable(GL_COLOR_MATERIAL); + material->setColorMode(osg::Material::AMBIENT); + material->setDiffuse(osg::Material::FRONT_AND_BACK, _amb.rgba()); } if (_update & EMISSION) - s->setMaterial(GL_EMISSION, _emis.rgba()); + material->setEmission(osg::Material::FRONT_AND_BACK, _emis.rgba()); if (_update & SPECULAR) - s->setMaterial(GL_SPECULAR, _spec.rgba()); + material->setSpecular(osg::Material::FRONT_AND_BACK, _spec.rgba()); if (_update & SHININESS) - s->setShininess(clamp(_shi, 0.0, 128.0)); + material->setShininess(osg::Material::FRONT_AND_BACK, + clamp(_shi, 0.0, 128.0)); if (_update & TRANSPARENCY) { - SGfloat *v = s->getMaterial(GL_DIFFUSE); - float trans = _trans.value * _trans.factor + _trans.offset; - trans = trans < _trans.min ? _trans.min : trans > _trans.max ? _trans.max : trans; - s->setMaterial(GL_DIFFUSE, v[0], v[1], v[2], trans); + osg::Vec4 v = material->getDiffuse(osg::Material::FRONT_AND_BACK); + float trans = _trans.value * _trans.factor + _trans.offset; + trans = trans < _trans.min ? _trans.min : trans > _trans.max ? _trans.max : trans; + material->setDiffuse(osg::Material::FRONT_AND_BACK, + osg::Vec4(v[0], v[1], v[2], trans)); } if (_update & THRESHOLD) - s->setAlphaClamp(clamp(_thresh)); - if (_update & TEXTURE) - s->setTexture(_texture.c_str()); - if (_update & (TEXTURE|TRANSPARENCY)) { - SGfloat alpha = s->getMaterial(GL_DIFFUSE)[3]; - ssgTexture *tex = s->getTexture(); - if ((tex && tex->hasAlpha()) || alpha < 0.999) { - s->setColourMaterial(GL_DIFFUSE); - s->enable(GL_COLOR_MATERIAL); - s->enable(GL_BLEND); - s->enable(GL_ALPHA_TEST); - s->setTranslucent(); - s->disable(GL_COLOR_MATERIAL); - } else { - s->disable(GL_BLEND); - s->disable(GL_ALPHA_TEST); - s->setOpaque(); - } - } - s->force(); + _alphaFunc->setReferenceValue(clamp(_thresh)); + // OSGFIXME +// if (_update & TEXTURE) +// s->setTexture(_texture.c_str()); +// if (_update & (TEXTURE|TRANSPARENCY)) { +// SGfloat alpha = s->getMaterial(GL_DIFFUSE)[3]; +// ssgTexture *tex = s->getTexture(); +// if ((tex && tex->hasAlpha()) || alpha < 0.999) { +// s->setColourMaterial(GL_DIFFUSE); +// s->enable(GL_COLOR_MATERIAL); +// s->enable(GL_BLEND); +// s->enable(GL_ALPHA_TEST); +// s->setTranslucent(); +// s->disable(GL_COLOR_MATERIAL); +// } else { +// s->disable(GL_BLEND); +// s->disable(GL_ALPHA_TEST); +// s->setOpaque(); +// } +// } + } } @@ -1423,70 +1482,106 @@ void SGMaterialAnimation::setMaterialBranch(ssgBranch *b) //////////////////////////////////////////////////////////////////////// // Implementation of SGFlashAnimation //////////////////////////////////////////////////////////////////////// -SGFlashAnimation::SGFlashAnimation(SGPropertyNode_ptr props) - : SGAnimation( props, new SGCustomTransform ) -{ - _axis[0] = props->getFloatValue("axis/x", 0); - _axis[1] = props->getFloatValue("axis/y", 0); - _axis[2] = props->getFloatValue("axis/z", 1); +class SGFlashAnimationTransform : public osg::Transform { +public: + SGFlashAnimationTransform(SGPropertyNode* props) + { + getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); - _center[0] = props->getFloatValue("center/x-m", 0); - _center[1] = props->getFloatValue("center/y-m", 0); - _center[2] = props->getFloatValue("center/z-m", 0); + _axis[0] = props->getFloatValue("axis/x", 0); + _axis[1] = props->getFloatValue("axis/y", 0); + _axis[2] = props->getFloatValue("axis/z", 1); + _axis.normalize(); + + _center[0] = props->getFloatValue("center/x-m", 0); + _center[1] = props->getFloatValue("center/y-m", 0); + _center[2] = props->getFloatValue("center/z-m", 0); + + _offset = props->getFloatValue("offset", 0.0); + _factor = props->getFloatValue("factor", 1.0); + _power = props->getFloatValue("power", 1.0); + _two_sides = props->getBoolValue("two-sides", false); + + _min_v = props->getFloatValue("min", 0.0); + _max_v = props->getFloatValue("max", 1.0); + } - _offset = props->getFloatValue("offset", 0.0); - _factor = props->getFloatValue("factor", 1.0); - _power = props->getFloatValue("power", 1.0); - _two_sides = props->getBoolValue("two-sides", false); + virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix, + osg::NodeVisitor* nv) const + { + double scale_factor = computeScaleFactor(nv); + osg::Matrix transform; + transform(0,0) = scale_factor; + transform(1,1) = scale_factor; + transform(2,2) = scale_factor; + transform(3,0) = _center[0] * ( 1 - scale_factor ); + transform(3,1) = _center[1] * ( 1 - scale_factor ); + transform(3,2) = _center[2] * ( 1 - scale_factor ); + if (_referenceFrame == RELATIVE_RF) + matrix.preMult(transform); + else + matrix = transform; + + return true; + } + + virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix, + osg::NodeVisitor* nv) const + { + double scale_factor = computeScaleFactor(nv); + if (fabs(scale_factor) <= std::numeric_limits::min()) + return false; + osg::Matrix transform; + double rScaleFactor = 1/scale_factor; + transform(0,0) = rScaleFactor; + transform(1,1) = rScaleFactor; + transform(2,2) = rScaleFactor; + transform(3,0) = rScaleFactor*_center[0] * ( scale_factor - 1 ); + transform(3,1) = rScaleFactor*_center[1] * ( scale_factor - 1 ); + transform(3,2) = rScaleFactor*_center[2] * ( scale_factor - 1 ); + if (_referenceFrame == RELATIVE_RF) + matrix.postMult(transform); + else + matrix = transform; + return true; + } - _min_v = props->getFloatValue("min", 0.0); - _max_v = props->getFloatValue("max", 1.0); + double computeScaleFactor(osg::NodeVisitor* nv) const + { + if (!nv) + return 1; + + osg::Vec3 localEyeToCenter = nv->getEyePoint() - _center; + localEyeToCenter.normalize(); + + double cos_angle = localEyeToCenter*_axis; + double scale_factor = 0; + if ( _two_sides && cos_angle < 0 ) + scale_factor = _factor * pow( -cos_angle, _power ) + _offset; + else if ( cos_angle > 0 ) + scale_factor = _factor * pow( cos_angle, _power ) + _offset; + + if ( scale_factor < _min_v ) + scale_factor = _min_v; + if ( scale_factor > _max_v ) + scale_factor = _max_v; - ((SGCustomTransform *)_branch)->setTransCallback( &SGFlashAnimation::flashCallback, this ); -} + return scale_factor; + } -SGFlashAnimation::~SGFlashAnimation() -{ -} +private: + osg::Vec3 _axis, _center; + double _power, _factor, _offset, _min_v, _max_v; + bool _two_sides; +}; -void SGFlashAnimation::flashCallback( sgMat4 r, sgFrustum *f, sgMat4 m, void *d ) +SGFlashAnimation::SGFlashAnimation(SGPropertyNode_ptr props) + : SGAnimation( props, new SGFlashAnimationTransform(props) ) { - ((SGFlashAnimation *)d)->flashCallback( r, f, m ); } -void SGFlashAnimation::flashCallback( sgMat4 r, sgFrustum *f, sgMat4 m ) +SGFlashAnimation::~SGFlashAnimation() { - sgVec3 transformed_axis; - sgXformVec3( transformed_axis, _axis, m ); - sgNormalizeVec3( transformed_axis ); - - sgVec3 view; - sgFullXformPnt3( view, _center, m ); - sgNormalizeVec3( view ); - - float cos_angle = -sgScalarProductVec3( transformed_axis, view ); - float scale_factor = 0.f; - if ( _two_sides && cos_angle < 0 ) - scale_factor = _factor * (float)pow( -cos_angle, _power ) + _offset; - else if ( cos_angle > 0 ) - scale_factor = _factor * (float)pow( cos_angle, _power ) + _offset; - - if ( scale_factor < _min_v ) - scale_factor = _min_v; - if ( scale_factor > _max_v ) - scale_factor = _max_v; - - sgMat4 transform; - sgMakeIdentMat4( transform ); - transform[0][0] = scale_factor; - transform[1][1] = scale_factor; - transform[2][2] = scale_factor; - transform[3][0] = _center[0] * ( 1 - scale_factor ); - transform[3][1] = _center[1] * ( 1 - scale_factor ); - transform[3][2] = _center[2] * ( 1 - scale_factor ); - - sgCopyMat4( r, m ); - sgPreMultMat4( r, transform ); } @@ -1494,59 +1589,102 @@ void SGFlashAnimation::flashCallback( sgMat4 r, sgFrustum *f, sgMat4 m ) //////////////////////////////////////////////////////////////////////// // Implementation of SGDistScaleAnimation //////////////////////////////////////////////////////////////////////// -SGDistScaleAnimation::SGDistScaleAnimation(SGPropertyNode_ptr props) - : SGAnimation( props, new SGCustomTransform ), - _factor(props->getFloatValue("factor", 1.0)), - _offset(props->getFloatValue("offset", 0.0)), - _min_v(props->getFloatValue("min", 0.0)), - _max_v(props->getFloatValue("max", 1.0)), - _has_min(props->hasValue("min")), - _has_max(props->hasValue("max")), - _table(read_interpolation_table(props)) -{ - _center[0] = props->getFloatValue("center/x-m", 0); - _center[1] = props->getFloatValue("center/y-m", 0); - _center[2] = props->getFloatValue("center/z-m", 0); - - ((SGCustomTransform *)_branch)->setTransCallback( &SGDistScaleAnimation::distScaleCallback, this ); -} +class SGDistScaleTransform : public osg::Transform { +public: + SGDistScaleTransform(SGPropertyNode* props) + { + getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); + + _factor = props->getFloatValue("factor", 1.0); + _offset = props->getFloatValue("offset", 0.0); + _min_v = props->getFloatValue("min", 0.0); + _max_v = props->getFloatValue("max", 1.0); + _has_min = props->hasValue("min"); + _has_max = props->hasValue("max"); + _table = read_interpolation_table(props); + _center[0] = props->getFloatValue("center/x-m", 0); + _center[1] = props->getFloatValue("center/y-m", 0); + _center[2] = props->getFloatValue("center/z-m", 0); + } + ~SGDistScaleTransform() + { + delete _table; + } -SGDistScaleAnimation::~SGDistScaleAnimation() -{ -} + virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix, + osg::NodeVisitor* nv) const + { + osg::Matrix transform; + double scale_factor = computeScaleFactor(nv); + transform(0,0) = scale_factor; + transform(1,1) = scale_factor; + transform(2,2) = scale_factor; + transform(3,0) = _center[0] * ( 1 - scale_factor ); + transform(3,1) = _center[1] * ( 1 - scale_factor ); + transform(3,2) = _center[2] * ( 1 - scale_factor ); + if (_referenceFrame == RELATIVE_RF) + matrix.preMult(transform); + else + matrix = transform; + return true; + } + + virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix, + osg::NodeVisitor* nv) const + { + double scale_factor = computeScaleFactor(nv); + if (fabs(scale_factor) <= std::numeric_limits::min()) + return false; + osg::Matrix transform; + double rScaleFactor = 1/scale_factor; + transform(0,0) = rScaleFactor; + transform(1,1) = rScaleFactor; + transform(2,2) = rScaleFactor; + transform(3,0) = rScaleFactor*_center[0] * ( scale_factor - 1 ); + transform(3,1) = rScaleFactor*_center[1] * ( scale_factor - 1 ); + transform(3,2) = rScaleFactor*_center[2] * ( scale_factor - 1 ); + if (_referenceFrame == RELATIVE_RF) + matrix.postMult(transform); + else + matrix = transform; + return true; + } -void SGDistScaleAnimation::distScaleCallback( sgMat4 r, sgFrustum *f, sgMat4 m, void *d ) -{ - ((SGDistScaleAnimation *)d)->distScaleCallback( r, f, m ); -} + double computeScaleFactor(osg::NodeVisitor* nv) const + { + if (!nv) + return 1; -void SGDistScaleAnimation::distScaleCallback( sgMat4 r, sgFrustum *f, sgMat4 m ) -{ - sgVec3 view; - sgFullXformPnt3( view, _center, m ); + osg::Vec3 localEyeToCenter = _center - nv->getEyePoint(); + double scale_factor = localEyeToCenter.length(); + if (_table == 0) { + scale_factor = _factor * scale_factor + _offset; + if ( _has_min && scale_factor < _min_v ) + scale_factor = _min_v; + if ( _has_max && scale_factor > _max_v ) + scale_factor = _max_v; + } else { + scale_factor = _table->interpolate( scale_factor ); + } - float scale_factor = sgLengthVec3( view ); - if (_table == 0) { - scale_factor = _factor * scale_factor + _offset; - if ( _has_min && scale_factor < _min_v ) - scale_factor = _min_v; - if ( _has_max && scale_factor > _max_v ) - scale_factor = _max_v; - } else { - scale_factor = _table->interpolate( scale_factor ); + return scale_factor; } - sgMat4 transform; - sgMakeIdentMat4( transform ); - transform[0][0] = scale_factor; - transform[1][1] = scale_factor; - transform[2][2] = scale_factor; - transform[3][0] = _center[0] * ( 1 - scale_factor ); - transform[3][1] = _center[1] * ( 1 - scale_factor ); - transform[3][2] = _center[2] * ( 1 - scale_factor ); - sgCopyMat4( r, m ); - sgPreMultMat4( r, transform ); +private: + osg::Vec3 _center; + float _factor, _offset, _min_v, _max_v; + bool _has_min, _has_max; + SGInterpTable * _table; +}; + +SGDistScaleAnimation::SGDistScaleAnimation(SGPropertyNode_ptr props) + : SGAnimation( props, new SGDistScaleTransform(props) ) +{ +} + +SGDistScaleAnimation::~SGDistScaleAnimation() +{ } //////////////////////////////////////////////////////////////////////// @@ -1554,34 +1692,40 @@ void SGDistScaleAnimation::distScaleCallback( sgMat4 r, sgFrustum *f, sgMat4 m ) //////////////////////////////////////////////////////////////////////// SGShadowAnimation::SGShadowAnimation ( SGPropertyNode *prop_root, - SGPropertyNode_ptr props ) - : SGAnimation(props, new ssgBranch), + SGPropertyNode_ptr props ) + : SGAnimation(props, new osg::Group), _condition(0), - _condition_value(true) + _condition_value(true) { - animation_type = 1; - SGPropertyNode_ptr node = props->getChild("condition"); - if (node != 0) { - _condition = sgReadCondition(prop_root, node); - _condition_value = false; - } + animation_type = 1; + SGPropertyNode_ptr node = props->getChild("condition"); + if (node != 0) { + _condition = sgReadCondition(prop_root, node); + _condition_value = false; + } } SGShadowAnimation::~SGShadowAnimation () { - delete _condition; + delete _condition; } int SGShadowAnimation::update() { - if (_condition) - _condition_value = _condition->test(); - return 2; + if (_condition) + _condition_value = _condition->test(); + + if ( _condition_value ) { + _branch->setNodeMask(SG_NODEMASK_SHADOW_BIT|_branch->getNodeMask()); + } else { + _branch->setNodeMask(~SG_NODEMASK_SHADOW_BIT&_branch->getNodeMask()); + } + return 2; } bool SGShadowAnimation::get_condition_value(void) { - return _condition_value; + return _condition_value; } // end of animation.cxx diff --git a/simgear/scene/model/animation.hxx b/simgear/scene/model/animation.hxx index abd4363b..e2052b03 100644 --- a/simgear/scene/model/animation.hxx +++ b/simgear/scene/model/animation.hxx @@ -14,25 +14,35 @@ #include #include -#include -#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include #include #include #include +#include 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 _factor; SGPersonalityParameter _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 _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 _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 _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 _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 _materialList; + osg::ref_ptr _alphaFunc; + osg::ref_ptr _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 _effectTexture; unsigned char *_textureData; GLint _texWidth, _texHeight; - sgVec4 _envColor; + osg::Vec4 _envColor; }; diff --git a/simgear/scene/model/custtrans.hxx b/simgear/scene/model/custtrans.hxx index 50df8985..2b0da4a5 100755 --- a/simgear/scene/model/custtrans.hxx +++ b/simgear/scene/model/custtrans.hxx @@ -5,8 +5,6 @@ #ifndef _SG_CUSTOM_TRANSFORM_HXX #define _SG_CUSTOM_TRANSFORM_HXX 1 -#include "plib/ssg.h" - class SGCustomTransform : public ssgBranch { public: diff --git a/simgear/scene/model/model.cxx b/simgear/scene/model/model.cxx index 622e8fcd..613b4595 100644 --- a/simgear/scene/model/model.cxx +++ b/simgear/scene/model/model.cxx @@ -9,12 +9,22 @@ #include // for strcmp() -#include -#include - -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include #include #include @@ -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; -} +// 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: + SGDatabaseReference(osg::Referenced* referenced) : + mReferenced(referenced) + { } + virtual void objectDeleted(void*) + { + mReferenced = 0; + } +private: + osg::ref_ptr mReferenced; +}; -/** - * Callback and userData class for conditional rendering. - */ -class SGConditionalRender : public ssgBase { +class SGTexCompressionVisitor : public SGTextureStateAttributeVisitor { public: - SGConditionalRender(SGCondition *c) : _condition(c) {} - bool test() { return _condition->test(); } + SGTexCompressionVisitor(osg::Texture::InternalFormatMode formatMode) : + mFormatMode(formatMode) + { } + + virtual void apply(int, osg::StateSet::RefAttributePair& refAttr) + { + osg::Texture2D* texture = dynamic_cast(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: - SGCondition *_condition; + osg::Texture::InternalFormatMode mFormatMode; }; -static int -model_condition_callback (ssgEntity * entity, int mask) -{ - return ((SGConditionalRender *)entity->getUserData())->test(); -} +class SGAcMaterialCrippleVisitor : public SGStateAttributeVisitor { +public: + virtual void apply(osg::StateSet::RefAttributePair& refAttr) + { + osg::Material* material = dynamic_cast(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; + } -/** - * Locate a named SSG node in a branch. - */ -static ssgEntity * -find_named_node (ssgEntity * node, const char * name) + 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 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) { - 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; + 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 0; + } + 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(node)); + osg::Switch* s = static_cast(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; +}; + /** - * Splice a branch in between all child nodes and their parents. + * Locate a named node in a branch. */ -static void -splice_branch (ssgBranch * branch, ssgEntity * child) -{ - int nParents = child->getNumParents(); - branch->addKid(child); - for (int i = 0; i < nParents; i++) { - ssgBranch * parent = child->getParent(i); - parent->replaceKid(child, branch); +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; + } + traverse(node); } -} + + osg::Node* getNode() const + { return mNode; } +private: + std::string mName; + osg::Node* mNode; +}; /** - * Make an offset matrix from rotations and position offset. + * Splice a branch in between all child nodes and their parents. */ -void -sgMakeOffsetsMatrix( sgMat4 * result, double h_rot, double p_rot, double r_rot, - double x_off, double y_off, double z_off ) +static void +splice_branch(osg::Group* group, osg::Node* child) { - 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); + 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); } - void -sgMakeAnimation( ssgBranch * model, +sgMakeAnimation( osg::Node * model, const char * name, vector &name_nodes, SGPropertyNode *prop_root, SGPropertyNode_ptr node, double sim_time_sec, SGPath &texture_path, - set &ignore_branches ) + set &ignore_branches ) { bool ignore = false; SGAnimation * animation = 0; @@ -191,14 +442,16 @@ sgMakeAnimation( ssgBranch * model, } if (name != 0) - animation->setName((char *)name); - - ssgEntity * object; - if (name_nodes.size() > 0) { - object = find_named_node(model, name_nodes[0]->getStringValue()); + animation->setName(name); + + 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 &ignore ) -{ - int nb = b->getNumKids(); - for (int i = 0; igetKid(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 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); - - ssgBranch * kid; + 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); + + 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); - 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); + model->addChild(align); + + SGPropertyNode *cond = node->getNode("condition", false); + if (cond) + model->setUpdateCallback(new SGSwitchUpdateCallback(sgReadCondition(prop_root, cond))); } + // restore old path list + osgDB::setDataFilePathList(pathList); + if ( load_panel ) { // Load panels vector 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 ignore_branches; + set ignore_branches; vector 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 diff --git a/simgear/scene/model/model.hxx b/simgear/scene/model/model.hxx index 5d64a5d8..29306f05 100644 --- a/simgear/scene/model/model.hxx +++ b/simgear/scene/model/model.hxx @@ -18,8 +18,8 @@ SG_USING_STD(vector); SG_USING_STD(set); -#include -#include +#include +#include #include #include @@ -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 &name_nodes, SGPropertyNode *prop_root, SGPropertyNode_ptr node, double sim_time_sec, SGPath &texture_path, - set &ignore_branches ); + set &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 diff --git a/simgear/scene/model/modellib.cxx b/simgear/scene/model/modellib.cxx index f5f15784..46c09154 100644 --- a/simgear/scene/model/modellib.cxx +++ b/simgear/scene/model/modellib.cxx @@ -6,6 +6,7 @@ #include #include +#include #include "model.hxx" #include "animation.hxx" @@ -48,11 +49,11 @@ SGModelLib::flush1() return; - map >::iterator it = _table.begin(); + map >::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 >::iterator it = _table.find(path); + map >::iterator it = _table.find(path); if (!cache_object || it == _table.end()) { - ssgSharedPtr model = sgLoad3DModel(fg_root, path, prop_root, + osg::ref_ptr 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; } diff --git a/simgear/scene/model/modellib.hxx b/simgear/scene/model/modellib.hxx index 73866f20..3842a73f 100644 --- a/simgear/scene/model/modellib.hxx +++ b/simgear/scene/model/modellib.hxx @@ -12,9 +12,9 @@ #include #include STL_STRING -#include +#include +#include -#include #include #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 > _table; + map > _table; }; diff --git a/simgear/scene/model/personality.cxx b/simgear/scene/model/personality.cxx index 60b8a987..c6a6d176 100755 --- a/simgear/scene/model/personality.cxx +++ b/simgear/scene/model/personality.cxx @@ -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(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 ) diff --git a/simgear/scene/model/personality.hxx b/simgear/scene/model/personality.hxx index 6a314e7c..fc48088e 100755 --- a/simgear/scene/model/personality.hxx +++ b/simgear/scene/model/personality.hxx @@ -6,7 +6,7 @@ #define _SG_PERSONALITY_HXX 1 #include -#include +#include #include @@ -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) {} diff --git a/simgear/scene/model/placement.cxx b/simgear/scene/model/placement.cxx index 75f3fb84..64ce3dad 100644 --- a/simgear/scene/model/placement.cxx +++ b/simgear/scene/model/placement.cxx @@ -11,8 +11,6 @@ #include // for strcmp() -#include -#include #include #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 diff --git a/simgear/scene/model/placement.hxx b/simgear/scene/model/placement.hxx index 962139ea..ace50b84 100644 --- a/simgear/scene/model/placement.hxx +++ b/simgear/scene/model/placement.hxx @@ -11,17 +11,16 @@ # error This library requires C++ #endif -#include -#include +#include +#include +#include -#include #include -#include +#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 _selector; - ssgSharedPtr _position; + osg::ref_ptr _selector; + osg::ref_ptr _position; // Location SGLocation * _location; diff --git a/simgear/scene/model/placementtrans.cxx b/simgear/scene/model/placementtrans.cxx index 34636d2e..34a7f215 100644 --- a/simgear/scene/model/placementtrans.cxx +++ b/simgear/scene/model/placementtrans.cxx @@ -27,74 +27,57 @@ #include #include -#include -#include - #include "placementtrans.hxx" -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) { - sgdSetVec3(_placement_offset, 0, 0, 0); - sgdSetVec3(_scenery_center, 0, 0, 0); } -ssgPlacementTransform::~ssgPlacementTransform(void) +SGPlacementTransform::~SGPlacementTransform(void) { } -ssgBase *ssgPlacementTransform::clone(int clone_flags) +bool +SGPlacementTransform::computeLocalToWorldMatrix(osg::Matrix& matrix, + osg::NodeVisitor*) const { - ssgPlacementTransform *b = new ssgPlacementTransform; - b->copy_from(this, clone_flags); - return b; + 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::copy_from(ssgPlacementTransform *src, int clone_flags) +bool +SGPlacementTransform::computeWorldToLocalMatrix(osg::Matrix& matrix, + osg::NodeVisitor*) const { - ssgBaseTransform::copy_from(src, clone_flags); - sgdCopyVec3(_placement_offset, src->_placement_offset); - sgdCopyVec3(_scenery_center, src->_scenery_center); -} - -void ssgPlacementTransform::setTransform(sgdVec3 off) -{ - 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; } diff --git a/simgear/scene/model/placementtrans.hxx b/simgear/scene/model/placementtrans.hxx index d5765c4a..c72fbaba 100644 --- a/simgear/scene/model/placementtrans.hxx +++ b/simgear/scene/model/placementtrans.hxx @@ -29,33 +29,28 @@ #include #include +#include -#include -#include +#include -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 diff --git a/simgear/scene/model/shadanim.cxx b/simgear/scene/model/shadanim.cxx index f7d0d9fd..ab76f23f 100644 --- a/simgear/scene/model/shadanim.cxx +++ b/simgear/scene/model/shadanim.cxx @@ -24,8 +24,6 @@ # include #endif -#include -#include #include #include @@ -34,9 +32,8 @@ #include -#include - #include "animation.hxx" +#include "model.hxx" /* shader @@ -69,473 +66,471 @@ */ -static Shader *shFresnel=NULL; -static GLuint texFresnel = 0; - -static GLuint texBackground = 0; -static int texBackgroundWidth = 1024, texBackgroundHeight = 1024; -static GLenum texBackgroundTarget = GL_TEXTURE_2D; -static bool isRectangleTextureSupported = false; -static bool istexBackgroundRectangle = false; -static bool initDone = false; +// static Shader *shFresnel=NULL; +// static GLuint texFresnel = 0; + +// static GLuint texBackground = 0; +// static int texBackgroundWidth = 1024, texBackgroundHeight = 1024; +// static GLenum texBackgroundTarget = GL_TEXTURE_2D; +// static bool isRectangleTextureSupported = false; +// static bool istexBackgroundRectangle = false; +// static bool initDone = false; static bool haveBackground = false; -static glActiveTextureProc glActiveTexturePtr = 0; -static double totalTime = 0.0; -static sgMat4 shadIdentMatrix; - - -static int null_shader_callback( ssgEntity *e ) { - GLuint dlist = 0; - ssgLeaf *leaf = (ssgLeaf *) e; -#ifdef _SSG_USE_DLIST - dlist = leaf->getDListIndex(); - if( ! dlist ) { - leaf->makeDList(); - dlist = leaf->getDListIndex(); - } -#endif - if( ! dlist ) - return true; - ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState()); - if ( sst ) - sst->apply(); - - SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() ); - if( ! my_shader->_depth_test ) - glDisable( GL_DEPTH_TEST ); - glCallList ( dlist ) ; - // restore states - if( ! my_shader->_depth_test ) - glEnable( GL_DEPTH_TEST ); - - // don't draw ! - return false; -} - -static int heat_haze_shader_callback( ssgEntity *e ) { - if( ! ((SGShadowAnimation *)e->getUserData())->get_condition_value() ) - return true; - - GLuint dlist = 0; - ssgLeaf *leaf = (ssgLeaf *) e; -#ifdef _SSG_USE_DLIST - dlist = leaf->getDListIndex(); - if( ! dlist ) { - leaf->makeDList(); - dlist = leaf->getDListIndex(); - } -#endif - if( ! dlist ) - return true; - - GLint viewport[4]; - glGetIntegerv( GL_VIEWPORT, viewport ); - const int screen_width = viewport[2]; - const int screen_height = viewport[3]; - if( ! haveBackground ) { - // store the backbuffer in a texture - if( ! texBackground ) { - // allocate our texture here so we don't waste memory if no model use that effect - // check if we need a rectangle texture and if the card support it - if( (screen_width > 1024 || screen_height > 1024) && isRectangleTextureSupported ) { - // Note that the 3 (same) extensions use the same enumerants - texBackgroundTarget = GL_TEXTURE_RECTANGLE_NV; - istexBackgroundRectangle = true; - texBackgroundWidth = screen_width; - texBackgroundHeight = screen_height; - } - glGenTextures(1, &texBackground); - glEnable(texBackgroundTarget); - glBindTexture(texBackgroundTarget, texBackground); - // trying to match the backbuffer pixel format - GLint internalFormat = GL_RGB8; - GLint colorBits = 0, alphaBits = 0; - glGetIntegerv( GL_BLUE_BITS, &colorBits ); - glGetIntegerv( GL_ALPHA_BITS, &alphaBits ); - if(colorBits == 5) { - if( alphaBits == 0 ) - internalFormat = GL_RGB5; - else - internalFormat = GL_RGB5_A1; - } else { - if( alphaBits != 0 ) - internalFormat = GL_RGBA8; - } - glTexImage2D(texBackgroundTarget, 0, internalFormat, - texBackgroundWidth, texBackgroundHeight, 0, GL_RGB, GL_FLOAT, NULL); - - glTexParameteri(texBackgroundTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(texBackgroundTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(texBackgroundTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(texBackgroundTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } - glEnable(texBackgroundTarget); - glBindTexture(texBackgroundTarget, texBackground); - // center of texture = center of screen - // obviously we don't have the whole screen if screen_width > texBackgroundWidth - // if rectangle textures are not supported, this give some artifacts on the borders - if( istexBackgroundRectangle ) { - glCopyTexSubImage2D( texBackgroundTarget, 0, 0, 0, - 0, 0, texBackgroundWidth, texBackgroundHeight ); - } else { - glCopyTexSubImage2D( texBackgroundTarget, 0, 0, 0, - (screen_width - texBackgroundWidth) / 2, - (screen_height - texBackgroundHeight) / 2, - texBackgroundWidth, texBackgroundHeight ); - } - haveBackground = true; - glBindTexture(texBackgroundTarget, 0); - glDisable(texBackgroundTarget); - } - ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState()); - if ( sst ) - sst->apply(); - - SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() ); - if( ! my_shader->_depth_test ) - glDisable( GL_DEPTH_TEST ); - glDepthMask( GL_FALSE ); - glDisable( GL_LIGHTING ); - if(1) { - // noise texture, tex coord from the model translated by a time factor - glActiveTexturePtr( GL_TEXTURE0_ARB ); - glEnable(GL_TEXTURE_2D); - const float noiseDist = fmod(- totalTime * my_shader->_factor * my_shader->_speed, 4.0); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glTranslatef( noiseDist, 0.0f, 0.0f ); - glMatrixMode(GL_MODELVIEW); - - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - - // background texture - glActiveTexturePtr( GL_TEXTURE1_ARB ); - glEnable(texBackgroundTarget); - glBindTexture(texBackgroundTarget, texBackground); - - // automatic generation of texture coordinates - // map to screen space - sgMat4 CameraProjM, CameraViewM; - glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat *) CameraProjM); - glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) CameraViewM); - // const float dummy_scale = 1.0f; //0.95f; - const float deltaPos = 0.05f; - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - if( istexBackgroundRectangle ) { - // coords go from 0.0 to n, not from 0.0 to 1.0 - glTranslatef( texBackgroundWidth * 0.5f, texBackgroundHeight * 0.5f, 0.0f ); - glScalef( texBackgroundWidth * 0.5f, - texBackgroundHeight * 0.5f, 1.0f ); - } else { - glTranslatef( 0.5f, 0.5f, 0.0f ); - glScalef( float( screen_width ) / float( texBackgroundWidth ) * 0.5f, - float( screen_height ) / float( texBackgroundHeight ) * 0.5f, 1.0f ); - } - glMultMatrixf( (GLfloat *) CameraProjM ); - glMultMatrixf( (GLfloat *) CameraViewM ); - glTranslatef( deltaPos, deltaPos, deltaPos ); - glMatrixMode(GL_MODELVIEW); - - glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); - glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); - glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); - glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); - glTexGenfv( GL_S, GL_EYE_PLANE, shadIdentMatrix[0] ); - glTexGenfv( GL_T, GL_EYE_PLANE, shadIdentMatrix[1] ); - glTexGenfv( GL_R, GL_EYE_PLANE, shadIdentMatrix[2] ); - glTexGenfv( GL_Q, GL_EYE_PLANE, shadIdentMatrix[3] ); - glEnable( GL_TEXTURE_GEN_S ); - glEnable( GL_TEXTURE_GEN_T ); - glEnable( GL_TEXTURE_GEN_R ); - glEnable( GL_TEXTURE_GEN_Q ); - - sgVec4 enviro = {1.00f, 1.00f, 1.00f, 0.85f}; - - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB ); - glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE ); - glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE ); - glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR ); - glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_CONSTANT_ARB ); - glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR ); - glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, enviro); - - glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE); - glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE0_ARB); - glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); - glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PRIMARY_COLOR_ARB ); - glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA ); - - glCallList ( dlist ) ; - glMatrixMode(GL_TEXTURE); - glTranslatef( - deltaPos*2.0f, -deltaPos*2.5f, -deltaPos*2.0f ); - glMatrixMode(GL_MODELVIEW); - glCallList ( dlist ) ; - - // alter colors only on last rendering - // sgVec4 fLight = {0.93f, 0.93f, 1.00f, 0.85f}; - glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB ); - glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR ); - - glMatrixMode(GL_TEXTURE); - glTranslatef( deltaPos*0.7f, deltaPos*1.7f, deltaPos*0.7f ); - glMatrixMode(GL_MODELVIEW); - glCallList ( dlist ) ; - - - glActiveTexturePtr( GL_TEXTURE1_ARB ); - glDisable( GL_TEXTURE_GEN_S ); - glDisable( GL_TEXTURE_GEN_T ); - glDisable( GL_TEXTURE_GEN_R ); - glDisable( GL_TEXTURE_GEN_Q ); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - glDisable(texBackgroundTarget); - glActiveTexturePtr( GL_TEXTURE0_ARB ); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, 0); - } - // restore states - if( ! my_shader->_depth_test ) - glEnable( GL_DEPTH_TEST ); - - glEnable( GL_LIGHTING ); - glDepthMask( GL_TRUE ); - if( sst ) - sst->force(); - - // don't draw ! - return false; -} - -static int fresnel_shader_callback( ssgEntity *e ) { - if( ! ((SGShadowAnimation *)e->getUserData())->get_condition_value() ) - return true; - - GLuint dlist = 0; - ssgLeaf *leaf = (ssgLeaf *) e; -#ifdef _SSG_USE_DLIST - dlist = leaf->getDListIndex(); - if( ! dlist ) { - leaf->makeDList(); - dlist = leaf->getDListIndex(); - } -#endif - if( ! dlist ) - return true; - ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState()); - if ( sst ) - sst->apply(); - - sgVec4 sunColor, ambientColor; - ssgGetLight( 0 )->getColour(GL_DIFFUSE, sunColor ); - ssgGetLight( 0 )->getColour(GL_AMBIENT, ambientColor ); - - // SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() ); - glEnable(GL_BLEND); - glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ; - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.0f); - - if( true ) { -// sgVec4 R = {0.5,0.0,0.0,0.0}; - sgVec4 enviro = {1.0,0.0,0.0,1.0}; -// sgCopyVec4( enviro, sunColor ); - glActiveTexturePtr( GL_TEXTURE0_ARB ); - glEnable(GL_TEXTURE_2D); - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - glActiveTexturePtr( GL_TEXTURE1_ARB ); - glDisable(GL_TEXTURE_2D); - glEnable(GL_TEXTURE_1D); - glBindTexture(GL_TEXTURE_1D, texFresnel); - // c = a0 * a2 + a1 * (1-a2) -// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); -// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB ); - glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB ); - glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_CONSTANT_ARB ); - glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR ); - glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB ); - glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR ); - glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE ); - glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR ); - glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, enviro); - shFresnel->enable(); - shFresnel->bind(); - glCallList ( dlist ) ; - shFresnel->disable(); - glActiveTexturePtr( GL_TEXTURE1_ARB ); - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - glDisable(GL_TEXTURE_1D); - glActiveTexturePtr( GL_TEXTURE0_ARB ); - glDisable(GL_TEXTURE_1D); - glEnable(GL_TEXTURE_2D); - } - // restore states -// glBindTexture(GL_TEXTURE_2D, 0); -// glDepthFunc(GL_LESS); -// glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ; - if( sst ) - sst->force(); - - // don't draw ! - return false; -} - - - -static int chrome_shader_callback( ssgEntity *e ) { - if( ! ((SGShadowAnimation *)e->getUserData())->get_condition_value() ) - return true; - - GLuint dlist = 0; - ssgLeaf *leaf = (ssgLeaf *) e; -#ifdef _SSG_USE_DLIST - dlist = leaf->getDListIndex(); - if( ! dlist ) { - leaf->makeDList(); - dlist = leaf->getDListIndex(); - } -#endif - if( ! dlist ) - return true; - ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState()); - if ( sst ) - sst->apply(); - - SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() ); - if( ! my_shader->_depth_test ) - glDisable( GL_DEPTH_TEST ); - - GLint maskTexComponent = 3; - glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_COMPONENTS, &maskTexComponent); - - // The fake env chrome texture - glActiveTexturePtr( GL_TEXTURE1_ARB ); - glEnable(GL_TEXTURE_2D); - { - // No lighting is computed in spherical mapping mode because the environment - // is supposed to be allready lighted. We must reshade our environment texture. - sgVec4 sunColor, ambientColor, envColor; - ssgGetLight( 0 )->getColour(GL_DIFFUSE, sunColor ); - ssgGetLight( 0 )->getColour(GL_AMBIENT, ambientColor ); - sgAddScaledVec3( envColor, ambientColor, sunColor, 0.4f); - glBindTexture(GL_TEXTURE_2D, my_shader->_effectTexture->getHandle()); - - sgVec3 delta_light; - sgSubVec3(delta_light, envColor, my_shader->_envColor); - if( (fabs(delta_light[0]) + fabs(delta_light[1]) + fabs(delta_light[2])) > 0.05f ) { - sgCopyVec3( my_shader->_envColor, envColor ); - // reload the texture data and let the driver reshade it for us - glPixelTransferf( GL_RED_SCALE, envColor[0] ); - glPixelTransferf( GL_GREEN_SCALE, envColor[1] ); - glPixelTransferf( GL_BLUE_SCALE, envColor[2] ); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, my_shader->_texWidth, my_shader->_texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, my_shader->_textureData); - glPixelTransferf( GL_RED_SCALE, 1.0f ); - glPixelTransferf( GL_GREEN_SCALE, 1.0f ); - glPixelTransferf( GL_BLUE_SCALE, 1.0f ); - } - } - if( maskTexComponent == 4 ) { - // c = lerp(model tex, chrome tex, model tex alpha) - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB ); - glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB ); - glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB ); - glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR ); - glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE ); - glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR ); - glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PREVIOUS_ARB ); - glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA ); - - glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); - glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); - glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); - } else { - // c = chrome tex - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); - glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE ); - glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR ); - - glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); - glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); - glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); - } - // automatic generation of texture coordinates - // from normals - - glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP ); - glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP ); - glEnable( GL_TEXTURE_GEN_S ); - glEnable( GL_TEXTURE_GEN_T ); - - glCallList ( dlist ) ; - - glActiveTexturePtr( GL_TEXTURE1_ARB ); - glDisable( GL_TEXTURE_GEN_S ); - glDisable( GL_TEXTURE_GEN_T ); - - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - - glDisable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexturePtr( GL_TEXTURE0_ARB ); - - // restore states - if( ! my_shader->_depth_test ) - glEnable( GL_DEPTH_TEST ); - - if( sst ) - sst->force(); - - // don't draw ! - return false; -} - -static void init_shaders(void) { - Shader::Init(); - if( false && Shader::is_VP_supported() ) { - shFresnel = new Shader("/FlightGear/data/Textures/fresnel_vp.txt", "fresnel_vp"); -// shFresnel->bindNames("somedata", 0); - } - glActiveTexturePtr = (glActiveTextureProc) SGLookupFunction("glActiveTextureARB"); - const int fresnelSize = 512; - unsigned char imageFresnel[ fresnelSize * 3 ]; - for(int i = 0; i < fresnelSize; i++) { - const float R0 = 0.2f; - float NdotV = float( i ) / float( fresnelSize ); - float f = R0 + (1.0f-R0)*pow(1.0f - NdotV, 5); - unsigned char ff = (unsigned char) (f * 255.0); - imageFresnel[i*3+0] = imageFresnel[i*3+1] = imageFresnel[i*3+2] = ff; - } - glGenTextures( 1, &texFresnel ); - glBindTexture(GL_TEXTURE_1D, texFresnel ); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_1D, GL_GENERATE_MIPMAP_SGIS, true); - glTexImage1D(GL_TEXTURE_1D, 0, 3, fresnelSize, 0, GL_RGB, GL_UNSIGNED_BYTE, imageFresnel); - glBindTexture(GL_TEXTURE_1D, 0 ); - - sgMakeIdentMat4( shadIdentMatrix ); - - initDone = true; -} - -//////////////////////////////////////////////////////////////////////// -// Implementation of SGShaderAnimation -//////////////////////////////////////////////////////////////////////// +// static glActiveTextureProc glActiveTexturePtr = 0; +// static sgMat4 shadIdentMatrix; + + +// static int null_shader_callback( ssgEntity *e ) { +// GLuint dlist = 0; +// ssgLeaf *leaf = (ssgLeaf *) e; +// #ifdef _SSG_USE_DLIST +// dlist = leaf->getDListIndex(); +// if( ! dlist ) { +// leaf->makeDList(); +// dlist = leaf->getDListIndex(); +// } +// #endif +// if( ! dlist ) +// return true; +// ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState()); +// if ( sst ) +// sst->apply(); + +// SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() ); +// if( ! my_shader->_depth_test ) +// glDisable( GL_DEPTH_TEST ); +// glCallList ( dlist ) ; +// // restore states +// if( ! my_shader->_depth_test ) +// glEnable( GL_DEPTH_TEST ); + +// // don't draw ! +// return false; +// } + +// static int heat_haze_shader_callback( ssgEntity *e ) { +// if( ! ((SGShadowAnimation *)e->getUserData())->get_condition_value() ) +// return true; + +// GLuint dlist = 0; +// ssgLeaf *leaf = (ssgLeaf *) e; +// #ifdef _SSG_USE_DLIST +// dlist = leaf->getDListIndex(); +// if( ! dlist ) { +// leaf->makeDList(); +// dlist = leaf->getDListIndex(); +// } +// #endif +// if( ! dlist ) +// return true; + +// GLint viewport[4]; +// glGetIntegerv( GL_VIEWPORT, viewport ); +// const int screen_width = viewport[2]; +// const int screen_height = viewport[3]; +// if( ! haveBackground ) { +// // store the backbuffer in a texture +// if( ! texBackground ) { +// // allocate our texture here so we don't waste memory if no model use that effect +// // check if we need a rectangle texture and if the card support it +// if( (screen_width > 1024 || screen_height > 1024) && isRectangleTextureSupported ) { +// // Note that the 3 (same) extensions use the same enumerants +// texBackgroundTarget = GL_TEXTURE_RECTANGLE_NV; +// istexBackgroundRectangle = true; +// texBackgroundWidth = screen_width; +// texBackgroundHeight = screen_height; +// } +// glGenTextures(1, &texBackground); +// glEnable(texBackgroundTarget); +// glBindTexture(texBackgroundTarget, texBackground); +// // trying to match the backbuffer pixel format +// GLint internalFormat = GL_RGB8; +// GLint colorBits = 0, alphaBits = 0; +// glGetIntegerv( GL_BLUE_BITS, &colorBits ); +// glGetIntegerv( GL_ALPHA_BITS, &alphaBits ); +// if(colorBits == 5) { +// if( alphaBits == 0 ) +// internalFormat = GL_RGB5; +// else +// internalFormat = GL_RGB5_A1; +// } else { +// if( alphaBits != 0 ) +// internalFormat = GL_RGBA8; +// } +// glTexImage2D(texBackgroundTarget, 0, internalFormat, +// texBackgroundWidth, texBackgroundHeight, 0, GL_RGB, GL_FLOAT, NULL); + +// glTexParameteri(texBackgroundTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); +// glTexParameteri(texBackgroundTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +// glTexParameteri(texBackgroundTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +// glTexParameteri(texBackgroundTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +// } +// glEnable(texBackgroundTarget); +// glBindTexture(texBackgroundTarget, texBackground); +// // center of texture = center of screen +// // obviously we don't have the whole screen if screen_width > texBackgroundWidth +// // if rectangle textures are not supported, this give some artifacts on the borders +// if( istexBackgroundRectangle ) { +// glCopyTexSubImage2D( texBackgroundTarget, 0, 0, 0, +// 0, 0, texBackgroundWidth, texBackgroundHeight ); +// } else { +// glCopyTexSubImage2D( texBackgroundTarget, 0, 0, 0, +// (screen_width - texBackgroundWidth) / 2, +// (screen_height - texBackgroundHeight) / 2, +// texBackgroundWidth, texBackgroundHeight ); +// } +// haveBackground = true; +// glBindTexture(texBackgroundTarget, 0); +// glDisable(texBackgroundTarget); +// } +// ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState()); +// if ( sst ) +// sst->apply(); + +// SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() ); +// if( ! my_shader->_depth_test ) +// glDisable( GL_DEPTH_TEST ); +// glDepthMask( GL_FALSE ); +// glDisable( GL_LIGHTING ); +// if(1) { +// // noise texture, tex coord from the model translated by a time factor +// glActiveTexturePtr( GL_TEXTURE0_ARB ); +// glEnable(GL_TEXTURE_2D); +// const float noiseDist = fmod(- totalTime * my_shader->_factor * my_shader->_speed, 4.0); +// glMatrixMode(GL_TEXTURE); +// glLoadIdentity(); +// glTranslatef( noiseDist, 0.0f, 0.0f ); +// glMatrixMode(GL_MODELVIEW); + +// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + +// // background texture +// glActiveTexturePtr( GL_TEXTURE1_ARB ); +// glEnable(texBackgroundTarget); +// glBindTexture(texBackgroundTarget, texBackground); + +// // automatic generation of texture coordinates +// // map to screen space +// sgMat4 CameraProjM, CameraViewM; +// glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat *) CameraProjM); +// glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) CameraViewM); +// // const float dummy_scale = 1.0f; //0.95f; +// const float deltaPos = 0.05f; +// glMatrixMode(GL_TEXTURE); +// glLoadIdentity(); +// if( istexBackgroundRectangle ) { +// // coords go from 0.0 to n, not from 0.0 to 1.0 +// glTranslatef( texBackgroundWidth * 0.5f, texBackgroundHeight * 0.5f, 0.0f ); +// glScalef( texBackgroundWidth * 0.5f, +// texBackgroundHeight * 0.5f, 1.0f ); +// } else { +// glTranslatef( 0.5f, 0.5f, 0.0f ); +// glScalef( float( screen_width ) / float( texBackgroundWidth ) * 0.5f, +// float( screen_height ) / float( texBackgroundHeight ) * 0.5f, 1.0f ); +// } +// glMultMatrixf( (GLfloat *) CameraProjM ); +// glMultMatrixf( (GLfloat *) CameraViewM ); +// glTranslatef( deltaPos, deltaPos, deltaPos ); +// glMatrixMode(GL_MODELVIEW); + +// glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); +// glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); +// glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); +// glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); +// glTexGenfv( GL_S, GL_EYE_PLANE, shadIdentMatrix[0] ); +// glTexGenfv( GL_T, GL_EYE_PLANE, shadIdentMatrix[1] ); +// glTexGenfv( GL_R, GL_EYE_PLANE, shadIdentMatrix[2] ); +// glTexGenfv( GL_Q, GL_EYE_PLANE, shadIdentMatrix[3] ); +// glEnable( GL_TEXTURE_GEN_S ); +// glEnable( GL_TEXTURE_GEN_T ); +// glEnable( GL_TEXTURE_GEN_R ); +// glEnable( GL_TEXTURE_GEN_Q ); + +// sgVec4 enviro = {1.00f, 1.00f, 1.00f, 0.85f}; + +// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB ); +// glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE ); +// glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE ); +// glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR ); +// glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_CONSTANT_ARB ); +// glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR ); +// glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, enviro); + +// glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE); +// glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE0_ARB); +// glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); +// glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PRIMARY_COLOR_ARB ); +// glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA ); + +// glCallList ( dlist ) ; +// glMatrixMode(GL_TEXTURE); +// glTranslatef( - deltaPos*2.0f, -deltaPos*2.5f, -deltaPos*2.0f ); +// glMatrixMode(GL_MODELVIEW); +// glCallList ( dlist ) ; + +// // alter colors only on last rendering +// // sgVec4 fLight = {0.93f, 0.93f, 1.00f, 0.85f}; +// glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB ); +// glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR ); + +// glMatrixMode(GL_TEXTURE); +// glTranslatef( deltaPos*0.7f, deltaPos*1.7f, deltaPos*0.7f ); +// glMatrixMode(GL_MODELVIEW); +// glCallList ( dlist ) ; + + +// glActiveTexturePtr( GL_TEXTURE1_ARB ); +// glDisable( GL_TEXTURE_GEN_S ); +// glDisable( GL_TEXTURE_GEN_T ); +// glDisable( GL_TEXTURE_GEN_R ); +// glDisable( GL_TEXTURE_GEN_Q ); +// glMatrixMode(GL_TEXTURE); +// glLoadIdentity(); +// glMatrixMode(GL_MODELVIEW); +// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); +// glDisable(texBackgroundTarget); +// glActiveTexturePtr( GL_TEXTURE0_ARB ); +// glMatrixMode(GL_TEXTURE); +// glLoadIdentity(); +// glMatrixMode(GL_MODELVIEW); +// glEnable(GL_TEXTURE_2D); +// glBindTexture(GL_TEXTURE_2D, 0); +// } +// // restore states +// if( ! my_shader->_depth_test ) +// glEnable( GL_DEPTH_TEST ); + +// glEnable( GL_LIGHTING ); +// glDepthMask( GL_TRUE ); +// if( sst ) +// sst->force(); + +// // don't draw ! +// return false; +// } + +// static int fresnel_shader_callback( ssgEntity *e ) { +// if( ! ((SGShadowAnimation *)e->getUserData())->get_condition_value() ) +// return true; + +// GLuint dlist = 0; +// ssgLeaf *leaf = (ssgLeaf *) e; +// #ifdef _SSG_USE_DLIST +// dlist = leaf->getDListIndex(); +// if( ! dlist ) { +// leaf->makeDList(); +// dlist = leaf->getDListIndex(); +// } +// #endif +// if( ! dlist ) +// return true; +// ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState()); +// if ( sst ) +// sst->apply(); + +// sgVec4 sunColor, ambientColor; +// ssgGetLight( 0 )->getColour(GL_DIFFUSE, sunColor ); +// ssgGetLight( 0 )->getColour(GL_AMBIENT, ambientColor ); + +// // SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() ); +// glEnable(GL_BLEND); +// glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ; +// glEnable(GL_ALPHA_TEST); +// glAlphaFunc(GL_GREATER, 0.0f); + +// if( true ) { +// // sgVec4 R = {0.5,0.0,0.0,0.0}; +// sgVec4 enviro = {1.0,0.0,0.0,1.0}; +// // sgCopyVec4( enviro, sunColor ); +// glActiveTexturePtr( GL_TEXTURE0_ARB ); +// glEnable(GL_TEXTURE_2D); +// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); +// glActiveTexturePtr( GL_TEXTURE1_ARB ); +// glDisable(GL_TEXTURE_2D); +// glEnable(GL_TEXTURE_1D); +// glBindTexture(GL_TEXTURE_1D, texFresnel); +// // c = a0 * a2 + a1 * (1-a2) +// // glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); +// // glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); +// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB ); +// glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB ); +// glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_CONSTANT_ARB ); +// glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR ); +// glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB ); +// glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR ); +// glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE ); +// glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR ); +// glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, enviro); +// shFresnel->enable(); +// shFresnel->bind(); +// glCallList ( dlist ) ; +// shFresnel->disable(); +// glActiveTexturePtr( GL_TEXTURE1_ARB ); +// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); +// glDisable(GL_TEXTURE_1D); +// glActiveTexturePtr( GL_TEXTURE0_ARB ); +// glDisable(GL_TEXTURE_1D); +// glEnable(GL_TEXTURE_2D); +// } +// // restore states +// // glBindTexture(GL_TEXTURE_2D, 0); +// // glDepthFunc(GL_LESS); +// // glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ; +// if( sst ) +// sst->force(); + +// // don't draw ! +// return false; +// } + + + +// static int chrome_shader_callback( ssgEntity *e ) { +// if( ! ((SGShadowAnimation *)e->getUserData())->get_condition_value() ) +// return true; + +// GLuint dlist = 0; +// ssgLeaf *leaf = (ssgLeaf *) e; +// #ifdef _SSG_USE_DLIST +// dlist = leaf->getDListIndex(); +// if( ! dlist ) { +// leaf->makeDList(); +// dlist = leaf->getDListIndex(); +// } +// #endif +// if( ! dlist ) +// return true; +// ssgSimpleState *sst = ((ssgSimpleState *)leaf->getState()); +// if ( sst ) +// sst->apply(); + +// SGShaderAnimation *my_shader = (SGShaderAnimation *) ( e->getUserData() ); +// if( ! my_shader->_depth_test ) +// glDisable( GL_DEPTH_TEST ); + +// GLint maskTexComponent = 3; +// glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_COMPONENTS, &maskTexComponent); + +// // The fake env chrome texture +// glActiveTexturePtr( GL_TEXTURE1_ARB ); +// glEnable(GL_TEXTURE_2D); +// { +// // No lighting is computed in spherical mapping mode because the environment +// // is supposed to be allready lighted. We must reshade our environment texture. +// sgVec4 sunColor, ambientColor, envColor; +// ssgGetLight( 0 )->getColour(GL_DIFFUSE, sunColor ); +// ssgGetLight( 0 )->getColour(GL_AMBIENT, ambientColor ); +// sgAddScaledVec3( envColor, ambientColor, sunColor, 0.4f); +// glBindTexture(GL_TEXTURE_2D, my_shader->_effectTexture->getHandle()); + +// sgVec3 delta_light; +// sgSubVec3(delta_light, envColor, my_shader->_envColor); +// if( (fabs(delta_light[0]) + fabs(delta_light[1]) + fabs(delta_light[2])) > 0.05f ) { +// sgCopyVec3( my_shader->_envColor, envColor ); +// // reload the texture data and let the driver reshade it for us +// glPixelTransferf( GL_RED_SCALE, envColor[0] ); +// glPixelTransferf( GL_GREEN_SCALE, envColor[1] ); +// glPixelTransferf( GL_BLUE_SCALE, envColor[2] ); +// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, my_shader->_texWidth, my_shader->_texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, my_shader->_textureData); +// glPixelTransferf( GL_RED_SCALE, 1.0f ); +// glPixelTransferf( GL_GREEN_SCALE, 1.0f ); +// glPixelTransferf( GL_BLUE_SCALE, 1.0f ); +// } +// } +// if( maskTexComponent == 4 ) { +// // c = lerp(model tex, chrome tex, model tex alpha) +// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB ); +// glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB ); +// glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB ); +// glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR ); +// glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE ); +// glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR ); +// glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PREVIOUS_ARB ); +// glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA ); + +// glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); +// glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); +// glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); +// } else { +// // c = chrome tex +// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); +// glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE ); +// glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR ); + +// glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); +// glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); +// glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); +// } +// // automatic generation of texture coordinates +// // from normals + +// glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP ); +// glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP ); +// glEnable( GL_TEXTURE_GEN_S ); +// glEnable( GL_TEXTURE_GEN_T ); + +// glCallList ( dlist ) ; + +// glActiveTexturePtr( GL_TEXTURE1_ARB ); +// glDisable( GL_TEXTURE_GEN_S ); +// glDisable( GL_TEXTURE_GEN_T ); + +// glMatrixMode(GL_TEXTURE); +// glLoadIdentity(); +// glMatrixMode(GL_MODELVIEW); + +// glDisable(GL_TEXTURE_2D); +// glBindTexture(GL_TEXTURE_2D, 0); +// glActiveTexturePtr( GL_TEXTURE0_ARB ); + +// // restore states +// if( ! my_shader->_depth_test ) +// glEnable( GL_DEPTH_TEST ); + +// if( sst ) +// sst->force(); + +// // don't draw ! +// return false; +// } + +// static void init_shaders(void) { +// Shader::Init(); +// if( false && Shader::is_VP_supported() ) { +// shFresnel = new Shader("/FlightGear/data/Textures/fresnel_vp.txt", "fresnel_vp"); +// } +// glActiveTexturePtr = (glActiveTextureProc) SGLookupFunction("glActiveTextureARB"); +// const int fresnelSize = 512; +// unsigned char imageFresnel[ fresnelSize * 3 ]; +// for(int i = 0; i < fresnelSize; i++) { +// const float R0 = 0.2f; +// float NdotV = float( i ) / float( fresnelSize ); +// float f = R0 + (1.0f-R0)*pow(1.0f - NdotV, 5); +// unsigned char ff = (unsigned char) (f * 255.0); +// imageFresnel[i*3+0] = imageFresnel[i*3+1] = imageFresnel[i*3+2] = ff; +// } +// glGenTextures( 1, &texFresnel ); +// glBindTexture(GL_TEXTURE_1D, texFresnel ); +// glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); +// glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +// glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +// glTexParameteri(GL_TEXTURE_1D, GL_GENERATE_MIPMAP_SGIS, true); +// glTexImage1D(GL_TEXTURE_1D, 0, 3, fresnelSize, 0, GL_RGB, GL_UNSIGNED_BYTE, imageFresnel); +// glBindTexture(GL_TEXTURE_1D, 0 ); + +// sgMakeIdentMat4( shadIdentMatrix ); + +// initDone = true; +// } + +// //////////////////////////////////////////////////////////////////////// +// // Implementation of SGShaderAnimation +// //////////////////////////////////////////////////////////////////////// SGShaderAnimation::SGShaderAnimation ( SGPropertyNode *prop_root, SGPropertyNode_ptr props ) - : SGAnimation(props, new ssgBranch), + : SGAnimation(props, new osg::Group), _condition(0), _condition_value(true), _shader_type(0), @@ -545,7 +540,6 @@ SGShaderAnimation::SGShaderAnimation ( SGPropertyNode *prop_root, _factor_prop(0), _speed(props->getFloatValue("speed", 1.0f)), _speed_prop(0), - _effectTexture(0), _textureData(0), _texWidth(0), _texHeight(0) @@ -563,78 +557,67 @@ SGShaderAnimation::SGShaderAnimation ( SGPropertyNode *prop_root, if( node ) _speed_prop = prop_root->getNode(node->getStringValue(), true); - sgSetVec4(_envColor, 0.0f, 0.0f, 0.0f, 1.0f); + _envColor = osg::Vec4(0, 0, 0, 1); node = props->getChild("texture"); if( node ) { - _effectTexture = ssgGetCurrentOptions()->createTexture( (char *) node->getStringValue(), 0, 0, 0); - glBindTexture(GL_TEXTURE_2D, _effectTexture->getHandle() ); - glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &_texWidth); - glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &_texHeight); - - _textureData = new unsigned char[_texWidth * _texHeight * 3]; - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, _textureData); - glBindTexture(GL_TEXTURE_2D, 0 ); + _effectTexture = SGLoadTexture2D(node->getStringValue()); +// glBindTexture(GL_TEXTURE_2D, _effectTexture->getHandle() ); +// glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &_texWidth); +// glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &_texHeight); + +// _textureData = new unsigned char[_texWidth * _texHeight * 3]; +// glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, _textureData); +// glBindTexture(GL_TEXTURE_2D, 0 ); } string shader_name = props->getStringValue("shader"); if( shader_name == "fresnel" || shader_name == "reflection" ) _shader_type = 1; else if( shader_name == "heat-haze" ) _shader_type = 2; - else if( shader_name == "chrome" && _effectTexture) + else if( shader_name == "chrome" && _effectTexture.valid()) _shader_type = 3; } -static void setCallBack(ssgBranch *branch, ssgBase *user_data, ssgCallback cb) { - for (int i = 0; i < branch->getNumKids(); i++) { - ssgEntity *e = branch->getKid(i); - if( e->isAKindOf( ssgTypeBranch() ) ) - setCallBack( (ssgBranch *) e, user_data, cb); - else if( e->isAKindOf( ssgTypeVtxTable() ) ) { - e->setCallback( SSG_CALLBACK_PREDRAW, cb ); - e->setUserData( user_data ); - } - } -} - void SGShaderAnimation::init() { - if( ! initDone ) - init_shaders(); - if( _shader_type == 1 && Shader::is_VP_supported() && shFresnel) - setCallBack( getBranch(), (ssgBase *) this, fresnel_shader_callback ); - else if( _shader_type == 2 ) { - // this is the same extension with different names - isRectangleTextureSupported = SGIsOpenGLExtensionSupported("GL_EXT_texture_rectangle") || - SGIsOpenGLExtensionSupported("GL_ARB_texture_rectangle") || - SGIsOpenGLExtensionSupported("GL_NV_texture_rectangle"); - setCallBack( getBranch(), (ssgBase *) this, heat_haze_shader_callback ); - } - else if( _shader_type == 3 ) - setCallBack( getBranch(), (ssgBase *) this, chrome_shader_callback ); - else - setCallBack( getBranch(), (ssgBase *) this, null_shader_callback ); +// if( ! initDone ) +// init_shaders(); +// if( _shader_type == 1 && Shader::is_VP_supported() && shFresnel) +// setCallBack( getBranch(), (ssgBase *) this, fresnel_shader_callback ); +// else if( _shader_type == 2 ) { +// // this is the same extension with different names +// isRectangleTextureSupported = SGIsOpenGLExtensionSupported("GL_EXT_texture_rectangle") || +// SGIsOpenGLExtensionSupported("GL_ARB_texture_rectangle") || +// SGIsOpenGLExtensionSupported("GL_NV_texture_rectangle"); +// setCallBack( getBranch(), (ssgBase *) this, heat_haze_shader_callback ); +// } +// else if( _shader_type == 3 ) +// setCallBack( getBranch(), (ssgBase *) this, chrome_shader_callback ); +// else +// setCallBack( getBranch(), (ssgBase *) this, null_shader_callback ); } SGShaderAnimation::~SGShaderAnimation() { - delete _condition; - delete _effectTexture; - delete _textureData; -} - -int -SGShaderAnimation::update() -{ - if (_condition) - _condition_value = _condition->test(); - if( _factor_prop) - _factor = _factor_prop->getFloatValue(); - if( _speed_prop) - _speed = _speed_prop->getFloatValue(); - return 2; + delete _condition; + delete _textureData; } -void sgShaderFrameInit(double delta_time_sec) { - haveBackground = false; - totalTime += delta_time_sec; +void +SGShaderAnimation::operator()(osg::Node* node, osg::NodeVisitor* nv) +{ + if (_condition) + _condition_value = _condition->test(); + if( _factor_prop) + _factor = _factor_prop->getFloatValue(); + if( _speed_prop) + _speed = _speed_prop->getFloatValue(); + + // OSGFIXME fiddle with totalTime + totalTime = nv->getFrameStamp()->getReferenceTime(); + + // 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); } diff --git a/simgear/scene/model/shadowvolume.hxx b/simgear/scene/model/shadowvolume.hxx index 2a46cecc..8f5ebcde 100644 --- a/simgear/scene/model/shadowvolume.hxx +++ b/simgear/scene/model/shadowvolume.hxx @@ -24,12 +24,8 @@ #define _SHADOWVOLUME_HXX #include -#include #include -#include -#include - #include #include diff --git a/simgear/scene/sky/cloud.cxx b/simgear/scene/sky/cloud.cxx index b3f7440f..f236b46a 100644 --- a/simgear/scene/sky/cloud.cxx +++ b/simgear/scene/sky/cloud.cxx @@ -26,188 +26,124 @@ #include -// #include +#include + #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include -#include #include #include -#include -#include -#include +#include +#include +#include #include "newcloud.hxx" #include "cloudfield.hxx" #include "cloud.hxx" -#if defined(__MINGW32__) -#define isnan(x) _isnan(x) -#endif +// #if defined(__MINGW32__) +// #define isnan(x) _isnan(x) +// #endif -#if defined (__FreeBSD__) -# if __FreeBSD_version < 500000 - extern "C" { - inline int isnan(double r) { return !(r <= 0 || r >= 0); } - } -# endif -#endif +// #if defined (__FreeBSD__) +// # if __FreeBSD_version < 500000 +// extern "C" { +// inline int isnan(double r) { return !(r <= 0 || r >= 0); } +// } +// # endif +// #endif #if defined (__CYGWIN__) #include #endif -static ssgSharedPtr layer_states[SGCloudLayer::SG_MAX_CLOUD_COVERAGES]; +static osg::ref_ptr layer_states[SGCloudLayer::SG_MAX_CLOUD_COVERAGES]; +static osg::ref_ptr layer_states2[SGCloudLayer::SG_MAX_CLOUD_COVERAGES]; +static osg::ref_ptr cubeMap; static bool state_initialized = false; static bool bump_mapping = false; -static GLint nb_texture_unit = 0; -static ssgSharedPtr normal_map[SGCloudLayer::SG_MAX_CLOUD_COVERAGES][2]; -static ssgSharedPtr color_map[SGCloudLayer::SG_MAX_CLOUD_COVERAGES][2]; -static GLuint normalization_cube_map; - -static glActiveTextureProc glActiveTexturePtr = 0; -static glClientActiveTextureProc glClientActiveTexturePtr = 0; -static glBlendColorProc glBlendColorPtr = 0; bool SGCloudLayer::enable_bump_mapping = false; -static void -generateNormalizationCubeMap() +// make an StateSet for a cloud layer given the named texture +static osg::StateSet* +SGMakeState(const SGPath &path, const char* colorTexture, const char* normalTexture) { - unsigned char data[ 32 * 32 * 3 ]; - const int size = 32; - const float half_size = 16.0f, - offset = 0.5f; - sgVec3 zero_normal; - sgSetVec3( zero_normal, 0.5f, 0.5f, 0.5f ); - int i, j; - - unsigned char *ptr = data; - for ( j = 0; j < size; j++ ) { - for ( i = 0; i < size; i++ ) { - sgVec3 tmp; - sgSetVec3( tmp, half_size, - -( j + offset - half_size ), - -( i + offset - half_size ) ); - sgNormalizeVec3( tmp ); - sgScaleVec3( tmp, 0.5f ); - sgAddVec3( tmp, zero_normal ); - - *ptr++ = (unsigned char)( tmp[ 0 ] * 255 ); - *ptr++ = (unsigned char)( tmp[ 1 ] * 255 ); - *ptr++ = (unsigned char)( tmp[ 2 ] * 255 ); - } - } - glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, - 0, GL_RGBA8, 32, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, data ); - - ptr = data; - for ( j = 0; j < size; j++ ) { - for ( i = 0; i < size; i++ ) { - sgVec3 tmp; - sgSetVec3( tmp, -half_size, - -( j + offset - half_size ), - ( i + offset - half_size ) ); - sgNormalizeVec3( tmp ); - sgScaleVec3( tmp, 0.5f ); - sgAddVec3( tmp, zero_normal ); - - *ptr++ = (unsigned char)( tmp[ 0 ] * 255 ); - *ptr++ = (unsigned char)( tmp[ 1 ] * 255 ); - *ptr++ = (unsigned char)( tmp[ 2 ] * 255 ); - } - } - glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, - 0, GL_RGBA8, 32, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, data ); - - ptr = data; - for ( j = 0; j < size; j++ ) { - for ( i = 0; i < size; i++ ) { - sgVec3 tmp; - sgSetVec3( tmp, ( i + offset - half_size ), - half_size, - ( j + offset - half_size ) ); - sgNormalizeVec3( tmp ); - sgScaleVec3( tmp, 0.5f ); - sgAddVec3( tmp, zero_normal ); - - *ptr++ = (unsigned char)( tmp[ 0 ] * 255 ); - *ptr++ = (unsigned char)( tmp[ 1 ] * 255 ); - *ptr++ = (unsigned char)( tmp[ 2 ] * 255 ); - } - } - glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, - 0, GL_RGBA8, 32, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, data ); - - ptr = data; - for ( j = 0; j < size; j++ ) { - for ( i = 0; i < size; i++ ) { - sgVec3 tmp; - sgSetVec3( tmp, ( i + offset - half_size ), - -half_size, - -( j + offset - half_size ) ); - sgNormalizeVec3( tmp ); - sgScaleVec3( tmp, 0.5f ); - sgAddVec3( tmp, zero_normal ); - - *ptr++ = (unsigned char)( tmp[ 0 ] * 255 ); - *ptr++ = (unsigned char)( tmp[ 1 ] * 255 ); - *ptr++ = (unsigned char)( tmp[ 2 ] * 255 ); - } - } - glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, - 0, GL_RGBA8, 32, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, data ); - - ptr = data; - for ( j = 0; j < size; j++ ) { - for ( i = 0; i < size; i++ ) { - sgVec3 tmp; - sgSetVec3( tmp, ( i + offset - half_size ), - -( j + offset - half_size ), - half_size ); - sgNormalizeVec3( tmp ); - sgScaleVec3( tmp, 0.5f ); - sgAddVec3( tmp, zero_normal ); - - *ptr++ = (unsigned char)( tmp[ 0 ] * 255 ); - *ptr++ = (unsigned char)( tmp[ 1 ] * 255 ); - *ptr++ = (unsigned char)( tmp[ 2 ] * 255 ); - } - } - glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, - 0, GL_RGBA8, 32, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, data ); - - ptr = data; - for ( j = 0; j < size; j++ ) { - for ( i = 0; i < size; i++ ) { - sgVec3 tmp; - sgSetVec3( tmp, -( i + offset - half_size ), - -( j + offset - half_size ), - -half_size ); - sgNormalizeVec3( tmp ); - sgScaleVec3( tmp, 0.5f ); - sgAddVec3( tmp, zero_normal ); - - *ptr++ = (unsigned char)( tmp[ 0 ] * 255 ); - *ptr++ = (unsigned char)( tmp[ 1 ] * 255 ); - *ptr++ = (unsigned char)( tmp[ 2 ] * 255 ); - } - } - glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, - 0, GL_RGBA8, 32, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, data ); + osg::StateSet *stateSet = new osg::StateSet; + + SGPath colorPath(path); + colorPath.append(colorTexture); + stateSet->setTextureAttribute(0, SGLoadTexture2D(colorPath)); + stateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); + + osg::TexEnv* texEnv = new osg::TexEnv; + texEnv->setMode(osg::TexEnv::MODULATE); + stateSet->setTextureAttribute(0, texEnv); + + osg::ShadeModel* shadeModel = new osg::ShadeModel; + // FIXME: TRUE?? + shadeModel->setMode(osg::ShadeModel::SMOOTH); + stateSet->setAttributeAndModes(shadeModel); + + stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF); + +// osg::AlphaFunc* alphaFunc = new osg::AlphaFunc; +// alphaFunc->setFunction(osg::AlphaFunc::GREATER); +// alphaFunc->setReferenceValue(0.01); +// stateSet->setAttribute(alphaFunc); +// stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON); + stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::OFF); + + osg::BlendFunc* blendFunc = new osg::BlendFunc; + blendFunc->setSource(osg::BlendFunc::SRC_ALPHA); + blendFunc->setDestination(osg::BlendFunc::ONE_MINUS_SRC_ALPHA); + stateSet->setAttribute(blendFunc); + stateSet->setMode(GL_BLEND, 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.05, 0.05, 0.05, 0)); +// material->setSpecular(osg::Material::FRONT_AND_BACK, +// osg::Vec4(0, 0, 0, 1)); +// stateSet->setAttribute(material); +// stateSet->setMode(GL_COLOR_MATERIAL, osg::StateAttribute::ON); + + stateSet->setMode(GL_FOG, osg::StateAttribute::OFF); + + // OSGFIXME: invented by me ... +// stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); +// stateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON); + +// stateSet->setMode(GL_LIGHT0, osg::StateAttribute::OFF); + + // If the normal texture is given prepare a bumpmapping enabled state +// if (normalTexture) { +// SGPath normalPath(path); +// normalPath.append(normalTexture); +// stateSet->setTextureAttribute(2, SGLoadTexture2D(normalPath)); +// stateSet->setTextureMode(2, GL_TEXTURE_2D, osg::StateAttribute::ON); +// } + + return stateSet; } - // Constructor SGCloudLayer::SGCloudLayer( const string &tex_path ) : - vertices(0), - indices(0), - layer_root(new ssgRoot), - layer_transform(new ssgTransform), - state_sel(0), + layer_root(new osg::Switch), + group_top(new osg::Group), + group_bottom(new osg::Group), + layer_transform(new osg::MatrixTransform), cloud_alpha(1.0), texture_path(tex_path), layer_span(0.0), @@ -221,23 +157,20 @@ SGCloudLayer::SGCloudLayer( const string &tex_path ) : last_lon(0.0), last_lat(0.0) { - cl[0] = cl[1] = cl[2] = cl[3] = NULL; - vl[0] = vl[1] = vl[2] = vl[3] = NULL; - tl[0] = tl[1] = tl[2] = tl[3] = NULL; - layer[0] = layer[1] = layer[2] = layer[3] = NULL; - - layer_root->addKid(layer_transform); - layer3D = new SGCloudField; - rebuild(); + layer_root->addChild(group_bottom.get()); + layer_root->addChild(group_top.get()); + + group_top->addChild(layer_transform.get()); + group_bottom->addChild(layer_transform.get()); + + layer3D = new SGCloudField; + rebuild(); } // Destructor SGCloudLayer::~SGCloudLayer() { - delete layer3D; - delete vertices; - delete indices; - delete layer_root; // deletes layer_transform and layer as well + delete layer3D; } float @@ -313,7 +246,6 @@ SGCloudLayer::setCoverage (Coverage coverage) } } - // build the cloud object void SGCloudLayer::rebuild() @@ -324,525 +256,277 @@ SGCloudLayer::rebuild() SG_LOG(SG_ASTRO, SG_INFO, "initializing cloud layers"); - bump_mapping = SGIsOpenGLExtensionSupported("GL_ARB_multitexture") && - SGIsOpenGLExtensionSupported("GL_ARB_texture_cube_map") && - SGIsOpenGLExtensionSupported("GL_ARB_texture_env_combine") && - SGIsOpenGLExtensionSupported("GL_ARB_texture_env_dot3") && - SGIsOpenGLExtensionSupported("GL_ARB_imaging"); - - if ( bump_mapping ) { - glGetIntegerv( GL_MAX_TEXTURE_UNITS_ARB, &nb_texture_unit ); - if ( nb_texture_unit < 2 ) { - bump_mapping = false; - } - //nb_texture_unit = 2; // Force the number of units for now - } - - if ( bump_mapping ) { - - // This bump mapping code was inspired by the tutorial available at - // http://www.paulsprojects.net/tutorials/simplebump/simplebump.html - // and a NVidia white paper - // http://developer.nvidia.com/object/bumpmappingwithregistercombiners.html - // The normal map textures were generated by the normal map Gimp plugin : - // http://nifelheim.dyndns.org/~cocidius/normalmap/ - // - SGPath cloud_path; - - glActiveTexturePtr = (glActiveTextureProc)SGLookupFunction("glActiveTextureARB"); - glClientActiveTexturePtr = (glClientActiveTextureProc)SGLookupFunction("glClientActiveTextureARB"); - glBlendColorPtr = (glBlendColorProc)SGLookupFunction("glBlendColor"); - - cloud_path.set(texture_path.str()); - cloud_path.append("overcast.rgb"); - color_map[ SG_CLOUD_OVERCAST ][ 0 ] = new ssgTexture( cloud_path.str().c_str() ); - cloud_path.set(texture_path.str()); - cloud_path.append("overcast_n.rgb"); - normal_map[ SG_CLOUD_OVERCAST ][ 0 ] = new ssgTexture( cloud_path.str().c_str() ); - - cloud_path.set(texture_path.str()); - cloud_path.append("overcast_top.rgb"); - color_map[ SG_CLOUD_OVERCAST ][ 1 ] = new ssgTexture( cloud_path.str().c_str() ); - cloud_path.set(texture_path.str()); - cloud_path.append("overcast_top_n.rgb"); - normal_map[ SG_CLOUD_OVERCAST ][ 1 ] = new ssgTexture( cloud_path.str().c_str() ); - - cloud_path.set(texture_path.str()); - cloud_path.append("broken.rgba"); - color_map[ SG_CLOUD_BROKEN ][ 0 ] = new ssgTexture( cloud_path.str().c_str() ); - cloud_path.set(texture_path.str()); - cloud_path.append("broken_n.rgb"); - normal_map[ SG_CLOUD_BROKEN ][ 0 ] = new ssgTexture( cloud_path.str().c_str() ); - - cloud_path.set(texture_path.str()); - cloud_path.append("scattered.rgba"); - color_map[ SG_CLOUD_SCATTERED ][ 0 ] = new ssgTexture( cloud_path.str().c_str() ); - cloud_path.set(texture_path.str()); - cloud_path.append("scattered_n.rgb"); - normal_map[ SG_CLOUD_SCATTERED ][ 0 ] = new ssgTexture( cloud_path.str().c_str() ); - - cloud_path.set(texture_path.str()); - cloud_path.append("few.rgba"); - color_map[ SG_CLOUD_FEW ][ 0 ] = new ssgTexture( cloud_path.str().c_str() ); - cloud_path.set(texture_path.str()); - cloud_path.append("few_n.rgb"); - normal_map[ SG_CLOUD_FEW ][ 0 ] = new ssgTexture( cloud_path.str().c_str() ); - - cloud_path.set(texture_path.str()); - cloud_path.append("cirrus.rgba"); - color_map[ SG_CLOUD_CIRRUS ][ 0 ] = new ssgTexture( cloud_path.str().c_str() ); - cloud_path.set(texture_path.str()); - cloud_path.append("cirrus_n.rgb"); - normal_map[ SG_CLOUD_CIRRUS ][ 0 ] = new ssgTexture( cloud_path.str().c_str() ); - - glGenTextures( 1, &normalization_cube_map ); - glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, normalization_cube_map ); - generateNormalizationCubeMap(); - glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); - glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); - glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE ); - } /* else */ { - SGPath cloud_path; - ssgStateSelector *state_sel; - ssgSimpleState *state; - - state_sel = new ssgStateSelector( 2 ); - cloud_path.set(texture_path.str()); - cloud_path.append("overcast.rgb"); - state_sel->setStep( 0, sgCloudMakeState(cloud_path.str()) ); - cloud_path.set(texture_path.str()); - cloud_path.append("overcast_top.rgb"); - state_sel->setStep( 1, sgCloudMakeState(cloud_path.str()) ); - layer_states[SG_CLOUD_OVERCAST] = state_sel; - - state_sel = new ssgStateSelector( 2 ); - cloud_path.set(texture_path.str()); - cloud_path.append("broken.rgba"); - state = sgCloudMakeState(cloud_path.str()); - state_sel->setStep( 0, state ); - state_sel->setStep( 1, state ); - layer_states[SG_CLOUD_BROKEN] = state_sel; - - state_sel = new ssgStateSelector( 2 ); - cloud_path.set(texture_path.str()); - cloud_path.append("scattered.rgba"); - state = sgCloudMakeState(cloud_path.str()); - state_sel->setStep( 0, state ); - state_sel->setStep( 1, state ); - layer_states[SG_CLOUD_SCATTERED] = state_sel; - - state_sel = new ssgStateSelector( 2 ); - cloud_path.set(texture_path.str()); - cloud_path.append("few.rgba"); - state = sgCloudMakeState(cloud_path.str()); - state_sel->setStep( 0, state ); - state_sel->setStep( 1, state ); - layer_states[SG_CLOUD_FEW] = state_sel; - - state_sel = new ssgStateSelector( 2 ); - cloud_path.set(texture_path.str()); - cloud_path.append("cirrus.rgba"); - state = sgCloudMakeState(cloud_path.str()); - state_sel->setStep( 0, state ); - state_sel->setStep( 1, state ); - layer_states[SG_CLOUD_CIRRUS] = state_sel; - - layer_states[SG_CLOUD_CLEAR] = 0; - } - SGNewCloud::loadTextures(texture_path.str()); - layer3D->buildTestLayer(); - } - - if ( bump_mapping ) { - - if ( !vertices ) { - vertices = new CloudVertex[ 25 ]; - indices = new unsigned int[ 40 ]; + osg::Texture::Extensions* extensions; + extensions = osg::Texture::getExtensions(0, true); + // OSGFIXME + bump_mapping = extensions->isMultiTexturingSupported() && + (2 <= extensions->numTextureUnits()) && + SGIsOpenGLExtensionSupported("GL_ARB_texture_env_combine") && + SGIsOpenGLExtensionSupported("GL_ARB_texture_env_dot3"); + + osg::TextureCubeMap::Extensions* extensions2; + extensions2 = osg::TextureCubeMap::getExtensions(0, true); + bump_mapping = bump_mapping && extensions2->isCubeMapSupported(); + + // This bump mapping code was inspired by the tutorial available at + // http://www.paulsprojects.net/tutorials/simplebump/simplebump.html + // and a NVidia white paper + // http://developer.nvidia.com/object/bumpmappingwithregistercombiners.html + // The normal map textures were generated by the normal map Gimp plugin : + // http://nifelheim.dyndns.org/~cocidius/normalmap/ + // + cubeMap = new osg::TextureCubeMap; + cubeMap->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); + cubeMap->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); + cubeMap->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); + cubeMap->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); + cubeMap->setWrap(osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_EDGE); + + const int size = 32; + const float half_size = 16.0f; + const float offset = 0.5f; + osg::Vec3 zero_normal(0.5, 0.5, 0.5); + + osg::Image* image = new osg::Image; + image->allocateImage(size, size, 1, GL_RGB, GL_UNSIGNED_BYTE); + unsigned char *ptr = image->data(0, 0); + for (int j = 0; j < size; j++ ) { + for (int i = 0; i < size; i++ ) { + osg::Vec3 tmp(half_size, -( j + offset - half_size ), + -( i + offset - half_size ) ); + tmp.normalize(); + tmp = tmp*0.5 - zero_normal; + + *ptr++ = (unsigned char)( tmp[ 0 ] * 255 ); + *ptr++ = (unsigned char)( tmp[ 1 ] * 255 ); + *ptr++ = (unsigned char)( tmp[ 2 ] * 255 ); + } } - - sgVec2 base; - sgSetVec2( base, sg_random(), sg_random() ); - - const float layer_scale = layer_span / scale; - const float layer_to_core = (SG_EARTH_RAD * 1000 + layer_asl); - const float half_angle = 0.5 * layer_span / layer_to_core; - - int i; - for ( i = -2; i <= 2; i++ ) { - for ( int j = -2; j <= 2; j++ ) { - CloudVertex &v1 = vertices[ (i+2)*5 + (j+2) ]; - sgSetVec3( v1.position, - 0.5 * i * layer_span, - 0.5 * j * layer_span, - -layer_to_core * ( 1 - cos( i * half_angle ) * cos( j * half_angle ) ) ); - sgSetVec2( v1.texCoord, - base[0] + layer_scale * i * 0.25, - base[1] + layer_scale * j * 0.25 ); - sgSetVec3( v1.sTangent, - cos( i * half_angle ), - 0.f, - -sin( i * half_angle ) ); - sgSetVec3( v1.tTangent, - 0.f, - cos( j * half_angle ), - -sin( j * half_angle ) ); - sgVectorProductVec3( v1.normal, v1.tTangent, v1.sTangent ); - sgSetVec4( v1.color, 1.0f, 1.0f, 1.0f, (i == 0) ? 0.0f : cloud_alpha * 0.15f ); - } + cubeMap->setImage(osg::TextureCubeMap::POSITIVE_X, image); + + image = new osg::Image; + image->allocateImage(size, size, 1, GL_RGB, GL_UNSIGNED_BYTE); + ptr = image->data(0, 0); + for (int j = 0; j < size; j++ ) { + for (int i = 0; i < size; i++ ) { + osg::Vec3 tmp(-half_size, -( j + offset - half_size ), + ( i + offset - half_size ) ); + tmp.normalize(); + tmp = tmp*0.5 - zero_normal; + + *ptr++ = (unsigned char)( tmp[ 0 ] * 255 ); + *ptr++ = (unsigned char)( tmp[ 1 ] * 255 ); + *ptr++ = (unsigned char)( tmp[ 2 ] * 255 ); + } } - /* - * 0 1 5 6 10 11 15 16 20 21 - * 1 2 6 7 11 12 16 17 21 22 - * 2 3 7 8 12 13 17 18 22 23 - * 3 4 8 9 13 14 18 19 23 24 - */ - for ( i = 0; i < 4; i++ ) { - for ( int j = 0; j < 5; j++ ) { - indices[ i*10 + (j*2) ] = i + 5 * j; - indices[ i*10 + (j*2) + 1 ] = 1 + i + 5 * j; - } + cubeMap->setImage(osg::TextureCubeMap::NEGATIVE_X, image); + + image = new osg::Image; + image->allocateImage(size, size, 1, GL_RGB, GL_UNSIGNED_BYTE); + ptr = image->data(0, 0); + for (int j = 0; j < size; j++ ) { + for (int i = 0; i < size; i++ ) { + osg::Vec3 tmp(( i + offset - half_size ), half_size, + ( j + offset - half_size ) ); + tmp.normalize(); + tmp = tmp*0.5 - zero_normal; + + *ptr++ = (unsigned char)( tmp[ 0 ] * 255 ); + *ptr++ = (unsigned char)( tmp[ 1 ] * 255 ); + *ptr++ = (unsigned char)( tmp[ 2 ] * 255 ); + } } + cubeMap->setImage(osg::TextureCubeMap::POSITIVE_Y, image); + + image = new osg::Image; + image->allocateImage(size, size, 1, GL_RGB, GL_UNSIGNED_BYTE); + ptr = image->data(0, 0); + for (int j = 0; j < size; j++ ) { + for (int i = 0; i < size; i++ ) { + osg::Vec3 tmp(( i + offset - half_size ), -half_size, + -( j + offset - half_size ) ); + tmp.normalize(); + tmp = tmp*0.5 - zero_normal; - } /* else */ { - - scale = 4000.0; - last_lon = last_lat = -999.0f; - - sgVec2 base; - sgSetVec2( base, sg_random(), sg_random() ); - - // build the cloud layer - sgVec4 color; - sgVec3 vertex; - sgVec2 tc; - - const float layer_scale = layer_span / scale; - const float mpi = SG_PI/4; - - // caclculate the difference between a flat-earth model and - // a round earth model given the span and altutude ASL of - // the cloud layer. This is the difference in altitude between - // the top of the inverted bowl and the edge of the bowl. - // const float alt_diff = layer_asl * 0.8; - const float layer_to_core = (SG_EARTH_RAD * 1000 + layer_asl); - const float layer_angle = 0.5*layer_span / layer_to_core; // The angle is half the span - const float border_to_core = layer_to_core * cos(layer_angle); - const float alt_diff = layer_to_core - border_to_core; - - for (int i = 0; i < 4; i++) - { - if ( layer[i] != NULL ) { - layer_transform->removeKid(layer[i]); // automatic delete - } - - vl[i] = new ssgVertexArray( 10 ); - cl[i] = new ssgColourArray( 10 ); - tl[i] = new ssgTexCoordArray( 10 ); - - - sgSetVec3( vertex, layer_span*(i-2)/2, -layer_span, - alt_diff * (sin(i*mpi) - 2) ); - - sgSetVec2( tc, base[0] + layer_scale * i/4, base[1] ); - - sgSetVec4( color, 1.0f, 1.0f, 1.0f, (i == 0) ? 0.0f : 0.15f ); - - cl[i]->add( color ); - vl[i]->add( vertex ); - tl[i]->add( tc ); - - for (int j = 0; j < 4; j++) - { - sgSetVec3( vertex, layer_span*(i-1)/2, layer_span*(j-2)/2, - alt_diff * (sin((i+1)*mpi) + sin(j*mpi) - 2) ); - - sgSetVec2( tc, base[0] + layer_scale * (i+1)/4, - base[1] + layer_scale * j/4 ); - - sgSetVec4( color, 1.0f, 1.0f, 1.0f, - ( (j == 0) || (i == 3)) ? - ( (j == 0) && (i == 3)) ? 0.0f : 0.15f : 1.0f ); - - cl[i]->add( color ); - vl[i]->add( vertex ); - tl[i]->add( tc ); - - - sgSetVec3( vertex, layer_span*(i-2)/2, layer_span*(j-1)/2, - alt_diff * (sin(i*mpi) + sin((j+1)*mpi) - 2) ); - - sgSetVec2( tc, base[0] + layer_scale * i/4, - base[1] + layer_scale * (j+1)/4 ); - - sgSetVec4( color, 1.0f, 1.0f, 1.0f, - ((j == 3) || (i == 0)) ? - ((j == 3) && (i == 0)) ? 0.0f : 0.15f : 1.0f ); - cl[i]->add( color ); - vl[i]->add( vertex ); - tl[i]->add( tc ); - } - - sgSetVec3( vertex, layer_span*(i-1)/2, layer_span, - alt_diff * (sin((i+1)*mpi) - 2) ); - - sgSetVec2( tc, base[0] + layer_scale * (i+1)/4, - base[1] + layer_scale ); - - sgSetVec4( color, 1.0f, 1.0f, 1.0f, (i == 3) ? 0.0f : 0.15f ); - - cl[i]->add( color ); - vl[i]->add( vertex ); - tl[i]->add( tc ); - - layer[i] = new ssgVtxTable(GL_TRIANGLE_STRIP, vl[i], NULL, tl[i], cl[i]); - layer_transform->addKid( layer[i] ); - - if ( layer_states[layer_coverage] != NULL ) { - layer[i]->setState( layer_states[layer_coverage] ); - } - state_sel = layer_states[layer_coverage]; + *ptr++ = (unsigned char)( tmp[ 0 ] * 255 ); + *ptr++ = (unsigned char)( tmp[ 1 ] * 255 ); + *ptr++ = (unsigned char)( tmp[ 2 ] * 255 ); + } } - - // force a repaint of the sky colors with arbitrary defaults - repaint( color ); - } -} - - -// repaint the cloud layer colors -bool SGCloudLayer::repaint( sgVec3 fog_color ) { - - if ( bump_mapping && enable_bump_mapping ) { - - for ( int i = 0; i < 25; i++ ) { - sgCopyVec3( vertices[ i ].color, fog_color ); + cubeMap->setImage(osg::TextureCubeMap::NEGATIVE_Y, image); + + image = new osg::Image; + image->allocateImage(size, size, 1, GL_RGB, GL_UNSIGNED_BYTE); + ptr = image->data(0, 0); + for (int j = 0; j < size; j++ ) { + for (int i = 0; i < size; i++ ) { + osg::Vec3 tmp(( i + offset - half_size ), + -( j + offset - half_size ), half_size ); + tmp.normalize(); + tmp = tmp*0.5 - zero_normal; + + *ptr++ = (unsigned char)( tmp[ 0 ] * 255 ); + *ptr++ = (unsigned char)( tmp[ 1 ] * 255 ); + *ptr++ = (unsigned char)( tmp[ 2 ] * 255 ); + } } - - } else { - float *color; - - for ( int i = 0; i < 4; i++ ) { - color = cl[i]->get( 0 ); - sgCopyVec3( color, fog_color ); - color[3] = (i == 0) ? 0.0f : cloud_alpha * 0.15f; - - for ( int j = 0; j < 4; ++j ) { - color = cl[i]->get( (2*j) + 1 ); - sgCopyVec3( color, fog_color ); - color[3] = - ((j == 0) || (i == 3)) ? - ((j == 0) && (i == 3)) ? 0.0f : cloud_alpha * 0.15f : cloud_alpha; - - color = cl[i]->get( (2*j) + 2 ); - sgCopyVec3( color, fog_color ); - color[3] = - ((j == 3) || (i == 0)) ? - ((j == 3) && (i == 0)) ? 0.0f : cloud_alpha * 0.15f : cloud_alpha; - } - - color = cl[i]->get( 9 ); - sgCopyVec3( color, fog_color ); - color[3] = (i == 3) ? 0.0f : cloud_alpha * 0.15f; + cubeMap->setImage(osg::TextureCubeMap::POSITIVE_Z, image); + + image = new osg::Image; + image->allocateImage(size, size, 1, GL_RGB, GL_UNSIGNED_BYTE); + ptr = image->data(0, 0); + for (int j = 0; j < size; j++ ) { + for (int i = 0; i < size; i++ ) { + osg::Vec3 tmp(-( i + offset - half_size ), + -( j + offset - half_size ), -half_size ); + tmp.normalize(); + tmp = tmp*0.5 - zero_normal; + *ptr++ = (unsigned char)( tmp[ 0 ] * 255 ); + *ptr++ = (unsigned char)( tmp[ 1 ] * 255 ); + *ptr++ = (unsigned char)( tmp[ 2 ] * 255 ); + } } - } - - return true; -} - -// reposition the cloud layer 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 SGCloudLayer::reposition( sgVec3 p, sgVec3 up, double lon, double lat, - double alt, double dt ) -{ - sgMat4 T1, LON, LAT; - sgVec3 axis; - - // combine p and asl (meters) to get translation offset - sgVec3 asl_offset; - sgCopyVec3( asl_offset, up ); - sgNormalizeVec3( asl_offset ); - if ( alt <= layer_asl ) { - sgScaleVec3( asl_offset, layer_asl ); - } else { - sgScaleVec3( asl_offset, layer_asl + layer_thickness ); - } - // cout << "asl_offset = " << asl_offset[0] << "," << asl_offset[1] - // << "," << asl_offset[2] << endl; - sgAddVec3( asl_offset, p ); - // cout << " asl_offset = " << asl_offset[0] << "," << asl_offset[1] - // << "," << asl_offset[2] << endl; - - // Translate to zero elevation - // Point3D zero_elev = current_view.get_cur_zero_elev(); - sgMakeTransMat4( T1, asl_offset ); + cubeMap->setImage(osg::TextureCubeMap::NEGATIVE_Z, image); - // printf(" Translated to %.2f %.2f %.2f\n", - // zero_elev.x, zero_elev.y, zero_elev.z ); - - // Rotate to proper orientation - // printf(" lon = %.2f lat = %.2f\n", - // lon * SGD_RADIANS_TO_DEGREES, - // lat * SGD_RADIANS_TO_DEGREES); - sgSetVec3( axis, 0.0, 0.0, 1.0 ); - sgMakeRotMat4( LON, lon * SGD_RADIANS_TO_DEGREES, axis ); - - sgSetVec3( axis, 0.0, 1.0, 0.0 ); - sgMakeRotMat4( LAT, 90.0 - lat * SGD_RADIANS_TO_DEGREES, axis ); - - sgMat4 TRANSFORM; - - sgCopyMat4( TRANSFORM, T1 ); - sgPreMultMat4( TRANSFORM, LON ); - sgPreMultMat4( TRANSFORM, LAT ); - - sgCoord layerpos; - sgSetCoord( &layerpos, TRANSFORM ); - - layer_transform->setTransform( &layerpos ); + osg::StateSet* state; + state = SGMakeState(texture_path, "overcast.rgb", "overcast_n.rgb"); + layer_states[SG_CLOUD_OVERCAST] = state; + state = SGMakeState(texture_path, "overcast_top.rgb", "overcast_top_n.rgb"); + layer_states2[SG_CLOUD_OVERCAST] = state; + + state = SGMakeState(texture_path, "broken.rgba", "broken_n.rgb"); + layer_states[SG_CLOUD_BROKEN] = state; + layer_states2[SG_CLOUD_BROKEN] = state; + + state = SGMakeState(texture_path, "scattered.rgba", "scattered_n.rgb"); + layer_states[SG_CLOUD_SCATTERED] = state; + layer_states2[SG_CLOUD_SCATTERED] = state; + + state = SGMakeState(texture_path, "few.rgba", "few_n.rgb"); + layer_states[SG_CLOUD_FEW] = state; + layer_states2[SG_CLOUD_FEW] = state; + + state = SGMakeState(texture_path, "cirrus.rgba", "cirrus_n.rgb"); + layer_states[SG_CLOUD_CIRRUS] = state; + layer_states2[SG_CLOUD_CIRRUS] = state; + + layer_states[SG_CLOUD_CLEAR] = 0; + layer_states2[SG_CLOUD_CLEAR] = 0; - // now calculate update texture coordinates - if ( last_lon < -900 ) { - last_lon = lon; - last_lat = lat; + // OSGFIXME +// SGNewCloud::loadTextures(texture_path.str()); +// layer3D->buildTestLayer(); } - double sp_dist = speed*dt; - - if ( lon != last_lon || lat != last_lat || sp_dist != 0 ) { - Point3D start( last_lon, last_lat, 0.0 ); - Point3D dest( lon, lat, 0.0 ); - double course = 0.0, dist = 0.0; - - calc_gc_course_dist( dest, start, &course, &dist ); - // cout << "course = " << course << ", dist = " << dist << endl; - - // if start and dest are too close together, - // calc_gc_course_dist() can return a course of "nan". If - // this happens, lets just use the last known good course. - // This is a hack, and it would probably be better to make - // calc_gc_course_dist() more robust. - if ( isnan(course) ) { - course = last_course; - } else { - last_course = course; - } - - // calculate cloud movement due to external forces - double ax = 0.0, ay = 0.0, bx = 0.0, by = 0.0; - - if (dist > 0.0) { - ax = cos(course) * dist; - ay = sin(course) * dist; - } - - if (sp_dist > 0) { - bx = cos((180.0-direction) * SGD_DEGREES_TO_RADIANS) * sp_dist; - by = sin((180.0-direction) * SGD_DEGREES_TO_RADIANS) * sp_dist; - } - - - double xoff = (ax + bx) / (2 * scale); - double yoff = (ay + by) / (2 * scale); - - const float layer_scale = layer_span / scale; - - // cout << "xoff = " << xoff << ", yoff = " << yoff << endl; - - float *base; - if ( bump_mapping && enable_bump_mapping ) { - base = vertices[12].texCoord; - } else { - base = tl[0]->get( 0 ); - } - base[0] += xoff; - - // the while loops can lead to *long* pauses if base[0] comes - // with a bogus value. - // while ( base[0] > 1.0 ) { base[0] -= 1.0; } - // while ( base[0] < 0.0 ) { base[0] += 1.0; } - if ( base[0] > -10.0 && base[0] < 10.0 ) { - base[0] -= (int)base[0]; - } else { - SG_LOG(SG_ASTRO, SG_DEBUG, - "Error: base = " << base[0] << "," << base[1] << - " course = " << course << " dist = " << dist ); - base[0] = 0.0; - } - - base[1] += yoff; - // the while loops can lead to *long* pauses if base[0] comes - // with a bogus value. - // while ( base[1] > 1.0 ) { base[1] -= 1.0; } - // while ( base[1] < 0.0 ) { base[1] += 1.0; } - if ( base[1] > -10.0 && base[1] < 10.0 ) { - base[1] -= (int)base[1]; - } else { - SG_LOG(SG_ASTRO, SG_DEBUG, - "Error: base = " << base[0] << "," << base[1] << - " course = " << course << " dist = " << dist ); - base[1] = 0.0; - } - - if ( bump_mapping && enable_bump_mapping ) { - - for ( int i = -2; i <= 2; i++ ) { - for ( int j = -2; j <= 2; j++ ) { - if ( i == 0 && j == 0 ) - continue; // Already done on base - CloudVertex &v1 = vertices[ (i+2)*5 + (j+2) ]; - sgSetVec2( v1.texCoord, - base[0] + layer_scale * i * 0.25, - base[1] + layer_scale * j * 0.25 ); - } - } - - } else { - // cout << "base = " << base[0] << "," << base[1] << endl; - - float *tc; - for (int i = 0; i < 4; i++) { - tc = tl[i]->get( 0 ); - sgSetVec2( tc, base[0] + layer_scale * i/4, base[1] ); - - for (int j = 0; j < 4; j++) - { - tc = tl[i]->get( j*2+1 ); - sgSetVec2( tc, base[0] + layer_scale * (i+1)/4, - base[1] + layer_scale * j/4 ); + scale = 4000.0; + last_lon = last_lat = -999.0f; + + base = osg::Vec2(sg_random(), sg_random()); + + // build the cloud layer + const float layer_scale = layer_span / scale; + const float mpi = SG_PI/4; + + // caclculate the difference between a flat-earth model and + // a round earth model given the span and altutude ASL of + // the cloud layer. This is the difference in altitude between + // the top of the inverted bowl and the edge of the bowl. + // const float alt_diff = layer_asl * 0.8; + const float layer_to_core = (SG_EARTH_RAD * 1000 + layer_asl); + const float layer_angle = 0.5*layer_span / layer_to_core; // The angle is half the span + const float border_to_core = layer_to_core * cos(layer_angle); + const float alt_diff = layer_to_core - border_to_core; + + for (int i = 0; i < 4; i++) { + if ( layer[i] != NULL ) { + layer_transform->removeChild(layer[i].get()); // automatic delete + } + + vl[i] = new osg::Vec3Array; + cl[i] = new osg::Vec4Array; + tl[i] = new osg::Vec2Array; + + + osg::Vec3 vertex(layer_span*(i-2)/2, -layer_span, + alt_diff * (sin(i*mpi) - 2)); + osg::Vec2 tc(base[0] + layer_scale * i/4, base[1]); + osg::Vec4 color(1.0f, 1.0f, 1.0f, (i == 0) ? 0.0f : 0.15f); + + cl[i]->push_back(color); + vl[i]->push_back(vertex); + tl[i]->push_back(tc); + + for (int j = 0; j < 4; j++) { + vertex = osg::Vec3(layer_span*(i-1)/2, layer_span*(j-2)/2, + alt_diff * (sin((i+1)*mpi) + sin(j*mpi) - 2)); + tc = osg::Vec2(base[0] + layer_scale * (i+1)/4, + base[1] + layer_scale * j/4); + color = osg::Vec4(1.0f, 1.0f, 1.0f, + ( (j == 0) || (i == 3)) ? + ( (j == 0) && (i == 3)) ? 0.0f : 0.15f : 1.0f ); - tc = tl[i]->get( (j+1)*2 ); - sgSetVec2( tc, base[0] + layer_scale * i/4, - base[1] + layer_scale * (j+1)/4 ); - } + cl[i]->push_back(color); + vl[i]->push_back(vertex); + tl[i]->push_back(tc); - tc = tl[i]->get( 9 ); - sgSetVec2( tc, base[0] + layer_scale * (i+1)/4, - base[1] + layer_scale ); - } - } - - last_lon = lon; - last_lat = lat; + vertex = osg::Vec3(layer_span*(i-2)/2, layer_span*(j-1)/2, + alt_diff * (sin(i*mpi) + sin((j+1)*mpi) - 2) ); + tc = osg::Vec2(base[0] + layer_scale * i/4, + base[1] + layer_scale * (j+1)/4 ); + color = osg::Vec4(1.0f, 1.0f, 1.0f, + ((j == 3) || (i == 0)) ? + ((j == 3) && (i == 0)) ? 0.0f : 0.15f : 1.0f ); + cl[i]->push_back(color); + vl[i]->push_back(vertex); + tl[i]->push_back(tc); + } + + vertex = osg::Vec3(layer_span*(i-1)/2, layer_span, + alt_diff * (sin((i+1)*mpi) - 2)); + + tc = osg::Vec2(base[0] + layer_scale * (i+1)/4, + base[1] + layer_scale); + + color = osg::Vec4(1.0f, 1.0f, 1.0f, (i == 3) ? 0.0f : 0.15f ); + + cl[i]->push_back( color ); + vl[i]->push_back( vertex ); + tl[i]->push_back( tc ); + + osg::Geometry* geometry = new osg::Geometry; + geometry->setUseDisplayList(false); + geometry->setVertexArray(vl[i].get()); + geometry->setNormalBinding(osg::Geometry::BIND_OFF); + geometry->setColorArray(cl[i].get()); + geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); + geometry->setTexCoordArray(0, tl[i].get()); + geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, vl[i]->size())); + layer[i] = new osg::Geode; + + std::stringstream sstr; + sstr << "Cloud Layer (" << i << ")"; + geometry->setName(sstr.str()); + layer[i]->setName(sstr.str()); + layer[i]->addDrawable(geometry); + layer_transform->addChild(layer[i].get()); + } + + //OSGFIXME: true + if ( layer_states[layer_coverage].valid() ) { + osg::CopyOp copyOp(osg::CopyOp::DEEP_COPY_ALL + & ~osg::CopyOp::DEEP_COPY_TEXTURES); + + osg::StateSet* stateSet = static_cast(layer_states2[layer_coverage]->clone(copyOp)); + // OSGFIXME + stateSet->setRenderBinDetails(4, "RenderBin"); + group_top->setStateSet(stateSet); + stateSet = static_cast(layer_states2[layer_coverage]->clone(copyOp)); + stateSet->setRenderBinDetails(4, "RenderBin"); + group_bottom->setStateSet(stateSet); } - - layer3D->reposition( p, up, lon, lat, alt, dt, direction, speed); - return true; } - -void SGCloudLayer::draw( bool top ) { - if ( layer_coverage != SG_CLOUD_CLEAR ) { - - if ( SGCloudField::enable3D && layer3D->is3D()) - layer3D->Render(); - else - if ( bump_mapping && enable_bump_mapping ) { - +#if 0 sgMat4 modelview, tmp, transform; @@ -942,6 +626,15 @@ void SGCloudLayer::draw( bool top ) { glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE ); glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE ); +// use TexEnvCombine to add the highlights to the original lighting +osg::TexEnvCombine *te = new osg::TexEnvCombine; +te->setSource0_RGB(osg::TexEnvCombine::TEXTURE); +te->setCombine_RGB(osg::TexEnvCombine::REPLACE); +te->setSource0_Alpha(osg::TexEnvCombine::TEXTURE); +te->setCombine_Alpha(osg::TexEnvCombine::REPLACE); +ss->setTextureAttributeAndModes(0, te, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON); + + glActiveTexturePtr( GL_TEXTURE1_ARB ); glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB ); @@ -951,6 +644,15 @@ void SGCloudLayer::draw( bool top ) { glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB ); glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE ); +osg::TexEnvCombine *te = new osg::TexEnvCombine; +te->setSource0_RGB(osg::TexEnvCombine::TEXTURE); +te->setCombine_RGB(osg::TexEnvCombine::DOT3_RGB); +te->setSource1_RGB(osg::TexEnvCombine::PREVIOUS); +te->setSource0_Alpha(osg::TexEnvCombine::PREVIOUS); +te->setCombine_Alpha(osg::TexEnvCombine::REPLACE); +ss->setTextureAttributeAndModes(0, te, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON); + + if ( nb_texture_unit >= 3 ) { glActiveTexturePtr( GL_TEXTURE2_ARB ); glBindTexture( GL_TEXTURE_2D, decal->getHandle() ); @@ -1075,35 +777,176 @@ void SGCloudLayer::draw( bool top ) { glDepthFunc(GL_LESS); ssgLoadModelviewMatrix( modelview ); +#endif - } else { - state_sel->selectStep( top ? 1 : 0 ); - ssgCullAndDraw( layer_root ); - } +// repaint the cloud layer colors +bool SGCloudLayer::repaint( const SGVec3f& fog_color ) { + for ( int i = 0; i < 4; i++ ) { + osg::Vec4 color(fog_color.osg(), 1); + color[3] = (i == 0) ? 0.0f : cloud_alpha * 0.15f; + (*cl[i])[0] = color; + + for ( int j = 0; j < 4; ++j ) { + color[3] = + ((j == 0) || (i == 3)) ? + ((j == 0) && (i == 3)) ? 0.0f : cloud_alpha * 0.15f : cloud_alpha; + (*cl[i])[(2*j) + 1] = color; + + color[3] = + ((j == 3) || (i == 0)) ? + ((j == 3) && (i == 0)) ? 0.0f : cloud_alpha * 0.15f : cloud_alpha; + (*cl[i])[(2*j) + 2] = color; } + + color[3] = (i == 3) ? 0.0f : cloud_alpha * 0.15f; + (*cl[i])[9] = color; + + cl[i]->dirty(); + } + + return true; } +// reposition the cloud layer 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 SGCloudLayer::reposition( const SGVec3f& p, const SGVec3f& up, double lon, double lat, + double alt, double dt ) +{ + // combine p and asl (meters) to get translation offset + osg::Vec3 asl_offset(up.osg()); + asl_offset.normalize(); + if ( alt <= layer_asl ) { + asl_offset *= layer_asl; + } else { + asl_offset *= layer_asl + layer_thickness; + } -// make an ssgSimpleState for a cloud layer given the named texture -ssgSimpleState *sgCloudMakeState( const string &path ) { - ssgSimpleState *state = new ssgSimpleState(); - - SG_LOG(SG_ASTRO, SG_INFO, " texture = "); - - state->setTexture( (char *)path.c_str() ); - state->setShadeModel( GL_SMOOTH ); - state->disable( GL_LIGHTING ); - state->disable( GL_CULL_FACE ); - state->enable( GL_TEXTURE_2D ); - state->enable( GL_COLOR_MATERIAL ); - state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); - state->setMaterial( GL_EMISSION, 0.05, 0.05, 0.05, 0.0 ); - state->setMaterial( GL_AMBIENT, 0.2, 0.2, 0.2, 0.0 ); - state->setMaterial( GL_DIFFUSE, 0.5, 0.5, 0.5, 0.0 ); - state->setMaterial( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 ); - state->enable( GL_BLEND ); - state->enable( GL_ALPHA_TEST ); - state->setAlphaClamp( 0.01 ); - - return state; + // cout << "asl_offset = " << asl_offset[0] << "," << asl_offset[1] + // << "," << asl_offset[2] << endl; + asl_offset += p.osg(); + // cout << " asl_offset = " << asl_offset[0] << "," << asl_offset[1] + // << "," << asl_offset[2] << endl; + + osg::Matrix T, LON, LAT; + // Translate to zero elevation + // Point3D zero_elev = current_view.get_cur_zero_elev(); + T.makeTranslate( asl_offset ); + + // printf(" Translated to %.2f %.2f %.2f\n", + // zero_elev.x, zero_elev.y, zero_elev.z ); + + // Rotate to proper orientation + // printf(" lon = %.2f lat = %.2f\n", + // lon * SGD_RADIANS_TO_DEGREES, + // lat * SGD_RADIANS_TO_DEGREES); + LON.makeRotate(lon, osg::Vec3(0, 0, 1)); + + // xglRotatef( 90.0 - f->get_Latitude() * SGD_RADIANS_TO_DEGREES, + // 0.0, 1.0, 0.0 ); + LAT.makeRotate(90.0 * SGD_DEGREES_TO_RADIANS - lat, osg::Vec3(0, 1, 0)); + + layer_transform->setMatrix( LAT*LON*T ); + + if ( alt <= layer_asl ) { + layer_root->setSingleChildOn(0); + } else { + layer_root->setSingleChildOn(1); + } + + // now calculate update texture coordinates + if ( last_lon < -900 ) { + last_lon = lon; + last_lat = lat; + } + + double sp_dist = speed*dt; + + if ( lon != last_lon || lat != last_lat || sp_dist != 0 ) { + Point3D start( last_lon, last_lat, 0.0 ); + Point3D dest( lon, lat, 0.0 ); + double course = 0.0, dist = 0.0; + + calc_gc_course_dist( dest, start, &course, &dist ); + // cout << "course = " << course << ", dist = " << dist << endl; + + // if start and dest are too close together, + // calc_gc_course_dist() can return a course of "nan". If + // this happens, lets just use the last known good course. + // This is a hack, and it would probably be better to make + // calc_gc_course_dist() more robust. + if ( isnan(course) ) { + course = last_course; + } else { + last_course = course; + } + + // calculate cloud movement due to external forces + double ax = 0.0, ay = 0.0, bx = 0.0, by = 0.0; + + if (dist > 0.0) { + ax = cos(course) * dist; + ay = sin(course) * dist; + } + + if (sp_dist > 0) { + bx = cos((180.0-direction) * SGD_DEGREES_TO_RADIANS) * sp_dist; + by = sin((180.0-direction) * SGD_DEGREES_TO_RADIANS) * sp_dist; + } + + + double xoff = (ax + bx) / (2 * scale); + double yoff = (ay + by) / (2 * scale); + + const float layer_scale = layer_span / scale; + + // cout << "xoff = " << xoff << ", yoff = " << yoff << endl; + base[0] += xoff; + + // the while loops can lead to *long* pauses if base[0] comes + // with a bogus value. + // while ( base[0] > 1.0 ) { base[0] -= 1.0; } + // while ( base[0] < 0.0 ) { base[0] += 1.0; } + if ( base[0] > -10.0 && base[0] < 10.0 ) { + base[0] -= (int)base[0]; + } else { + SG_LOG(SG_ASTRO, SG_DEBUG, + "Error: base = " << base[0] << "," << base[1] << + " course = " << course << " dist = " << dist ); + base[0] = 0.0; + } + + base[1] += yoff; + // the while loops can lead to *long* pauses if base[0] comes + // with a bogus value. + // while ( base[1] > 1.0 ) { base[1] -= 1.0; } + // while ( base[1] < 0.0 ) { base[1] += 1.0; } + if ( base[1] > -10.0 && base[1] < 10.0 ) { + base[1] -= (int)base[1]; + } else { + SG_LOG(SG_ASTRO, SG_DEBUG, + "Error: base = " << base[0] << "," << base[1] << + " course = " << course << " dist = " << dist ); + base[1] = 0.0; + } + + // cout << "base = " << base[0] << "," << base[1] << endl; + + for (int i = 0; i < 4; i++) { + (*tl[i])[0] = base + osg::Vec2(i, 0)*layer_scale/4; + for (int j = 0; j < 4; j++) { + (*tl[i])[j*2+1] = base + osg::Vec2(i+1, j)*layer_scale/4; + (*tl[i])[j*2+2] = base + osg::Vec2(i, j+1)*layer_scale/4; + } + (*tl[i])[9] = base + osg::Vec2(i+1, 4)*layer_scale/4; + } + + last_lon = lon; + last_lat = lat; + } + +// layer3D->reposition( p, up, lon, lat, alt, dt, direction, speed); + return true; } diff --git a/simgear/scene/sky/cloud.hxx b/simgear/scene/sky/cloud.hxx index 4baa0d58..9e38687c 100644 --- a/simgear/scene/sky/cloud.hxx +++ b/simgear/scene/sky/cloud.hxx @@ -29,22 +29,25 @@ #include #include - -#include +#include +#include #include STL_STRING SG_USING_STD(string); -// #include -// SG_USING_STD(cout); -// SG_USING_STD(endl); +#include +#include +#include +#include +#include +#include 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 layer_root; + osg::ref_ptr group_top, group_bottom; + osg::ref_ptr layer_transform; + osg::ref_ptr 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 cl[4]; + osg::ref_ptr vl[4]; + osg::ref_ptr tl[4]; + osg::ref_ptr 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; -}; - - -// make an ssgSimpleState for a cloud layer given the named texture -ssgSimpleState *sgCloudMakeState( const string &path ); + osg::Vec2 base; + SGCloudField *layer3D; +}; #endif // _SG_CLOUD_HXX_ diff --git a/simgear/scene/sky/cloudfield.cxx b/simgear/scene/sky/cloudfield.cxx index 809efb52..be60bc8d 100644 --- a/simgear/scene/sky/cloudfield.cxx +++ b/simgear/scene/sky/cloudfield.cxx @@ -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 } - diff --git a/simgear/scene/sky/dome.cxx b/simgear/scene/sky/dome.cxx index c41c4c8a..a859958e 100644 --- a/simgear/scene/sky/dome.cxx +++ b/simgear/scene/sky/dome.cxx @@ -34,10 +34,15 @@ #include -#include SG_GL_H - -#include - +#include +#include +#include +#include +#include +#include +#include + +#include #include #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 ); + // initially seed to all blue + 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 ssgVertexArray( 26 ); - upper_ring_cl = new ssgColourArray( 26 ); + 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 ssgVertexArray( 26 ); - middle_ring_cl = new ssgColourArray( 26 ); + 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 ssgVertexArray( 26 ); - lower_ring_cl = new ssgColourArray( 26 ); + lower_ring_vl = new osg::Vec3Array; + lower_ring_cl = new osg::Vec3Array; + lower_ring_cl->assign(26, osg::Vec3(0, 0, 1)); - // initially seed to all blue - sgSetVec4( color, 0.0, 0.0, 1.0, 1.0 ); // generate the raw vertex data - sgVec3 center_vertex; - sgVec3 upper_vertex[12]; - sgVec3 middle_vertex[12]; - sgVec3 lower_vertex[12]; - sgVec3 bottom_vertex[12]; - - sgSetVec3( center_vertex, 0.0, 0.0, center_elev * vscale ); - - for ( i = 0; i < 12; i++ ) { - theta = (i * 30.0) * SGD_DEGREES_TO_RADIANS; - - sgSetVec3( upper_vertex[i], - cos(theta) * upper_radius * hscale, - sin(theta) * upper_radius * hscale, - upper_elev * vscale ); - - sgSetVec3( middle_vertex[i], - cos(theta) * middle_radius * hscale, - sin(theta) * middle_radius * hscale, - middle_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 ); + 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]; + + 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); + + upper_vertex[i] = osg::Vec3(cTheta * upper_radius, + sTheta * upper_radius, + upper_elev * vscale); + + middle_vertex[i] = osg::Vec3(cTheta * middle_radius, + sTheta * middle_radius, + middle_elev * vscale); + + lower_vertex[i] = osg::Vec3(cTheta * lower_radius, + sTheta * lower_radius, + lower_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; - - center_disk = new ssgVtxTable( GL_TRIANGLE_FAN, - center_disk_vl, NULL, NULL, center_disk_cl ); - - upper_ring = new ssgVtxTable( GL_TRIANGLE_STRIP, - upper_ring_vl, NULL, NULL, upper_ring_cl ); - - middle_ring = new ssgVtxTable( GL_TRIANGLE_STRIP, - middle_ring_vl, NULL, NULL, middle_ring_cl ); - - lower_ring = new ssgVtxTable( GL_TRIANGLE_STRIP, - lower_ring_vl, NULL, NULL, lower_ring_cl ); - - 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; + 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); + + 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); + + 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); + + 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); + + dome_transform = new osg::MatrixTransform; + dome_transform->addChild(geode); + + 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 ); - - sgMat4 TRANSFORM; - - sgCopyMat4( TRANSFORM, T ); - sgPreMultMat4( TRANSFORM, LON ); - sgPreMultMat4( TRANSFORM, LAT ); - sgPreMultMat4( TRANSFORM, SPIN ); - - sgCoord skypos; - sgSetCoord( &skypos, TRANSFORM ); + SPIN.makeRotate(spin, osg::Vec3(0, 0, 1)); - dome_transform->setTransform( &skypos ); - asl = - skypos.xyz[2]; + dome_transform->setMatrix( SPIN*LAT*LON*T ); return true; } diff --git a/simgear/scene/sky/dome.hxx b/simgear/scene/sky/dome.hxx index 401e2380..dfed58e1 100644 --- a/simgear/scene/sky/dome.hxx +++ b/simgear/scene/sky/dome.hxx @@ -30,27 +30,29 @@ # error This library requires C++ #endif +#include +#include +#include -#include // plib include +#include +#include +class SGSkyDome : public SGReferenced { + osg::ref_ptr dome_transform; -class SGSkyDome { - ssgTransform *dome_transform; - ssgSimpleState *dome_state; + osg::ref_ptr center_disk_vl; + osg::ref_ptr center_disk_cl; - ssgVertexArray *center_disk_vl; - ssgColourArray *center_disk_cl; + osg::ref_ptr upper_ring_vl; + osg::ref_ptr upper_ring_cl; - ssgVertexArray *upper_ring_vl; - ssgColourArray *upper_ring_cl; + osg::ref_ptr middle_ring_vl; + osg::ref_ptr middle_ring_cl; - ssgVertexArray *middle_ring_vl; - ssgColourArray *middle_ring_cl; + osg::ref_ptr lower_ring_vl; + osg::ref_ptr 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 ); }; diff --git a/simgear/scene/sky/moon.cxx b/simgear/scene/sky/moon.cxx index 68724379..568a89bd 100644 --- a/simgear/scene/sky/moon.cxx +++ b/simgear/scene/sky/moon.cxx @@ -32,80 +32,24 @@ #include #include STL_IOSTREAM -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include #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 ); - - ssgBranch *orb = ssgMakeSphere( orb_state, cl, moon_size, 15, 15, - sgMoonOrbPreDraw, sgMoonOrbPostDraw ); + + 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); + + 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; - - 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; - - 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; + if (prev_moon_angle == moon_angle) + return true; - gamma_correct_rgb( color ); + prev_moon_angle = moon_angle; - // cout << "color = " << color[0] << " " << color[1] << " " - // << color[2] << endl; + 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 ); - 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 ); - - sgMat4 TRANSFORM; - sgCopyMat4( TRANSFORM, T1 ); - sgPreMultMat4( TRANSFORM, GST ); - sgPreMultMat4( TRANSFORM, RA ); - sgPreMultMat4( TRANSFORM, DEC ); - sgPreMultMat4( TRANSFORM, T2 ); - - sgCoord skypos; - sgSetCoord( &skypos, TRANSFORM ); + T2.makeTranslate(osg::Vec3(0, moon_dist, 0)); - moon_transform->setTransform( &skypos ); + moon_transform->setMatrix(T2*DEC*RA*GST*T1); return true; } diff --git a/simgear/scene/sky/moon.hxx b/simgear/scene/sky/moon.hxx index ddba10b6..5365f895 100644 --- a/simgear/scene/sky/moon.hxx +++ b/simgear/scene/sky/moon.hxx @@ -29,21 +29,20 @@ #define _SG_MOON_HXX_ -#include - -#include +#include +#include +#include +#include +#include -class SGMoon { +#include - ssgTransform *moon_transform; - ssgSimpleState *orb_state; - ssgSimpleState *halo_state; - ssgColourArray *cl; +class SGMoon : public SGReferenced { - ssgVertexArray *halo_vl; - ssgTexCoordArray *halo_tl; + osg::ref_ptr moon_transform; + osg::ref_ptr 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 ); }; diff --git a/simgear/scene/sky/newcloud.cxx b/simgear/scene/sky/newcloud.cxx index 1c947cf1..901d0f78 100644 --- a/simgear/scene/sky/newcloud.cxx +++ b/simgear/scene/sky/newcloud.cxx @@ -24,13 +24,14 @@ # include #endif +#include +#include + #include #include -#include #include #include -#include #include STL_ALGORITHM #include SG_GLU_H @@ -42,7 +43,7 @@ /* */ -static ssgSharedPtr cloudTextures[SGNewCloud::CLTexture_max]; +static osg::ref_ptr 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; diff --git a/simgear/scene/sky/oursun.cxx b/simgear/scene/sky/oursun.cxx index 51ebbf99..dd0d2cad 100644 --- a/simgear/scene/sky/oursun.cxx +++ b/simgear/scene/sky/oursun.cxx @@ -30,78 +30,21 @@ #include -#include -#include - -// 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 -#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #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; -} +// initialize the sun object and connect it into our scene graph root +osg::Node* +SGSun::build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node ) { + env_node = property_tree_Node; -#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)); - } - } - } + SGPath ihalopath = path, ohalopath = path; - // *(buffer + (pixelSize*((win_height-1-i)*win_width+j)+k)); + // 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(); - fwrite(ibuffer, sizeof(unsigned char), RGB*win_width*win_height, fp); - fclose(fp); - free(ibuffer); + 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); - printf("wrote file (%d x %d pixels, %d bytes)\n", - win_width, win_height, RGB*win_width*win_height); -} -#endif + osg::ShadeModel* shadeModel = new osg::ShadeModel; + shadeModel->setMode(osg::ShadeModel::FLAT); + stateSet->setAttributeAndModes(shadeModel); -// 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::AlphaFunc* alphaFunc = new osg::AlphaFunc; + alphaFunc->setFunction(osg::AlphaFunc::GREATER); + alphaFunc->setReferenceValue(0.01); + stateSet->setAttributeAndModes(alphaFunc); - env_node = property_tree_Node; + osg::BlendFunc* blendFunc = new osg::BlendFunc; + blendFunc->setSource(osg::BlendFunc::SRC_ALPHA); + blendFunc->setDestination(osg::BlendFunc::ONE_MINUS_SRC_ALPHA); + stateSet->setAttributeAndModes(blendFunc); - SGPath ihalopath = path, ohalopath = path; + 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); - sgVec4 color; - sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); - sun_cl = new ssgColourArray( 1 ); - sun_cl->add( color ); + osg::Geode* geode = new osg::Geode; + stateSet = geode->getOrCreateStateSet(); - ihalo_cl = new ssgColourArray( 1 ); - ihalo_cl->add( color ); + stateSet->setRenderBinDetails(-8, "RenderBin"); - ohalo_cl = new ssgColourArray( 1 ); - ohalo_cl->add( color ); + // set up the sun-state + path.append( "sun.rgba" ); + osg::Texture2D* texture = SGLoadTexture2D(path); + stateSet->setTextureAttributeAndModes(0, texture); - // force a repaint of the sun colors with arbitrary defaults - repaint( 0.0, 1.0 ); + // Build scenegraph + sun_cl = new osg::Vec4Array; + sun_cl->push_back(osg::Vec4(1, 1, 1, 1)); + 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)); - // 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::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)); - // 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 ); - - 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 ); - - - ssgLeaf *sun = - new ssgVtxTable ( GL_TRIANGLE_STRIP, sun_vl, NULL, sun_tl, sun_cl ); - sun->setState( sun_state ); - - sun->setCallback( SSG_CALLBACK_PREDRAW, sgSunPreDraw ); - sun->setCallback( SSG_CALLBACK_POSTDRAW, sgSunPostDraw ); - + 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_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 ); - - 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 ); - - ssgLeaf *ihalo = - new ssgVtxTable ( GL_TRIANGLE_STRIP, ihalo_vl, NULL, ihalo_tl, ihalo_cl ); - ihalo->setState( ihalo_state ); + ihalo_cl = new osg::Vec4Array; + ihalo_cl->push_back(osg::Vec4(1, 1, 1, 1)); + + 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)); + + 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 - 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 ); - - 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 ); - - ssgLeaf *ohalo = - new ssgVtxTable ( GL_TRIANGLE_STRIP, ohalo_vl, NULL, ohalo_tl, ohalo_cl ); - ohalo->setState( ohalo_state ); - - - // build the ssg scene graph sub tree for the sky and connected - // into the provide scene graph branch - sun_transform = new ssgTransform; + ohalo_cl = new osg::Vec4Array; + ohalo_cl->push_back(osg::Vec4(1, 1, 1, 1)); - ihalo->setCallback( SSG_CALLBACK_PREDRAW, sgSunHaloPreDraw ); - ihalo->setCallback( SSG_CALLBACK_POSTDRAW, sgSunHaloPostDraw ); - ohalo->setCallback( SSG_CALLBACK_PREDRAW, sgSunHaloPreDraw ); - ohalo->setCallback( SSG_CALLBACK_POSTDRAW, sgSunHaloPostDraw ); + double ohalo_size = sun_size * 7.0; + 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)); + + 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)); + + 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 ); - 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 + // force a repaint of the sun colors with arbitrary defaults + repaint( 0.0, 1.0 ); - 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 ); - - - 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 ); + gamma_correct_rgb( i_halo_color._v ); + gamma_correct_rgb( o_halo_color._v ); + gamma_correct_rgb( sun_color._v ); + + (*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 ); - - sgMat4 TRANSFORM; - sgCopyMat4( TRANSFORM, T1 ); - sgPreMultMat4( TRANSFORM, GST ); - sgPreMultMat4( TRANSFORM, RA ); - sgPreMultMat4( TRANSFORM, DEC ); - sgPreMultMat4( TRANSFORM, T2 ); + T2.makeTranslate(osg::Vec3(0, sun_dist, 0)); - 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]); +} diff --git a/simgear/scene/sky/oursun.hxx b/simgear/scene/sky/oursun.hxx index 08fe03e5..ceed47e2 100644 --- a/simgear/scene/sky/oursun.hxx +++ b/simgear/scene/sky/oursun.hxx @@ -28,40 +28,30 @@ #ifndef _SG_SUN_HXX_ #define _SG_SUN_HXX_ +#include +#include +#include -#include +#include #include #include -class SGSun { +class SGSun : public SGReferenced { - ssgTransform *sun_transform; - ssgSimpleState *sun_state; - ssgSimpleState *ihalo_state; - ssgSimpleState *ohalo_state; + osg::ref_ptr 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 sun_cl; + osg::ref_ptr ihalo_cl; + osg::ref_ptr 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(); }; diff --git a/simgear/scene/sky/sky.cxx b/simgear/scene/sky/sky.cxx index 2bc97580..b1970e07 100644 --- a/simgear/scene/sky/sky.cxx +++ b/simgear/scene/sky/sky.cxx @@ -25,9 +25,6 @@ # include #endif -#include -#include - #include #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 * diff --git a/simgear/scene/sky/sky.hxx b/simgear/scene/sky/sky.hxx index c41e9ec8..4c4c47c1 100644 --- a/simgear/scene/sky/sky.hxx +++ b/simgear/scene/sky/sky.hxx @@ -33,15 +33,17 @@ # error This library requires C++ #endif - -#include // plib include - #include #include #include #include +#include +#include +#include +#include + #include #include #include @@ -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 > 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 dome; + SGSharedPtr oursun; + SGSharedPtr moon; + SGSharedPtr planets; + SGSharedPtr stars; layer_list_type cloud_layers; - ssgRoot *pre_root, *post_root; - - ssgSelector *pre_selector, *post_selector; - ssgTransform *pre_transform, *post_transform; + osg::ref_ptr pre_root, post_root, cloud_root; + osg::ref_ptr pre_selector, post_selector; + osg::ref_ptr 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. diff --git a/simgear/scene/sky/sphere.cxx b/simgear/scene/sky/sphere.cxx index 9ce1d7a4..11251b0a 100644 --- a/simgear/scene/sky/sphere.cxx +++ b/simgear/scene/sky/sphere.cxx @@ -28,23 +28,21 @@ #include STL_IOSTREAM -#include -#include +#include +#include +#include +#include // 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; } diff --git a/simgear/scene/sky/sphere.hxx b/simgear/scene/sky/sphere.hxx index 1ee808fe..5c5eced0 100644 --- a/simgear/scene/sky/sphere.hxx +++ b/simgear/scene/sky/sphere.hxx @@ -22,13 +22,10 @@ // $Id$ -#include - +#include // 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); diff --git a/simgear/scene/sky/stars.cxx b/simgear/scene/sky/stars.cxx index 6e8636e3..59717505 100644 --- a/simgear/scene/sky/stars.cxx +++ b/simgear/scene/sky/stars.cxx @@ -31,39 +31,17 @@ #include #include STL_IOSTREAM -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #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; +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 osg::MatrixTransform; + + osg::Geode* geode = new osg::Geode; + osg::StateSet* stateSet = geode->getOrCreateStateSet(); + stateSet->setRenderBinDetails(-9, "RenderBin"); + + // set up the star state + + // 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 - 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 ); + 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) - sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); - cl->add( color ); + cl->push_back(osg::Vec4(1, 1, 1, 1)); } - 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::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); - // build the ssg scene graph sub tree for the sky and connected - // into the provide scene graph branch - stars_transform = new ssgTransform; - - stars_transform->addKid( stars_obj ); + stars_transform->addChild(geode); - SG_LOG( SG_EVENT, SG_INFO, "stars = " << stars_transform); + SG_LOG( SG_EVENT, SG_INFO, "stars = " << stars_transform.get()); - return stars_transform; + 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; - - sgMakeTransMat4( T1, p ); - - sgSetVec3( axis, 0.0, 0.0, -1.0 ); - sgMakeRotMat4( GST, angle, axis ); - - sgMat4 TRANSFORM; - sgCopyMat4( TRANSFORM, T1 ); - sgPreMultMat4( TRANSFORM, GST ); + osg::Matrix T1, GST; + T1.makeTranslate(p.osg()); - sgCoord skypos; - sgSetCoord( &skypos, TRANSFORM ); + GST.makeRotate(angle*SGD_DEGREES_TO_RADIANS, osg::Vec3(0, 0, -1)); - stars_transform->setTransform( &skypos ); + stars_transform->setMatrix(GST*T1); return true; } diff --git a/simgear/scene/sky/stars.hxx b/simgear/scene/sky/stars.hxx index 8c02b44e..b44512c7 100644 --- a/simgear/scene/sky/stars.hxx +++ b/simgear/scene/sky/stars.hxx @@ -29,16 +29,18 @@ #define _SG_STARS_HXX_ -#include +#include +#include +#include +#include +#include -class SGStars { - ssgTransform *stars_transform; - ssgSimpleState *state; +class SGStars : public SGReferenced { - ssgColourArray *cl; - ssgVertexArray *vl; + osg::ref_ptr stars_transform; + osg::ref_ptr 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 ); }; diff --git a/simgear/scene/tgdb/apt_signs.cxx b/simgear/scene/tgdb/apt_signs.cxx index 3bda05cb..22d6344b 100644 --- a/simgear/scene/tgdb/apt_signs.cxx +++ b/simgear/scene/tgdb/apt_signs.cxx @@ -26,6 +26,11 @@ #include +#include +#include +#include +#include + #include #include #include @@ -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); - - ssgLeaf *leaf = new ssgVtxTable(GL_TRIANGLE_STRIP, vl, nl, tl, cl); - leaf->setState(element->state); - - object->addKid(leaf); + osg::Vec4Array* cl = new osg::Vec4Array; + cl->push_back(osg::Vec4(1, 1, 1, 1)); + + 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->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); - - ssgNormalArray *nl = new ssgNormalArray(1); - nl->add(0, 1, 0); - - ssgLeaf *leaf = new ssgVtxTable(GL_TRIANGLE_STRIP, vl, nl, 0, 0); + 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)); + + osg::Vec3Array* nl = new osg::Vec3Array; + nl->push_back(osg::Vec3(0, 1, 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; } diff --git a/simgear/scene/tgdb/apt_signs.hxx b/simgear/scene/tgdb/apt_signs.hxx index ba96d160..dceccef7 100644 --- a/simgear/scene/tgdb/apt_signs.hxx +++ b/simgear/scene/tgdb/apt_signs.hxx @@ -34,7 +34,7 @@ #include STL_STRING -#include // plib include +#include 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 diff --git a/simgear/scene/tgdb/leaf.cxx b/simgear/scene/tgdb/leaf.cxx index 77e0ed9e..dd8d743b 100644 --- a/simgear/scene/tgdb/leaf.cxx +++ b/simgear/scene/tgdb/leaf.cxx @@ -33,10 +33,17 @@ #include STL_STRING +#include +#include +#include +#include +#include + #include #include #include #include +// #include #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; } - -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 ); - } - } - } +/// class to implement the TrinagleFunctor class +struct SGRandomSurfacePointsFill { + osg::Vec3Array* lights; + float factor; + + 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; } -} - - -ssgVertexArray *sgGenRandomSurfacePoints( ssgLeaf *leaf, double factor ) { - ssgVertexArray *result = new ssgVertexArray(); - sgGenRandomSurfacePoints( leaf, factor, result ); + // 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 )); + } + } + } +}; - return result; +static void SGGenRandomSurfacePoints( osg::Geometry *leaf, double factor, + osg::Vec3Array *lights ) +{ + osg::TriangleFunctor 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 ); - // lookup the state record + 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); - leaf->setUserData( new SGMaterialUserData(mat) ); - leaf->setState( state ); + // lookup the state record + 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; } diff --git a/simgear/scene/tgdb/leaf.hxx b/simgear/scene/tgdb/leaf.hxx index 779e6740..eb4e663d 100644 --- a/simgear/scene/tgdb/leaf.hxx +++ b/simgear/scene/tgdb/leaf.hxx @@ -34,7 +34,8 @@ #include STL_STRING -#include // plib include +#include +#include #include @@ -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 diff --git a/simgear/scene/tgdb/obj.cxx b/simgear/scene/tgdb/obj.cxx index c0bf8d0f..a5bfcda9 100644 --- a/simgear/scene/tgdb/obj.cxx +++ b/simgear/scene/tgdb/obj.cxx @@ -32,6 +32,12 @@ #include STL_STRING +#include +#include +#include +#include +#include + #include #include #include @@ -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 ); - - 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 ); + osg::Vec3Array *vl = new osg::Vec3Array; + osg::Vec3Array *nl = new osg::Vec3Array; + osg::Vec2Array *tl = new osg::Vec2Array; - sgSetVec2( tmp2, texs[i].x(), texs[i].y()); - tl->add( tmp2 ); + for ( i = 0; i < 4; ++i ) { + 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(); - - 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; -} +// 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; +// } /** @@ -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 > 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; } diff --git a/simgear/scene/tgdb/obj.hxx b/simgear/scene/tgdb/obj.hxx index 883336ea..5e3ae30a 100644 --- a/simgear/scene/tgdb/obj.hxx +++ b/simgear/scene/tgdb/obj.hxx @@ -35,7 +35,8 @@ #include STL_STRING -#include // plib include +#include +#include #include @@ -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 diff --git a/simgear/scene/tgdb/pt_lights.cxx b/simgear/scene/tgdb/pt_lights.cxx index 21193f9c..6097d12d 100644 --- a/simgear/scene/tgdb/pt_lights.cxx +++ b/simgear/scene/tgdb/pt_lights.cxx @@ -24,31 +24,33 @@ # include #endif -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include #include "vasi.hxx" #include "pt_lights.hxx" - // static variables for use in ssg callbacks -static bool extensions_checked = false; -static bool glPointParameterIsSupported = false; -static glPointParameterfProc glPointParameterfPtr; -static glPointParameterfvProc glPointParameterfvPtr; -static bool SGPointLightsUseSprites = false; -static bool SGPointLightsEnhancedLighting = false; -static bool SGPointLightsDistanceAttenuation = false; +bool SGPointLightsUseSprites = false; +bool SGPointLightsEnhancedLighting = false; +bool SGPointLightsDistanceAttenuation = false; // 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 ) { SGPointLightsUseSprites = use_point_sprites; @@ -56,189 +58,18 @@ void sgConfigureDirectionalLights( bool use_point_sprites, SGPointLightsDistanceAttenuation = distance_attenuation; } - -// runtime check for the availability of various opengl extensions. -static void check_for_extensions() { - // get the address of our OpenGL extensions - if (SGIsOpenGLExtensionSupported("GL_EXT_point_parameters") ) { - glPointParameterIsSupported = true; - glPointParameterfPtr = (glPointParameterfProc) - SGLookupFunction("glPointParameterfEXT"); - glPointParameterfvPtr = (glPointParameterfvProc) - SGLookupFunction("glPointParameterfvEXT"); - } else if ( SGIsOpenGLExtensionSupported("GL_ARB_point_parameters") ) { - glPointParameterIsSupported = true; - glPointParameterfPtr = (glPointParameterfProc) - SGLookupFunction("glPointParameterfARB"); - glPointParameterfvPtr = (glPointParameterfvProc) - SGLookupFunction("glPointParameterfvARB"); - } else { - glPointParameterIsSupported = false; - } -} - - -// strobe pre-draw (we want a larger point size) -static int StrobePreDraw( ssgEntity *e ) { - // check for the availability of point parameter extension, but - // just once. - if ( !extensions_checked ) { - check_for_extensions(); - extensions_checked = true; - } - - glPushAttrib( GL_POINT_BIT ); - if ( glPointParameterIsSupported && SGPointLightsEnhancedLighting ) { - if ( SGPointLightsUseSprites ) { - glPointSize(10.0); - } else { - glPointSize(8.0); - } - } else { - glPointSize(4.0); - } - glEnable(GL_POINT_SMOOTH); - - return true; -} - -// strobe post-draw (we want a larger point size) -static int StrobePostDraw( ssgEntity *e ) { - glPopAttrib(); - - return true; -} - - -// vasi pre-draw (we want a larger point size) -static int VASIPreDraw( ssgEntity *e ) { - // check for the availability of point parameter extension, but - // just once. - if ( !extensions_checked ) { - check_for_extensions(); - extensions_checked = true; - } - - glPushAttrib( GL_POINT_BIT ); - if ( glPointParameterIsSupported && SGPointLightsEnhancedLighting ) { - if ( SGPointLightsUseSprites ) { - glPointSize(10.0); - } else { - glPointSize(8.0); - } - } else { - glPointSize(4.0); - } - glEnable(GL_POINT_SMOOTH); - - return true; -} - -// vasi post-draw (we want a larger point size) -static int VASIPostDraw( ssgEntity *e ) { - glPopAttrib(); - - return true; -} - - -// Generate a directional light -ssgLeaf *sgMakeDirectionalLight( sgVec3 pt, sgVec3 dir, sgVec3 up, - const SGMaterial *mat ) { - - // calculate a vector perpendicular to dir and up - sgVec3 perp; - sgVectorProductVec3( perp, dir, up ); - - ssgVertexArray *vl = new ssgVertexArray( 3 ); - ssgNormalArray *nl = new ssgNormalArray( 3 ); - ssgColourArray *cl = new ssgColourArray( 3 ); - - // front face - sgVec3 tmp3; - sgCopyVec3( tmp3, pt ); - vl->add( tmp3 ); - sgAddVec3( tmp3, up ); - vl->add( tmp3 ); - sgAddVec3( tmp3, perp ); - vl->add( tmp3 ); - // sgSubVec3( tmp3, up ); - // vl->add( tmp3 ); - - nl->add( dir ); - nl->add( dir ); - nl->add( dir ); - // nl->add( dir ); - - sgVec4 color; - sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); - cl->add( color ); - sgSetVec4( color, 1.0, 1.0, 1.0, 0.0 ); - cl->add( color ); - cl->add( color ); - // cl->add( color ); - - /* - // temporarily do back face - sgCopyVec3( tmp3, pt ); - vl->add( tmp3 ); - sgAddVec3( tmp3, up ); - vl->add( tmp3 ); - sgAddVec3( tmp3, perp ); - vl->add( tmp3 ); - - sgNegateVec3( dir ); - nl->add( dir ); - nl->add( dir ); - nl->add( dir ); - - sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); - cl->add( color ); - sgSetVec4( color, 1.0, 1.0, 1.0, 0.0 ); - cl->add( color ); - cl->add( color ); - */ - - /* ssgTexCoordArray *tl = new ssgTexCoordArray( 4 ); - sgVec2 tmp2; - sgSetVec2( tmp2, 0.0, 0.0 ); - tl->add( tmp2 ); - sgSetVec2( tmp2, 1.0, 0.0 ); - tl->add( tmp2 ); - sgSetVec2( tmp2, 1.0, 1.0 ); - tl->add( tmp2 ); - sgSetVec2( tmp2, 0.0, 1.0 ); - tl->add( tmp2 ); */ - - ssgLeaf *leaf = - new ssgVtxTable ( GL_TRIANGLES, vl, nl, NULL, cl ); - - if ( mat != NULL ) { - leaf->setState( mat->get_state() ); - } else { - SG_LOG( SG_TERRAIN, SG_ALERT, "Warning: mat = NULL" ); - } - - return leaf; -} - - static void calc_center_point( const point_list &nodes, const int_list &pnt_i, - sgVec3 result ) { - sgVec3 pt; - sgSetVec3( pt, nodes[pnt_i[0]][0], nodes[pnt_i[0]][1], nodes[pnt_i[0]][2] ); - - double minx = pt[0]; - double maxx = pt[0]; - double miny = pt[1]; - double maxy = pt[1]; - double minz = pt[2]; - double maxz = pt[2]; + Point3D& result ) { + double minx = nodes[pnt_i[0]][0]; + double maxx = nodes[pnt_i[0]][0]; + double miny = nodes[pnt_i[0]][1]; + double maxy = nodes[pnt_i[0]][1]; + double minz = nodes[pnt_i[0]][2]; + double maxz = nodes[pnt_i[0]][2]; for ( unsigned int i = 0; i < pnt_i.size(); ++i ) { - sgSetVec3( pt, nodes[pnt_i[i]][0], nodes[pnt_i[i]][1], - nodes[pnt_i[i]][2] ); + Point3D pt = nodes[pnt_i[i]]; if ( pt[0] < minx ) { minx = pt[0]; } if ( pt[0] > maxx ) { minx = pt[0]; } if ( pt[1] < miny ) { miny = pt[1]; } @@ -247,223 +78,231 @@ static void calc_center_point( const point_list &nodes, if ( pt[2] > maxz ) { minz = pt[2]; } } - sgSetVec3( result, (minx + maxx) / 2.0, (miny + maxy) / 2.0, - (minz + maxz) / 2.0 ); + result = Point3D((minx + maxx) / 2.0, (miny + maxy) / 2.0, + (minz + maxz) / 2.0); } -static ssgTransform *gen_dir_light_group( const point_list &nodes, - const point_list &normals, - const int_list &pnt_i, - const int_list &nml_i, - const SGMaterial *mat, - sgVec3 up, bool vertical ) +static osg::Node* +gen_dir_light_group( const point_list &nodes, + const point_list &normals, + const int_list &pnt_i, + const int_list &nml_i, + const SGMaterial *mat, + const osg::Vec3& up, bool vertical, bool vasi ) { - sgVec3 center; + Point3D center; calc_center_point( nodes, pnt_i, center ); // cout << center[0] << "," << center[1] << "," << center[2] << endl; // find a vector perpendicular to the normal. - sgVec3 perp1; + osg::Vec3 perp1; if ( !vertical ) { // normal isn't vertical so we can use up as our first vector - sgNormalizeVec3( perp1, up ); + perp1 = up; } else { // normal is vertical so we have to work a bit harder to // determine our first vector - sgVec3 pt1, pt2; - sgSetVec3( pt1, nodes[pnt_i[0]][0], nodes[pnt_i[0]][1], - nodes[pnt_i[0]][2] ); - sgSetVec3( pt2, nodes[pnt_i[1]][0], nodes[pnt_i[1]][1], - nodes[pnt_i[1]][2] ); - - sgSubVec3( perp1, pt2, pt1 ); - sgNormalizeVec3( perp1 ); + osg::Vec3 pt1(nodes[pnt_i[0]][0], nodes[pnt_i[0]][1], + nodes[pnt_i[0]][2] ); + osg::Vec3 pt2(nodes[pnt_i[1]][0], nodes[pnt_i[1]][1], + nodes[pnt_i[1]][2] ); + + perp1 = pt2 - pt1; } + perp1.normalize(); - ssgVertexArray *vl = new ssgVertexArray( 3 * pnt_i.size() ); - ssgNormalArray *nl = new ssgNormalArray( 3 * pnt_i.size() ); - ssgColourArray *cl = new ssgColourArray( 3 * pnt_i.size() ); + osg::Vec3Array *vl = new osg::Vec3Array; + osg::Vec3Array *nl = new osg::Vec3Array; + osg::Vec4Array *cl = new osg::Vec4Array; unsigned int i; - sgVec3 pt, normal; for ( i = 0; i < pnt_i.size(); ++i ) { - sgSetVec3( pt, nodes[pnt_i[i]][0], nodes[pnt_i[i]][1], - nodes[pnt_i[i]][2] ); - sgSubVec3( pt, center ); - sgSetVec3( normal, normals[nml_i[i]][0], normals[nml_i[i]][1], - normals[nml_i[i]][2] ); + Point3D ppt = nodes[pnt_i[i]] - center; + osg::Vec3 pt(ppt[0], ppt[1], ppt[2]); + osg::Vec3 normal(normals[nml_i[i]][0], normals[nml_i[i]][1], + normals[nml_i[i]][2] ); // calculate a vector perpendicular to dir and up - sgVec3 perp2; - sgVectorProductVec3( perp2, normal, perp1 ); + osg::Vec3 perp2 = normal^perp1; // front face - sgVec3 tmp3; - sgCopyVec3( tmp3, pt ); - vl->add( tmp3 ); - sgAddVec3( tmp3, perp1 ); - vl->add( tmp3 ); - sgAddVec3( tmp3, perp2 ); - vl->add( tmp3 ); - // sgSubVec3( tmp3, perp1 ); - // vl->add( tmp3 ); - - nl->add( normal ); - nl->add( normal ); - nl->add( normal ); - // nl->add( normal ); - - sgVec4 color; - sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); - cl->add( color ); - sgSetVec4( color, 1.0, 1.0, 1.0, 0.0 ); - cl->add( color ); - cl->add( color ); - // cl->add( color ); + osg::Vec3 tmp3 = pt; + vl->push_back( tmp3 ); + tmp3 += perp1; + vl->push_back( tmp3 ); + tmp3 += perp2; + vl->push_back( tmp3 ); + + nl->push_back( normal ); + nl->push_back( normal ); + nl->push_back( normal ); + + cl->push_back(osg::Vec4(1, 1, 1, 1)); + cl->push_back(osg::Vec4(1, 1, 1, 0)); + cl->push_back(osg::Vec4(1, 1, 1, 0)); } - ssgLeaf *leaf = - new ssgVtxTable ( GL_TRIANGLES, vl, nl, NULL, cl ); + osg::Geometry* geometry = new osg::Geometry; + geometry->setName("Dir Lights " + mat->get_names().front()); +// geometry->setDrawCallback(new SGDebugDrawCallback); +// geometry->setUseDisplayList(false); + geometry->setVertexArray(vl); + geometry->setNormalArray(nl); + geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); + geometry->setColorArray(cl); + geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); + geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLES, 0, vl->size())); + osg::Geode* geode = new osg::Geode; + geode->addDrawable(geometry); + + if (vasi) { + // this one is dynamic in its colors, so do not bother with dlists + geometry->setUseDisplayList(false); + geometry->setUseVertexBufferObjects(false); + osg::Vec3 dir(normals[nml_i[0]][0], normals[nml_i[0]][1], + normals[nml_i[0]][2]); + + // calculate the reference position of this vasi and use it + // to init the vasi structure + Point3D ppt = nodes[pnt_i[0]] - center; + osg::Vec3 pt(ppt[0], ppt[1], ppt[2]); + // up is the "up" vector which is also + // the reference center point of this tile. The reference + // center + the coordinate of the first light gives the actual + // location of the first light. + pt += up; + + // Set up the callback + geode->setCullCallback(new SGVasiUpdateCallback(cl, pt, up, dir)); + } if ( mat != NULL ) { - leaf->setState( mat->get_state() ); + geode->setStateSet(mat->get_state()); } else { SG_LOG( SG_TERRAIN, SG_ALERT, "Warning: material = NULL" ); } // put an LOD on each lighting component - ssgRangeSelector *lod = new ssgRangeSelector; - lod->setRange( 0, SG_ZERO ); - lod->setRange( 1, 20000 ); - lod->addKid( leaf ); + osg::LOD *lod = new osg::LOD; + lod->addChild( geode, 0, 20000 ); // create the transformation. - sgCoord coord; - sgSetCoord( &coord, center[0], center[1], center[2], 0.0, 0.0, 0.0 ); - ssgTransform *trans = new ssgTransform; - trans->setTransform( &coord ); - trans->addKid( lod ); + osg::MatrixTransform *trans = new osg::MatrixTransform; + trans->setMatrix(osg::Matrixd::translate(osg::Vec3d(center[0], center[1], center[2]))); + trans->addChild( lod ); return trans; } - -static ssgTransform *gen_reil_lights( const point_list &nodes, - const point_list &normals, - const int_list &pnt_i, - const int_list &nml_i, - SGMaterialLib *matlib, - sgVec3 up ) +static osg::Node *gen_reil_lights( const point_list &nodes, + const point_list &normals, + const int_list &pnt_i, + const int_list &nml_i, + SGMaterialLib *matlib, + const osg::Vec3& up ) { - sgVec3 center; + Point3D center; calc_center_point( nodes, pnt_i, center ); // cout << center[0] << "," << center[1] << "," << center[2] << endl; - sgVec3 nup; - sgNormalizeVec3( nup, up ); + osg::Vec3 nup = up; + nup.normalize(); - ssgVertexArray *vl = new ssgVertexArray( 3 * pnt_i.size() ); - ssgNormalArray *nl = new ssgNormalArray( 3 * pnt_i.size() ); - ssgColourArray *cl = new ssgColourArray( 3 * pnt_i.size() ); + osg::Vec3Array *vl = new osg::Vec3Array; + osg::Vec3Array *nl = new osg::Vec3Array; + osg::Vec4Array *cl = new osg::Vec4Array; unsigned int i; - sgVec3 pt, normal; for ( i = 0; i < pnt_i.size(); ++i ) { - sgSetVec3( pt, nodes[pnt_i[i]][0], nodes[pnt_i[i]][1], - nodes[pnt_i[i]][2] ); - sgSubVec3( pt, center ); - sgSetVec3( normal, normals[nml_i[i]][0], normals[nml_i[i]][1], - normals[nml_i[i]][2] ); + Point3D ppt = nodes[pnt_i[i]] - center; + osg::Vec3 pt(ppt[0], ppt[1], ppt[2]); + osg::Vec3 normal(normals[nml_i[i]][0], normals[nml_i[i]][1], + normals[nml_i[i]][2] ); // calculate a vector perpendicular to dir and up - sgVec3 perp; - sgVectorProductVec3( perp, normal, nup ); + osg::Vec3 perp = normal^up; // front face - sgVec3 tmp3; - sgCopyVec3( tmp3, pt ); - vl->add( tmp3 ); - sgAddVec3( tmp3, nup ); - vl->add( tmp3 ); - sgAddVec3( tmp3, perp ); - vl->add( tmp3 ); - // sgSubVec3( tmp3, nup ); - // vl->add( tmp3 ); - - nl->add( normal ); - nl->add( normal ); - nl->add( normal ); - // nl->add( normal ); - - sgVec4 color; - sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); - cl->add( color ); - sgSetVec4( color, 1.0, 1.0, 1.0, 0.0 ); - cl->add( color ); - cl->add( color ); - // cl->add( color ); + osg::Vec3 tmp3 = pt; + vl->push_back( tmp3 ); + tmp3 += nup; + vl->push_back( tmp3 ); + tmp3 += perp; + vl->push_back( tmp3 ); + + nl->push_back( normal ); + nl->push_back( normal ); + nl->push_back( normal ); + + cl->push_back(osg::Vec4(1, 1, 1, 1)); + cl->push_back(osg::Vec4(1, 1, 1, 0)); + cl->push_back(osg::Vec4(1, 1, 1, 0)); } - ssgLeaf *leaf = - new ssgVtxTable ( GL_TRIANGLES, vl, nl, NULL, cl ); - SGMaterial *mat = matlib->find( "RWY_WHITE_LIGHTS" ); + osg::Geometry* geometry = new osg::Geometry; + geometry->setName("Reil Lights " + mat->get_names().front()); + geometry->setVertexArray(vl); + geometry->setNormalArray(nl); + geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); + geometry->setColorArray(cl); + geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); + geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLES, 0, vl->size())); + osg::Geode* geode = new osg::Geode; + geode->addDrawable(geometry); + if ( mat != NULL ) { - leaf->setState( mat->get_state() ); + geode->setStateSet( mat->get_state() ); } else { SG_LOG( SG_TERRAIN, SG_ALERT, "Warning: can't find material = RWY_WHITE_LIGHTS" ); } - leaf->setCallback( SSG_CALLBACK_PREDRAW, StrobePreDraw ); - leaf->setCallback( SSG_CALLBACK_POSTDRAW, StrobePostDraw ); + // OSGFIXME +// leaf->setCallback( SSG_CALLBACK_PREDRAW, StrobePreDraw ); +// leaf->setCallback( SSG_CALLBACK_POSTDRAW, StrobePostDraw ); - ssgTimedSelector *reil = new ssgTimedSelector; + // OSGFIXME: implement an update callback that switches on/off + // based on the osg::FrameStamp + osg::Switch *reil = new osg::Switch; +// reil->setDuration( 60 ); +// reil->setLimits( 0, 2 ); +// reil->setMode( SSG_ANIM_SHUTTLE ); +// reil->control( SSG_ANIM_START ); // need to add this twice to work around an ssg bug - reil->addKid( leaf ); - reil->addKid( leaf ); - - reil->setDuration( 60 ); - reil->setLimits( 0, 2 ); - reil->setMode( SSG_ANIM_SHUTTLE ); - reil->control( SSG_ANIM_START ); + reil->addChild(geode, true); // put an LOD on each lighting component - ssgRangeSelector *lod = new ssgRangeSelector; - lod->setRange( 0, SG_ZERO ); - lod->setRange( 1, 12000 ); - lod->addKid( reil ); + osg::LOD *lod = new osg::LOD; + lod->addChild( reil, 0, 12000 /*OSGFIXME: hardcoded here?*/); // create the transformation. - sgCoord coord; - sgSetCoord( &coord, center[0], center[1], center[2], 0.0, 0.0, 0.0 ); - ssgTransform *trans = new ssgTransform; - trans->setTransform( &coord ); - trans->addKid( lod ); + osg::MatrixTransform *trans = new osg::MatrixTransform; + trans->setMatrix(osg::Matrixd::translate(osg::Vec3d(center[0], center[1], center[2]))); + trans->addChild( lod ); return trans; } -static ssgTransform *gen_odals_lights( const point_list &nodes, - const point_list &normals, - const int_list &pnt_i, - const int_list &nml_i, - SGMaterialLib *matlib, - sgVec3 up ) +static osg::Node *gen_odals_lights( const point_list &nodes, + const point_list &normals, + const int_list &pnt_i, + const int_list &nml_i, + SGMaterialLib *matlib, + const osg::Vec3& up ) { - sgVec3 center; + Point3D center; calc_center_point( nodes, pnt_i, center ); // cout << center[0] << "," << center[1] << "," << center[2] << endl; - ssgTimedSelector *odals = new ssgTimedSelector; - - sgVec4 color; - sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); + // OSGFIXME: implement like above +// osg::Switch *odals = new osg::Switch; + osg::Group *odals = new osg::Group; // we don't want directional lights here SGMaterial *mat = matlib->find( "GROUND_LIGHTS" ); @@ -472,94 +311,111 @@ static ssgTransform *gen_odals_lights( const point_list &nodes, "Warning: can't material = GROUND_LIGHTS" ); } - // center line strobes - int i; - sgVec3 pt; - for ( i = (int)pnt_i.size() - 1; i >= 2; --i ) { - ssgVertexArray *vl = new ssgVertexArray( 1 ); - ssgColourArray *cl = new ssgColourArray( 1 ); + osg::Vec3Array *vl = new osg::Vec3Array; + osg::Vec4Array *cl = new osg::Vec4Array; - sgSetVec3( pt, nodes[pnt_i[i]][0], nodes[pnt_i[i]][1], - nodes[pnt_i[i]][2] ); - sgSubVec3( pt, center ); - vl->add( pt ); - - cl->add( color ); + cl->push_back(osg::Vec4(1, 1, 1, 1)); - ssgLeaf *leaf = - new ssgVtxTable ( GL_POINTS, vl, NULL, NULL, cl ); - - leaf->setState( mat->get_state() ); - leaf->setCallback( SSG_CALLBACK_PREDRAW, StrobePreDraw ); - leaf->setCallback( SSG_CALLBACK_POSTDRAW, StrobePostDraw ); - - odals->addKid( leaf ); + // center line strobes + for ( unsigned i = pnt_i.size() - 1; i >= 2; --i ) { + Point3D ppt = nodes[pnt_i[i]] - center; + osg::Vec3 pt(ppt[0], ppt[1], ppt[2]); + vl->push_back(pt); } // runway end strobes - ssgVertexArray *vl = new ssgVertexArray( 2 ); - ssgColourArray *cl = new ssgColourArray( 2 ); - sgSetVec3( pt, nodes[pnt_i[0]][0], nodes[pnt_i[0]][1], - nodes[pnt_i[0]][2] ); - sgSubVec3( pt, center ); - vl->add( pt ); - cl->add( color ); - - sgSetVec3( pt, nodes[pnt_i[1]][0], nodes[pnt_i[1]][1], - nodes[pnt_i[1]][2] ); - sgSubVec3( pt, center ); - vl->add( pt ); - cl->add( color ); - - ssgLeaf *leaf = - new ssgVtxTable ( GL_POINTS, vl, NULL, NULL, cl ); - - leaf->setState( mat->get_state() ); - leaf->setCallback( SSG_CALLBACK_PREDRAW, StrobePreDraw ); - leaf->setCallback( SSG_CALLBACK_POSTDRAW, StrobePostDraw ); - - odals->addKid( leaf ); + Point3D ppt = nodes[pnt_i[0]] - center; + osg::Vec3 pt(ppt[0], ppt[1], ppt[2]); + vl->push_back(pt); + + ppt = nodes[pnt_i[1]] - center; + pt = osg::Vec3(ppt[0], ppt[1], ppt[2]); + vl->push_back(pt); + + osg::Geometry* geometry = new osg::Geometry; + geometry->setName("Odal Lights " + mat->get_names().front()); + geometry->setVertexArray(vl); + geometry->setColorArray(cl); + geometry->setColorBinding(osg::Geometry::BIND_OVERALL); + geometry->addPrimitiveSet(new osg::DrawArrays(GL_POINTS, 0, vl->size())); + osg::Geode* geode = new osg::Geode; + geode->addDrawable(geometry); + + geode->setStateSet( mat->get_state() ); + // OSGFIXME +// leaf->setCallback( SSG_CALLBACK_PREDRAW, StrobePreDraw ); +// leaf->setCallback( SSG_CALLBACK_POSTDRAW, StrobePostDraw ); + + odals->addChild( geode ); // setup animition - odals->setDuration( 10 ); - odals->setLimits( 0, pnt_i.size() - 1 ); - odals->setMode( SSG_ANIM_SHUTTLE ); - odals->control( SSG_ANIM_START ); +// odals->setDuration( 10 ); +// odals->setLimits( 0, pnt_i.size() - 1 ); +// odals->setMode( SSG_ANIM_SHUTTLE ); +// odals->control( SSG_ANIM_START ); // put an LOD on each lighting component - ssgRangeSelector *lod = new ssgRangeSelector; - lod->setRange( 0, SG_ZERO ); - lod->setRange( 1, 12000 ); - lod->addKid( odals ); + osg::LOD *lod = new osg::LOD; + lod->addChild( odals, 0, 12000 /*OSGFIXME hardcoded visibility*/ ); // create the transformation. - sgCoord coord; - sgSetCoord( &coord, center[0], center[1], center[2], 0.0, 0.0, 0.0 ); - ssgTransform *trans = new ssgTransform; - trans->setTransform( &coord ); - trans->addKid( lod ); + osg::MatrixTransform *trans = new osg::MatrixTransform; + trans->setMatrix(osg::Matrixd::translate(osg::Vec3d(center[0], center[1], center[2]))); + trans->addChild(lod); return trans; } - -static ssgTransform *gen_rabbit_lights( const point_list &nodes, - const point_list &normals, - const int_list &pnt_i, - const int_list &nml_i, - SGMaterialLib *matlib, - sgVec3 up ) +class SGRabbitUpdateCallback : public osg::NodeCallback { +public: + SGRabbitUpdateCallback(double duration) : + mBaseTime(sg_random()), mDuration(duration) + { + if (fabs(mDuration) < 1e-3) + mDuration = 1e-3; + mBaseTime -= mDuration*floor(mBaseTime/mDuration); + } + + virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + { + assert(dynamic_cast(node)); + osg::Switch* sw = static_cast(node); + double frameTime = nv->getFrameStamp()->getReferenceTime(); + double timeDiff = (frameTime - mBaseTime)/mDuration; + double reminder = timeDiff - unsigned(floor(timeDiff)); + unsigned nChildren = sw->getNumChildren(); + unsigned activeChild = unsigned(nChildren*reminder); + if (nChildren <= activeChild) + activeChild = nChildren; + sw->setSingleChildOn(activeChild); + + osg::NodeCallback::operator()(node, nv); + } +public: + double mBaseTime; + double mDuration; +}; + + +static osg::Node *gen_rabbit_lights( const point_list &nodes, + const point_list &normals, + const int_list &pnt_i, + const int_list &nml_i, + SGMaterialLib *matlib, + const osg::Vec3& up ) { - sgVec3 center; + Point3D center; calc_center_point( nodes, pnt_i, center ); // cout << center[0] << "," << center[1] << "," << center[2] << endl; - sgVec3 nup; - sgNormalizeVec3( nup, up ); + osg::Vec3 nup = up; + nup.normalize(); - ssgTimedSelector *rabbit = new ssgTimedSelector; + // OSGFIXME: implement like above ... + osg::Switch *rabbit = new osg::Switch; + rabbit->setUpdateCallback(new SGRabbitUpdateCallback(10)); SGMaterial *mat = matlib->find( "RWY_WHITE_LIGHTS" ); if ( mat == NULL ) { @@ -567,182 +423,106 @@ static ssgTransform *gen_rabbit_lights( const point_list &nodes, "Warning: can't material = RWY_WHITE_LIGHTS" ); } - int i; - sgVec3 pt, normal; - for ( i = (int)pnt_i.size() - 1; i >= 0; --i ) { - ssgVertexArray *vl = new ssgVertexArray( 3 ); - ssgNormalArray *nl = new ssgNormalArray( 3 ); - ssgColourArray *cl = new ssgColourArray( 3 ); - - sgSetVec3( pt, nodes[pnt_i[i]][0], nodes[pnt_i[i]][1], - nodes[pnt_i[i]][2] ); - sgSubVec3( pt, center ); + for ( int i = pnt_i.size() - 1; i >= 0; --i ) { + osg::Vec3Array *vl = new osg::Vec3Array; + osg::Vec3Array *nl = new osg::Vec3Array; + osg::Vec4Array *cl = new osg::Vec4Array; + - sgSetVec3( normal, normals[nml_i[i]][0], normals[nml_i[i]][1], - normals[nml_i[i]][2] ); + Point3D ppt = nodes[pnt_i[i]] - center; + osg::Vec3 pt(ppt[0], ppt[1], ppt[2]); + osg::Vec3 normal(normals[nml_i[i]][0], normals[nml_i[i]][1], + normals[nml_i[i]][2] ); // calculate a vector perpendicular to dir and up - sgVec3 perp; - sgVectorProductVec3( perp, normal, nup ); + osg::Vec3 perp = normal^nup; // front face - sgVec3 tmp3; - sgCopyVec3( tmp3, pt ); - vl->add( tmp3 ); - sgAddVec3( tmp3, nup ); - vl->add( tmp3 ); - sgAddVec3( tmp3, perp ); - vl->add( tmp3 ); - // sgSubVec3( tmp3, nup ); - // vl->add( tmp3 ); - - nl->add( normal ); - nl->add( normal ); - nl->add( normal ); - // nl->add( normal ); - - sgVec4 color; - sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); - cl->add( color ); - sgSetVec4( color, 1.0, 1.0, 1.0, 0.0 ); - cl->add( color ); - cl->add( color ); - // cl->add( color ); - - ssgLeaf *leaf = - new ssgVtxTable ( GL_TRIANGLES, vl, nl, NULL, cl ); - - leaf->setState( mat->get_state() ); - leaf->setCallback( SSG_CALLBACK_PREDRAW, StrobePreDraw ); - leaf->setCallback( SSG_CALLBACK_POSTDRAW, StrobePostDraw ); - - rabbit->addKid( leaf ); + osg::Vec3 tmp3 = pt; + vl->push_back( tmp3 ); + tmp3 += nup; + vl->push_back( tmp3 ); + tmp3 += perp; + vl->push_back( tmp3 ); + + nl->push_back(normal); + + cl->push_back(osg::Vec4(1, 1, 1, 1)); + cl->push_back(osg::Vec4(1, 1, 1, 0)); + cl->push_back(osg::Vec4(1, 1, 1, 0)); + + osg::Geometry* geometry = new osg::Geometry; + geometry->setName("Rabbit Lights " + mat->get_names().front()); + geometry->setVertexArray(vl); + geometry->setNormalArray(nl); + geometry->setNormalBinding(osg::Geometry::BIND_OVERALL); + geometry->setColorArray(cl); + geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); + geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLES, 0, vl->size())); + osg::Geode* geode = new osg::Geode; + geode->addDrawable(geometry); + + geode->setStateSet( mat->get_state() ); + + // OSGFIXME +// leaf->setCallback( SSG_CALLBACK_PREDRAW, StrobePreDraw ); +// leaf->setCallback( SSG_CALLBACK_POSTDRAW, StrobePostDraw ); + + rabbit->addChild( geode ); } - rabbit->setDuration( 10 ); - rabbit->setLimits( 0, pnt_i.size() - 1 ); - rabbit->setMode( SSG_ANIM_SHUTTLE ); - rabbit->control( SSG_ANIM_START ); +// rabbit->setDuration( 10 ); +// rabbit->setLimits( 0, pnt_i.size() - 1 ); +// rabbit->setMode( SSG_ANIM_SHUTTLE ); +// rabbit->control( SSG_ANIM_START ); // put an LOD on each lighting component - ssgRangeSelector *lod = new ssgRangeSelector; - lod->setRange( 0, SG_ZERO ); - lod->setRange( 1, 12000 ); - lod->addKid( rabbit ); + osg::LOD *lod = new osg::LOD; + lod->addChild( rabbit, 0, 12000 /*OSGFIXME: hadcoded*/ ); // create the transformation. - sgCoord coord; - sgSetCoord( &coord, center[0], center[1], center[2], 0.0, 0.0, 0.0 ); - ssgTransform *trans = new ssgTransform; - trans->setTransform( &coord ); - trans->addKid( lod ); + osg::MatrixTransform *trans = new osg::MatrixTransform; + trans->setMatrix(osg::Matrixd::translate(osg::Vec3d(center[0], center[1], center[2]))); + trans->addChild(lod); return trans; } -#if 0 // debugging infrastructure -// Generate a normal line -static ssgLeaf *gen_normal_line( SGMaterialLib *matlib, - sgVec3 pt, sgVec3 dir, sgVec3 up ) -{ - - ssgVertexArray *vl = new ssgVertexArray( 3 ); - ssgColourArray *cl = new ssgColourArray( 3 ); - - sgVec3 tmp3; - sgCopyVec3( tmp3, pt ); - vl->add( tmp3 ); - sgAddVec3( tmp3, dir ); - vl->add( tmp3 ); - - sgVec4 color; - sgSetVec4( color, 1.0, 0.0, 0.0, 1.0 ); - cl->add( color ); - cl->add( color ); - - ssgLeaf *leaf = - new ssgVtxTable ( GL_LINES, vl, NULL, NULL, cl ); - - SGMaterial *mat = matlib->find( "GROUND_LIGHTS" ); - leaf->setState( mat->get_state() ); - - return leaf; -} -#endif - - -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 ) { - sgVec3 up; - sgSetVec3( up, dup ); - - sgVec3 nup; - sgNormalizeVec3( nup, up ); + osg::Vec3 nup = toVec3f(dup).osg(); + nup.normalize(); SGMaterial *mat = matlib->find( material ); if ( material == "RWY_REIL_LIGHTS" ) { // cout << "found a reil" << endl; - ssgTransform *reil = gen_reil_lights( nodes, normals, pnt_i, nml_i, - matlib, up ); - return reil; + return gen_reil_lights( nodes, normals, pnt_i, nml_i, + matlib, nup ); } else if ( material == "RWY_ODALS_LIGHTS" ) { // cout << "found a odals" << endl; - ssgTransform *odals = gen_odals_lights( nodes, normals, pnt_i, nml_i, - matlib, up ); - return odals; + return gen_odals_lights( nodes, normals, pnt_i, nml_i, + matlib, nup ); } else if ( material == "RWY_SEQUENCED_LIGHTS" ) { // cout << "found a rabbit" << endl; - ssgTransform *rabbit = gen_rabbit_lights( nodes, normals, - pnt_i, nml_i, - matlib, up ); - return rabbit; + return gen_rabbit_lights( nodes, normals, pnt_i, nml_i, + matlib, nup ); } else if ( material == "RWY_VASI_LIGHTS" ) { - ssgTransform *light_group = gen_dir_light_group( nodes, normals, pnt_i, - nml_i, mat, up, - false ); - - // calculate the geocentric position of this vasi and use it - // to init the vasi structure and save it in the userdata slot - sgdVec3 pos; - sgdSetVec3( pos, nodes[pnt_i[0]][0], nodes[pnt_i[0]][1], - nodes[pnt_i[0]][2] ); - // dup is the double version of the "up" vector which is also - // the reference center point of this tile. The reference - // center + the coordinate of the first light gives the actual - // location of the first light. - sgdAddVec3( pos, dup ); - - // extract a pointer to the leaf node so a) we can set the - // phat light call back and b) we can pass this to the vasi - // structure. - ssgRangeSelector *lod = (ssgRangeSelector *)light_group->getKid(0); - ssgLeaf *leaf = (ssgLeaf *)lod->getKid(0); - leaf->setCallback( SSG_CALLBACK_PREDRAW, VASIPreDraw ); - leaf->setCallback( SSG_CALLBACK_POSTDRAW, VASIPostDraw ); - - SGVASIUserData *vasi = new SGVASIUserData( pos, leaf ); - - light_group->setUserData( vasi ); - - return light_group; + return gen_dir_light_group( nodes, normals, pnt_i, + nml_i, mat, nup, false, true ); } else if ( material == "RWY_BLUE_TAXIWAY_LIGHTS" ) { - ssgTransform *light_group = gen_dir_light_group( nodes, normals, pnt_i, - nml_i, mat, up, - true ); - return light_group; + return gen_dir_light_group( nodes, normals, pnt_i, nml_i, mat, nup, + true, false ); } else { - ssgTransform *light_group = gen_dir_light_group( nodes, normals, pnt_i, - nml_i, mat, up, - false ); - return light_group; + return gen_dir_light_group( nodes, normals, pnt_i, nml_i, mat, nup, + false, false ); } return NULL; diff --git a/simgear/scene/tgdb/pt_lights.hxx b/simgear/scene/tgdb/pt_lights.hxx index de5240a3..431233ce 100644 --- a/simgear/scene/tgdb/pt_lights.hxx +++ b/simgear/scene/tgdb/pt_lights.hxx @@ -35,9 +35,6 @@ #include STL_STRING #include // STL -#include -#include // plib include - #include #include @@ -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 ); diff --git a/simgear/scene/tgdb/userdata.cxx b/simgear/scene/tgdb/userdata.cxx index 9bb7c9c8..52f0a6f8 100644 --- a/simgear/scene/tgdb/userdata.cxx +++ b/simgear/scene/tgdb/userdata.cxx @@ -25,9 +25,6 @@ # include #endif -#include -#include - #include #include #include @@ -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; - - 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[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); - - mat[3][3] = SG_ONE ; + // 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] = -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; + +// // 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 ; } /** @@ -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); - - 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); +// 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); + +// // 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); - - // 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); - - // 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; - - // 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 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); - } +// // 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); + +// // 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); + +// // 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 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); +// } } diff --git a/simgear/scene/tgdb/userdata.hxx b/simgear/scene/tgdb/userdata.hxx index dfb43903..7001e995 100644 --- a/simgear/scene/tgdb/userdata.hxx +++ b/simgear/scene/tgdb/userdata.hxx @@ -29,7 +29,11 @@ #include STL_STRING -#include +#include + +#include +#include +#include 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 diff --git a/simgear/scene/tgdb/vasi.hxx b/simgear/scene/tgdb/vasi.hxx index 10319d4f..92a790cb 100644 --- a/simgear/scene/tgdb/vasi.hxx +++ b/simgear/scene/tgdb/vasi.hxx @@ -24,159 +24,174 @@ #ifndef _SG_VASI_HXX #define _SG_VASI_HXX - #ifndef __cplusplus # error This library requires C++ #endif - #include -#include STL_STRING -SG_USING_STD(string); - -#include // plib include - -#include - - -class SGVASIUserData : public ssgBase -{ - -private: - - sgdVec3 abs_pos; - double alt_m; - ssgLeaf *leaf; - +#include +#include +#include +#include +#include +#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: - - SGVASIUserData( sgdVec3 pos_cart, ssgLeaf *l ) { - sgdCopyVec3( abs_pos, pos_cart ); - - double lat, lon; - sgCartToGeod( abs_pos, &lat, &lon, &alt_m ); - - leaf = l; + SGVasiUpdateCallback(osg::Vec4Array* vasiColorArray, + const osg::Vec3& referencePoint, + const osg::Vec3& glideSlopeUp, + const osg::Vec3& glideSlopeDir) : + mVasiColorArray(vasiColorArray), + mReferencePoint(referencePoint), + mGlideSlopeUp(glideSlopeUp), + mGlideSlopeDir(glideSlopeDir) + { + mGlideSlopeUp.normalize(); + mGlideSlopeDir.normalize(); + } + virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + { + // Rerieve the eye point relative to the vasi reference point + osg::Vec3 eyePoint = nv->getEyePoint() - mReferencePoint; + // Now project the eye point vector into the plane defined by the + // glideslope direction and the up direction + osg::Vec3 normal = mGlideSlopeUp^mGlideSlopeDir; + normal.normalize(); + osg::Vec3 projEyePoint = eyePoint - normal * (eyePoint*normal); + + double projEyePointLength = projEyePoint.length(); + if (fabs(projEyePointLength) < 1e-3) + set_color(3); + else { + double aSinAngle = projEyePoint*mGlideSlopeUp/projEyePointLength; + if (aSinAngle < -1) + aSinAngle = -1; + if (1 < aSinAngle) + aSinAngle = 1; + + double angle = asin(aSinAngle)*SGD_RADIANS_TO_DEGREES; + set_color(angle); } - ~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; - } - } + // call the base implementation + osg::NodeCallback::operator()(node, nv); + } + + // color the vasi/papi correctly based on angle in degree + void set_color( double angle_deg ) { + unsigned count = mVasiColorArray->size(); + double trans = 0.05; + double color = 1; + double ref; + + if ( count == 12 ) { + // PAPI configuration + + // papi D + ref = 3.5; + if ( angle_deg < ref - trans ) { + color = 0.0; + } else if ( angle_deg < ref + trans ) { + color = 1.0 - (ref + trans - angle_deg) * (1 / (2 * trans) ); + } else { + color = 1.0; + } + for ( unsigned i = 0; i < 3; ++i ) { + (*mVasiColorArray)[i][1] = color; + (*mVasiColorArray)[i][2] = color; + } + + // papi C + ref = 3.167; + if ( angle_deg < ref - trans ) { + color = 0.0; + } else if ( angle_deg < ref + trans ) { + color = 1.0 - (ref + trans - angle_deg) * (1 / (2 * trans) ); + } else { + color = 1.0; + } + for ( unsigned i = 3; i < 6; ++i ) { + (*mVasiColorArray)[i][1] = color; + (*mVasiColorArray)[i][2] = color; + } + + // papi B + ref = 2.833; + if ( angle_deg < ref - trans ) { + color = 0.0; + } else if ( angle_deg < ref + trans ) { + color = 1.0 - (ref + trans - angle_deg) * (1 / (2 * trans) ); + } else { + color = 1.0; + } + for ( unsigned i = 6; i < 9; ++i ) { + (*mVasiColorArray)[i][1] = color; + (*mVasiColorArray)[i][2] = color; + } + + // papi A + ref = 2.5; + if ( angle_deg < ref - trans ) { + color = 0.0; + } else if ( angle_deg < ref + trans ) { + color = 1.0 - (ref + trans - angle_deg) * (1 / (2 * trans) ); + } else { + color = 1.0; + } + for ( unsigned i = 9; i < 12; ++i ) { + (*mVasiColorArray)[i][1] = color; + (*mVasiColorArray)[i][2] = color; + } + } else if ( count == 36 ) { + // probably vasi, first 18 are downwind bar (2.5 deg) + ref = 2.5; + if ( angle_deg < ref - trans ) { + color = 0.0; + } else if ( angle_deg < ref + trans ) { + color = 1.0 - (ref + trans - angle_deg) * (1 / (2 * trans) ); + } else { + color = 1.0; + } + for ( unsigned i = 0; i < 18; ++i ) { + (*mVasiColorArray)[i][1] = color; + (*mVasiColorArray)[i][2] = color; + } + + // last 6 are upwind bar (3.0 deg) + ref = 3.0; + if ( angle_deg < ref - trans ) { + color = 0.0; + } else if ( angle_deg < ref + trans ) { + color = 1.0 - (ref + trans - angle_deg) * (1 / (2 * trans) ); + } else { + color = 1.0; + } + for ( unsigned i = 18; i < 36; ++i ) { + (*mVasiColorArray)[i][1] = color; + (*mVasiColorArray)[i][2] = color; + } + } else { + // fail safe + cout << "unknown vasi/papi configuration, count = " << count << endl; + for ( unsigned i = 0; i < count; ++i ) { + (*mVasiColorArray)[i][1] = color; + (*mVasiColorArray)[i][2] = color; + } } -}; + // Finally mark the color array dirty + mVasiColorArray->dirty(); + } +private: + osg::ref_ptr mVasiColorArray; + osg::Vec3 mReferencePoint; + osg::Vec3 mGlideSlopeUp; + osg::Vec3 mGlideSlopeDir; +}; #endif // _SG_VASI_HXX diff --git a/simgear/scene/util/Makefile.am b/simgear/scene/util/Makefile.am new file mode 100644 index 00000000..0241c3e0 --- /dev/null +++ b/simgear/scene/util/Makefile.am @@ -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) diff --git a/simgear/scene/util/SGDebugDrawCallback.hxx b/simgear/scene/util/SGDebugDrawCallback.hxx new file mode 100644 index 00000000..3754423b --- /dev/null +++ b/simgear/scene/util/SGDebugDrawCallback.hxx @@ -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 +#include +#include +#include + +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 diff --git a/simgear/scene/util/SGNodeMasks.hxx b/simgear/scene/util/SGNodeMasks.hxx new file mode 100644 index 00000000..f89f7f2f --- /dev/null +++ b/simgear/scene/util/SGNodeMasks.hxx @@ -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 diff --git a/simgear/scene/util/SGStateAttributeVisitor.hxx b/simgear/scene/util/SGStateAttributeVisitor.hxx new file mode 100644 index 00000000..cd381413 --- /dev/null +++ b/simgear/scene/util/SGStateAttributeVisitor.hxx @@ -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 diff --git a/simgear/scene/util/SGTextureStateAttributeVisitor.hxx b/simgear/scene/util/SGTextureStateAttributeVisitor.hxx new file mode 100644 index 00000000..7458f85a --- /dev/null +++ b/simgear/scene/util/SGTextureStateAttributeVisitor.hxx @@ -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 diff --git a/simgear/scene/util/SGUpdateVisitor.hxx b/simgear/scene/util/SGUpdateVisitor.hxx new file mode 100644 index 00000000..7fdba11f --- /dev/null +++ b/simgear/scene/util/SGUpdateVisitor.hxx @@ -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 +#include + +#include + +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 + +// class SGNodeCallback : public osg::NodeCallback { +// public: +// virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) +// { +// } +// }; + +#endif diff --git a/simgear/screen/jpgfactory.cxx b/simgear/screen/jpgfactory.cxx index 49621fe5..a5160cfc 100644 --- a/simgear/screen/jpgfactory.cxx +++ b/simgear/screen/jpgfactory.cxx @@ -25,8 +25,6 @@ # include #endif -#include - #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(), diff --git a/simgear/screen/ssgEntityArray.cxx b/simgear/screen/ssgEntityArray.cxx deleted file mode 100644 index bf1c12da..00000000 --- a/simgear/screen/ssgEntityArray.cxx +++ /dev/null @@ -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 -#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 - diff --git a/simgear/screen/ssgEntityArray.hxx b/simgear/screen/ssgEntityArray.hxx deleted file mode 100644 index 3b0c65cc..00000000 --- a/simgear/screen/ssgEntityArray.hxx +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef _SSG_ENTITY_ARRAY_HXX -#define _SSG_ENTITY_ARRAY_HXX - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - - -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 diff --git a/simgear/screen/tr.cxx b/simgear/screen/tr.cxx index 53e1bf82..85e9f3a8 100644 --- a/simgear/screen/tr.cxx +++ b/simgear/screen/tr.cxx @@ -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 #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 ); diff --git a/simgear/structure/Makefile.am b/simgear/structure/Makefile.am index e7d361ae..6324da17 100644 --- a/simgear/structure/Makefile.am +++ b/simgear/structure/Makefile.am @@ -7,7 +7,6 @@ include_HEADERS = \ commands.hxx \ exception.hxx \ event_mgr.hxx \ - ssgSharedPtr.hxx \ subsystem_mgr.hxx \ SGReferenced.hxx \ SGSharedPtr.hxx diff --git a/simgear/structure/ssgSharedPtr.hxx b/simgear/structure/ssgSharedPtr.hxx deleted file mode 100644 index 44471afb..00000000 --- a/simgear/structure/ssgSharedPtr.hxx +++ /dev/null @@ -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 -class ssgSharedPtr { -public: - ssgSharedPtr(void) : _ptr(0) - {} - ssgSharedPtr(T* ptr) : _ptr(ptr) - { get(_ptr); } - ssgSharedPtr(const ssgSharedPtr& p) : _ptr(p.ptr()) - { get(_ptr); } - template - ssgSharedPtr(const ssgSharedPtr& p) : _ptr(p.ptr()) - { get(_ptr); } - ~ssgSharedPtr(void) - { put(); } - - ssgSharedPtr& operator=(const ssgSharedPtr& p) - { assign(p.ptr()); return *this; } - template - ssgSharedPtr& operator=(const ssgSharedPtr& p) - { assign(p.ptr()); return *this; } - template - 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 diff --git a/simgear/threads/SGThread.hxx b/simgear/threads/SGThread.hxx index d04d60af..5179ab80 100644 --- a/simgear/threads/SGThread.hxx +++ b/simgear/threads/SGThread.hxx @@ -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 */