]> git.mxchange.org Git - simgear.git/commitdiff
Modified Files:
authorfrohlich <frohlich>
Sun, 29 Oct 2006 19:27:08 +0000 (19:27 +0000)
committerfrohlich <frohlich>
Sun, 29 Oct 2006 19:27:08 +0000 (19:27 +0000)
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.

73 files changed:
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/scene/util/Makefile.am [new file with mode: 0644]
simgear/scene/util/SGDebugDrawCallback.hxx [new file with mode: 0644]
simgear/scene/util/SGNodeMasks.hxx [new file with mode: 0644]
simgear/scene/util/SGStateAttributeVisitor.hxx [new file with mode: 0644]
simgear/scene/util/SGTextureStateAttributeVisitor.hxx [new file with mode: 0644]
simgear/scene/util/SGUpdateVisitor.hxx [new file with mode: 0644]
simgear/screen/jpgfactory.cxx
simgear/screen/ssgEntityArray.cxx [deleted file]
simgear/screen/ssgEntityArray.hxx [deleted file]
simgear/screen/tr.cxx
simgear/structure/Makefile.am
simgear/structure/ssgSharedPtr.hxx [deleted file]
simgear/threads/SGThread.hxx

index b59695a84d001355a9f4953358c1d65880c6d140..fcc326d768e0c88117a9e2fe0c8759f72620dc04 100644 (file)
@@ -430,6 +430,7 @@ AC_CONFIG_FILES([ \
        simgear/scene/model/Makefile \
        simgear/scene/sky/Makefile \
        simgear/scene/tgdb/Makefile \
+       simgear/scene/util/Makefile \
        simgear/screen/Makefile \
        simgear/serial/Makefile \
        simgear/sound/Makefile \
index 1f8d3acf8fd0f4196de71d21193eb6bf1dac794b..9371503e5b35f95af824b3ba869ef5b268ea491b 100644 (file)
@@ -189,6 +189,8 @@ SGEnviro::SGEnviro() :
 }
 
 SGEnviro::~SGEnviro(void) {
+  // OSGFIXME
+  return;
        list_of_lightning::iterator iLightning;
        for( iLightning = lightnings.begin() ; iLightning != lightnings.end() ; iLightning++ ) {
                delete (*iLightning);
@@ -197,6 +199,8 @@ SGEnviro::~SGEnviro(void) {
 }
 
 void SGEnviro::startOfFrame( sgVec3 p, sgVec3 up, double lon, double lat, double alt, double delta_time) {
+  // OSGFIXME
+  return;
        view_in_cloud = false;
        // ask the impostor cache to do some cleanup
        if(SGNewCloud::cldCache)
@@ -319,6 +323,8 @@ void SGEnviro::set_lightning_enable_state(bool enable) {
 }
 
 void SGEnviro::setLight(sgVec4 adj_fog_color) {
+  // OSGFIXME
+  return;
        sgCopyVec4( fog_color, adj_fog_color );
        if( false ) {
        //    ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, l->scene_diffuse() );
@@ -326,6 +332,8 @@ void SGEnviro::setLight(sgVec4 adj_fog_color) {
 }
 
 void SGEnviro::callback_cloud(float heading, float alt, float radius, int family, float dist, int cloudId) {
+  // OSGFIXME
+  return;
        // send data to wx radar
        // compute turbulence
        // draw precipitation
@@ -440,6 +448,8 @@ list_of_SGWxRadarEcho *SGEnviro::get_radar_echo(void) {
 
 // precipitation rendering code
 void SGEnviro::DrawCone2(float baseRadius, float height, int slices, bool down, double rain_norm, double speed) {
+  // OSGFIXME
+  return;
        sgVec3 light;
        sgAddVec3( light, fog_color, min_light );
        float da = SG_PI * 2.0f / (float) slices;
@@ -488,6 +498,8 @@ void SGEnviro::DrawCone2(float baseRadius, float height, int slices, bool down,
 }
 
 void SGEnviro::drawRain(double pitch, double roll, double heading, double hspeed, double rain_norm) {
+  // OSGFIXME
+  return;
 
 #if 0
        static int debug_period = 0;
@@ -557,6 +569,8 @@ void SGEnviro::set_soundMgr(SGSoundMgr *mgr) {
 }
 
 void SGEnviro::drawPrecipitation(double rain_norm, double snow_norm, double hail_norm, double pitch, double roll, double heading, double hspeed) {
+  // OSGFIXME
+  return;
        if( precipitation_enable_state && rain_norm > 0.0)
          if( precipitation_max_alt >= last_alt )
                drawRain(pitch, roll, heading, hspeed, rain_norm);
@@ -579,6 +593,8 @@ SGLightning::~SGLightning() {
 
 // lightning rendering code
 void SGLightning::lt_build_tree_branch(int tree_nr, Point3D &start, float energy, int nbseg, float segsize) {
+  // OSGFIXME
+  return;
 
        sgVec3 dir, newdir;
        int nseg = 0;
@@ -626,6 +642,8 @@ void SGLightning::lt_build_tree_branch(int tree_nr, Point3D &start, float energy
 }
 
 void SGLightning::lt_build(void) {
+  // OSGFIXME
+  return;
     Point3D top;
     nb_tree = 0;
     top[PX] = 0 ;
@@ -651,6 +669,8 @@ void SGLightning::lt_build(void) {
 
 
 void SGLightning::lt_Render(void) {
+  // OSGFIXME
+  return;
        float flash = 0.5;
        if( fmod(sgEnviro.elapsed_time*100.0, 100.0) > 50.0 )
                flash = sg_random() * 0.75f + 0.25f;
@@ -675,10 +695,12 @@ void SGLightning::lt_Render(void) {
        glDisable( GL_FOG );
        glPushMatrix();
        sgMat4 modelview, tmp;
-    ssgGetModelviewMatrix( modelview );
+    // OSGFIXME
+//     ssgGetModelviewMatrix( modelview );
        sgCopyMat4( tmp, sgEnviro.transform );
     sgPostMultMat4( tmp, modelview );
-    ssgLoadModelviewMatrix( tmp );
+    // OSGFIXME
+//     ssgLoadModelviewMatrix( tmp );
 
     Point3D start( sgEnviro.last_lon*SG_DEGREES_TO_RADIANS, sgEnviro.last_lat*SG_DEGREES_TO_RADIANS, 0.0 );
     Point3D dest( lon*SG_DEGREES_TO_RADIANS, lat*SG_DEGREES_TO_RADIANS, 0.0 );
@@ -736,6 +758,8 @@ void SGLightning::lt_Render(void) {
 }
 
 void SGEnviro::addLightning(double lon, double lat, double alt) {
+  // OSGFIXME
+  return;
        if( lightnings.size() > 10)
                return;
        SGLightning *lt= new SGLightning(lon, lat, alt);
@@ -743,6 +767,8 @@ void SGEnviro::addLightning(double lon, double lat, double alt) {
 }
 
 void SGEnviro::drawLightning(void) {
+  // OSGFIXME
+  return;
        list_of_lightning::iterator iLightning;
        // play 'thunder' for lightning
        if( snd_active )
index 46c7df2c973ba324173b414ae7182bec0996b2b7..7f14dd6f8f62dc266df7ec91fd88a1a4aad51a63 100644 (file)
@@ -43,7 +43,7 @@ SGEphemeris::SGEphemeris( const string &path ) {
     neptune = new Neptune;
     nplanets = 7;
     for ( int i = 0; i < nplanets; ++i ) {
-        sgdSetVec3( planets[i], 0.0, 0.0, 0.0 );
+       sgdSetVec3( planets[i].sg(), 0.0, 0.0, 0.0 );
     }
     stars = new SGStarData( SGPath(path) );
 }
index e8fd02cfb77950a02b7003a1e8d8d5febde5f090..7554391f1c37f9253b9dbf610edcfa64cd478c69 100644 (file)
@@ -83,7 +83,7 @@ class SGEphemeris {
     // planets[i][1] = Declination
     // planets[i][2] = Magnitude
     int nplanets;
-    sgdVec3 planets[7];
+    SGVec3d planets[7];
 
     SGStarData *stars;
 
@@ -155,7 +155,7 @@ public:
      * the second is the declination, and the third is the magnitude.
      * @return planets array
      */
-    inline sgdVec3 *getPlanets() { return planets; }
+    inline SGVec3d *getPlanets() { return planets; }
 
     /** @return the numbers of defined stars. */
     inline int getNumStars() const { return stars->getNumStars(); }
@@ -167,7 +167,7 @@ public:
      * third is the magnitude.
      * @returns star array
      */
-    inline sgdVec3 *getStars() { return stars->getStars(); }
+    inline SGVec3d *getStars() { return stars->getStars(); }
 };
 
 
index 4c703cf9cf1eb593a29ef8dee108300ce36106fe..7f04b8b21055f7cb93824ee8c4d2ad2694e9741f 100644 (file)
@@ -56,7 +56,7 @@ bool SGStarData::load() {
 
     // -dw- avoid local data > 32k error by dynamic allocation of the
     // array, problem for some compilers
-    stars = new sgdVec3[SG_MAX_STARS];
+    stars = new SGVec3d[SG_MAX_STARS];
 
      // build the full path name to the stars data base file
     data_path.append( "stars" );
@@ -117,7 +117,7 @@ bool SGStarData::load() {
 
        // cout << " star data = " << ra << " " << dec << " " << mag << endl;
 
-       sgdSetVec3( stars[nstars], ra, dec, mag );
+       sgdSetVec3( stars[nstars].sg(), ra, dec, mag );
 
        ++nstars;
     }
index 7f2078886fc59fe5804e5deaa7d4d6ffd1582f8a..5ac685b30117c0f10509aaf154bda1826dd2341c 100644 (file)
@@ -36,7 +36,7 @@
 class SGStarData {
 
     int nstars;
-    sgdVec3 *stars;
+    SGVec3d *stars;
     
     SGPath data_path;
 
@@ -54,7 +54,7 @@ public:
 
     // stars
     inline int getNumStars() const { return nstars; }
-    inline sgdVec3 *getStars() { return stars; }
+    inline SGVec3d *getStars() { return stars; }
 };
 
 
index 9f0edce9c798a8b59d308424ebb3007675e3d158..ed146038dc59b71dab43eb505e3467ad449ea710 100644 (file)
@@ -574,8 +574,8 @@ toMatrixf(const SGMatrixd& m)
 {
   return SGMatrixf((float)m(0,0), (float)m(0,1), (float)m(0,2), (float)m(0,3),
                    (float)m(1,0), (float)m(1,1), (float)m(1,2), (float)m(1,3),
-                   (float)m(3,0), (float)m(2,1), (float)m(2,2), (float)m(2,3),
-                   (float)m(4,0), (float)m(4,1), (float)m(4,2), (float)m(4,3));
+                   (float)m(2,0), (float)m(2,1), (float)m(2,2), (float)m(2,3),
+                   (float)m(3,0), (float)m(3,1), (float)m(3,2), (float)m(3,3));
 }
 
 inline
@@ -584,8 +584,8 @@ toMatrixd(const SGMatrixf& m)
 {
   return SGMatrixd(m(0,0), m(0,1), m(0,2), m(0,3),
                    m(1,0), m(1,1), m(1,2), m(1,3),
-                   m(3,0), m(2,1), m(2,2), m(2,3),
-                   m(4,0), m(4,1), m(4,2), m(4,3));
+                   m(2,0), m(2,1), m(2,2), m(2,3),
+                   m(3,0), m(3,1), m(3,2), m(3,3));
 }
 
 #endif
index c50f185dc022670d97f52b11f9f88f3355cfc041..f05568e04b0d056a83116bba1e71c179f667c357 100644 (file)
 #undef max
 #endif
 
+#include <osg/Quat>
+
+template<typename T>
+struct SGQuatStorage {
+  /// Readonly raw storage interface
+  const T (&data(void) const)[4]
+  { return _data; }
+  /// Readonly raw storage interface
+  T (&data(void))[4]
+  { return _data; }
+
+  void osg() const
+  { }
+
+private:
+  T _data[4];
+};
+
+template<>
+struct SGQuatStorage<double> : public osg::Quat {
+  /// Access raw data by index, the index is unchecked
+  const double (&data(void) const)[4]
+  { return osg::Quat::_v; }
+  /// Access raw data by index, the index is unchecked
+  double (&data(void))[4]
+  { return osg::Quat::_v; }
+
+  const osg::Quat& osg() const
+  { return *this; }
+  osg::Quat& osg()
+  { return *this; }
+};
 
 /// 3D Vector Class
 template<typename T>
-class SGQuat {
+class SGQuat : protected SGQuatStorage<T> {
 public:
   typedef T value_type;
 
@@ -42,7 +74,7 @@ public:
     /// uninitialized values in the debug build very fast ...
 #ifndef NDEBUG
     for (unsigned i = 0; i < 4; ++i)
-      _data[i] = SGLimits<T>::quiet_NaN();
+      data()[i] = SGLimits<T>::quiet_NaN();
 #endif
   }
   /// Constructor. Initialize by the given values
@@ -51,7 +83,9 @@ public:
   /// Constructor. Initialize by the content of a plain array,
   /// make sure it has at least 4 elements
   explicit SGQuat(const T* d)
-  { _data[0] = d[0]; _data[1] = d[1]; _data[2] = d[2]; _data[3] = d[3]; }
+  { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; }
+  explicit SGQuat(const osg::Quat& d)
+  { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; }
 
   /// Return a unit quaternion
   static SGQuat unit(void)
@@ -236,67 +270,66 @@ public:
 
   /// Access by index, the index is unchecked
   const T& operator()(unsigned i) const
-  { return _data[i]; }
+  { return data()[i]; }
   /// Access by index, the index is unchecked
   T& operator()(unsigned i)
-  { return _data[i]; }
+  { return data()[i]; }
 
   /// Access raw data by index, the index is unchecked
   const T& operator[](unsigned i) const
-  { return _data[i]; }
+  { return data()[i]; }
   /// Access raw data by index, the index is unchecked
   T& operator[](unsigned i)
-  { return _data[i]; }
+  { return data()[i]; }
 
   /// Access the x component
   const T& x(void) const
-  { return _data[0]; }
+  { return data()[0]; }
   /// Access the x component
   T& x(void)
-  { return _data[0]; }
+  { return data()[0]; }
   /// Access the y component
   const T& y(void) const
-  { return _data[1]; }
+  { return data()[1]; }
   /// Access the y component
   T& y(void)
-  { return _data[1]; }
+  { return data()[1]; }
   /// Access the z component
   const T& z(void) const
-  { return _data[2]; }
+  { return data()[2]; }
   /// Access the z component
   T& z(void)
-  { return _data[2]; }
+  { return data()[2]; }
   /// Access the w component
   const T& w(void) const
-  { return _data[3]; }
+  { return data()[3]; }
   /// Access the w component
   T& w(void)
-  { return _data[3]; }
+  { return data()[3]; }
 
-  /// Get the data pointer, usefull for interfacing with plib's sg*Vec
-  const T* data(void) const
-  { return _data; }
-  /// Get the data pointer, usefull for interfacing with plib's sg*Vec
-  T* data(void)
-  { return _data; }
+  /// Get the data pointer
+  using SGQuatStorage<T>::data;
 
   /// Readonly interface function to ssg's sgQuat/sgdQuat
   const T (&sg(void) const)[4]
-  { return _data; }
+  { return data(); }
   /// Interface function to ssg's sgQuat/sgdQuat
   T (&sg(void))[4]
-  { return _data; }
+  { return data(); }
+
+  /// Interface function to osg's Quat*
+  using SGQuatStorage<T>::osg;
 
   /// Inplace addition
   SGQuat& operator+=(const SGQuat& v)
-  { _data[0]+=v(0);_data[1]+=v(1);_data[2]+=v(2);_data[3]+=v(3);return *this; }
+  { data()[0]+=v(0);data()[1]+=v(1);data()[2]+=v(2);data()[3]+=v(3);return *this; }
   /// Inplace subtraction
   SGQuat& operator-=(const SGQuat& v)
-  { _data[0]-=v(0);_data[1]-=v(1);_data[2]-=v(2);_data[3]-=v(3);return *this; }
+  { data()[0]-=v(0);data()[1]-=v(1);data()[2]-=v(2);data()[3]-=v(3);return *this; }
   /// Inplace scalar multiplication
   template<typename S>
   SGQuat& operator*=(S s)
-  { _data[0] *= s; _data[1] *= s; _data[2] *= s; _data[3] *= s; return *this; }
+  { data()[0] *= s; data()[1] *= s; data()[2] *= s; data()[3] *= s; return *this; }
   /// Inplace scalar multiplication by 1/s
   template<typename S>
   SGQuat& operator/=(S s)
@@ -343,10 +376,6 @@ public:
     
     return deriv;
   }
-
-private:
-  /// The actual data
-  T _data[4];
 };
 
 /// Unary +, do nothing ...
index c6f9965743f4b0410ef019c152263c0dcc9af1fc..ee75415c022083f79976fe984bd808539aa90b9a 100644 (file)
 #ifndef SGVec3_H
 #define SGVec3_H
 
+#include <osg/Vec3f>
+#include <osg/Vec3d>
+
+template<typename T>
+struct SGVec3Storage {
+  /// Readonly raw storage interface
+  const T (&data(void) const)[3]
+  { return _data; }
+  /// Readonly raw storage interface
+  T (&data(void))[3]
+  { return _data; }
+
+  void osg() const
+  { }
+
+private:
+  T _data[3];
+};
+
+template<>
+struct SGVec3Storage<float> : public osg::Vec3f {
+  /// Access raw data by index, the index is unchecked
+  const float (&data(void) const)[3]
+  { return osg::Vec3f::_v; }
+  /// Access raw data by index, the index is unchecked
+  float (&data(void))[3]
+  { return osg::Vec3f::_v; }
+
+  const osg::Vec3f& osg() const
+  { return *this; }
+  osg::Vec3f& osg()
+  { return *this; }
+};
+
+template<>
+struct SGVec3Storage<double> : public osg::Vec3d {
+  /// Access raw data by index, the index is unchecked
+  const double (&data(void) const)[3]
+  { return osg::Vec3d::_v; }
+  /// Access raw data by index, the index is unchecked
+  double (&data(void))[3]
+  { return osg::Vec3d::_v; }
+
+  const osg::Vec3d& osg() const
+  { return *this; }
+  osg::Vec3d& osg()
+  { return *this; }
+};
+
 /// 3D Vector Class
 template<typename T>
-class SGVec3 {
+class SGVec3 : protected SGVec3Storage<T> {
 public:
   typedef T value_type;
 
@@ -33,74 +82,77 @@ public:
     /// uninitialized values in the debug build very fast ...
 #ifndef NDEBUG
     for (unsigned i = 0; i < 3; ++i)
-      _data[i] = SGLimits<T>::quiet_NaN();
+      data()[i] = SGLimits<T>::quiet_NaN();
 #endif
   }
   /// Constructor. Initialize by the given values
   SGVec3(T x, T y, T z)
-  { _data[0] = x; _data[1] = y; _data[2] = z; }
+  { data()[0] = x; data()[1] = y; data()[2] = z; }
   /// Constructor. Initialize by the content of a plain array,
   /// make sure it has at least 3 elements
-  explicit SGVec3(const T* data)
-  { _data[0] = data[0]; _data[1] = data[1]; _data[2] = data[2]; }
+  explicit SGVec3(const T* d)
+  { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; }
+  explicit SGVec3(const osg::Vec3f& d)
+  { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; }
+  explicit SGVec3(const osg::Vec3d& d)
+  { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; }
 
   /// Access by index, the index is unchecked
   const T& operator()(unsigned i) const
-  { return _data[i]; }
+  { return data()[i]; }
   /// Access by index, the index is unchecked
   T& operator()(unsigned i)
-  { return _data[i]; }
+  { return data()[i]; }
 
   /// Access raw data by index, the index is unchecked
   const T& operator[](unsigned i) const
-  { return _data[i]; }
+  { return data()[i]; }
   /// Access raw data by index, the index is unchecked
   T& operator[](unsigned i)
-  { return _data[i]; }
+  { return data()[i]; }
 
   /// Access the x component
   const T& x(void) const
-  { return _data[0]; }
+  { return data()[0]; }
   /// Access the x component
   T& x(void)
-  { return _data[0]; }
+  { return data()[0]; }
   /// Access the y component
   const T& y(void) const
-  { return _data[1]; }
+  { return data()[1]; }
   /// Access the y component
   T& y(void)
-  { return _data[1]; }
+  { return data()[1]; }
   /// Access the z component
   const T& z(void) const
-  { return _data[2]; }
+  { return data()[2]; }
   /// Access the z component
   T& z(void)
-  { return _data[2]; }
+  { return data()[2]; }
 
   /// Get the data pointer
-  const T* data(void) const
-  { return _data; }
-  /// Get the data pointer
-  T* data(void)
-  { return _data; }
+  using SGVec3Storage<T>::data;
 
   /// Readonly interface function to ssg's sgVec3/sgdVec3
   const T (&sg(void) const)[3]
-  { return _data; }
+  { return data(); }
   /// Interface function to ssg's sgVec3/sgdVec3
   T (&sg(void))[3]
-  { return _data; }
+  { return data(); }
+
+  /// Interface function to osg's Vec3*
+  using SGVec3Storage<T>::osg;
 
   /// Inplace addition
   SGVec3& operator+=(const SGVec3& v)
-  { _data[0] += v(0); _data[1] += v(1); _data[2] += v(2); return *this; }
+  { data()[0] += v(0); data()[1] += v(1); data()[2] += v(2); return *this; }
   /// Inplace subtraction
   SGVec3& operator-=(const SGVec3& v)
-  { _data[0] -= v(0); _data[1] -= v(1); _data[2] -= v(2); return *this; }
+  { data()[0] -= v(0); data()[1] -= v(1); data()[2] -= v(2); return *this; }
   /// Inplace scalar multiplication
   template<typename S>
   SGVec3& operator*=(S s)
-  { _data[0] *= s; _data[1] *= s; _data[2] *= s; return *this; }
+  { data()[0] *= s; data()[1] *= s; data()[2] *= s; return *this; }
   /// Inplace scalar multiplication by 1/s
   template<typename S>
   SGVec3& operator/=(S s)
@@ -123,10 +175,6 @@ public:
   /// Constructor. Initialize by a geocentric coordinate
   /// Note that this conversion is relatively expensive to compute
   static SGVec3 fromGeoc(const SGGeoc& geoc);
-
-private:
-  /// The actual data
-  T _data[3];
 };
 
 template<>
index feee964b4b5b57b68915e1be74db7f289a20ceef..50b138c9eb0e5c0668f81dee9c2aed6e479951e5 100644 (file)
 #ifndef SGVec4_H
 #define SGVec4_H
 
+#include <osg/Vec4f>
+#include <osg/Vec4d>
+
+template<typename T>
+struct SGVec4Storage {
+  /// Readonly raw storage interface
+  const T (&data(void) const)[4]
+  { return _data; }
+  /// Readonly raw storage interface
+  T (&data(void))[4]
+  { return _data; }
+
+  void osg() const
+  { }
+
+private:
+  T _data[4];
+};
+
+template<>
+struct SGVec4Storage<float> : public osg::Vec4f {
+  /// Access raw data by index, the index is unchecked
+  const float (&data(void) const)[4]
+  { return osg::Vec4f::_v; }
+  /// Access raw data by index, the index is unchecked
+  float (&data(void))[4]
+  { return osg::Vec4f::_v; }
+
+  const osg::Vec4f& osg() const
+  { return *this; }
+  osg::Vec4f& osg()
+  { return *this; }
+};
+
+template<>
+struct SGVec4Storage<double> : public osg::Vec4d {
+  /// Access raw data by index, the index is unchecked
+  const double (&data(void) const)[4]
+  { return osg::Vec4d::_v; }
+  /// Access raw data by index, the index is unchecked
+  double (&data(void))[4]
+  { return osg::Vec4d::_v; }
+
+  const osg::Vec4d& osg() const
+  { return *this; }
+  osg::Vec4d& osg()
+  { return *this; }
+};
+
 /// 4D Vector Class
 template<typename T>
-class SGVec4 {
+class SGVec4 : protected SGVec4Storage<T> {
 public:
   typedef T value_type;
 
@@ -33,82 +82,84 @@ public:
     /// uninitialized values in the debug build very fast ...
 #ifndef NDEBUG
     for (unsigned i = 0; i < 4; ++i)
-      _data[i] = SGLimits<T>::quiet_NaN();
+      data()[i] = SGLimits<T>::quiet_NaN();
 #endif
   }
   /// Constructor. Initialize by the given values
   SGVec4(T x, T y, T z, T w)
-  { _data[0] = x; _data[1] = y; _data[2] = z; _data[3] = w; }
+  { data()[0] = x; data()[1] = y; data()[2] = z; data()[3] = w; }
   /// Constructor. Initialize by the content of a plain array,
   /// make sure it has at least 3 elements
   explicit SGVec4(const T* d)
-  { _data[0] = d[0]; _data[1] = d[1]; _data[2] = d[2]; _data[3] = d[3]; }
+  { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; }
+  explicit SGVec4(const osg::Vec4f& d)
+  { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; }
+  explicit SGVec4(const osg::Vec4d& d)
+  { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; }
 
 
   /// Access by index, the index is unchecked
   const T& operator()(unsigned i) const
-  { return _data[i]; }
+  { return data()[i]; }
   /// Access by index, the index is unchecked
   T& operator()(unsigned i)
-  { return _data[i]; }
+  { return data()[i]; }
 
   /// Access raw data by index, the index is unchecked
   const T& operator[](unsigned i) const
-  { return _data[i]; }
+  { return data()[i]; }
   /// Access raw data by index, the index is unchecked
   T& operator[](unsigned i)
-  { return _data[i]; }
+  { return data()[i]; }
 
   /// Access the x component
   const T& x(void) const
-  { return _data[0]; }
+  { return data()[0]; }
   /// Access the x component
   T& x(void)
-  { return _data[0]; }
+  { return data()[0]; }
   /// Access the y component
   const T& y(void) const
-  { return _data[1]; }
+  { return data()[1]; }
   /// Access the y component
   T& y(void)
-  { return _data[1]; }
+  { return data()[1]; }
   /// Access the z component
   const T& z(void) const
-  { return _data[2]; }
+  { return data()[2]; }
   /// Access the z component
   T& z(void)
-  { return _data[2]; }
+  { return data()[2]; }
   /// Access the x component
   const T& w(void) const
-  { return _data[3]; }
+  { return data()[3]; }
   /// Access the x component
   T& w(void)
-  { return _data[3]; }
-
+  { return data()[3]; }
 
-  /// Get the data pointer, 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<T>::data;
 
-  /// Readonly interface function to ssg's sgVec3/sgdVec3
+  /// Readonly interface function to ssg's sgVec4/sgdVec4
   const T (&sg(void) const)[4]
-  { return _data; }
-  /// Interface function to ssg's sgVec3/sgdVec3
+  { return data(); }
+  /// Interface function to ssg's sgVec4/sgdVec4
   T (&sg(void))[4]
-  { return _data; }
+  { return data(); }
+
+  /// Interface function to osg's Vec4*
+  using SGVec4Storage<T>::osg;
 
   /// Inplace addition
   SGVec4& operator+=(const SGVec4& v)
-  { _data[0]+=v(0);_data[1]+=v(1);_data[2]+=v(2);_data[3]+=v(3);return *this; }
+  { data()[0]+=v(0);data()[1]+=v(1);data()[2]+=v(2);data()[3]+=v(3);return *this; }
   /// Inplace subtraction
   SGVec4& operator-=(const SGVec4& v)
-  { _data[0]-=v(0);_data[1]-=v(1);_data[2]-=v(2);_data[3]-=v(3);return *this; }
+  { data()[0]-=v(0);data()[1]-=v(1);data()[2]-=v(2);data()[3]-=v(3);return *this; }
   /// Inplace scalar multiplication
   template<typename S>
   SGVec4& operator*=(S s)
-  { _data[0] *= s; _data[1] *= s; _data[2] *= s; _data[3] *= s; return *this; }
+  { data()[0] *= s; data()[1] *= s; data()[2] *= s; data()[3] *= s; return *this; }
   /// Inplace scalar multiplication by 1/s
   template<typename S>
   SGVec4& operator/=(S s)
@@ -126,10 +177,6 @@ public:
   { return SGVec4(0, 0, 1, 0); }
   static SGVec4 e4(void)
   { return SGVec4(0, 0, 0, 1); }
-
-private:
-  /// The actual data
-  T _data[4];
 };
 
 /// Unary +, do nothing ...
index c6aed399cce64b52da94e2a72cabc4e74e84021d..ff99d550932865ba44ed50495450900683a0a6c8 100644 (file)
@@ -1,6 +1,6 @@
 includedir = @includedir@/scene
 
-SUBDIRS = material model sky tgdb
+SUBDIRS = material model sky tgdb util
 
 # lib_LIBRARIES = libsgscene.a
 
index b8af8091faacf0a8f878a9466bb4909a4ab3918a..b9d4fa6db6731f3e782452aa000523baf956f3f6 100644 (file)
@@ -37,14 +37,21 @@ SG_USING_STD(map);
 #  include <math.h>
 #endif
 
+#include <osg/CullFace>
+#include <osg/Material>
+#include <osg/ShadeModel>
+#include <osg/TexEnv>
+#include <osg/Texture2D>
+#include <osgDB/ReadFile>
+
 #include <simgear/debug/logstream.hxx>
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/misc/sgstream.hxx>
 
+#include <simgear/scene/model/model.hxx>
 #include "mat.hxx"
 
-static map<string, ssgTexture *> _tex_cache;
-static map<string, ssgTexture *>::iterator _tex_cache_iter;
+static map<string, osg::ref_ptr<osg::Texture2D> > _tex_cache;
 
 \f
 ////////////////////////////////////////////////////////////////////////
@@ -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<string, osg::ref_ptr<osg::Texture2D> >::iterator _tex_cache_iter;
    _tex_cache_iter = _tex_cache.find(fname);
    if (_tex_cache_iter == _tex_cache.end())
    {
-      state->setTexture((char *)fname.c_str(), _wrapu, _wrapv, _mipmap);
-      _tex_cache[fname] = state->getTexture();
+      osg::Texture2D* texture = SGLoadTexture2D(fname, _wrapu, _wrapv,
+                                                mipmap ? -1 : 0);
+      state->setTextureAttributeAndModes(0, texture);
+      _tex_cache[fname] = texture;
    }
    else
    {
-      state->setTexture(_tex_cache_iter->second);
+      state->setTextureAttributeAndModes(0, _tex_cache_iter->second.get());
       // cout << "Cache hit: " << fname << endl;
    }
+   osg::TexEnv* texEnv = new osg::TexEnv;
+   texEnv->setMode(osg::TexEnv::MODULATE);
+   state->setTextureAttributeAndModes(0, texEnv);
 }
 
 SGMaterialGlyph* SGMaterial::get_glyph (const string& name) const
index e3e38a13b4d92b6066ad68f3450c4426ca9cc92f..a55ddd73ffcbb418486d3a3270ae9b094711309f 100644 (file)
 
 #include <simgear/math/SGMath.hxx>
 
-#include <plib/sg.h>
-#include <plib/ssg.h>
+#include <osg/ref_ptr>
+#include <osg/StateSet>
 
 #include <simgear/props/props.hxx>
-#include <simgear/structure/ssgSharedPtr.hxx>
 #include <simgear/structure/SGSharedPtr.hxx>
 
 #include "matmodel.hxx"
@@ -93,15 +92,15 @@ public:
 
 
   /**
-   * Construct a material around an existing SSG state.
+   * Construct a material around an existing state.
    *
    * This constructor allows the application to create a custom,
    * low-level state for the scene graph and wrap a material around
    * it.  Note: the pointer ownership is transferred to the material.
    *
-   * @param s The SSG state for this material.
+   * @param s The state for this material.
    */
-  SGMaterial( ssgSimpleState *s );
+  SGMaterial( osg::StateSet *s );
 
   /**
    * Destructor.
@@ -126,7 +125,7 @@ public:
   /**
    * Get the textured state.
    */
-  ssgSimpleState *get_state (int n = -1) const;
+  osg::StateSet *get_state (int n = -1) const;
 
 
   /**
@@ -224,9 +223,9 @@ protected:
 protected:
 
   struct _internal_state {
-     _internal_state( ssgSimpleState *s, const string &t, bool l )
+      _internal_state( osg::StateSet *s, const string &t, bool l )
                   : state(s), texture_path(t), texture_loaded(l) {}
-      ssgSharedPtr<ssgSimpleState> state;
+      osg::ref_ptr<osg::StateSet> state;
       string texture_path;
       bool texture_loaded;
   };
@@ -242,7 +241,7 @@ private:
   vector<_internal_state> _status;
 
   // Round-robin counter
-  unsigned int _current_ptr;
+  mutable unsigned int _current_ptr;
 
   // texture size
   double xsize, ysize;
@@ -291,10 +290,10 @@ private:
   SGMaterial( const string &fg_root, const SGMaterial &mat ); // unimplemented
 
   void read_properties( const string &fg_root, const SGPropertyNode *props, const char *season );
-  void build_ssg_state( bool defer_tex_load );
-  void set_ssg_state( ssgSimpleState *s );
+  void build_state( bool defer_tex_load );
+  void set_state( osg::StateSet *s );
 
-  void assignTexture( ssgSimpleState *state, string &fname, int _wrapu = TRUE, int _wrapv = TRUE, int _mipmap = TRUE );
+  void assignTexture( osg::StateSet *state, const std::string &fname, int _wrapu = TRUE, int _wrapv = TRUE, int _mipmap = TRUE );
 
 };
 
@@ -311,7 +310,7 @@ protected:
   double _right;
 };
 
-class SGMaterialUserData : public ssgBase {
+class SGMaterialUserData : public osg::Referenced {
 public:
   SGMaterialUserData(const SGMaterial* material) :
     mMaterial(material)
index b3f702cc9cb1500c1a7b985073cd6a124e27e290..07a20b11ddf70834c441e3d4008c24b35a8ba56d 100644 (file)
@@ -33,8 +33,6 @@
 #  include <windows.h>
 #endif
 
-#include <plib/ssg.h>
-
 #include <simgear/compiler.h>
 #include <simgear/constants.h>
 #include <simgear/structure/exception.hxx>
 #include <string.h>
 #include STL_STRING
 
+#include <osg/AlphaFunc>
+#include <osg/BlendFunc>
+#include <osg/CullFace>
+#include <osg/Material>
+// #include <osg/Multisample>
+#include <osg/Point>
+#include <osg/PointSprite>
+#include <osg/PolygonMode>
+#include <osg/PolygonOffset>
+#include <osg/StateSet>
+#include <osg/TexEnv>
+#include <osg/TexGen>
+#include <osg/Texture2D>
+
 #include <simgear/debug/logstream.hxx>
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/misc/sgstream.hxx>
 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<osg::StateSet> lightStateSet = new osg::StateSet;
+    {
+//       lightStateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
+//       lightStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
+      lightStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
+//       lightStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
+
+      lightStateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::OFF);
+//       lightStateSet->setAttribute(new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0));
+//       lightStateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON);
+
+      osg::CullFace* cullFace = new osg::CullFace;
+      cullFace->setMode(osg::CullFace::BACK);
+      lightStateSet->setAttributeAndModes(cullFace, osg::StateAttribute::ON);
+
+      osg::BlendFunc* blendFunc = new osg::BlendFunc;
+      blendFunc->setFunction(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA);
+      lightStateSet->setAttributeAndModes(blendFunc, osg::StateAttribute::ON);
+
+      osg::PolygonMode* polygonMode = new osg::PolygonMode;
+      polygonMode->setMode(osg::PolygonMode::FRONT, osg::PolygonMode::POINT);
+      lightStateSet->setAttribute(polygonMode);
+
+//       if (SGPointLightsUseSprites) {
+        osg::PointSprite* pointSprite = new osg::PointSprite;
+        lightStateSet->setTextureAttributeAndModes(0, pointSprite, osg::StateAttribute::ON);
+//       }
+
+//       if (SGPointLightsDistanceAttenuation) {
+        osg::Point* point = new osg::Point;
+        point->setMinSize(2);
+        point->setSize(8);
+        point->setDistanceAttenuation(osg::Vec3(1.0, 0.001, 0.000001));
+        lightStateSet->setAttribute(point);
+//       }
+
+      osg::PolygonOffset* polygonOffset = new osg::PolygonOffset;
+      polygonOffset->setFactor(-1);
+      polygonOffset->setUnits(-1);
+      lightStateSet->setAttributeAndModes(polygonOffset, osg::StateAttribute::ON);
+      
+      osg::TexGen* texGen = new osg::TexGen;
+      texGen->setMode(osg::TexGen::SPHERE_MAP);
+      lightStateSet->setTextureAttribute(0, texGen);
+      lightStateSet->setTextureMode(0, GL_TEXTURE_GEN_S, osg::StateAttribute::ON);
+      lightStateSet->setTextureMode(0, GL_TEXTURE_GEN_T, osg::StateAttribute::ON);
+      osg::TexEnv* texEnv = new osg::TexEnv;
+      texEnv->setMode(osg::TexEnv::MODULATE);
+      lightStateSet->setTextureAttribute(0, texEnv);
+
+      osg::Material* material = new osg::Material;
+      lightStateSet->setAttribute(material);
+//       lightStateSet->setMode(GL_COLOR_MATERIAL, osg::StateAttribute::OFF);
+    }
+    
+
     // hard coded ground light state
-    ssgSimpleState *gnd_lights = new ssgSimpleState;
-    gnd_lights->disable( GL_TEXTURE_2D );
-    gnd_lights->enable( GL_CULL_FACE );
-    gnd_lights->enable( GL_COLOR_MATERIAL );
-    gnd_lights->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
-    gnd_lights->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
-    gnd_lights->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
-    gnd_lights->enable( GL_BLEND );
-    gnd_lights->disable( GL_ALPHA_TEST );
-    gnd_lights->disable( GL_LIGHTING );
+    osg::StateSet *gnd_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
+//     if (SGPointLightsDistanceAttenuation) {
+    osg::Point* point = new osg::Point;
+      point->setMinSize(1);
+      point->setSize(2);
+      point->setMaxSize(4);
+      point->setDistanceAttenuation(osg::Vec3(1.0, 0.01, 0.0001));
+      while (gnd_lights->getAttribute(osg::StateAttribute::POINT)) {
+        gnd_lights->removeAttribute(osg::StateAttribute::POINT);
+      }
+      gnd_lights->setAttribute(point);
+//     }
     m = new SGMaterial( gnd_lights );
     m->add_name("GROUND_LIGHTS");
     matlib["GROUND_LIGHTS"] = m;
 
-    GLuint tex_name;
-
     // hard coded runway white light state
+    osg::Texture2D* texture;
     if ( sprite_lighting ) {
-        tex_name = gen_standard_light_sprite( 235, 235, 195, 255 );
+      texture = gen_standard_light_sprite(235, 235, 195, 255);
     } else {
-        tex_name = gen_standard_dir_light_map( 235, 235, 195, 255 );
+      texture = gen_standard_dir_light_map(235, 235, 195, 255);
     }
-    ssgSimpleState *rwy_white_lights = new ssgSimpleState();
-    rwy_white_lights->disable( GL_LIGHTING );
-    rwy_white_lights->enable ( GL_CULL_FACE ) ;
-    rwy_white_lights->enable( GL_TEXTURE_2D );
-    rwy_white_lights->enable( GL_BLEND );
-    rwy_white_lights->enable( GL_ALPHA_TEST );
-    rwy_white_lights->enable( GL_COLOR_MATERIAL );
-    rwy_white_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
-    rwy_white_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
-    rwy_white_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
-    rwy_white_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
-    rwy_white_lights->setTexture( tex_name );
+    osg::StateSet *rwy_white_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
+    rwy_white_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
+
     m = new SGMaterial( rwy_white_lights );
     m->add_name("RWY_WHITE_LIGHTS");
     matlib["RWY_WHITE_LIGHTS"] = m;
@@ -301,242 +309,133 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
 
     // hard coded runway medium intensity white light state
     if ( sprite_lighting ) {
-        tex_name = gen_standard_light_sprite( 235, 235, 195, 205 );
+      texture = gen_standard_light_sprite( 235, 235, 195, 205 );
     } else {
-        tex_name = gen_standard_dir_light_map( 235, 235, 195, 205 );
+      texture = gen_standard_dir_light_map( 235, 235, 195, 205 );
     }
-    ssgSimpleState *rwy_white_medium_lights = new ssgSimpleState();
-    rwy_white_medium_lights->disable( GL_LIGHTING );
-    rwy_white_medium_lights->enable ( GL_CULL_FACE ) ;
-    rwy_white_medium_lights->enable( GL_TEXTURE_2D );
-    rwy_white_medium_lights->enable( GL_BLEND );
-    rwy_white_medium_lights->enable( GL_ALPHA_TEST );
-    rwy_white_medium_lights->enable( GL_COLOR_MATERIAL );
-    rwy_white_medium_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
-    rwy_white_medium_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
-    rwy_white_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
-    rwy_white_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
-    rwy_white_medium_lights->setTexture( tex_name );
+    osg::StateSet *rwy_white_medium_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
+    rwy_white_medium_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
+
     m = new SGMaterial( rwy_white_medium_lights );
     m->add_name("RWY_WHITE_MEDIUM_LIGHTS");
     matlib["RWY_WHITE_MEDIUM_LIGHTS"] = m;
 
     // hard coded runway low intensity white light state
     if ( sprite_lighting ) {
-        tex_name = gen_standard_light_sprite( 235, 235, 195, 155 );
+      texture = gen_standard_light_sprite( 235, 235, 195, 155 );
     } else {
-        tex_name = gen_standard_dir_light_map( 235, 235, 195, 155 );
+      texture = gen_standard_dir_light_map( 235, 235, 195, 155 );
     }
-    ssgSimpleState *rwy_white_low_lights = new ssgSimpleState();
-    rwy_white_low_lights->disable( GL_LIGHTING );
-    rwy_white_low_lights->enable ( GL_CULL_FACE ) ;
-    rwy_white_low_lights->enable( GL_TEXTURE_2D );
-    rwy_white_low_lights->enable( GL_BLEND );
-    rwy_white_low_lights->enable( GL_ALPHA_TEST );
-    rwy_white_low_lights->enable( GL_COLOR_MATERIAL );
-    rwy_white_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
-    rwy_white_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
-    rwy_white_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
-    rwy_white_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
-    rwy_white_low_lights->setTexture( tex_name );
+    osg::StateSet *rwy_white_low_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
+    rwy_white_medium_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
     m = new SGMaterial( rwy_white_low_lights );
     m->add_name("RWY_WHITE_LOW_LIGHTS");
     matlib["RWY_WHITE_LOW_LIGHTS"] = m;
 
     // hard coded runway yellow light state
     if ( sprite_lighting ) {
-        tex_name = gen_standard_light_sprite( 235, 215, 20, 255 );
+      texture = gen_standard_light_sprite( 235, 215, 20, 255 );
     } else {
-        tex_name = gen_standard_dir_light_map( 235, 215, 20, 255 );
+      texture = gen_standard_dir_light_map( 235, 215, 20, 255 );
     }
-    ssgSimpleState *rwy_yellow_lights = new ssgSimpleState();
-    rwy_yellow_lights->disable( GL_LIGHTING );
-    rwy_yellow_lights->enable ( GL_CULL_FACE ) ;
-    rwy_yellow_lights->enable( GL_TEXTURE_2D );
-    rwy_yellow_lights->enable( GL_BLEND );
-    rwy_yellow_lights->enable( GL_ALPHA_TEST );
-    rwy_yellow_lights->enable( GL_COLOR_MATERIAL );
-    rwy_yellow_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
-    rwy_yellow_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
-    rwy_yellow_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
-    rwy_yellow_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
-    rwy_yellow_lights->setTexture( tex_name );
+    osg::StateSet *rwy_yellow_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
+    rwy_yellow_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
     m = new SGMaterial( rwy_yellow_lights );
     m->add_name("RWY_YELLOW_LIGHTS");
     matlib["RWY_YELLOW_LIGHTS"] = m;
 
     // hard coded runway medium intensity yellow light state
     if ( sprite_lighting ) {
-        tex_name = gen_standard_light_sprite( 235, 215, 20, 205 );
+      texture = gen_standard_light_sprite( 235, 215, 20, 205 );
     } else {
-        tex_name = gen_standard_dir_light_map( 235, 215, 20, 205 );
+      texture = gen_standard_dir_light_map( 235, 215, 20, 205 );
     }
-    ssgSimpleState *rwy_yellow_medium_lights = new ssgSimpleState();
-    rwy_yellow_medium_lights->disable( GL_LIGHTING );
-    rwy_yellow_medium_lights->enable ( GL_CULL_FACE ) ;
-    rwy_yellow_medium_lights->enable( GL_TEXTURE_2D );
-    rwy_yellow_medium_lights->enable( GL_BLEND );
-    rwy_yellow_medium_lights->enable( GL_ALPHA_TEST );
-    rwy_yellow_medium_lights->enable( GL_COLOR_MATERIAL );
-    rwy_yellow_medium_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
-    rwy_yellow_medium_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
-    rwy_yellow_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
-    rwy_yellow_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
-    rwy_yellow_medium_lights->setTexture( tex_name );
+    osg::StateSet *rwy_yellow_medium_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
+    rwy_yellow_medium_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
     m = new SGMaterial( rwy_yellow_medium_lights );
     m->add_name("RWY_YELLOW_MEDIUM_LIGHTS");
     matlib["RWY_YELLOW_MEDIUM_LIGHTS"] = m;
 
     // hard coded runway low intensity yellow light state
     if ( sprite_lighting ) {
-        tex_name = gen_standard_light_sprite( 235, 215, 20, 155 );
+      texture = gen_standard_light_sprite( 235, 215, 20, 155 );
     } else {
-        tex_name = gen_standard_dir_light_map( 235, 215, 20, 155 );
+      texture = gen_standard_dir_light_map( 235, 215, 20, 155 );
     }
-    ssgSimpleState *rwy_yellow_low_lights = new ssgSimpleState();
-    rwy_yellow_low_lights->disable( GL_LIGHTING );
-    rwy_yellow_low_lights->enable ( GL_CULL_FACE ) ;
-    rwy_yellow_low_lights->enable( GL_TEXTURE_2D );
-    rwy_yellow_low_lights->enable( GL_BLEND );
-    rwy_yellow_low_lights->enable( GL_ALPHA_TEST );
-    rwy_yellow_low_lights->enable( GL_COLOR_MATERIAL );
-    rwy_yellow_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
-    rwy_yellow_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
-    rwy_yellow_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
-    rwy_yellow_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
-    rwy_yellow_low_lights->setTexture( tex_name );
+    osg::StateSet *rwy_yellow_low_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
+    rwy_yellow_low_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
     m = new SGMaterial( rwy_yellow_low_lights );
     m->add_name("RWY_YELLOW_LOW_LIGHTS");
     matlib["RWY_YELLOW_LOW_LIGHTS"] = m;
 
     // hard coded runway red light state
     if ( sprite_lighting ) {
-        tex_name = gen_standard_light_sprite( 235, 90, 90, 255 );
+      texture = gen_standard_light_sprite( 235, 90, 90, 255 );
     } else {
-        tex_name = gen_standard_dir_light_map( 235, 90, 90, 255 );
+      texture = gen_standard_dir_light_map( 235, 90, 90, 255 );
     }
-    ssgSimpleState *rwy_red_lights = new ssgSimpleState();
-    rwy_red_lights->disable( GL_LIGHTING );
-    rwy_red_lights->enable ( GL_CULL_FACE ) ;
-    rwy_red_lights->enable( GL_TEXTURE_2D );
-    rwy_red_lights->enable( GL_BLEND );
-    rwy_red_lights->enable( GL_ALPHA_TEST );
-    rwy_red_lights->enable( GL_COLOR_MATERIAL );
-    rwy_red_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
-    rwy_red_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
-    rwy_red_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
-    rwy_red_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
-    rwy_red_lights->setTexture( tex_name );
+    osg::StateSet *rwy_red_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
+    rwy_red_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
     m = new SGMaterial( rwy_red_lights );
     m->add_name("RWY_RED_LIGHTS");
     matlib["RWY_RED_LIGHTS"] = m;
 
     // hard coded medium intensity runway red light state
     if ( sprite_lighting ) {
-        tex_name = gen_standard_light_sprite( 235, 90, 90, 205 );
+      texture = gen_standard_light_sprite( 235, 90, 90, 205 );
     } else {
-        tex_name = gen_standard_dir_light_map( 235, 90, 90, 205 );
+      texture = gen_standard_dir_light_map( 235, 90, 90, 205 );
     }
-    ssgSimpleState *rwy_red_medium_lights = new ssgSimpleState();
-    rwy_red_medium_lights->disable( GL_LIGHTING );
-    rwy_red_medium_lights->enable ( GL_CULL_FACE ) ;
-    rwy_red_medium_lights->enable( GL_TEXTURE_2D );
-    rwy_red_medium_lights->enable( GL_BLEND );
-    rwy_red_medium_lights->enable( GL_ALPHA_TEST );
-    rwy_red_medium_lights->enable( GL_COLOR_MATERIAL );
-    rwy_red_medium_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
-    rwy_red_medium_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
-    rwy_red_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
-    rwy_red_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
-    rwy_red_medium_lights->setTexture( tex_name );
+    osg::StateSet *rwy_red_medium_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
+    rwy_red_medium_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
     m = new SGMaterial( rwy_red_medium_lights );
     m->add_name("RWY_RED_MEDIUM_LIGHTS");
     matlib["RWY_RED_MEDIUM_LIGHTS"] = m;
 
     // hard coded low intensity runway red light state
     if ( sprite_lighting ) {
-        tex_name = gen_standard_light_sprite( 235, 90, 90, 155 );
+      texture = gen_standard_light_sprite( 235, 90, 90, 155 );
     } else {
-        tex_name = gen_standard_dir_light_map( 235, 90, 90, 155 );
+      texture = gen_standard_dir_light_map( 235, 90, 90, 155 );
     }
-    ssgSimpleState *rwy_red_low_lights = new ssgSimpleState();
-    rwy_red_low_lights->disable( GL_LIGHTING );
-    rwy_red_low_lights->enable ( GL_CULL_FACE ) ;
-    rwy_red_low_lights->enable( GL_TEXTURE_2D );
-    rwy_red_low_lights->enable( GL_BLEND );
-    rwy_red_low_lights->enable( GL_ALPHA_TEST );
-    rwy_red_low_lights->enable( GL_COLOR_MATERIAL );
-    rwy_red_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
-    rwy_red_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
-    rwy_red_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
-    rwy_red_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
-    rwy_red_low_lights->setTexture( tex_name );
+    osg::StateSet *rwy_red_low_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
+    rwy_red_low_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
     m = new SGMaterial( rwy_red_low_lights );
     m->add_name("RWY_RED_LOW_LIGHTS");
     matlib["RWY_RED_LOW_LIGHTS"] = m;
 
     // hard coded runway green light state
     if ( sprite_lighting ) {
-        tex_name = gen_standard_light_sprite( 20, 235, 20, 255 );
+      texture = gen_standard_light_sprite( 20, 235, 20, 255 );
     } else {
-        tex_name = gen_standard_dir_light_map( 20, 235, 20, 255 );
+      texture = gen_standard_dir_light_map( 20, 235, 20, 255 );
     }
-    ssgSimpleState *rwy_green_lights = new ssgSimpleState();
-    rwy_green_lights->disable( GL_LIGHTING );
-    rwy_green_lights->enable ( GL_CULL_FACE ) ;
-    rwy_green_lights->enable( GL_TEXTURE_2D );
-    rwy_green_lights->enable( GL_BLEND );
-    rwy_green_lights->enable( GL_ALPHA_TEST );
-    rwy_green_lights->enable( GL_COLOR_MATERIAL );
-    rwy_green_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
-    rwy_green_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
-    rwy_green_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
-    rwy_green_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
-    rwy_green_lights->setTexture( tex_name );
+    osg::StateSet *rwy_green_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
+    rwy_green_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
     m = new SGMaterial( rwy_green_lights );
     m->add_name("RWY_GREEN_LIGHTS");
     matlib["RWY_GREEN_LIGHTS"] = m;
 
     // hard coded medium intensity runway green light state
     if ( sprite_lighting ) {
-        tex_name = gen_standard_light_sprite( 20, 235, 20, 205 );
+      texture = gen_standard_light_sprite( 20, 235, 20, 205 );
     } else {
-        tex_name = gen_standard_dir_light_map( 20, 235, 20, 205 );
+      texture = gen_standard_dir_light_map( 20, 235, 20, 205 );
     }
-    ssgSimpleState *rwy_green_medium_lights = new ssgSimpleState();
-    rwy_green_medium_lights->disable( GL_LIGHTING );
-    rwy_green_medium_lights->enable ( GL_CULL_FACE ) ;
-    rwy_green_medium_lights->enable( GL_TEXTURE_2D );
-    rwy_green_medium_lights->enable( GL_BLEND );
-    rwy_green_medium_lights->enable( GL_ALPHA_TEST );
-    rwy_green_medium_lights->enable( GL_COLOR_MATERIAL );
-    rwy_green_medium_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
-    rwy_green_medium_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
-    rwy_green_medium_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
-    rwy_green_medium_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
-    rwy_green_medium_lights->setTexture( tex_name );
+    osg::StateSet *rwy_green_medium_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
+    rwy_green_medium_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
     m = new SGMaterial( rwy_green_medium_lights );
     m->add_name("RWY_GREEN_MEDIUM_LIGHTS");
     matlib["RWY_GREEN_MEDIUM_LIGHTS"] = m;
 
     // hard coded low intensity runway green light state
     if ( sprite_lighting ) {
-        tex_name = gen_standard_light_sprite( 20, 235, 20, 155 );
+      texture = gen_standard_light_sprite( 20, 235, 20, 155 );
     } else {
-        tex_name = gen_standard_dir_light_map( 20, 235, 20, 155 );
+      texture = gen_standard_dir_light_map( 20, 235, 20, 155 );
     }
-    ssgSimpleState *rwy_green_low_lights = new ssgSimpleState();
-    rwy_green_low_lights->disable( GL_LIGHTING );
-    rwy_green_low_lights->enable ( GL_CULL_FACE ) ;
-    rwy_green_low_lights->enable( GL_TEXTURE_2D );
-    rwy_green_low_lights->enable( GL_BLEND );
-    rwy_green_low_lights->enable( GL_ALPHA_TEST );
-    rwy_green_low_lights->enable( GL_COLOR_MATERIAL );
-    rwy_green_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
-    rwy_green_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
-    rwy_green_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
-    rwy_green_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
-    rwy_green_low_lights->setTexture( tex_name );
+    osg::StateSet *rwy_green_low_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
+    rwy_green_low_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
     m = new SGMaterial( rwy_green_low_lights );
     m->add_name("RWY_GREEN_LOW_LIGHTS");
     matlib["RWY_GREEN_LOW_LIGHTS"] = m;
@@ -545,45 +444,34 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
 
     // hard coded low intensity taxiway blue light state
     if ( sprite_lighting ) {
-        tex_name = gen_standard_light_sprite( 90, 90, 235, 205 );
+      texture = gen_standard_light_sprite( 90, 90, 235, 205 );
     } else {
-        tex_name = gen_taxiway_dir_light_map( 90, 90, 235, 205 );
+      texture = gen_taxiway_dir_light_map( 90, 90, 235, 205 );
     }
-    ssgSimpleState *taxiway_blue_low_lights = new ssgSimpleState();
-    taxiway_blue_low_lights->disable( GL_LIGHTING );
-    taxiway_blue_low_lights->enable ( GL_CULL_FACE ) ;
-    taxiway_blue_low_lights->enable( GL_TEXTURE_2D );
-    taxiway_blue_low_lights->enable( GL_BLEND );
-    taxiway_blue_low_lights->enable( GL_ALPHA_TEST );
-    taxiway_blue_low_lights->enable( GL_COLOR_MATERIAL );
-    taxiway_blue_low_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
-    taxiway_blue_low_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
-    taxiway_blue_low_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
-    taxiway_blue_low_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
-    taxiway_blue_low_lights->setTexture( tex_name );
+    osg::StateSet *taxiway_blue_low_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
+    taxiway_blue_low_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
     m = new SGMaterial( taxiway_blue_low_lights );
     m->add_name("RWY_BLUE_TAXIWAY_LIGHTS");
     matlib["RWY_BLUE_TAXIWAY_LIGHTS"] = m;
 
     // hard coded runway vasi light state
     if ( sprite_lighting ) {
-        tex_name = gen_standard_light_sprite( 235, 235, 195, 255 );
+      texture = gen_standard_light_sprite( 235, 235, 195, 255 );
     } else {
-        tex_name = gen_standard_dir_light_map( 235, 235, 195, 255 );
+      texture = gen_standard_dir_light_map( 235, 235, 195, 255 );
     }
-    ssgSimpleState *rwy_vasi_lights = new ssgSimpleState();
-    rwy_vasi_lights->disable( GL_LIGHTING );
-    rwy_vasi_lights->enable ( GL_CULL_FACE ) ;
-    rwy_vasi_lights->enable( GL_TEXTURE_2D );
-    rwy_vasi_lights->enable( GL_BLEND );
-    rwy_vasi_lights->enable( GL_ALPHA_TEST );
-    rwy_vasi_lights->enable( GL_COLOR_MATERIAL );
-    rwy_vasi_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
-    rwy_vasi_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
-    rwy_vasi_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
-    rwy_vasi_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
-    // rwy_vasi_lights->setTexture( gen_vasi_light_map_old() );
-    rwy_vasi_lights->setTexture( tex_name );
+    osg::StateSet *rwy_vasi_lights = static_cast<osg::StateSet*>(lightStateSet->clone(osg::CopyOp::DEEP_COPY_ALL));
+//     if (SGPointLightsDistanceAttenuation) {
+      point = new osg::Point;
+      point->setMinSize(4);
+      point->setSize(10);
+      point->setDistanceAttenuation(osg::Vec3(1.0, 0.01, 0.0001));
+      while (rwy_vasi_lights->getAttribute(osg::StateAttribute::POINT)) {
+        rwy_vasi_lights->removeAttribute(osg::StateAttribute::POINT);
+      }
+      rwy_vasi_lights->setAttribute(point);
+//     }
+    rwy_vasi_lights->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
     m = new SGMaterial( rwy_vasi_lights );
     m->add_name("RWY_VASI_LIGHTS");
     matlib["RWY_VASI_LIGHTS"] = m;
@@ -621,13 +509,13 @@ bool SGMaterialLib::add_item ( const string &mat_name, const string &full_path )
 
 
 // Load a library of material properties
-bool SGMaterialLib::add_item ( const string &mat_name, ssgSimpleState *state )
+bool SGMaterialLib::add_item ( const string &mat_name, osg::StateSet *state )
 {
     matlib[mat_name] = new SGMaterial( state );
     matlib[mat_name]->add_name(mat_name);
 
     SG_LOG( SG_TERRAIN, SG_INFO, "  Loading material given a premade "
-           << "ssgSimpleState = " << mat_name );
+           << "osg::StateSet = " << mat_name );
 
     return true;
 }
@@ -665,16 +553,17 @@ void SGMaterialLib::load_next_deferred() {
 }
 
 // Return the material from that given leaf
-const SGMaterial* SGMaterialLib::findMaterial(/*const*/ssgLeaf* leaf) const
+const SGMaterial* SGMaterialLib::findMaterial(const osg::Node* leaf) const
 {
   if (!leaf)
     return 0;
   
-  ssgBase* base = leaf->getUserData();
+  const osg::Referenced* base = leaf->getUserData();
   if (!base)
     return 0;
 
-  SGMaterialUserData* matUserData = dynamic_cast<SGMaterialUserData*>(base);
+  const SGMaterialUserData* matUserData
+    = dynamic_cast<const SGMaterialUserData*>(base);
   if (!matUserData)
     return 0;
 
index 057c42207a6b04e276fa9d5a632528fce7d21c7d..14a0a8d10bd04364729ca4cc0b33a7bd3e1d62fe 100644 (file)
@@ -37,8 +37,8 @@
 #include <map>                 // STL associative "array"
 #include <vector>              // STL "array"
 
-#include <plib/ssg.h>          // plib include
-
+#include <osg/Node>
+#include <osg/StateSet>
 
 class SGMaterial;
 
@@ -47,7 +47,6 @@ SG_USING_STD(map);
 SG_USING_STD(vector);
 SG_USING_STD(less);
 
-
 // Material management class
 class SGMaterialLib {
 
@@ -71,7 +70,7 @@ public:
     // Add the named texture with default properties
     bool add_item( const string &tex_path );
     bool add_item( const string &mat_name, const string &tex_path );
-    bool add_item( const string &mat_name, ssgSimpleState *state );
+    bool add_item( const string &mat_name, osg::StateSet *state );
 
     // find a material record by material name
     SGMaterial *find( const string& material );
@@ -87,7 +86,7 @@ public:
     material_map_iterator end() { return matlib.end(); }
     const_material_map_iterator end() const { return matlib.end(); }
 
-    const SGMaterial* findMaterial(/*const*/ssgLeaf* leaf) const;
+    const SGMaterial* findMaterial(const osg::Node* leaf) const;
 
     // Destructor
     ~SGMaterialLib ( void );
index 314f1403882dfb02acf0397ea8d4b4999f0a1566..789f29ee0867512f14590944b8ac5f86714292bb 100644 (file)
 #include <map>
 SG_USING_STD(map);
 
-#include <simgear/compiler.h>
+#include <osg/AlphaFunc>
+#include <osg/Group>
+#include <osg/LOD>
+#include <osg/StateSet>
+#include <osg/Transform>
 
 #ifdef SG_MATH_EXCEPTION_CLASH
 #  include <math.h>
@@ -120,22 +124,6 @@ SGMatModel::get_model_count( SGModelLib *modellib,
   return _models.size();
 }
 
-static void
-setAlphaClampToBranch( ssgBranch *b, float clamp )
-{
-  int nb = b->getNumKids();
-  for (int i = 0; i<nb; i++) {
-    ssgEntity *e = b->getKid(i);
-    if (e->isAKindOf(ssgTypeLeaf())) {
-      ssgSimpleState*s = (ssgSimpleState*)((ssgLeaf*)e)->getState();
-      s->enable( GL_ALPHA_TEST );
-      s->setAlphaClamp( clamp );
-    } else if (e->isAKindOf(ssgTypeBranch())) {
-      setAlphaClampToBranch( (ssgBranch*)e, clamp );
-    }
-  }
-}
-
 inline void
 SGMatModel::load_models ( SGModelLib *modellib,
                           const string &fg_root,
@@ -145,7 +133,7 @@ SGMatModel::load_models ( SGModelLib *modellib,
                                // Load model only on demand
   if (!_models_loaded) {
     for (unsigned int i = 0; i < _paths.size(); i++) {
-      ssgEntity *entity = modellib->load_model( fg_root, _paths[i],
+      osg::Node *entity = modellib->load_model( fg_root, _paths[i],
                                                 prop_root, sim_time_sec,
                                                 /*cache_object*/ true );
       if (entity != 0) {
@@ -153,23 +141,29 @@ SGMatModel::load_models ( SGModelLib *modellib,
                                 // in the XML wrapper as well (at least,
                                 // the billboarding should be handled
                                 // there).
-       float ranges[] = {0, _range_m};
-       ssgRangeSelector * lod = new ssgRangeSelector;
-        lod->setRanges(ranges, 2);
+        osg::LOD * lod = new osg::LOD;
+        lod->setName("Model LOD");
+        lod->setRangeMode(osg::LOD::DISTANCE_FROM_EYE_POINT);
+        lod->setRange(0, 0, _range_m);
        if (_heading_type == HEADING_BILLBOARD) {
           // if the model is a billboard, it is likely :
           // 1. a branch with only leaves,
           // 2. a tree or a non rectangular shape faked by transparency
           // We add alpha clamp then
-          if ( entity->isAKindOf(ssgTypeBranch()) ) {
-            ssgBranch *b = (ssgBranch *)entity;
-            setAlphaClampToBranch( b, 0.01f );
-          }
-         ssgCutout * cutout = new ssgCutout(false);
-         cutout->addKid(entity);
-         lod->addKid(cutout);
+          osg::StateSet* stateSet = entity->getOrCreateStateSet();
+          osg::AlphaFunc* alphaFunc =
+            new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.01f);
+          stateSet->setAttributeAndModes(alphaFunc,
+                                         osg::StateAttribute::OVERRIDE);
+          stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
+
+          osg::Transform* transform = new osg::Transform;
+          transform->setName("Model Billboard Transform");
+          transform->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
+         transform->addChild(entity);
+         lod->addChild(transform);
        } else {
-         lod->addKid(entity);
+         lod->addChild(entity);
        }
        _models.push_back(lod);
       } else {
@@ -180,7 +174,7 @@ SGMatModel::load_models ( SGModelLib *modellib,
   _models_loaded = true;
 }
 
-ssgEntity *
+osg::Node*
 SGMatModel::get_model( int index,
                        SGModelLib *modellib,
                        const string &fg_root,
@@ -188,10 +182,10 @@ SGMatModel::get_model( int index,
                        double sim_time_sec )
 {
   load_models( modellib, fg_root, prop_root, sim_time_sec ); // comment this out if preloading models
-  return _models[index];
+  return _models[index].get();
 }
 
-ssgEntity *
+osg::Node*
 SGMatModel::get_random_model( SGModelLib *modellib,
                               const string &fg_root,
                               SGPropertyNode *prop_root,
@@ -202,7 +196,7 @@ SGMatModel::get_random_model( SGModelLib *modellib,
   int index = int(sg_random() * nModels);
   if (index >= nModels)
     index = 0;
-  return _models[index];
+  return _models[index].get();
 }
 
 double
index 8802ad2b69498e01d59bf5f4d1e42ebc0b25b308..85363e80fe4140b0642ec63b3ff57d1c59dd820f 100644 (file)
 
 #include STL_STRING      // Standard C++ string library
 
-#include <plib/sg.h>
-#include <plib/ssg.h>
+#include <osg/ref_ptr>
+#include <osg/Node>
 
 #include <simgear/structure/SGReferenced.hxx>
 #include <simgear/structure/SGSharedPtr.hxx>
-#include <simgear/structure/ssgSharedPtr.hxx>
 #include <simgear/props/props.hxx>
 
 SG_USING_STD(string);
@@ -86,7 +85,7 @@ public:
      * @param index The index of the model.
      * @return The model.
      */
-    ssgEntity *get_model( int index,
+     osg::Node *get_model( int index,
                           SGModelLib *modellib,
                           const string &fg_root,
                           SGPropertyNode *prop_root,
@@ -98,7 +97,7 @@ public:
      *
      * @return A randomly select model from the variants.
      */
-    ssgEntity *get_random_model( SGModelLib *modellib,
+    osg::Node *get_random_model( SGModelLib *modellib,
                                  const string &fg_root,
                                  SGPropertyNode *prop_root,
                                  double sim_time_sec );
@@ -141,7 +140,7 @@ private:
                       double sim_time_sec );
 
     vector<string> _paths;
-    mutable vector<ssgSharedPtr<ssgEntity> > _models;
+    mutable vector<osg::ref_ptr<osg::Node> > _models;
     mutable bool _models_loaded;
     double _coverage_m2;
     double _range_m;
@@ -198,7 +197,6 @@ private:
 
     double _range_m;
     vector<SGSharedPtr<SGMatModel> > _objects;
-
 };
 
 
index acdd4716368e3f1d69698541906491d8ffe929f5..ac2b8e81449a649c9222a07a6b101f63e1982474 100644 (file)
@@ -6,19 +6,16 @@ noinst_HEADERS =
 
 include_HEADERS = \
        animation.hxx \
-       custtrans.hxx \
        location.hxx \
        model.hxx \
        modellib.hxx \
        personality.hxx \
        persparam.hxx \
        placement.hxx \
-       placementtrans.hxx \
-       shadowvolume.hxx
+       placementtrans.hxx
 
 libsgmodel_a_SOURCES = \
        animation.cxx \
-       custtrans.cxx \
        location.cxx \
        model.cxx \
        modellib.cxx \
@@ -26,7 +23,6 @@ libsgmodel_a_SOURCES = \
        persparam.cxx \
        placement.cxx \
        placementtrans.cxx \
-       shadowvolume.cxx \
        shadanim.cxx
 
 INCLUDES = -I$(top_srcdir)
index 36ae1e507284ffd07abe759bdb8c31ac9b288e3e..d99d846c7eaa89477b929036d7ceed45a4468227 100644 (file)
 #include <string.h>             // for strcmp()
 #include <math.h>
 
-#include <plib/sg.h>
-#include <plib/ssg.h>
-#include <plib/ul.h>
+#include <osg/AlphaFunc>
+#include <osg/AutoTransform>
+#include <osg/ColorMatrix>
+#include <osg/Drawable>
+#include <osg/Geode>
+#include <osg/LOD>
+#include <osg/MatrixTransform>
+#include <osg/StateSet>
+#include <osg/Switch>
+#include <osg/TexMat>
 
 #include <simgear/math/interpolater.hxx>
 #include <simgear/props/condition.hxx>
 #include <simgear/props/props.hxx>
 #include <simgear/math/sg_random.h>
+#include <simgear/scene/util/SGNodeMasks.hxx>
 
 #include "animation.hxx"
-#include "custtrans.hxx"
 #include "personality.hxx"
+#include "model.hxx"
 
 \f
 ////////////////////////////////////////////////////////////////////////
@@ -32,8 +40,8 @@
  * Set up the transform matrix for a spin or rotation.
  */
 static void
-set_rotation (sgMat4 &matrix, double position_deg,
-              sgVec3 &center, sgVec3 &axis)
+set_rotation (osg::Matrix &matrix, double position_deg,
+              const osg::Vec3 &center, 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<osg::LOD*>(_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<osg::LOD*>(_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<osg::AutoTransform*>(_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<osg::Switch*>(_branch)->setAllChildrenOn();
   else
-      ((ssgSelector *)_branch)->select(0x0000);
-  return 2;
+    static_cast<osg::Switch*>(_branch)->setAllChildrenOff();
+  traverse(node, nv);
 }
 
-
 \f
 ////////////////////////////////////////////////////////////////////////
 // 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<osg::MatrixTransform*>(_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<osg::Switch*>(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<osg::Switch*>(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<osg::Switch*>(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<osg::MatrixTransform*>(_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<osg::MatrixTransform*>(_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<osg::MatrixTransform*>(_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; i<nb; i++) {
-    ssgEntity *e = b->getKid(i);
-    if (e->isAKindOf(ssgTypeLeaf())) {
-      ssgSimpleState*s = (ssgSimpleState*)((ssgLeaf*)e)->getState();
-      s->enable( GL_ALPHA_TEST );
-      s->setAlphaClamp( clamp );
-    } else if (e->isAKindOf(ssgTypeBranch())) {
-      setAlphaClampToBranch( (ssgBranch*)e, clamp );
-    }
-  }
+  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<osg::StateSet*>(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<osg::StateSet*>(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<osg::Material*>(object);
+    materialList.push_back(material);
+    while (stateSet->getAttribute(osg::StateAttribute::MATERIAL)) {
+      stateSet->removeAttribute(osg::StateAttribute::MATERIAL);
+    }
+    stateSet->setAttribute(material);
+  }
+  std::vector<osg::Material*> 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<osg::Material*>::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<double>::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<double>::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
index abd4363b394bc37854f624bde950526b0cdf9a27..e2052b03394a3e4edb069725992509a2d165240a 100644 (file)
 #include <vector>
 #include <map>
 
-#include <plib/sg.h>
-#include <plib/ssg.h>
+#include <osg/Vec3>
+#include <osg/Vec4>
+
+#include <osg/ref_ptr>
+#include <osg/AlphaFunc>
+#include <osg/ColorMatrix>
+#include <osg/Group>
+#include <osg/Material>
+#include <osg/Node>
+#include <osg/NodeCallback>
+#include <osg/NodeVisitor>
+#include <osg/StateSet>
+#include <osg/Texture2D>
+#include <osg/TexMat>
 
-#include <simgear/math/point3d.hxx>
 #include <simgear/props/props.hxx>
 #include <simgear/misc/sg_path.hxx>
 
 #include <simgear/scene/model/persparam.hxx>
+#include <simgear/scene/util/SGNodeMasks.hxx>
 
 SG_USING_STD(vector);
 SG_USING_STD(map);
 
-
 // Don't pull in the headers, since we don't need them here.
 class SGInterpTable;
 class SGCondition;
 class SGPersonalityBranch;
 
-
 // Has anyone done anything *really* stupid, like making min and max macros?
 #ifdef min
 #undef min
@@ -50,7 +60,7 @@ class SGPersonalityBranch;
 /**
  * Abstract base class for all animations.
  */
-class SGAnimation :  public ssgBase
+class SGAnimation :  public osg::NodeCallback
 {
 public:
   enum PersonalityVar { INIT_SPIN, LAST_TIME_SEC_SPIN, FACTOR_SPIN, 
@@ -62,14 +72,14 @@ public:
                         INIT_SCALE, X_FACTOR_SCALE, Y_FACTOR_SCALE, Z_FACTOR_SCALE,
                             X_OFFSET_SCALE, Y_OFFSET_SCALE, Z_OFFSET_SCALE };
 
-  SGAnimation (SGPropertyNode_ptr props, ssgBranch * branch);
+  SGAnimation (SGPropertyNode_ptr props, osg::Group * branch);
 
   virtual ~SGAnimation ();
 
   /**
    * Get the SSG branch holding the animation.
    */
-  virtual ssgBranch * getBranch () { return _branch; }
+  virtual osg::Group * getBranch () { return _branch; }
 
   /**
    * Initialize the animation, after children have been added.
@@ -79,6 +89,14 @@ public:
   /**
    * Update the animation.
    */
+  virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
+  { 
+    // note, callback is responsible for scenegraph traversal so
+    // should always include call traverse(node,nv) to ensure 
+    // that the rest of cullbacks and the scene graph are traversed.
+    update();
+    traverse(node, nv);
+  }
   virtual int update();
 
   /**
@@ -104,7 +122,7 @@ protected:
 
   static double sim_time_sec;
 
-  ssgBranch * _branch;
+  osg::Group* _branch;
 
   int animation_type;
 };
@@ -162,7 +180,7 @@ public:
   SGSelectAnimation( SGPropertyNode *prop_root,
                    SGPropertyNode_ptr props );
   virtual ~SGSelectAnimation ();
-  virtual int update();
+  virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
 private:
   SGCondition * _condition;
 };
@@ -187,9 +205,8 @@ private:
   SGPersonalityParameter<double> _factor;
   SGPersonalityParameter<double> _position_deg;
   double _last_time_sec;
-  sgMat4 _matrix;
-  sgVec3 _center;
-  sgVec3 _axis;
+  osg::Vec3 _center;
+  osg::Vec3 _axis;
   SGCondition * _condition;
 };
 
@@ -209,7 +226,7 @@ private:
     double _duration_sec;
     double _last_time_sec;
     double _total_duration_sec;
-    int _step;
+    unsigned _step;
     struct DurationSpec {
         DurationSpec( double m = 0.0 ) : _min(m), _max(m) {}
         DurationSpec( double m1, double m2 ) : _min(m1), _max(m2) {}
@@ -241,9 +258,8 @@ private:
   bool _has_max;
   double _max_deg;
   double _position_deg;
-  sgMat4 _matrix;
-  sgVec3 _center;
-  sgVec3 _axis;
+  osg::Vec3 _center;
+  osg::Vec3 _axis;
   SGCondition * _condition;
 };
 
@@ -269,8 +285,7 @@ private:
   bool _has_max;
   double _max_m;
   double _position_m;
-  sgMat4 _matrix;
-  sgVec3 _axis;
+  osg::Vec3 _axis;
   SGCondition * _condition;
 };
 
@@ -295,6 +310,7 @@ private:
   double _min;
   bool _has_max;
   double _max;
+  osg::ref_ptr<osg::ColorMatrix> _colorMatrix;
 };
 
 /**
@@ -332,7 +348,6 @@ private:
   double _x_scale;
   double _y_scale;
   double _z_scale;
-  sgMat4 _matrix;
 };
 
 /**
@@ -356,10 +371,10 @@ private:
   bool _has_max;
   double _max_deg;
   double _position_deg;
-  sgMat4 _matrix;
-  sgVec3 _center;
-  sgVec3 _axis;
+  osg::Vec3 _center;
+  osg::Vec3 _axis;
   SGCondition * _condition;
+  osg::ref_ptr<osg::TexMat> _texMat;
 };
 
 
@@ -385,9 +400,9 @@ private:
   bool _has_max;
   double _max;
   double _position;
-  sgMat4 _matrix;
-  sgVec3 _axis;
+  osg::Vec3 _axis;
   SGCondition * _condition;
+  osg::ref_ptr<osg::TexMat> _texMat;
 };
 
 
@@ -419,13 +434,13 @@ private:
     bool has_max;
     double max;
     double position;
-    sgMat4 matrix;
-    sgVec3 center;
-    sgVec3 axis;
+    osg::Vec3 center;
+    osg::Vec3 axis;
   };
   SGPropertyNode_ptr _prop;
   TexTransform* _transform;
   int _num_transforms;
+  osg::ref_ptr<osg::TexMat> _texMat;
 };
 
 
@@ -439,7 +454,6 @@ public:
   virtual ~SGAlphaTestAnimation ();
   virtual void init();
 private:
-  void setAlphaClampToBranch(ssgBranch *b, float clamp);
   float _alpha_clamp;
 };
 
@@ -475,7 +489,7 @@ private:
         SGPropertyNode_ptr blue_prop;
         SGPropertyNode_ptr factor_prop;
         SGPropertyNode_ptr offset_prop;
-        sgVec4 v;
+        osg::Vec4 v;
         inline bool dirty() {
             return red >= 0.0 || green >= 0.0 || blue >= 0.0;
         }
@@ -487,7 +501,7 @@ private:
             return red != a.red || green != a.green || blue != a.blue
                     || factor != a.factor || offset != a.offset;
         }
-        sgVec4 &rgba() {
+        osg::Vec4 &rgba() {
             v[0] = clamp(red * factor + offset);
             v[1] = clamp(green * factor + offset);
             v[2] = clamp(blue * factor + offset);
@@ -520,8 +534,6 @@ private:
     SGPath _texture_base;
     SGPath _texture;
     string _texture_str;
-    ssgSimpleState* _cached_material;
-    ssgSimpleState* _cloned_material;
     unsigned _read;
     unsigned _update;
     unsigned _static_update;
@@ -538,9 +550,12 @@ private:
     SGPropertyNode_ptr _shi_prop;
     SGPropertyNode_ptr _thresh_prop;
     SGPropertyNode_ptr _tex_prop;
+    std::vector<osg::Material*> _materialList;
+    osg::ref_ptr<osg::AlphaFunc> _alphaFunc;
+    osg::ref_ptr<osg::Texture2D> _texture2D;
 
-    void cloneMaterials(ssgBranch *b);
-    void setMaterialBranch(ssgBranch *b);
+    void cloneMaterials(osg::Group *b);
+    void setMaterialBranch(osg::Group *b);
     void initColorGroup(SGPropertyNode_ptr, ColorSpec *, int flag);
     void updateColorGroup(ColorSpec *, int flag);
     inline float clamp(float val, float min = 0.0, float max = 1.0) {
@@ -561,14 +576,6 @@ class SGFlashAnimation : public SGAnimation
 public:
   SGFlashAnimation(SGPropertyNode_ptr props);
   virtual ~SGFlashAnimation ();
-
-  static void flashCallback( sgMat4 r, sgFrustum *f, sgMat4 m, void *d );
-  void flashCallback( sgMat4 r, sgFrustum *f, sgMat4 m );
-
-private:
-  sgVec3 _axis, _center;
-  float _power, _factor, _offset, _min_v, _max_v;
-  bool _two_sides;
 };
 
 
@@ -581,15 +588,6 @@ class SGDistScaleAnimation : public SGAnimation
 public:
   SGDistScaleAnimation(SGPropertyNode_ptr props);
   virtual ~SGDistScaleAnimation ();
-
-  static void distScaleCallback( sgMat4 r, sgFrustum *f, sgMat4 m, void *d );
-  void distScaleCallback( sgMat4 r, sgFrustum *f, sgMat4 m );
-
-private:
-  sgVec3 _center;
-  float _factor, _offset, _min_v, _max_v;
-  bool _has_min, _has_max;
-  SGInterpTable * _table;
 };
 
 /**
@@ -618,24 +616,25 @@ public:
                    SGPropertyNode_ptr props );
   virtual ~SGShaderAnimation ();
   virtual void init();
-  virtual int update();
+  virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
   bool get_condition_value(void);
 private:
   SGCondition * _condition;
   bool _condition_value;
   int _shader_type;
   float _param_1;
-  sgVec4 _param_color;
+  osg::Vec4 _param_color;
 public:
   bool _depth_test;
   float _factor;
   SGPropertyNode_ptr _factor_prop;
   float _speed;
+  float totalTime;
   SGPropertyNode_ptr _speed_prop;
-  ssgTexture *_effectTexture;
+  osg::ref_ptr<osg::Texture2D> _effectTexture;
   unsigned char *_textureData;
   GLint _texWidth, _texHeight;
-  sgVec4 _envColor;
+  osg::Vec4 _envColor;
 };
 
 
index 50df89853f4c400846fac7cbb02895c1ed91af6a..2b0da4a54be09a6b865aff7e02576e51b1f5f88f 100755 (executable)
@@ -5,8 +5,6 @@
 #ifndef _SG_CUSTOM_TRANSFORM_HXX
 #define _SG_CUSTOM_TRANSFORM_HXX 1
 
-#include "plib/ssg.h"
-
 class SGCustomTransform : public ssgBranch
 {
 public:
index 622e8fcd8c5025fff286c0aead8838dfaaa62891..613b459597ec9d1ee0f84cc9590ec7eaf96f5720 100644 (file)
@@ -9,12 +9,22 @@
 
 #include <string.h>             // for strcmp()
 
-#include <vector>
-#include <set>
-
-#include <plib/sg.h>
-#include <plib/ssg.h>
-#include <plib/ul.h>
+#include <osg/observer_ptr>
+#include <osg/ref_ptr>
+#include <osg/Group>
+#include <osg/NodeCallback>
+#include <osg/Switch>
+#include <osg/MatrixTransform>
+#include <osgDB/Archive>
+#include <osgDB/FileNameUtils>
+#include <osgDB/FileUtils>
+#include <osgDB/ReadFile>
+#include <osgDB/Registry>
+#include <osgDB/SharedStateManager>
+#include <osgUtil/Optimizer>
+
+#include <simgear/scene/util/SGStateAttributeVisitor.hxx>
+#include <simgear/scene/util/SGTextureStateAttributeVisitor.hxx>
 
 #include <simgear/structure/exception.hxx>
 #include <simgear/props/props.hxx>
 SG_USING_STD(vector);
 SG_USING_STD(set);
 
-bool sgUseDisplayList = true;
-\f
-////////////////////////////////////////////////////////////////////////
-// Global state
-////////////////////////////////////////////////////////////////////////
-static bool
-model_filter = true;
-
-\f
-////////////////////////////////////////////////////////////////////////
-// 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<osg::Referenced> 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<osg::Texture2D*>(refAttr.first.get());
+    if (!texture)
+      return;
+    
+    osg::Image* image = texture->getImage(0);
+    if (!image)
+      return;
+
+    int s = image->s();
+    int t = image->t();
+
+    int mipmaplevels = 0;
+    if (s < t) {
+      mipmaplevels = nMipMaps(s);
+    } else {
+      mipmaplevels = nMipMaps(t);
+    }
+    texture->setNumMipmapLevels(mipmaplevels);
+
+    if (s <= t && 32 <= s) {
+      texture->setInternalFormatMode(mFormatMode);
+    } else if (t < s && 32 <= t) {
+      texture->setInternalFormatMode(mFormatMode);
+    }
+  }
+
 private:
-  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<osg::Material*>(refAttr.first.get());
+    if (!material)
+      return;
+    material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
+  }
+};
 
+class SGReadFileCallback :
+  public osgDB::Registry::ReadFileCallback {
+public:
+  virtual osgDB::ReaderWriter::ReadResult
+  readImage(const std::string& fileName, const osgDB::ReaderWriter::Options* opt)
+  {
+    std::string absFileName = osgDB::findDataFile(fileName);
+    if (!osgDB::fileExists(absFileName)) {
+      SG_LOG(SG_IO, SG_ALERT, "Cannot find image file \""
+             << fileName << "\"");
+      return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND;
+    }
 
-/**
- * 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<osg::Group> root = new osg::Group;
+        osg::MatrixTransform* transform = new osg::MatrixTransform;
+        root->addChild(transform);
+        
+        transform->setDataVariance(osg::Object::STATIC);
+        transform->setMatrix(m);
+        transform->addChild(res.getNode());
+        
+        res = osgDB::ReaderWriter::ReadResult(0);
+        
+        osgUtil::Optimizer optimizer;
+        unsigned opts = osgUtil::Optimizer::FLATTEN_STATIC_TRANSFORMS;
+        optimizer.optimize(root.get(), opts);
+        
+        // Ok, this step is questionable.
+        // It is there to have the same visual appearance of ac objects for the
+        // first cut. Osg's ac3d loader will correctly set materials from the
+        // ac file. But the old plib loader used GL_AMBIENT_AND_DIFFUSE for the
+        // materials that in effect igored the ambient part specified in the
+        // file. We emulate that for the first cut here by changing all ac models
+        // here. But in the long term we should use the unchanged model and fix
+        // the input files instead ...
+        SGAcMaterialCrippleVisitor matCriple;
+        root->accept(matCriple);
+        
+        res = osgDB::ReaderWriter::ReadResult(root.get());
+      }
+      
+      osgUtil::Optimizer optimizer;
+      unsigned opts = 0;
+      // Don't use this one. It will break animation names ...
+      // opts |= osgUtil::Optimizer::REMOVE_REDUNDANT_NODES;
+      
+      // opts |= osgUtil::Optimizer::REMOVE_LOADED_PROXY_NODES;
+      // opts |= osgUtil::Optimizer::COMBINE_ADJACENT_LODS;
+      // opts |= osgUtil::Optimizer::SHARE_DUPLICATE_STATE;
+      opts |= osgUtil::Optimizer::MERGE_GEOMETRY;
+      // opts |= osgUtil::Optimizer::CHECK_GEOMETRY;
+      // opts |= osgUtil::Optimizer::SPATIALIZE_GROUPS;
+      // opts |= osgUtil::Optimizer::COPY_SHARED_NODES;
+      opts |= osgUtil::Optimizer::TRISTRIP_GEOMETRY;
+      // opts |= osgUtil::Optimizer::TESSELATE_GEOMETRY;
+      // opts |= osgUtil::Optimizer::OPTIMIZE_TEXTURE_SETTINGS;
+      optimizer.optimize(res.getNode(), opts);
+
+      // OSGFIXME
+      registry->getSharedStateManager()->share(res.getNode());
+      
+      // OSGFIXME: guard that with a flag
+      // OSGFIXME: in the long term it is unclear if we have an OpenGL context here...
+      osg::Texture::Extensions* e = osg::Texture::getExtensions(0, true);
+      if (e->isTextureCompressionARBSupported()) {
+        SGTexCompressionVisitor texComp(osg::Texture::USE_ARB_COMPRESSION);
+        res.getNode()->accept(texComp);
+      } else if (e->isTextureCompressionS3TCSupported()) {
+        SGTexCompressionVisitor texComp(osg::Texture::USE_S3TC_DXT5_COMPRESSION);
+        res.getNode()->accept(texComp);
+      }
+    }
+
+    // Add an extra reference to the model stored in the database.
+    // That it to avoid expiring the object from the cache even if it is still
+    // in use. Note that the object cache will think that a model is unused if the
+    // reference count is 1. If we clone all structural nodes here we need that extra
+    // reference to the original object
+    SGDatabaseReference* databaseReference = new SGDatabaseReference(res.getNode());
+    osg::CopyOp::CopyFlags flags = osg::CopyOp::DEEP_COPY_ALL;
+    flags &= ~osg::CopyOp::DEEP_COPY_TEXTURES;
+    flags &= ~osg::CopyOp::DEEP_COPY_IMAGES;
+    flags &= ~osg::CopyOp::DEEP_COPY_ARRAYS;
+    flags &= ~osg::CopyOp::DEEP_COPY_PRIMITIVES;
+    // This will safe display lists ...
+    flags &= ~osg::CopyOp::DEEP_COPY_DRAWABLES;
+    flags &= ~osg::CopyOp::DEEP_COPY_SHAPES;
+    res = osgDB::ReaderWriter::ReadResult(osg::CopyOp(flags)(res.getNode()));
+    res.getNode()->addObserver(databaseReference);
+
+    return res;
+  }
+};
+
+class SGReadCallbackInstaller {
+public:
+  SGReadCallbackInstaller()
+  {
+    osg::Referenced::setThreadSafeReferenceCounting(true);
+
+    osgDB::Registry* registry = osgDB::Registry::instance();
+    osgDB::ReaderWriter::Options* options = new osgDB::ReaderWriter::Options;
+    options->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_ALL);
+    registry->setOptions(options);
+    registry->getOrCreateSharedStateManager()->setShareMode(osgDB::SharedStateManager::SHARE_TEXTURES);
+    registry->setReadFileCallback(new SGReadFileCallback);
+  }
+};
+
+static SGReadCallbackInstaller readCallbackInstaller;
+
+osg::Texture2D*
+SGLoadTexture2D(const std::string& path, bool wrapu, bool wrapv,
+                int mipmaplevels)
 {
-  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<osg::Switch*>(node));
+    osg::Switch* s = static_cast<osg::Switch*>(node);
+
+    if (mCondition && mCondition->test()) {
+      s->setAllChildrenOn();
+      // note, callback is responsible for scenegraph traversal so
+      // should always include call traverse(node,nv) to ensure 
+      // that the rest of cullbacks and the scene graph are traversed.
+      traverse(node, nv);
+    } else
+      s->setAllChildrenOff();
+  }
+
+private:
+  SGCondition* mCondition;
+};
+
 /**
- * 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<SGPropertyNode_ptr> &name_nodes,
                  SGPropertyNode *prop_root,
                  SGPropertyNode_ptr node,
                  double sim_time_sec,
                  SGPath &texture_path,
-                 set<ssgBranch *> &ignore_branches )
+                 set<osg::Node*> &ignore_branches )
 {
   bool ignore = false;
   SGAnimation * animation = 0;
@@ -191,14 +442,16 @@ sgMakeAnimation( ssgBranch * model,
   }
 
   if (name != 0)
-      animation->setName((char *)name);
-
-  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<ssgBranch *> &ignore )
-{
-  int nb = b->getNumKids();
-  for (int i = 0; i<nb; i++) {
-    ssgEntity *e = b->getKid(i);
-    if (e->isAKindOf(ssgTypeLeaf())) {
-     if( ((ssgLeaf*)e)->getNumVertices() > 0)
-      ((ssgLeaf*)e)->makeDList();
-    } else if (e->isAKindOf(ssgTypeBranch()) && ignore.find((ssgBranch *)e) == ignore.end()) {
-      makeDList( (ssgBranch*)e, ignore );
-    }
-  }
-}
-
-class SGLoaderOptions : public ssgLoaderOptions {
-public:
-  SGLoaderOptions() { ssgSetCurrentOptions( this ); } // Install our own loader options at startup
-  void endLoad() {} // Avoid clearing the texture cache after every model load
-};
-
-static SGLoaderOptions loaderOptions;
-
 \f
 ////////////////////////////////////////////////////////////////////////
 // Global functions.
 ////////////////////////////////////////////////////////////////////////
 
-ssgBranch *
+osg::Node *
 sgLoad3DModel( const string &fg_root, const string &path,
                SGPropertyNode *prop_root,
-               double sim_time_sec, ssgEntity *(*load_panel)(SGPropertyNode *),
-               SGModelData *data )
+               double sim_time_sec, osg::Node *(*load_panel)(SGPropertyNode *),
+               SGModelData *data,
+               const SGPath& externalTexturePath )
 {
-  ssgBranch * model = 0;
+  osg::Switch* model = 0;
   SGPropertyNode props;
 
                                 // Load the 3D aircraft object itself
@@ -294,36 +525,48 @@ sgLoad3DModel( const string &fg_root, const string &path,
       }
     } else {
       if (model == 0)
-        model = new ssgBranch;
+        model = new osg::Switch;
     }
   }
 
+  osgDB::FilePathList pathList = osgDB::getDataFilePathList();
+  osgDB::Registry::instance()->initFilePathLists();
+
                                 // Assume that textures are in
                                 // the same location as the XML file.
   if (model == 0) {
     if (texturepath.extension() != "")
           texturepath = texturepath.dir();
 
-    ssgTexturePath((char *)texturepath.c_str());
-    model = (ssgBranch *)ssgLoad((char *)modelpath.c_str());
-    if (model == 0)
+    osgDB::Registry::instance()->getDataFilePathList().push_front(texturepath.str());
+
+    osg::Node* node = osgDB::readNodeFile(modelpath.str());
+    if (node == 0)
       throw sg_io_exception("Failed to load 3D model", 
-                         sg_location(modelpath.str()));
+                            sg_location(modelpath.str()));
+    model = new osg::Switch;
+    model->addChild(node, true);
   }
+
+  osgDB::Registry::instance()->getDataFilePathList().push_front(externalTexturePath.str());
+
                                 // Set up the alignment node
-  ssgTransform * alignmainmodel = new ssgTransform;
-  if ( load_panel == 0 )
-    alignmainmodel->setTravCallback( SSG_CALLBACK_PRETRAV, model_filter_callback );
-  alignmainmodel->addKid(model);
-  sgMat4 res_matrix;
-  sgMakeOffsetsMatrix(&res_matrix,
-                      props.getFloatValue("/offsets/heading-deg", 0.0),
-                      props.getFloatValue("/offsets/roll-deg", 0.0),
-                      props.getFloatValue("/offsets/pitch-deg", 0.0),
-                      props.getFloatValue("/offsets/x-m", 0.0),
-                      props.getFloatValue("/offsets/y-m", 0.0),
-                      props.getFloatValue("/offsets/z-m", 0.0));
-  alignmainmodel->setTransform(res_matrix);
+  osg::MatrixTransform* alignmainmodel = new osg::MatrixTransform;
+  alignmainmodel->addChild(model);
+  osg::Matrix res_matrix;
+  res_matrix.makeRotate(
+    props.getFloatValue("/offsets/heading-deg", 0.0)*SG_DEGREES_TO_RADIANS,
+    osg::Vec3(0, 0, 1),
+    props.getFloatValue("/offsets/roll-deg", 0.0)*SG_DEGREES_TO_RADIANS,
+    osg::Vec3(1, 0, 0),
+    props.getFloatValue("/offsets/pitch-deg", 0.0)*SG_DEGREES_TO_RADIANS,
+    osg::Vec3(0, 1, 0));
+
+  osg::Matrix tmat;
+  tmat.makeTranslate(props.getFloatValue("/offsets/x-m", 0.0),
+                     props.getFloatValue("/offsets/y-m", 0.0),
+                     props.getFloatValue("/offsets/z-m", 0.0));
+  alignmainmodel->setMatrix(res_matrix*tmat);
 
   unsigned int i;
 
@@ -331,18 +574,23 @@ sgLoad3DModel( const string &fg_root, const string &path,
   vector<SGPropertyNode_ptr> model_nodes = props.getChildren("model");
   for (i = 0; i < model_nodes.size(); i++) {
     SGPropertyNode_ptr node = model_nodes[i];
-    ssgTransform * align = new ssgTransform;
-    sgMat4 res_matrix;
-    sgMakeOffsetsMatrix(&res_matrix,
-                        node->getFloatValue("offsets/heading-deg", 0.0),
-                        node->getFloatValue("offsets/roll-deg", 0.0),
-                        node->getFloatValue("offsets/pitch-deg", 0.0),
-                        node->getFloatValue("offsets/x-m", 0.0),
-                        node->getFloatValue("offsets/y-m", 0.0),
-                        node->getFloatValue("offsets/z-m", 0.0));
-    align->setTransform(res_matrix);
-
-    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<SGPropertyNode_ptr> panel_nodes = props.getChildren("panel");
     for (i = 0; i < panel_nodes.size(); i++) {
         SG_LOG(SG_INPUT, SG_DEBUG, "Loading a panel");
-        ssgEntity * panel = load_panel(panel_nodes[i]);
+        osg::Node * panel = load_panel(panel_nodes[i]);
         if (panel_nodes[i]->hasValue("name"))
             panel->setName((char *)panel_nodes[i]->getStringValue("name"));
-        model->addKid(panel);
+        model->addChild(panel);
     }
   }
 
@@ -380,7 +629,7 @@ sgLoad3DModel( const string &fg_root, const string &path,
     data->modelLoaded(path, &props, alignmainmodel);
   }
                                 // Load animations
-  set<ssgBranch *> ignore_branches;
+  set<osg::Node*> ignore_branches;
   vector<SGPropertyNode_ptr> animation_nodes = props.getChildren("animation");
   for (i = 0; i < animation_nodes.size(); i++) {
     const char * name = animation_nodes[i]->getStringValue("name", 0);
@@ -390,31 +639,7 @@ sgLoad3DModel( const string &fg_root, const string &path,
                      sim_time_sec, texturepath, ignore_branches);
   }
 
-#if PLIB_VERSION > 183
-  if ( model != 0 && sgUseDisplayList ) {
-     makeDList( model, ignore_branches );
-  }
-#endif
-
-  int m = props.getIntValue("dump", 0);
-  if (m > 0)
-    model->print(stderr, "", m - 1);
-
   return alignmainmodel;
 }
 
-bool
-sgSetModelFilter( bool filter )
-{
-  bool old = model_filter;
-  model_filter = filter;
-  return old;
-}
-
-bool 
-sgCheckAnimationBranch (ssgEntity * entity)
-{
-    return entity->getTravCallback(SSG_CALLBACK_PRETRAV) == animation_callback;
-}
-
 // end of model.cxx
index 5d64a5d8add39daa9740e95e217104810d6b87e2..29306f0501378a52714ef474303e010ff0c11927 100644 (file)
@@ -18,8 +18,8 @@
 SG_USING_STD(vector);
 SG_USING_STD(set);
 
-#include <plib/sg.h>
-#include <plib/ssg.h>
+#include <osg/Node>
+#include <osg/Texture2D>
 
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/props/props.hxx>
@@ -39,11 +39,11 @@ SG_USING_STD(set);
  * called by sgLoad3DModel() after the model was loaded, and the destructor
  * when the branch is removed from the graph.
  */
-class SGModelData : public ssgBase {
+class SGModelData : public osg::Referenced {
 public:
     virtual ~SGModelData() {}
     virtual void modelLoaded( const string& path, SGPropertyNode *prop,
-                              ssgBranch *branch) {}
+                              osg::Node*branch) = 0;
 };
 
 
@@ -59,48 +59,37 @@ public:
  * Subsystems should not normally invoke this function directly;
  * instead, they should use the FGModelLoader declared in loader.hxx.
  */
-ssgBranch *
+osg::Node*
 sgLoad3DModel( const string& fg_root, const string &path,
-                          SGPropertyNode *prop_root, double sim_time_sec,
-                          ssgEntity *(*load_panel)(SGPropertyNode *) = 0,
-                          SGModelData *data = 0 );
+               SGPropertyNode *prop_root, double sim_time_sec,
+               osg::Node *(*load_panel)(SGPropertyNode *) = 0,
+               SGModelData *data = 0,
+               const SGPath& texturePath = SGPath() );
 
 
-/**
- * Make an offset matrix from rotations and position offset.
- */
-void
-sgMakeOffsetsMatrix( sgMat4 * result, double h_rot, double p_rot, double r_rot,
-                     double x_off, double y_off, double z_off );
-
 /**
  * Make the animation
  */
 void
-sgMakeAnimation( ssgBranch * model,
+sgMakeAnimation( osg::Node* model,
                  const char * name,
                  vector<SGPropertyNode_ptr> &name_nodes,
                  SGPropertyNode *prop_root,
                  SGPropertyNode_ptr node,
                  double sim_time_sec,
                  SGPath &texture_path,
-                 set<ssgBranch *> &ignore_branches );
+                 set<osg::Node*> &ignore_branches );
 
-/**
- * Set the filter state on models
- */
-bool
-sgSetModelFilter( bool filter );
 
-/**
- * Check if the ssg node contains an animation
- */
-bool 
-sgCheckAnimationBranch (ssgEntity * entity);
+osg::Texture2D*
+SGLoadTexture2D(const std::string& path, bool wrapu = true,
+                bool wrapv = true, int mipmaplevels = -1);
 
-/**
- * Enable or disable Display list usage
- */
-extern bool sgUseDisplayList;
+inline osg::Texture2D*
+SGLoadTexture2D(const SGPath& path, bool wrapu = true, bool wrapv = true,
+                int mipmaplevels = -1)
+{
+  return SGLoadTexture2D(path.str(), wrapu, wrapv, mipmaplevels);
+}
 
 #endif // __MODEL_HXX
index f5f15784c299ce434736f0600096c97f3a8a7adc..46c091541f142e1cad58a35059e5de2f3fe0bf6b 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <simgear/compiler.h>
 #include <simgear/props/props.hxx>
+#include <simgear/scene/util/SGNodeMasks.hxx>
 
 #include "model.hxx"
 #include "animation.hxx"
@@ -48,11 +49,11 @@ SGModelLib::flush1()
 
     return;
 
-    map<string, ssgSharedPtr<ssgEntity> >::iterator it = _table.begin();
+    map<string, osg::ref_ptr<osg::Node> >::iterator it = _table.begin();
     while (it != _table.end()) {
                                 // If there is only one reference, it's
                                 // ours; no one else is using the item.
-        if (!it->second.isShared()) {
+        if (it->second->referenceCount() <= 1) {
             string key = it->first;
             _table.erase(it);
             it = _table.upper_bound(key);
@@ -61,7 +62,7 @@ SGModelLib::flush1()
     }
 }
 
-ssgEntity *
+osg::Node*
 SGModelLib::load_model( const string &fg_root,
                            const string &path,
                            SGPropertyNode *prop_root,
@@ -69,21 +70,24 @@ SGModelLib::load_model( const string &fg_root,
                            bool cache_object,
                            SGModelData *data )
 {
-    ssgBranch *personality_branch = new SGPersonalityBranch;
+    osg::Group *personality_branch = new SGPersonalityBranch;
+    personality_branch->setName("Model Personality Group");
 
                                 // FIXME: normalize path to
                                 // avoid duplicates.
-    map<string, ssgSharedPtr<ssgEntity> >::iterator it = _table.find(path);
+    map<string, osg::ref_ptr<osg::Node> >::iterator it = _table.find(path);
     if (!cache_object || it == _table.end()) {
-        ssgSharedPtr<ssgEntity> model = sgLoad3DModel(fg_root, path, prop_root,
+        osg::ref_ptr<osg::Node> model = sgLoad3DModel(fg_root, path, prop_root,
                                                       sim_time_sec, 0, data );
+        model->setName("Loaded model node");
         if (cache_object)
             _table[path] = model;      // add one reference to keep it around
 
-        personality_branch->addKid( model );
+        personality_branch->addChild( model.get() );
     } else {
-        personality_branch->addKid( it->second );
+        personality_branch->addChild( it->second.get() );
     }
+
     return personality_branch;
 }
 
index 73866f206fe5460b589bcb7a13e3ac758b338659..3842a73fd619574e2d54b80f39a373bd2f06a3d7 100644 (file)
@@ -12,9 +12,9 @@
 #include <map>
 #include STL_STRING
 
-#include <plib/ssg.h>
+#include <osg/ref_ptr>
+#include <osg/Node>
 
-#include <simgear/structure/ssgSharedPtr.hxx>
 #include <simgear/props/props.hxx>
 #include "model.hxx"
 
@@ -34,7 +34,7 @@ public:
     virtual ~SGModelLib ();
     virtual void flush1();
 
-    virtual ssgEntity *load_model( const string &fg_root,
+    virtual osg::Node *load_model( const string &fg_root,
                                    const string &path,
                                    SGPropertyNode *prop_root,
                                    double sim_time_sec,
@@ -42,7 +42,7 @@ public:
                                    SGModelData *data = 0 );
 protected:
 
-    map<string,ssgSharedPtr<ssgEntity> > _table;
+    map<string, osg::ref_ptr<osg::Node> > _table;
 };
 
 
index 60b8a987cf7bfa0c2f57cb97e22d4877aa9b7983..c6a6d1767898cc499831db7c1875728ccdc953c9 100755 (executable)
@@ -9,26 +9,20 @@
 #include "personality.hxx"
 #include "animation.hxx"
 
-static int
-personality_pretrav_callback(ssgEntity * entity, int mask)
+class SGPersonalityBranchCallback :  public osg::NodeCallback
 {
-    ((SGPersonalityBranch *)entity)->_old_current = SGAnimation::current_object;
-    SGAnimation::current_object = (SGPersonalityBranch *)entity;
-    return 1;
-}
-
-static int
-personality_posttrav_callback(ssgEntity * entity, int mask)
-{
-    SGAnimation::current_object = ((SGPersonalityBranch *)entity)->_old_current;
-    ((SGPersonalityBranch *)entity)->_old_current = 0;
-    return 1;
-}
+  virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
+  { 
+    SGPersonalityBranch* old_current = SGAnimation::current_object;
+    SGAnimation::current_object = static_cast<SGPersonalityBranch*>(node);
+    traverse(node, nv);
+    SGAnimation::current_object = old_current;
+  }
+};
 
 SGPersonalityBranch::SGPersonalityBranch()
 {
-    setTravCallback(SSG_CALLBACK_PRETRAV, personality_pretrav_callback);
-    setTravCallback(SSG_CALLBACK_POSTTRAV, personality_posttrav_callback);
+  setUpdateCallback(new SGPersonalityBranchCallback);
 }
 
 void SGPersonalityBranch::setDoubleValue( double value, SGAnimation *anim, int var_id, int var_num )
index 6a314e7cd433fb224b50a71a9917494ae4a3c641..fc48088e4ba5e5ddb7c9de583fd5418917882044 100755 (executable)
@@ -6,7 +6,7 @@
 #define _SG_PERSONALITY_HXX 1
 
 #include <simgear/compiler.h>
-#include <plib/ssg.h>
+#include <osg/Group>
 
 #include <map>
 
@@ -14,7 +14,8 @@ SG_USING_STD(map);
 
 class SGAnimation;
 
-class SGPersonalityBranch : public ssgBranch {
+// OSGFIXME avoid personality with cloning the structural trees.
+class SGPersonalityBranch : public osg::Group {
 public:
     SGPersonalityBranch();
     void setDoubleValue( double value, SGAnimation *anim, int var_id, int var_num = 0 );
@@ -22,8 +23,6 @@ public:
     double getDoubleValue( SGAnimation *anim, int var_id, int var_num = 0 ) const;
     int getIntValue( SGAnimation *anim, int var_id, int var_num = 0 ) const;
 
-    SGPersonalityBranch *_old_current;
-
 private:
     struct Key {
         Key( SGAnimation *a, int i, int n = 0 ) : anim(a), var_id(i), var_num(n) {}
index 75f3fb842cd2d8757b0b6e0220201fdc32ccc531..64ce3dad32dc197516ca41efd74ecae8d1c137c7 100644 (file)
@@ -11,8 +11,6 @@
 
 #include <string.h>             // for strcmp()
 
-#include <plib/sg.h>
-#include <plib/ssg.h>
 #include <plib/ul.h>
 
 #include "location.hxx"
@@ -33,8 +31,8 @@ SGModelPlacement::SGModelPlacement ()
     _roll_deg(0),
     _pitch_deg(0),
     _heading_deg(0),
-    _selector(new ssgSelector),
-    _position(new ssgPlacementTransform),
+    _selector(new osg::Switch),
+    _position(new SGPlacementTransform),
     _location(new SGLocation)
 {
 }
@@ -45,13 +43,14 @@ SGModelPlacement::~SGModelPlacement ()
 }
 
 void
-SGModelPlacement::init( ssgBranch * model )
+SGModelPlacement::init( osg::Node * model )
 {
   if (model != 0) {
-      _position->addKid(model);
+      _position->addChild(model);
   }
-  _selector->addKid(_position);
-  _selector->clrTraversalMaskBits(SSGTRAV_HOT);
+  _selector->addChild(_position.get());
+//   _selector->setNodeMask(_selector->getNodeMask() & ~SG_HOT_TRAVERSAL_BIT);
+  _selector->setValue(0, 1);
 }
 
 void
@@ -60,21 +59,25 @@ SGModelPlacement::update()
   _location->setPosition( _lon_deg, _lat_deg, _elev_ft );
   _location->setOrientation( _roll_deg, _pitch_deg, _heading_deg );
 
-  sgMat4 rotation;
-  sgCopyMat4( rotation, _location->getTransformMatrix() );
-  _position->setTransform(_location->get_absolute_view_pos(), rotation);
+  const sgVec4 *t = _location->getTransformMatrix();
+  SGMatrixd rotation;
+  for (unsigned i = 0; i < 4; ++i)
+    for (unsigned j = 0; j < 4; ++j)
+      rotation(i, j) = t[j][i];
+  SGVec3d pos(_location->get_absolute_view_pos());
+  _position->setTransform(pos, rotation);
 }
 
 bool
 SGModelPlacement::getVisible () const
 {
-  return (_selector->getSelect() != 0);
+  return _selector->getValue(0);
 }
 
 void
 SGModelPlacement::setVisible (bool visible)
 {
-  _selector->select(visible);
+  _selector->setValue(0, visible);
 }
 
 void
index 962139ea068eb06d9f77c1c0d4d3ce4dbe8ee492..ace50b8495f4f3dec45dab96f4bd80d4a7189dde 100644 (file)
 # error This library requires C++
 #endif
 
-#include <plib/sg.h>
-#include <plib/ssg.h>
+#include <osg/ref_ptr>
+#include <osg/Node>
+#include <osg/Switch>
 
-#include <simgear/math/point3d.hxx>
 #include <simgear/props/props.hxx>
-#include <simgear/structure/ssgSharedPtr.hxx>
 
+#include "placementtrans.hxx"
 
 // Don't pull in the headers, since we don't need them here.
 class SGLocation;
-class ssgPlacementTransform;
 
 
 // Has anyone done anything *really* stupid, like making min and max macros?
@@ -47,11 +46,11 @@ public:
   SGModelPlacement ();
   virtual ~SGModelPlacement ();
 
-  virtual void init( ssgBranch * model );
+  virtual void init( osg::Node* model );
 
   virtual void update();
 
-  virtual ssgEntity * getSceneGraph () { return (ssgEntity *)_selector; }
+  virtual osg::Node* getSceneGraph () { return _selector.get(); }
 
   virtual SGLocation * getSGLocation () { return _location; }
 
@@ -79,8 +78,8 @@ public:
                                double heading_deg);
   void setOrientation(const SGQuatd& orientation);
   
-  ssgPlacementTransform * getTransform(void)
-  { return _position; }
+  SGPlacementTransform * getTransform(void)
+  { return _position.get(); }
 
 private:
 
@@ -94,8 +93,8 @@ private:
   double _pitch_deg;
   double _heading_deg;
 
-  ssgSharedPtr<ssgSelector> _selector;
-  ssgSharedPtr<ssgPlacementTransform> _position;
+  osg::ref_ptr<osg::Switch> _selector;
+  osg::ref_ptr<SGPlacementTransform> _position;
 
                                 // Location
   SGLocation * _location;
index 34636d2e208cc1715fc2319bc1a0fb1ac95e698d..34a7f21567b4d8c359f2f5b193254e0f6fb9933b 100644 (file)
 #include <simgear/compiler.h>
 #include <simgear/constants.h>
 
-#include <plib/sg.h>
-#include <plib/ssg.h>
-
 #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;
 }
index d5765c4a54a920ac009ecbefc89324dfb3b33447..c72fbaba6e92082e61c07aad0e9e979723c80673 100644 (file)
 
 #include <simgear/compiler.h>
 #include <simgear/constants.h>
+#include <simgear/math/SGMath.hxx>
 
-#include <plib/sg.h>
-#include <plib/ssg.h>
+#include <osg/Transform>
 
-class ssgPlacementTransform : public ssgTransform
+class SGPlacementTransform : public osg::Transform
 {
 public:
   
-  ssgPlacementTransform(void);
-  virtual ~ssgPlacementTransform(void);
+  SGPlacementTransform(void);
+  virtual ~SGPlacementTransform(void);
 
-//   using ssgTransform::addKid(ssgEntity*);
-
-  virtual ssgBase *clone(int clone_flags);
-protected:
-  void copy_from(ssgPlacementTransform *src, int clone_flags);
-
-private:
-//   virtual void setTransform(sgVec3 xyz);
-//   virtual void setTransform(sgCoord *xform);
-//   virtual void setTransform(sgCoord *xform, float sx, float sy, float sz);
-//   virtual void setTransform(sgMat4 xform);
 public:
 
-  void setTransform(sgdVec3 off);
-  void setTransform(sgdVec3 off, sgMat4 rot);
-  void setSceneryCenter(sgdVec3 xyz);
+  void setTransform(const SGVec3d& off)
+  { _placement_offset = off; dirtyBound(); }
+  void setTransform(const SGVec3d& off, const SGMatrixd& rot)
+  { _placement_offset = off; _rotation = rot; dirtyBound(); }
+  void setSceneryCenter(const SGVec3d& center)
+  { _scenery_center = center; dirtyBound(); }
+
+  virtual bool computeLocalToWorldMatrix(osg::Matrix&,osg::NodeVisitor*) const;
+  virtual bool computeWorldToLocalMatrix(osg::Matrix&,osg::NodeVisitor*) const;
 
 private:
 
@@ -63,9 +58,9 @@ private:
   // private data                                                 //
   //////////////////////////////////////////////////////////////////
   
-  sgdVec3 _placement_offset;
-  sgdVec3 _scenery_center;
-    
+  SGVec3d _placement_offset;
+  SGVec3d _scenery_center;
+  SGMatrixd _rotation;
 };
 
 #endif // _SG_LOCATION_HXX
index f7d0d9fdbf56517694a447657b92a312c44af941..ab76f23fa7253aaefb59e677131058f436eeba7d 100644 (file)
@@ -24,8 +24,6 @@
 #  include <simgear_config.h>
 #endif
 
-#include <plib/sg.h>
-#include <plib/ssg.h>
 #include <plib/ul.h>
 
 #include <simgear/props/condition.hxx>
@@ -34,9 +32,8 @@
 
 #include <simgear/debug/logstream.hxx>
 
-#include <simgear/screen/shader.h>
-
 #include "animation.hxx"
+#include "model.hxx"
 /*
     <animation>
         <type>shader</type>
     </animation>
 
 */
-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);
 }
index 2a46cecc226e844060b5e2220d7c2315ea64d221..8f5ebcde51d8589a128994b6d3c5aaec187315d0 100644 (file)
 #define _SHADOWVOLUME_HXX
 
 #include <simgear/compiler.h>
-#include <simgear/structure/ssgSharedPtr.hxx>
 #include <simgear/props/props.hxx>
 
-#include <plib/ssg.h>
-#include <plib/sg.h>
-
 #include <vector>
 #include <map>
 
index b3f7440f3ad21ff3c1e9ca7817d045c4f7f98b3f..f236b46a57c8a70472a6fa5a25d6fc4b34610ee3 100644 (file)
 
 #include <simgear/compiler.h>
 
-// #include <stdio.h>
+#include <sstream>
+
 #include <math.h>
 
-#include <plib/sg.h>
-#include <plib/ssg.h>
+#include <osg/AlphaFunc>
+#include <osg/BlendFunc>
+#include <osg/Geode>
+#include <osg/Geometry>
+#include <osg/Material>
+#include <osg/ShadeModel>
+#include <osg/TexEnv>
+#include <osg/Texture2D>
+#include <osg/TextureCubeMap>
 
-#include <simgear/math/point3d.hxx>
-#include <simgear/math/polar3d.hxx>
 #include <simgear/math/sg_random.h>
 #include <simgear/debug/logstream.hxx>
-#include <simgear/screen/extensions.hxx>
-#include <simgear/screen/texture.hxx>
-#include <simgear/structure/ssgSharedPtr.hxx>
+#include <simgear/scene/model/model.hxx>
+#include <simgear/scene/util/SGDebugDrawCallback.hxx>
+#include <simgear/math/polar3d.hxx>
 
 #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 <ieeefp.h>
 #endif
 
-static ssgSharedPtr<ssgStateSelector> layer_states[SGCloudLayer::SG_MAX_CLOUD_COVERAGES];
+static osg::ref_ptr<osg::StateSet> layer_states[SGCloudLayer::SG_MAX_CLOUD_COVERAGES];
+static osg::ref_ptr<osg::StateSet> layer_states2[SGCloudLayer::SG_MAX_CLOUD_COVERAGES];
+static osg::ref_ptr<osg::TextureCubeMap> cubeMap;
 static bool state_initialized = false;
 static bool bump_mapping = false;
-static GLint nb_texture_unit = 0;
-static ssgSharedPtr<ssgTexture> normal_map[SGCloudLayer::SG_MAX_CLOUD_COVERAGES][2];
-static ssgSharedPtr<ssgTexture> 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<osg::StateSet*>(layer_states2[layer_coverage]->clone(copyOp));
+      // OSGFIXME
+      stateSet->setRenderBinDetails(4, "RenderBin");
+      group_top->setStateSet(stateSet);
+      stateSet = static_cast<osg::StateSet*>(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;
 }
index 4baa0d5816d2440474efa5eaef81157c020fcaa9..9e38687c7ecb526c713cef63560dd4bf269fa956 100644 (file)
 
 #include <simgear/compiler.h>
 #include <simgear/misc/sg_path.hxx>
-
-#include <plib/ssg.h>
+#include <simgear/math/SGMath.hxx>
+#include <simgear/structure/SGReferenced.hxx>
 
 #include STL_STRING
 SG_USING_STD(string);
 
-// #include <iostream>
-// SG_USING_STD(cout);
-// SG_USING_STD(endl);
+#include <osg/ref_ptr>
+#include <osg/Array>
+#include <osg/Geode>
+#include <osg/Group>
+#include <osg/MatrixTransform>
+#include <osg/Switch>
 
 class SGCloudField;
 
 /**
  * A class layer to model a single cloud layer
  */
-class SGCloudLayer {
+class SGCloudLayer : public SGReferenced {
 public:
 
     /**
@@ -163,7 +166,7 @@ public:
      * repaint the cloud colors based on the specified fog_color
      * @param fog_color the fog color
      */
-    bool repaint( sgVec3 fog_color );
+    bool repaint( const SGVec3f& fog_color );
 
     /**
      * reposition the cloud layer at the specified origin and
@@ -176,42 +179,30 @@ public:
      *        (and orients the sunrise/set effects)
      * @param dt the time elapsed since the last call
      */
-    bool reposition( sgVec3 p, sgVec3 up, double lon, double lat, double alt,
+    bool reposition( const SGVec3f& p, const SGVec3f& up,
+                     double lon, double lat, double alt,
                      double dt = 0.0 );
 
-    /** draw the cloud layer */
-    void draw( bool top );
+    osg::Switch* getNode() { return layer_root.get(); }
 
     static bool enable_bump_mapping;
 
-       /** return the 3D layer cloud associated with this 2D layer */
-       SGCloudField *get_layer3D(void) { return layer3D; }
+    /** return the 3D layer cloud associated with this 2D layer */
+    SGCloudField *get_layer3D(void) { return layer3D; }
 
 private:
 
-    struct CloudVertex {
-        sgVec3 position;
-        sgVec2 texCoord;
-        sgVec3 tangentSpLight;
-        sgVec3 sTangent;
-        sgVec3 tTangent;
-        sgVec3 normal;
-        sgVec4 color;
-    };
-
-    CloudVertex *vertices;
-    unsigned int *indices;
-
-    ssgRoot *layer_root;
-    ssgTransform *layer_transform;
-    ssgLeaf *layer[4];
-    ssgStateSelector *state_sel;
+    osg::ref_ptr<osg::Switch> layer_root;
+    osg::ref_ptr<osg::Group> group_top, group_bottom;
+    osg::ref_ptr<osg::MatrixTransform> layer_transform;
+    osg::ref_ptr<osg::Geode> layer[4];
 
     float cloud_alpha;          // 1.0 = drawn fully, 0.0 faded out completely
 
-    ssgColourArray *cl[4]; 
-    ssgVertexArray *vl[4];
-    ssgTexCoordArray *tl[4];
+    osg::ref_ptr<osg::Vec4Array> cl[4];
+    osg::ref_ptr<osg::Vec3Array> vl[4];
+    osg::ref_ptr<osg::Vec2Array> tl[4];
+    osg::ref_ptr<osg::Vec3Array> tl2[4];
 
     // height above sea level (meters)
     SGPath texture_path;
@@ -230,12 +221,9 @@ private:
     // double xoff, yoff;
     double last_lon, last_lat, last_course;
 
-       SGCloudField *layer3D;
-};
-
-
-// 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_
index 809efb520ed6d6849278ac52b5f25ee7119afd44..be60bc8d1c0cff1600812ff3b199dfb0cab82de6 100644 (file)
@@ -78,10 +78,14 @@ static int cacheResolution = 64;
 static sgVec3 last_sunlight={0.0f, 0.0f, 0.0f};
 
 int SGCloudField::get_CacheResolution(void) {
+#if 0
        return cacheResolution;
+#endif
+        return 0;
 }
 
 void SGCloudField::set_CacheResolution(int resolutionPixels) {
+#if 0
        if(cacheResolution == resolutionPixels)
                return;
        cacheResolution = resolutionPixels;
@@ -91,13 +95,18 @@ void SGCloudField::set_CacheResolution(int resolutionPixels) {
                        count = 1;
                SGNewCloud::cldCache->setCacheSize(count, cacheResolution);
        }
+#endif
 }
 
 int SGCloudField::get_CacheSize(void) { 
+#if 0
        return SGNewCloud::cldCache->queryCacheSize(); 
+#endif
+        return 0;
 }
 
 void SGCloudField::set_CacheSize(int sizeKb) {
+#if 0
        // apply in rendering option dialog
        if(last_cache_size == sizeKb)
                return;
@@ -111,15 +120,21 @@ void SGCloudField::set_CacheSize(int sizeKb) {
                        count = 1;
                SGNewCloud::cldCache->setCacheSize(count, cacheResolution);
        }
+#endif
 }
 void SGCloudField::set_CloudVis(float distance) {
+#if 0
        if( distance <= fieldSize )
                SGCloudField::CloudVis = distance;
+#endif
 }
 void SGCloudField::set_density(float density) {
+#if 0
        SGCloudField::density = density;
+#endif
 }
 void SGCloudField::set_enable3dClouds(bool enable) {
+#if 0
        if(enable3D == enable)
                return;
        enable3D = enable;
@@ -131,10 +146,12 @@ void SGCloudField::set_enable3dClouds(bool enable) {
        } else {
                SGNewCloud::cldCache->setCacheSize(0);
        }
+#endif
 }
 
 // reposition the cloud layer at the specified origin and orientation
 void SGCloudField::reposition( sgVec3 p, sgVec3 up, double lon, double lat, double alt, double dt, float direction, float speed) {
+#if 0
     sgMat4 T1, LON, LAT;
     sgVec3 axis;
 
@@ -211,6 +228,7 @@ void SGCloudField::reposition( sgVec3 p, sgVec3 up, double lon, double lat, doub
        frustum.setFOV( w, h );
        frustum.setNearFar(1.0, CloudVis);
        timer_dt = dt;
+#endif
 }
 
 SGCloudField::SGCloudField() :
@@ -220,22 +238,29 @@ SGCloudField::SGCloudField() :
        last_density(0.0),
        draw_in_3d(true)
 {
+#if 0
        sgSetVec3( relative_position, 0,0,0);
        theField.reserve(200);
        inViewClouds.reserve(200);
         sg_srandom_time_10();
+#else
+       draw_in_3d = false;
+#endif
 }
 
 SGCloudField::~SGCloudField() {
+#if 0
        list_of_Cloud::iterator iCloud;
        for( iCloud = theField.begin() ; iCloud != theField.end() ; iCloud++ ) {
                delete iCloud->aCloud;
        }
        theField.clear();
+#endif
 }
 
 
 void SGCloudField::clear(void) {
+#if 0
        list_of_Cloud::iterator iCloud;
        for( iCloud = theField.begin() ; iCloud != theField.end() ; iCloud++ ) {
                delete iCloud->aCloud;
@@ -245,6 +270,7 @@ void SGCloudField::clear(void) {
        last_density = 0.0;
        // true to come back in set density after layer is built
        draw_in_3d = true;
+#endif
 }
 
 // use a table or else we see poping when moving the slider...
@@ -264,6 +290,7 @@ static int densTable[][10] = {
 
 // set the visible flag depending on density
 void SGCloudField::applyDensity(void) {
+#if 0
        int row = (int) (density / 10.0);
        int col = 0;
     sgBox fieldBox;
@@ -286,16 +313,19 @@ void SGCloudField::applyDensity(void) {
     center[1] = 0.0f;
     field_sphere.setCenter( center );
     field_sphere.setRadius( fieldSize * 0.5f * 1.414f );
+#endif
 }
 
 // add one cloud, data is not copied, ownership given
 void SGCloudField::addCloud( sgVec3 pos, SGNewCloud *cloud) {
+#if 0
        Cloud cl;
        cl.aCloud = cloud;
        cl.visible = true;
        cloud->SetPos( pos );
        sgCopyVec3( cl.pos, *cloud->getCenter() );
        theField.push_back( cl );
+#endif
 }
 
 
@@ -306,7 +336,7 @@ static float Rnd(float n) {
 // for debug only
 // build a field of cloud of size 25x25 km, its a grid of 11x11 clouds
 void SGCloudField::buildTestLayer(void) {
-
+#if 0
        const float s = 2250.0f;
 
        for( int z = -5 ; z <= 5 ; z++) {
@@ -318,10 +348,12 @@ void SGCloudField::buildTestLayer(void) {
                }
        }
        applyDensity();
+#endif
 }
 
 // cull all clouds of a tiled field
 void SGCloudField::cullClouds(sgVec3 eyePos, sgMat4 mat) {
+#if 0
        list_of_Cloud::iterator iCloud;
 
     sgSphere tile_sphere;
@@ -357,7 +389,7 @@ void SGCloudField::cullClouds(sgVec3 eyePos, sgMat4 mat) {
                                sgEnviro.set_view_in_cloud(true);
                }
        }
-
+#endif
 }
 
 
@@ -366,6 +398,7 @@ void SGCloudField::cullClouds(sgVec3 eyePos, sgMat4 mat) {
 // we draw this field and adjacent fields.
 // adjacent fields are not real, its the same field displaced by some offset
 void SGCloudField::Render(void) {
+#if 0
     sgVec3 eyePos;
        double relx, rely;
 
@@ -493,6 +526,5 @@ void SGCloudField::Render(void) {
        ssgLoadModelviewMatrix( modelview );
 
        glPopMatrix();
-
+#endif
 }
-
index c41c4c8a98ea3360656f2f9b9e2ac7929a23c02e..a859958ec983ba5164ccf59cc44c1291bbaa9a4b 100644 (file)
 
 #include <simgear/compiler.h>
 
-#include SG_GL_H
-
-#include <plib/sg.h>
-
+#include <osg/Array>
+#include <osg/Geode>
+#include <osg/Geometry>
+#include <osg/Node>
+#include <osg/MatrixTransform>
+#include <osg/Material>
+#include <osg/ShadeModel>
+
+#include <simgear/scene/util/SGDebugDrawCallback.hxx>
 #include <simgear/debug/logstream.hxx>
 
 #include "dome.hxx"
@@ -64,37 +69,9 @@ static const float bottom_radius = 0.8;
 static const float bottom_elev = -0.1;
 
 
-// Set up dome rendering callbacks
-static int sgSkyDomePreDraw( ssgEntity *e ) {
-    /* cout << endl << "Dome Pre Draw" << endl << "----------------" 
-        << endl << endl; */
-
-    ssgLeaf *f = (ssgLeaf *)e;
-    if ( f -> hasState () ) f->getState()->apply() ;
-
-    glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_FOG_BIT );
-    // cout << "push error = " << glGetError() << endl;
-
-    glDisable( GL_DEPTH_TEST );
-    glDisable( GL_FOG );
-
-    return true;
-}
-
-static int sgSkyDomePostDraw( ssgEntity *e ) {
-    /* cout << endl << "Dome Post Draw" << endl << "----------------" 
-        << endl << endl; */
-
-    glPopAttrib();
-    // cout << "pop error = " << glGetError() << endl;
-    
-    return true;
-}
-
-
 // Constructor
 SGSkyDome::SGSkyDome( void ) {
-    asl = 0.0f;
+    asl = 0;
 }
 
 
@@ -104,181 +81,176 @@ SGSkyDome::~SGSkyDome( void ) {
 
 
 // initialize the sky object and connect it into our scene graph
-ssgBranch * SGSkyDome::build( double hscale, double vscale ) {
-    sgVec4 color;
+osg::Node*
+SGSkyDome::build( double hscale, double vscale ) {
 
-    double theta;
-    int i;
+    osg::Geode* geode = new osg::Geode;
 
     // set up the state
-    dome_state = new ssgSimpleState();
-    dome_state->setShadeModel( GL_SMOOTH );
-    dome_state->disable( GL_LIGHTING );
-    dome_state->disable( GL_CULL_FACE );
-    dome_state->disable( GL_TEXTURE_2D );
-    dome_state->enable( GL_COLOR_MATERIAL );
-    dome_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
-    dome_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
-    dome_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
-    dome_state->disable( GL_BLEND );
-    dome_state->disable( GL_ALPHA_TEST );
+    osg::StateSet* stateSet = geode->getOrCreateStateSet();
+    stateSet->setRenderBinDetails(-10, "RenderBin");
+
+    osg::ShadeModel* shadeModel = new osg::ShadeModel;
+    shadeModel->setMode(osg::ShadeModel::SMOOTH);
+    stateSet->setAttributeAndModes(shadeModel);
+    stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
+    stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
+    stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
+    stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
+    stateSet->setMode(GL_BLEND, osg::StateAttribute::OFF);
+    stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::OFF);
+    osg::Material* material = new osg::Material;
+//     material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
+//     material->setEmission(osg::Material::FRONT_AND_BACK,
+//                           osg::Vec4(0, 0, 0, 1));
+//     material->setSpecular(osg::Material::FRONT_AND_BACK,
+//                           osg::Vec4(0, 0, 0, 1));
+//     material->setShininess(osg::Material::FRONT_AND_BACK, 0);
+    stateSet->setAttribute(material);
+//     stateSet->setMode(GL_COLOR_MATERIAL, osg::StateAttribute::OFF);
 
     // initialize arrays
-    center_disk_vl = new ssgVertexArray( 14 );
-    center_disk_cl = new ssgColourArray( 14 );
+    // 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( &center_color, asl * center_elev, 1);
     fade_to_black( upper_color, (asl+0.05f) * upper_elev, 12);
     fade_to_black( middle_color, (asl+0.05f) * middle_elev, 12);
     fade_to_black( lower_color, (asl+0.05f) * lower_elev, 12);
 
-    for ( i = 0; i < 12; i++ ) {
-       sgCopyVec4( bottom_color[i], fog_color );
-    }
+    for ( int i = 0; i < 12; i++ )
+        bottom_color[i] = fog_color.osg();
 
     //
     // Second, assign the basic colors to the object color arrays
     //
 
-    float *slot;
-    int counter;
-
     // update the center disk color arrays
-    counter = 0;
-    slot = center_disk_cl->get( counter++ );
-    // sgVec4 red;
-    // sgSetVec4( red, 1.0, 0.0, 0.0, 1.0 );
-    sgCopyVec4( slot, center_color );
-    for ( i = 11; i >= 0; i-- ) {
-       slot = center_disk_cl->get( counter++ );
-       sgCopyVec4( slot, upper_color[i] );
+    int counter = 0;
+    (*center_disk_cl)[counter++] = center_color;
+    for ( int i = 11; i >= 0; i-- ) {
+        (*center_disk_cl)[counter++] = upper_color[i];
     }
-    slot = center_disk_cl->get( counter++ );
-    sgCopyVec4( slot, upper_color[11] );
+    (*center_disk_cl)[counter++] = upper_color[11];
+    center_disk_cl->dirty();
 
     // generate the upper ring
     counter = 0;
-    for ( i = 0; i < 12; i++ ) {
-       slot = upper_ring_cl->get( counter++ );
-       sgCopyVec4( slot, middle_color[i] );
-
-       slot = upper_ring_cl->get( counter++ );
-       sgCopyVec4( slot, upper_color[i] );
+    for ( int i = 0; i < 12; i++ ) {
+        (*upper_ring_cl)[counter++] = middle_color[i];
+       (*upper_ring_cl)[counter++] = upper_color[i];
     }
-    slot = upper_ring_cl->get( counter++ );
-    sgCopyVec4( slot, middle_color[0] );
-
-    slot = upper_ring_cl->get( counter++ );
-    sgCopyVec4( slot, upper_color[0] );
+    (*upper_ring_cl)[counter++] = middle_color[0];
+    (*upper_ring_cl)[counter++] = upper_color[0];
+    upper_ring_cl->dirty();
 
     // generate middle ring
     counter = 0;
-    for ( i = 0; i < 12; i++ ) {
-       slot = middle_ring_cl->get( counter++ );
-       sgCopyVec4( slot, lower_color[i] );
-
-       slot = middle_ring_cl->get( counter++ );
-       sgCopyVec4( slot, middle_color[i] );
+    for ( int i = 0; i < 12; i++ ) {
+        (*middle_ring_cl)[counter++] = lower_color[i];
+        (*middle_ring_cl)[counter++] = middle_color[i];
     }
-    slot = middle_ring_cl->get( counter++ );
-    sgCopyVec4( slot, lower_color[0] );
-
-    slot = middle_ring_cl->get( counter++ );
-    sgCopyVec4( slot, middle_color[0] );
+    (*middle_ring_cl)[counter++] = lower_color[0];
+    (*middle_ring_cl)[counter++] = middle_color[0];
+    middle_ring_cl->dirty();
 
     // generate lower ring
     counter = 0;
-    for ( i = 0; i < 12; i++ ) {
-       slot = lower_ring_cl->get( counter++ );
-       sgCopyVec4( slot, bottom_color[i] );
-
-       slot = lower_ring_cl->get( counter++ );
-       sgCopyVec4( slot, lower_color[i] );
+    for ( int i = 0; i < 12; i++ ) {
+        (*lower_ring_cl)[counter++] = bottom_color[i];
+        (*lower_ring_cl)[counter++] = lower_color[i];
     }
-    slot = lower_ring_cl->get( counter++ );
-    sgCopyVec4( slot, bottom_color[0] );
-
-    slot = lower_ring_cl->get( counter++ );
-    sgCopyVec4( slot, lower_color[0] );
+    (*lower_ring_cl)[counter++] = bottom_color[0];
+    (*lower_ring_cl)[counter++] = lower_color[0];
+    lower_ring_cl->dirty();
 
     return true;
 }
@@ -527,14 +457,17 @@ bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle,
 // lat specifies a rotation about the new Y axis
 // spin specifies a rotation about the new Z axis (and orients the
 // sunrise/set effects
-bool SGSkyDome::reposition( sgVec3 p, double lon, double lat, double spin ) {
-    sgMat4 T, LON, LAT, SPIN;
-    sgVec3 axis;
+bool
+SGSkyDome::reposition( const SGVec3f& p, double _asl,
+                       double lon, double lat, double spin ) {
+    asl = _asl;
+
+    osg::Matrix T, LON, LAT, SPIN;
 
     // Translate to view position
     // Point3D zero_elev = current_view.get_cur_zero_elev();
     // xglTranslatef( zero_elev.x(), zero_elev.y(), zero_elev.z() );
-    sgMakeTransMat4( T, p );
+    T.makeTranslate( p.osg() );
 
     // printf("  Translated to %.2f %.2f %.2f\n", 
     //        zero_elev.x, zero_elev.y, zero_elev.z );
@@ -544,29 +477,15 @@ bool SGSkyDome::reposition( sgVec3 p, double lon, double lat, double spin ) {
     //        lon * SGD_RADIANS_TO_DEGREES,
     //        lat * SGD_RADIANS_TO_DEGREES);
     // xglRotatef( lon * SGD_RADIANS_TO_DEGREES, 0.0, 0.0, 1.0 );
-    sgSetVec3( axis, 0.0, 0.0, 1.0 );
-    sgMakeRotMat4( LON, lon * SGD_RADIANS_TO_DEGREES, axis );
+    LON.makeRotate(lon, osg::Vec3(0, 0, 1));
 
     // xglRotatef( 90.0 - f->get_Latitude() * SGD_RADIANS_TO_DEGREES,
     //             0.0, 1.0, 0.0 );
-    sgSetVec3( axis, 0.0, 1.0, 0.0 );
-    sgMakeRotMat4( LAT, 90.0 - lat * SGD_RADIANS_TO_DEGREES, axis );
+    LAT.makeRotate(90.0 * SGD_DEGREES_TO_RADIANS - lat, osg::Vec3(0, 1, 0));
 
     // xglRotatef( l->sun_rotation * SGD_RADIANS_TO_DEGREES, 0.0, 0.0, 1.0 );
-    sgSetVec3( axis, 0.0, 0.0, 1.0 );
-    sgMakeRotMat4( SPIN, spin * SGD_RADIANS_TO_DEGREES, axis );
-
-    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;
 }
index 401e238088eacb4391d617227430a60ea7fbef52..dfed58e19b72a3304cc73bc69ad312e04f044506 100644 (file)
 # error This library requires C++
 #endif
 
+#include <osg/ref_ptr>
+#include <osg/Array>
+#include <osg/MatrixTransform>
 
-#include <plib/ssg.h>          // plib include
+#include <simgear/structure/SGReferenced.hxx>
+#include <simgear/math/SGMath.hxx>
 
+class SGSkyDome : public SGReferenced {
+    osg::ref_ptr<osg::MatrixTransform> dome_transform;
 
-class SGSkyDome {
-    ssgTransform *dome_transform;
-    ssgSimpleState *dome_state;
+    osg::ref_ptr<osg::Vec3Array> center_disk_vl;
+    osg::ref_ptr<osg::Vec3Array> center_disk_cl;
 
-    ssgVertexArray *center_disk_vl;
-    ssgColourArray *center_disk_cl;
+    osg::ref_ptr<osg::Vec3Array> upper_ring_vl;
+    osg::ref_ptr<osg::Vec3Array> upper_ring_cl;
 
-    ssgVertexArray *upper_ring_vl;
-    ssgColourArray *upper_ring_cl;
+    osg::ref_ptr<osg::Vec3Array> middle_ring_vl;
+    osg::ref_ptr<osg::Vec3Array> middle_ring_cl;
 
-    ssgVertexArray *middle_ring_vl;
-    ssgColourArray *middle_ring_cl;
+    osg::ref_ptr<osg::Vec3Array> lower_ring_vl;
+    osg::ref_ptr<osg::Vec3Array> lower_ring_cl;
 
-    ssgVertexArray *lower_ring_vl;
-    ssgColourArray *lower_ring_cl;
-
-    float   asl;
+    double asl;
 
 public:
 
@@ -62,7 +64,7 @@ public:
 
     // initialize the sky object and connect it into our scene graph
     // root
-    ssgBranch *build( double hscale = 80000.0, double vscale = 80000.0 );
+    osg::Node *build( double hscale = 80000.0, double vscale = 80000.0 );
 
     // repaint the sky colors based on current value of sun_angle,
     // sky, and fog colors.  This updates the color arrays for
@@ -71,15 +73,16 @@ public:
     // 0 degrees = high noon
     // 90 degrees = sun rise/set
     // 180 degrees = darkest midnight
-    bool repaint( sgVec3 sky_color, sgVec3 fog_color, double sun_angle,
-                 double vis );
+    bool repaint( const SGVec3f& sky_color, const SGVec3f& fog_color,
+                  double sun_angle, double vis );
 
     // reposition the sky at the specified origin and orientation
     // lon specifies a rotation about the Z axis
     // lat specifies a rotation about the new Y axis
     // spin specifies a rotation about the new Z axis (and orients the
     // sunrise/set effects
-    bool reposition( sgVec3 p, double lon, double lat, double spin );
+    bool reposition( const SGVec3f& p, double asl,
+                     double lon, double lat, double spin );
 };
 
 
index 687243799082a52c85f12a4d2272b69d28cfb89b..568a89bd5849d352f97a0ffb5ea69e6730d44c6f 100644 (file)
 #include <stdio.h>
 #include STL_IOSTREAM
 
-#include <plib/sg.h>
-#include <plib/ssg.h>
+#include <osg/Array>
+#include <osg/AlphaFunc>
+#include <osg/BlendFunc>
+#include <osg/CullFace>
+#include <osg/Geometry>
+#include <osg/Geode>
+#include <osg/Node>
+#include <osg/ShadeModel>
+#include <osg/TexEnv>
+#include <osg/Texture2D>
 
 #include <simgear/constants.h>
 #include <simgear/screen/colors.hxx>
+#include <simgear/scene/model/model.hxx>
 
 #include "sphere.hxx"
 #include "moon.hxx"
 
-
-// Set up moon rendering call backs
-static int sgMoonOrbPreDraw( ssgEntity *e ) {
-    /* cout << endl << "Moon orb pre draw" << endl << "----------------" 
-        << endl << endl; */
-
-    ssgLeaf *f = (ssgLeaf *)e;
-    if ( f -> hasState () ) f->getState()->apply() ;
-
-    glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT );
-    // cout << "push error = " << glGetError() << endl;
-
-    glDisable( GL_DEPTH_TEST );
-    glDisable( GL_FOG );
-    glBlendFunc ( GL_SRC_ALPHA, GL_ONE ) ;
-
-    return true;
-}
-
-
-static int sgMoonOrbPostDraw( ssgEntity *e ) {
-    /* cout << endl << "Moon orb post draw" << endl << "----------------" 
-        << endl << endl; */
-
-    // Some drivers don't properly reset glBendFunc with a
-    // glPopAttrib() so we reset it to the 'default' here.
-    glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
-
-    glPopAttrib();
-    // cout << "pop error = " << glGetError() << endl;
-    
-    return true;
-}
-
-
-#if 0
-static int sgMoonHaloPreDraw( ssgEntity *e ) {
-    /* cout << endl << "Moon halo pre draw" << endl << "----------------" 
-        << endl << endl; */
-
-    ssgLeaf *f = (ssgLeaf *)e;
-    if ( f -> hasState () ) f->getState()->apply() ;
-
-    glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_FOG_BIT | GL_COLOR_BUFFER_BIT);
-    // cout << "push error = " << glGetError() << endl;
-
-    glDisable( GL_DEPTH_TEST );
-    glDisable( GL_FOG );
-    glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
-
-    return true;
-}
-
-static int sgMoonHaloPostDraw( ssgEntity *e ) {
-    /* cout << endl << "Moon halo post draw" << endl << "----------------" 
-        << endl << endl; */
-    
-    glPopAttrib();
-    // cout << "pop error = " << glGetError() << endl;
-
-    return true;
-}
-#endif
-
-
 // Constructor
 SGMoon::SGMoon( void ) :
     prev_moon_angle(-1)
@@ -119,99 +63,64 @@ SGMoon::~SGMoon( void ) {
 
 
 // build the moon object
-ssgBranch * SGMoon::build( SGPath path, double moon_size ) {
+osg::Node*
+SGMoon::build( SGPath path, double moon_size ) {
+
+    osg::Node* orb = SGMakeSphere(moon_size, 15, 15);
+    osg::StateSet* stateSet = orb->getOrCreateStateSet();
+    stateSet->setRenderBinDetails(-5, "RenderBin");
 
     // set up the orb state
     path.append( "moon.rgba" );
-    orb_state = new ssgSimpleState();
-    orb_state->setTexture( (char *)path.c_str() );
-    orb_state->setShadeModel( GL_SMOOTH );
-    orb_state->enable( GL_LIGHTING );
-    orb_state->enable( GL_CULL_FACE );
-    orb_state->enable( GL_TEXTURE_2D );
-    orb_state->enable( GL_COLOR_MATERIAL );
-    orb_state->setColourMaterial( GL_DIFFUSE );
-    orb_state->setMaterial( GL_AMBIENT, 0, 0, 0, 1.0 );
-    orb_state->setMaterial( GL_EMISSION, 0.0, 0.0, 0.0, 1 );
-    orb_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
-    orb_state->enable( GL_BLEND );
-    orb_state->enable( GL_ALPHA_TEST );
-    orb_state->setAlphaClamp( 0.01 );
-
-    cl = new ssgColourArray( 1 );
-    sgVec4 color;
-    sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
-    cl->add( color );
-
-    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;
 }
index ddba10b6cba88112206ba1c998ce6de2d32d8038..5365f8956d44fc8840466ae29911e8728d91316e 100644 (file)
 #define _SG_MOON_HXX_
 
 
-#include <plib/ssg.h>
-
-#include <simgear/misc/sg_path.hxx>
+#include <osg/ref_ptr>
+#include <osg/MatrixTransform>
+#include <osg/Material>
 
+#include <simgear/math/SGMath.hxx>
+#include <simgear/structure/SGReferenced.hxx>
 
-class SGMoon {
+#include <simgear/misc/sg_path.hxx>
 
-    ssgTransform *moon_transform;
-    ssgSimpleState *orb_state;
-    ssgSimpleState *halo_state;
 
-    ssgColourArray *cl;
+class SGMoon : public SGReferenced {
 
-    ssgVertexArray *halo_vl;
-    ssgTexCoordArray *halo_tl;
+    osg::ref_ptr<osg::MatrixTransform> moon_transform;
+    osg::ref_ptr<osg::Material> orb_material;
 
     double prev_moon_angle;
 
@@ -56,7 +55,7 @@ public:
     ~SGMoon( void );
 
     // build the moon object
-    ssgBranch *build( SGPath path, double moon_size );
+    osg::Node *build( SGPath path, double moon_size );
 
     // repaint the moon colors based on current value of moon_anglein
     // degrees relative to verticle
@@ -69,7 +68,7 @@ public:
     // declination, offset by our current position (p) so that it
     // appears fixed at a great distance from the viewer.  Also add in
     // an optional rotation (i.e. for the current time of day.)
-    bool reposition( sgVec3 p, double angle,
+    bool reposition( const SGVec3f& p, double angle,
                     double rightAscension, double declination,
                     double moon_dist  );
 };
index 1c947cf12c67b4e879fd16aaa98c996487163b09..901d0f78f23d08ecda6e5efb033e5bc30ba1ebad 100644 (file)
 #  include <simgear_config.h>
 #endif
 
+#include <osg/ref_ptr>
+#include <osg/Texture2D>
+
 #include <simgear/compiler.h>
 
 #include <plib/sg.h>
-#include <plib/ssg.h>
 #include <simgear/math/sg_random.h>
 #include <simgear/misc/sg_path.hxx>
-#include <simgear/structure/ssgSharedPtr.hxx>
 
 #include STL_ALGORITHM
 #include SG_GLU_H
@@ -42,7 +43,7 @@
 /*
 */
 
-static ssgSharedPtr<ssgTexture> cloudTextures[SGNewCloud::CLTexture_max];
+static osg::ref_ptr<osg::Texture2D> cloudTextures[SGNewCloud::CLTexture_max];
 
 
 bool SGNewCloud::useAnisotropic = true;
@@ -129,11 +130,15 @@ void SGNewCloud::loadTextures(const string &tex_path) {
 
     cloud_path.set(tex_path);
     cloud_path.append("cl_cumulus.rgb");
-    cloudTextures[ CLTexture_cumulus ] = new ssgTexture( cloud_path.str().c_str(), false, false, false );
+    // OSGFIXME
+//     cloudTextures[ CLTexture_cumulus ] = new osg::Texture2D( cloud_path.str().c_str(), false, false, false );
+    cloudTextures[ CLTexture_cumulus ] = new osg::Texture2D;
 
     cloud_path.set(tex_path);
     cloud_path.append("cl_stratus.rgb");
-    cloudTextures[ CLTexture_stratus ] = new ssgTexture( cloud_path.str().c_str(), false, false, false );
+    // OSGFIXME
+//     cloudTextures[ CLTexture_stratus ] = new ssgTexture( cloud_path.str().c_str(), false, false, false );
+    cloudTextures[ CLTexture_stratus ] = new osg::Texture2D;
 
 }
 
@@ -486,7 +491,8 @@ void SGNewCloud::Render3Dcloud( bool drawBB, sgVec3 FakeEyePos, sgVec3 deltaPos,
                // in practice there is no texture switch (atm)
                if( previousTexture != thisTexture ) {
                        previousTexture = thisTexture;
-                       glBindTexture(GL_TEXTURE_2D, cloudTextures[thisTexture]->getHandle());
+                        // OSGFIXME
+//                     glBindTexture(GL_TEXTURE_2D, cloudTextures[thisTexture]->getHandle());
                }
 
                        sgVec3 translate;
index 51ebbf99edf97ee4d790eaf6ba954f55a0f59845..dd0d2cad986c1ed208c90cb893d1acc67d2d7b3c 100644 (file)
 
 #include <simgear/compiler.h>
 
-#include <plib/sg.h>
-#include <plib/ssg.h>
-
-// define the following to enable a cheesy lens flare effect for the sun
-// #define FG_TEST_CHEESY_LENS_FLARE
-
-#ifdef FG_TEST_CHEESY_LENS_FLARE
-#  include <plib/ssgaLensFlare.h>
-#endif
+#include <osg/AlphaFunc>
+#include <osg/BlendFunc>
+#include <osg/Fog>
+#include <osg/Geode>
+#include <osg/Geometry>
+#include <osg/Material>
+#include <osg/ShadeModel>
+#include <osg/TexEnv>
+#include <osg/Texture2D>
+#include <osgDB/ReadFile>
 
 #include <simgear/screen/colors.hxx>
+#include <simgear/scene/model/model.hxx>
 #include "oursun.hxx"
 
-
-static double sun_exp2_punch_through;
-
-// Set up sun rendering call backs
-static int sgSunPreDraw( ssgEntity *e ) {
-    /* cout << endl << "Sun orb pre draw" << endl << "----------------" 
-        << endl << endl; */
-
-    ssgLeaf *f = (ssgLeaf *)e;
-    if ( f -> hasState () ) f->getState()->apply() ;
-
-    glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_FOG_BIT );
-    // cout << "push error = " << glGetError() << endl;
-
-    glDisable( GL_DEPTH_TEST );
-    glDisable( GL_FOG );
-    glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
-    return true;
-}
-
-static int sgSunPostDraw( ssgEntity *e ) {
-    /* cout << endl << "Sun orb post draw" << endl << "----------------" 
-        << endl << endl; */
-
-    glPopAttrib();
-    // cout << "pop error = " << glGetError() << endl;
-
-    return true;
-}
-
-static int sgSunHaloPreDraw( ssgEntity *e ) {
-    /* cout << endl << "Sun halo pre draw" << endl << "----------------" 
-        << endl << endl; */
-
-    ssgLeaf *f = (ssgLeaf *)e;
-    if ( f -> hasState () ) f->getState()->apply() ;
-
-    glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_FOG_BIT );
-    // cout << "push error = " << glGetError() << endl;
-
-    glDisable( GL_DEPTH_TEST );
-    // glDisable( GL_FOG );
-    glFogf (GL_FOG_DENSITY, sun_exp2_punch_through);
-    glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
-
-    return true;
-}
-
-static int sgSunHaloPostDraw( ssgEntity *e ) {
-    /* cout << endl << "Sun halo post draw" << endl << "----------------" 
-        << endl << endl; */
-
-    glPopAttrib();
-    // cout << "pop error = " << glGetError() << endl;
-
-    return true;
-}
-
-
 // Constructor
 SGSun::SGSun( void ) {
     prev_sun_angle = -9999.0;
@@ -114,308 +57,170 @@ SGSun::~SGSun( void ) {
 }
 
 
-#if 0
-// this might be nice to keep, just as an example of how to generate a
-// texture on the fly ...
-static GLuint makeHalo( GLubyte *sun_texbuf, int width ) {
-    int texSize;
-    GLuint texid;
-    GLubyte *p;
-    int i,j;
-    double radius;
-  
-    // create a texture id
-#ifdef GL_VERSION_1_1
-    glGenTextures(1, &texid);
-    glBindTexture(GL_TEXTURE_2D, texid);
-#elif GL_EXT_texture_object
-    glGenTexturesEXT(1, &texid);
-    glBindTextureEXT(GL_TEXTURE_2D, texid);
-#else
-#   error port me
-#endif
-
-    glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
-    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
-    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
-    glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ;
-    // create the actual texture contents
-    texSize = width * width;
-  
-    if ( !sun_texbuf ) {
-        SG_LOG( SG_EVENT, SG_ALERT,
-                               "Could not allocate memroy for the sun texture");
-       exit(-1);  // Ugly!
-    }
-
-    p = sun_texbuf;
-  
-    radius = (double)(width / 2);
-  
-    GLubyte value;
-    double x, y, d;
-    for ( i = 0; i < width; i++ ) {
-       for ( j = 0; j < width; j++ ) {
-           x = fabs((double)(i - (width / 2)));
-           y = fabs((double)(j - (width / 2)));
-           d = sqrt((x * x) + (y * y));
-           if (d < radius) {
-               // t is 1.0 at center, 0.0 at edge
-               double t = 1.0 - (d / radius);
-
-               // inverse square looks nice 
-               value = (int)((double) 0xff * (t*t));
-           } else {
-               value = 0x00;
-           }
-           *p = value;
-           *(p+1) = value;
-           *(p+2) = value;
-           // *(p+3) = value;
-
-           p += 3;
-       }
-    }
-
-    /* glTexImage2D( GL_TEXTURE_2D,
-                 0,
-                 GL_RGBA,
-                 width, width,
-                 0,
-                 GL_RGBA, GL_UNSIGNED_BYTE,
-                 sun_texbuf ); */
-
-    return texid;
-}
+// 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]);
+}
index 08fe03e577fd7cc6d503af215e667992d5c72279..ceed47e209391119e7d4a5ab7342056232586218 100644 (file)
 #ifndef _SG_SUN_HXX_
 #define _SG_SUN_HXX_
 
+#include <osg/Array>
+#include <osg/Node>
+#include <osg/MatrixTransform>
 
-#include <plib/ssg.h>
+#include <simgear/structure/SGReferenced.hxx>
 
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/props/props.hxx>
 
-class SGSun {
+class SGSun : public SGReferenced {
 
-    ssgTransform *sun_transform;
-    ssgSimpleState *sun_state; 
-    ssgSimpleState *ihalo_state;
-    ssgSimpleState *ohalo_state;
+    osg::ref_ptr<osg::MatrixTransform> sun_transform;
 
-    ssgColourArray *sun_cl;
-    ssgColourArray *ihalo_cl;
-    ssgColourArray *ohalo_cl;
-
-    ssgVertexArray *sun_vl;
-    ssgVertexArray *ihalo_vl;
-    ssgVertexArray *ohalo_vl;
-
-    ssgTexCoordArray *sun_tl;
-    ssgTexCoordArray *ihalo_tl;
-    ssgTexCoordArray *ohalo_tl;
-
-    GLuint sun_texid;
-    GLubyte *sun_texbuf;
+    osg::ref_ptr<osg::Vec4Array> sun_cl;
+    osg::ref_ptr<osg::Vec4Array> ihalo_cl;
+    osg::ref_ptr<osg::Vec4Array> ohalo_cl;
 
     double visibility;
     double prev_sun_angle;
     // distance of light traveling through the atmosphere
     double path_distance;
+    double sun_exp2_punch_through;
 
-    SGPropertyNode *env_node;
+    SGPropertyNode_ptr env_node;
 
 public:
 
@@ -72,7 +62,7 @@ public:
     ~SGSun( void );
 
     // return the sun object
-    ssgBranch *build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node );
+    osg::Node* build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node );
 
     // repaint the sun colors based on current value of sun_anglein
     // degrees relative to verticle
@@ -85,15 +75,12 @@ public:
     // declination, offset by our current position (p) so that it
     // appears fixed at a great distance from the viewer.  Also add in
     // an optional rotation (i.e. for the current time of day.)
-    bool reposition( sgVec3 p, double angle,
+    bool reposition( const SGVec3f& p, double angle,
                     double rightAscension, double declination,
                     double sun_dist, double lat, double alt_asl, double sun_angle );
 
     // retrun the current color of the sun
-    inline float *get_color() { return  ohalo_cl->get( 0 ); }
-
-    // return the texture id of the sun halo texture
-    inline GLuint get_texture_id() { return ohalo_state->getTextureHandle(); }
+    SGVec4f get_color();
 };
 
 
index 2bc97580fbec59156b42db13737351b70c96d7af..b1970e07ea7b44a9ca04c1a589b584aada399577 100644 (file)
@@ -25,9 +25,6 @@
 #  include <simgear_config.h>
 #endif
 
-#include <plib/sg.h>
-#include <plib/ssg.h>
-
 #include <simgear/math/sg_random.h>
 
 #include "sky.hxx"
@@ -43,18 +40,24 @@ SGSky::SGSky( void ) {
     puff_progression = 0;
     ramp_up = 0.15;
     ramp_down = 0.15;
-    // ramp_up = 4.0;
-    // ramp_down = 4.0;
 
     in_cloud  = -1;
+
+    pre_root = new osg::Group;
+    post_root = new osg::Group;
+    cloud_root = new osg::Group;
+
+    pre_selector = new osg::Switch;
+    post_selector = new osg::Switch;
+
+    pre_transform = new osg::MatrixTransform;
+    post_transform = new osg::MatrixTransform;
 }
 
 
 // Destructor
 SGSky::~SGSky( void )
 {
-    for (unsigned int i = 0; i < cloud_layers.size(); i++)
-        delete cloud_layers[i];
 }
 
 
@@ -62,41 +65,30 @@ SGSky::~SGSky( void )
 // the provided branch
 void SGSky::build( double h_radius_m, double v_radius_m,
                    double sun_size, double moon_size,
-                  int nplanets, sgdVec3 *planet_data,
-                  int nstars, sgdVec3 *star_data, SGPropertyNode *property_tree_node )
+                  int nplanets, SGVec3d planet_data[7],
+                  int nstars, SGVec3d star_data[], SGPropertyNode *property_tree_node )
 {
-    pre_root = new ssgRoot;
-    post_root = new ssgRoot;
-
-    pre_selector = new ssgSelector;
-    post_selector = new ssgSelector;
-
-    pre_transform = new ssgTransform;
-    post_transform = new ssgTransform;
-
     dome = new SGSkyDome;
-    pre_transform -> addKid( dome->build( h_radius_m, v_radius_m ) );
+    pre_transform->addChild( dome->build( h_radius_m, v_radius_m ) );
 
     planets = new SGStars;
-    pre_transform -> addKid(planets->build(nplanets, planet_data, h_radius_m));
+    pre_transform->addChild(planets->build(nplanets, planet_data, h_radius_m));
 
     stars = new SGStars;
-    pre_transform -> addKid( stars->build(nstars, star_data, h_radius_m) );
+    pre_transform->addChild( stars->build(nstars, star_data, h_radius_m) );
     
     moon = new SGMoon;
-    pre_transform -> addKid( moon->build(tex_path, moon_size) );
+    pre_transform->addChild( moon->build(tex_path, moon_size) );
 
     oursun = new SGSun;
-    pre_transform -> addKid( oursun->build(tex_path, sun_size, property_tree_node ) );
+    pre_transform->addChild( oursun->build(tex_path, sun_size, property_tree_node ) );
 
-    pre_selector->addKid( pre_transform );
-    pre_selector->clrTraversalMaskBits( SSGTRAV_HOT );
+    pre_selector->addChild( pre_transform.get() );
 
-    post_selector->addKid( post_transform );
-    post_selector->clrTraversalMaskBits( SSGTRAV_HOT );
+    post_selector->addChild( post_transform.get() );
 
-    pre_root->addKid( pre_selector );
-    post_root->addKid( post_selector );
+    pre_root->addChild( pre_selector.get() );
+    post_root->addChild( post_selector.get() );
 }
 
 
@@ -119,7 +111,7 @@ bool SGSky::repaint( const SGSkyColor &sc )
        oursun->repaint( sc.sun_angle, effective_visibility );
        moon->repaint( sc.moon_angle );
 
-       for ( int i = 0; i < (int)cloud_layers.size(); ++i ) {
+       for ( unsigned i = 0; i < cloud_layers.size(); ++i ) {
             if (cloud_layers[i]->getCoverage() != SGCloudLayer::SG_CLOUD_CLEAR){
                 cloud_layers[i]->repaint( sc.cloud_color );
             }
@@ -145,7 +137,7 @@ bool SGSky::reposition( SGSkyState &st, double dt )
 
     double angle = st.gst * 15;        // degrees
 
-    dome->reposition( st.zero_elev, st.lon, st.lat, st.spin );
+    dome->reposition( st.zero_elev, st.alt, st.lon, st.lat, st.spin );
 
     stars->reposition( st.view_pos, angle );
     planets->reposition( st.view_pos, angle );
@@ -156,87 +148,22 @@ bool SGSky::reposition( SGSkyState &st, double dt )
     moon->reposition( st.view_pos, angle,
                       st.moon_ra, st.moon_dec, st.moon_dist );
 
-    for ( int i = 0; i < (int)cloud_layers.size(); ++i ) {
+    for ( unsigned i = 0; i < cloud_layers.size(); ++i ) {
         if ( cloud_layers[i]->getCoverage() != SGCloudLayer::SG_CLOUD_CLEAR ) {
             cloud_layers[i]->reposition( st.zero_elev, st.view_up,
                                          st.lon, st.lat, st.alt, dt );
-        }
+        } else
+          cloud_layers[i]->getNode()->setAllChildrenOff();
     }
 
     return true;
 }
 
-
-// draw background portions of the sky ... do this before you draw the
-// rest of your scene.
-void SGSky::preDraw( float alt, float fog_exp2_density ) {
-    ssgCullAndDraw( pre_root );
-
-    // if we are closer than this to a cloud layer, don't draw clouds
-    static const float slop = 5.0;
-    int i;
-
-    // check where we are relative to the cloud layers
-    in_cloud = -1;
-    for ( i = 0; i < (int)cloud_layers.size(); ++i ) {
-        float asl = cloud_layers[i]->getElevation_m();
-        float thickness = cloud_layers[i]->getThickness_m();
-
-        if ( alt < asl - slop ) {
-            // below cloud layer
-        } else if ( alt < asl + thickness + slop ) {
-            // in cloud layer
-
-            // bail now and don't draw any clouds
-                       if( cloud_layers[i]->get_layer3D()->is3D() && SGCloudField::enable3D )
-                               continue;
-            in_cloud = i;
-        } else {
-            // above cloud layer
-        }
-    }
-
-    // determine rendering order
-    cur_layer_pos = 0;
-    while ( cur_layer_pos < (int)cloud_layers.size() &&
-            alt > cloud_layers[cur_layer_pos]->getElevation_m() )
-    {
-        ++cur_layer_pos;
-    }
-
-    // FIXME: This should not be needed, but at this time (08/15/2003)
-    //        certain NVidia drivers don't seem to implement
-    //        glPushAttrib(FG_FOG_BIT) properly. The result is that
-    //        there is not fog when looking at the sun.
-    glFogf ( GL_FOG_DENSITY, fog_exp2_density );
-}
-
-void SGSky::drawUpperClouds( ) {
-    // draw the cloud layers that are above us, top to bottom
-    for ( int i = (int)cloud_layers.size() - 1; i >= cur_layer_pos; --i ) {
-        if ( i != in_cloud ) {
-            cloud_layers[i]->draw( false );
-        }
-    }
-}
-
-
-// draw translucent clouds ... do this after you've drawn all the
-// oapaque elements of your scene.
-void SGSky::drawLowerClouds() {
-
-    // draw the cloud layers that are below us, bottom to top
-    for ( int i = 0; i < cur_layer_pos; ++i ) {
-        if ( i != in_cloud ) {
-            cloud_layers[i]->draw( true );
-        }
-    }
-}
-
 void
 SGSky::add_cloud_layer( SGCloudLayer * layer )
 {
     cloud_layers.push_back(layer);
+    cloud_root->addChild(layer->getNode());
 }
 
 const SGCloudLayer *
index c41e9ec82589269e469bfa8f5402c15ad1616732..4c4c47c1081e89b005a43cd04a8f07fd0c6b93a7 100644 (file)
 # error This library requires C++
 #endif
 
-
-#include <plib/ssg.h>          // plib include
-
 #include <simgear/compiler.h>
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/props/props.hxx>
 
 #include <vector>
 
+#include <osg/ref_ptr>
+#include <osg/MatrixTransform>
+#include <osg/Node>
+#include <osg/Switch>
+
 #include <simgear/scene/sky/cloud.hxx>
 #include <simgear/scene/sky/dome.hxx>
 #include <simgear/scene/sky/moon.hxx>
 SG_USING_STD(vector);
 
 
-typedef vector < SGCloudLayer* > layer_list_type;
-typedef layer_list_type::iterator layer_list_iterator;
-typedef layer_list_type::const_iterator layer_list_const_iterator;
-
 typedef struct {
-       float *view_pos, *zero_elev, *view_up;
+       SGVec3f view_pos, zero_elev, view_up;
        double lon, lat, alt, spin;
        double gst;
        double sun_ra, sun_dec, sun_dist;
@@ -65,10 +63,12 @@ typedef struct {
 } SGSkyState;
 
 typedef struct {
-       float *sky_color, *fog_color, *cloud_color;
+       SGVec3f sky_color, fog_color;
+       SGVec3f cloud_color;
        double sun_angle, moon_angle;
        int nplanets, nstars;
-       sgdVec3 *planet_data, *star_data;
+        SGVec3d *planet_data;
+        SGVec3d *star_data;
 } SGSkyColor;
 
 /**
@@ -205,19 +205,21 @@ typedef struct {
 class SGSky {
 
 private:
+    typedef std::vector<SGSharedPtr<SGCloudLayer> > layer_list_type;
+    typedef layer_list_type::iterator layer_list_iterator;
+    typedef layer_list_type::const_iterator layer_list_const_iterator;
 
     // components of the sky
-    SGSkyDome *dome;
-    SGSun *oursun;
-    SGMoon *moon;
-    SGStars *planets;
-    SGStars *stars;
+    SGSharedPtr<SGSkyDome> dome;
+    SGSharedPtr<SGSun> oursun;
+    SGSharedPtr<SGMoon> moon;
+    SGSharedPtr<SGStars> planets;
+    SGSharedPtr<SGStars> stars;
     layer_list_type cloud_layers;
 
-    ssgRoot *pre_root, *post_root;
-
-    ssgSelector *pre_selector, *post_selector;
-    ssgTransform *pre_transform, *post_transform;
+    osg::ref_ptr<osg::Group> pre_root, post_root, cloud_root;
+    osg::ref_ptr<osg::Switch> pre_selector, post_selector;
+    osg::ref_ptr<osg::MatrixTransform> pre_transform, post_transform;
 
     SGPath tex_path;
 
@@ -260,8 +262,8 @@ public:
      */
     void build( double h_radius_m, double v_radius_m,
                 double sun_size, double moon_size,
-               int nplanets, sgdVec3 *planet_data,
-               int nstars, sgdVec3 *star_data, SGPropertyNode *property_tree_node );
+                int nplanets, SGVec3d planet_data[7],
+                int nstars, SGVec3d star_data[], SGPropertyNode *property_tree_node );
 
     /**
      * Repaint the sky components based on current value of sun_angle,
@@ -329,28 +331,9 @@ public:
      */
     void modify_vis( float alt, float time_factor );
 
-    /**
-     * Draw background portions of the sky ... do this before you draw
-     * the rest of your scene.  See discussion in detailed
-     * class description.
-     * @param alt current altitude
-     */
-    void preDraw( float alt, float fog_exp2_density );
-
-    /**
-     * Draw upper translucent clouds ... do this before you've drawn 
-     * all the translucent elements of your scene.  See discussion in 
-     * detailed class description.
-     * @param fog_exp2_density fog density of the current cloud layer
-     */
-    void drawUpperClouds();
-
-    /**
-     * Draw lower translucent clouds ... do this after you've drawn 
-     * all the opaque elements of your scene.  See discussion in detailed
-     * class description.
-     */
-    void drawLowerClouds();
+    osg::Node* getPreRoot() { return pre_root.get(); }
+    osg::Node* getPostRoot() { return post_root.get(); }
+    osg::Node* getCloudRoot() { return cloud_root.get(); }
 
     /** 
      * Specify the texture path (optional, defaults to current directory)
@@ -362,8 +345,8 @@ public:
 
     /** Enable drawing of the sky. */
     inline void enable() {
-       pre_selector->select( 1 );
-       post_selector->select( 1 );
+        pre_selector->setValue(0, 1);
+       post_selector->setValue(0, 1);
     }
 
     /**
@@ -371,21 +354,14 @@ public:
      * there, how ever it won't be traversed on by ssgCullandRender()
      */
     inline void disable() {
-       pre_selector->select( 0 );
-       post_selector->select( 0 );
+        pre_selector->setValue(0, 0);
+       post_selector->setValue(0, 0);
     }
 
-
     /**
      * Get the current sun color
      */
-    inline float *get_sun_color() { return oursun->get_color(); }
-
-    /**
-     * Get the sun halo texture handle
-     */
-    inline GLuint get_sun_texture_id() { return oursun->get_texture_id(); }
-
+    inline SGVec4f get_sun_color() { return oursun->get_color(); }
 
     /**
      * Add a cloud layer.
index 9ce1d7a40f63b59d0a4ff9ca62057812ac10d99f..11251b0ab6a0003734b1d34442f5d6fa85acabb4 100644 (file)
 
 #include STL_IOSTREAM
 
-#include <plib/sg.h>
-#include <plib/ssg.h>
+#include <osg/Node>
+#include <osg/Geometry>
+#include <osg/Geode>
+#include <osg/Array>
 
 
 // return a sphere object as an ssgBranch
-ssgBranch *ssgMakeSphere( ssgSimpleState *state, ssgColourArray *cl,
-                         double radius, int slices, int stacks,
-                         ssgCallback predraw, ssgCallback postdraw )
+osg::Node*
+SGMakeSphere(double radius, int slices, int stacks)
 {
-    float rho, drho, theta, dtheta;
-    float x, y, z;
+    float rho, drho, dtheta;
     float s, t, ds, dt;
     int i, j, imin, imax;
     float nsign = 1.0;
-    ssgBranch *sphere = new ssgBranch;
-    sgVec2 vec2;
-    sgVec3 vec3;
+    osg::Geode* geode = new osg::Geode;
 
     drho = SGD_PI / (float) stacks;
     dtheta = SGD_2PI / (float) slices;
@@ -62,69 +60,67 @@ ssgBranch *ssgMakeSphere( ssgSimpleState *state, ssgColourArray *cl,
 
     /* build slices as quad strips */
     for ( i = imin; i < imax; i++ ) {
-       ssgVertexArray   *vl = new ssgVertexArray();
-       ssgNormalArray   *nl = new ssgNormalArray();
-       ssgTexCoordArray *tl = new ssgTexCoordArray();
+        osg::Geometry* geometry = new osg::Geometry;
+        osg::Vec3Array* vl = new osg::Vec3Array;
+        osg::Vec3Array* nl = new osg::Vec3Array;
+        osg::Vec2Array* tl = new osg::Vec2Array;
 
        rho = i * drho;
        s = 0.0;
        for ( j = 0; j <= slices; j++ ) {
-           theta = (j == slices) ? 0.0 : j * dtheta;
-           x = -sin(theta) * sin(rho);
-           y = cos(theta) * sin(rho);
-           z = nsign * cos(rho);
+           double theta = (j == slices) ? 0.0 : j * dtheta;
+           double x = -sin(theta) * sin(rho);
+           double y = cos(theta) * sin(rho);
+           double z = nsign * cos(rho);
 
            // glNormal3f( x*nsign, y*nsign, z*nsign );
-           sgSetVec3( vec3, x*nsign, y*nsign, z*nsign );
-           sgNormalizeVec3( vec3 );
-           nl->add( vec3 );
+            osg::Vec3 normal(x*nsign, y*nsign, z*nsign);
+           normal.normalize();
+           nl->push_back(normal);
 
            // glTexCoord2f(s,t);
-           sgSetVec2( vec2, s, t );
-           tl->add( vec2 );
+           tl->push_back(osg::Vec2(s, t));
 
            // glVertex3f( x*radius, y*radius, z*radius );
-           sgSetVec3( vec3, x*radius, y*radius, z*radius );
-           vl->add( vec3 );
+           vl->push_back(osg::Vec3(x*radius, y*radius, z*radius));
 
            x = -sin(theta) * sin(rho+drho);
            y = cos(theta) * sin(rho+drho);
            z = nsign * cos(rho+drho);
 
            // glNormal3f( x*nsign, y*nsign, z*nsign );
-           sgSetVec3( vec3, x*nsign, y*nsign, z*nsign );
-           sgNormalizeVec3( vec3 );
-           nl->add( vec3 );
+            normal = osg::Vec3(x*nsign, y*nsign, z*nsign);
+           normal.normalize();
+           nl->push_back(normal);
 
            // glTexCoord2f(s,t-dt);
-           sgSetVec2( vec2, s, t-dt );
-           tl->add( vec2 );
+           tl->push_back(osg::Vec2(s, t-dt));
            s += ds;
 
            // glVertex3f( x*radius, y*radius, z*radius );
-           sgSetVec3( vec3, x*radius, y*radius, z*radius );
-           vl->add( vec3 );
+           vl->push_back(osg::Vec3(x*radius, y*radius, z*radius));
        }
 
-       ssgLeaf *slice = 
-           new ssgVtxTable ( GL_TRIANGLE_STRIP, vl, nl, tl, cl );
-
-       if ( vl->getNum() != nl->getNum() ) {
+       if ( vl->size() != nl->size() ) {
             SG_LOG( SG_EVENT, SG_ALERT, "bad sphere1");
            exit(-1);
        }
-       if ( vl->getNum() != tl->getNum() ) {
+       if ( vl->size() != tl->size() ) {
             SG_LOG( SG_EVENT, SG_ALERT, "bad sphere2");
            exit(-1);
        }
-       slice->setState( state );
-       slice->setCallback( SSG_CALLBACK_PREDRAW, predraw );
-       slice->setCallback( SSG_CALLBACK_POSTDRAW, postdraw );
 
-       sphere->addKid( slice );
+        geometry->setUseDisplayList(false);
+        geometry->setVertexArray(vl);
+        geometry->setNormalArray(nl);
+        geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
+        geometry->setTexCoordArray(0, tl);
+        geometry->setColorBinding(osg::Geometry::BIND_OFF);
+        geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, vl->size()));
+        geode->addDrawable(geometry);
 
        t -= dt;
     }
 
-    return sphere;
+    return geode;
 }
index 1ee808fe7778a5da5a057e2fc48af0f89140fcec..5c5eced0f066b83ec204e37e80095a2ee93a0a49 100644 (file)
 // $Id$
 
 
-#include <plib/ssg.h>
-
+#include <osg/Node>
 
 // return a sphere object as an ssgBranch (and connect in the
 // specified ssgSimpleState
-ssgBranch *ssgMakeSphere( ssgSimpleState *state, ssgColourArray *cl, 
-                         double radius, int slices, int stacks,
-                         ssgCallback predraw, ssgCallback postdraw );
+osg::Node* SGMakeSphere(double radius, int slices, int stacks);
 
 
index 6e8636e31ddd22e109e9ef5b092144dd6bc0f0f8..59717505be60a8602c753c319c66646c5886bf69 100644 (file)
 #include <stdio.h>
 #include STL_IOSTREAM
 
-#include <plib/sg.h>
-#include <plib/ssg.h>
+#include <osg/AlphaFunc>
+#include <osg/BlendFunc>
+#include <osg/Geode>
+#include <osg/Geometry>
+#include <osg/Image>
+#include <osg/Material>
+#include <osg/Point>
+#include <osg/ShadeModel>
 
 #include "stars.hxx"
 
-
-// Set up star rendering call backs
-static int sgStarPreDraw( ssgEntity *e ) {
-    /* cout << endl << "Star pre draw" << endl << "----------------" 
-       << endl << endl; */
-
-    ssgLeaf *f = (ssgLeaf *)e;
-    if ( f -> hasState () ) f->getState()->apply() ;
-
-    glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_FOG_BIT | GL_COLOR_BUFFER_BIT );
-
-    glDisable( GL_DEPTH_TEST );
-    glDisable( GL_FOG );
-    // glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
-
-    return true;
-}
-
-static int sgStarPostDraw( ssgEntity *e ) {
-    /* cout << endl << "Star post draw" << endl << "----------------" 
-       << endl << endl; */
-
-    glPopAttrib();
-
-    return true;
-}
-
-
 // Constructor
 SGStars::SGStars( void ) :
 old_phase(-1)
@@ -77,64 +55,76 @@ SGStars::~SGStars( void ) {
 
 
 // initialize the stars object and connect it into our scene graph root
-ssgBranch * SGStars::build( int num, sgdVec3 *star_data, double star_dist ) {
-    sgVec4 color;
-
-    if ( star_data == NULL )
-        SG_LOG( SG_EVENT, SG_WARN, "null star data passed to SGStars::build()");
-
-
-    // set up the orb state
-    state = new ssgSimpleState();
-    state->disable( GL_LIGHTING );
-    state->disable( GL_CULL_FACE );
-    state->disable( GL_TEXTURE_2D );
-    state->enable( GL_COLOR_MATERIAL );
-    state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
-    state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
-    state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
-    state->enable( GL_BLEND );
-    state->disable( GL_ALPHA_TEST );
-
-    vl = new ssgVertexArray( num );
-    cl = new ssgColourArray( num );
-    // cl = new ssgColourArray( 1 );
-    // sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
-    // cl->add( color );
-
-    // Build ssg structure
-    sgVec3 p;
+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;
 }
index 8c02b44e532f69622891f66a88cc07cacc307959..b44512c7656503917737742c467019c6338c50f9 100644 (file)
 #define _SG_STARS_HXX_
 
 
-#include <plib/ssg.h>
+#include <osg/Array>
+#include <osg/Node>
+#include <osg/MatrixTransform>
 
+#include <simgear/math/SGMath.hxx>
+#include <simgear/structure/SGReferenced.hxx>
 
-class SGStars {
 
-    ssgTransform *stars_transform;
-    ssgSimpleState *state;
+class SGStars : public SGReferenced {
 
-    ssgColourArray *cl;
-    ssgVertexArray *vl;
+    osg::ref_ptr<osg::MatrixTransform> stars_transform;
+    osg::ref_ptr<osg::Vec4Array> cl;
 
     int old_phase;             // data for optimization
 
@@ -51,7 +53,7 @@ public:
     ~SGStars( void );
 
     // initialize the stars structure
-    ssgBranch *build( int num, sgdVec3 *star_data, double star_dist );
+    osg::Node* build( int num, const SGVec3d star_data[], double star_dist );
 
     // repaint the planet magnitudes based on current value of
     // sun_angle in degrees relative to verticle (so we can make them
@@ -59,12 +61,12 @@ public:
     // 0 degrees = high noon
     // 90 degrees = sun rise/set
     // 180 degrees = darkest midnight
-    bool repaint( double sun_angle, int num, sgdVec3 *star_data );
+    bool repaint( double sun_angle, int num, const SGVec3d star_data[] );
 
     // reposition the stars for the specified time (GST rotation),
     // offset by our current position (p) so that it appears fixed at
     // a great distance from the viewer.
-    bool reposition( sgVec3 p, double angle );
+    bool reposition( const SGVec3f& p, double angle );
 };
 
 
index 3bda05cb4a3e4984b614c054f4bc6a83d2fe91fd..22d6344b3f13d804644f94443ed535a308b6321a 100644 (file)
 
 #include <vector>
 
+#include <osg/StateSet>
+#include <osg/Geode>
+#include <osg/Geometry>
+#include <osg/Group>
+
 #include <simgear/debug/logstream.hxx>
 #include <simgear/math/sg_types.hxx>
 #include <simgear/scene/tgdb/leaf.hxx>
@@ -41,14 +46,14 @@ SG_USING_STD(vector);
 
 // for temporary storage of sign elements
 struct element_info {
-    element_info(SGMaterial *m, ssgSimpleState *s, SGMaterialGlyph *g, double h)
+    element_info(SGMaterial *m, osg::StateSet *s, SGMaterialGlyph *g, double h)
         : material(m), state(s), glyph(g), height(h)
     {
         scale = h * m->get_xsize()
                 / (m->get_ysize() < 0.001 ? 1.0 : m->get_ysize());
     }
     SGMaterial *material;
-    ssgSimpleState *state;
+    osg::StateSet *state;
     SGMaterialGlyph *glyph;
     double height;
     double scale;
@@ -82,7 +87,8 @@ struct pair {
 
 // see $FG_ROOT/Docs/README.scenery
 //
-ssgBranch *sgMakeSign(SGMaterialLib *matlib, const string path, const string content)
+osg::Node*
+SGMakeSign(SGMaterialLib *matlib, const string& path, const string& content)
 {
     double sign_height = 1.0;  // meter
     bool lighted = true;
@@ -95,12 +101,12 @@ ssgBranch *sgMakeSign(SGMaterialLib *matlib, const string path, const string con
     int size = -1;
     char oldtype = 0, newtype = 0;
 
-    ssgBranch *object = new ssgBranch();
-    object->setName((char *)content.c_str());
+    osg::Group* object = new osg::Group;
+    object->setName(content);
 
     SGMaterial *material;
-    ssgSimpleState *lighted_state;
-    ssgSimpleState *unlighted_state;
+    osg::StateSet *lighted_state;
+    osg::StateSet *unlighted_state;
 
     // Part I: parse & measure
     for (const char *s = content.data(); *s; s++) {
@@ -239,7 +245,7 @@ ssgBranch *sgMakeSign(SGMaterialLib *matlib, const string path, const string con
         }
 
         // in managed mode push frame stop and frame start first
-        ssgSimpleState *state = lighted ? lighted_state : unlighted_state;
+        osg::StateSet *state = lighted ? lighted_state : unlighted_state;
         element_info *e;
         if (newtype && newtype != oldtype) {
             if (close) {
@@ -276,12 +282,6 @@ ssgBranch *sgMakeSign(SGMaterialLib *matlib, const string path, const string con
     double hpos = -total_width / 2;
     const double dist = 0.25;        // hard-code distance from surface for now
 
-    sgVec3 normal;
-    sgSetVec3(normal, 0, -1, 0);
-
-    sgVec4 color;
-    sgSetVec4(color, 1.0, 1.0, 1.0, 1.0);
-
     for (unsigned int i = 0; i < elements.size(); i++) {
         element_info *element = elements[i];
 
@@ -291,51 +291,67 @@ ssgBranch *sgMakeSign(SGMaterialLib *matlib, const string path, const string con
         double abswidth = width * element->scale;
 
         // vertices
-        ssgVertexArray *vl = new ssgVertexArray(4);
-        vl->add(0, hpos,            dist);
-        vl->add(0, hpos + abswidth, dist);
-        vl->add(0, hpos,            dist + height);
-        vl->add(0, hpos + abswidth, dist + height);
+        osg::Vec3Array* vl = new osg::Vec3Array;
+        vl->push_back(osg::Vec3(0, hpos,            dist));
+        vl->push_back(osg::Vec3(0, hpos + abswidth, dist));
+        vl->push_back(osg::Vec3(0, hpos,            dist + height));
+        vl->push_back(osg::Vec3(0, hpos + abswidth, dist + height));
 
         // texture coordinates
-        ssgTexCoordArray *tl = new ssgTexCoordArray(4);
-        tl->add(xoffset,         0);
-        tl->add(xoffset + width, 0);
-        tl->add(xoffset,         1);
-        tl->add(xoffset + width, 1);
+        osg::Vec2Array* tl = new osg::Vec2Array;
+        tl->push_back(osg::Vec2(xoffset,         0));
+        tl->push_back(osg::Vec2(xoffset + width, 0));
+        tl->push_back(osg::Vec2(xoffset,         1));
+        tl->push_back(osg::Vec2(xoffset + width, 1));
 
         // normals
-        ssgNormalArray *nl = new ssgNormalArray(1);
-        nl->add(normal);
+        osg::Vec3Array* nl = new osg::Vec3Array;
+        nl->push_back(osg::Vec3(0, -1, 0));
 
         // colors
-        ssgColourArray *cl = new ssgColourArray(1);
-        cl->add(color);
-
-        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;
 }
index ba96d1609db83511e62f0332fe3f6578288cd2db..dceccef7152bcba1f160409b775c584242b90b29 100644 (file)
@@ -34,7 +34,7 @@
 
 #include STL_STRING
 
-#include <plib/ssg.h>          // plib include
+#include <osg/Node>
 
 class SGMaterialLib;            // forward declaration
 
@@ -42,13 +42,13 @@ SG_USING_STD(string);
 
 
 // Generate a generic sign
-ssgBranch *sgMakeSign( SGMaterialLib *matlib,
-                       const string path, const string content );
+osg::Node* SGMakeSign( SGMaterialLib *matlib,
+                       const string& path, const string& content );
 
 
 // Generate a runway sign
-ssgBranch *sgMakeRunwaySign( SGMaterialLib *matlib,
-                             const string path, const string name );
+osg::Node* SGMakeRunwaySign( SGMaterialLib *matlib,
+                             const string& path, const string& name );
 
 
 #endif // _SG_APT_SIGNS_HXX
index 77e0ed9e26529ae290a93c7e650b2cea3984e992..dd8d743b98a97cb777b35f4a168b233aa71184bd 100644 (file)
 
 #include STL_STRING
 
+#include <osg/Geode>
+#include <osg/Geometry>
+#include <osg/Group>
+#include <osg/StateSet>
+#include <osg/TriangleFunctor>
+
 #include <simgear/debug/logstream.hxx>
 #include <simgear/math/sg_random.h>
 #include <simgear/scene/material/mat.hxx>
 #include <simgear/scene/material/matlib.hxx>
+// #include <simgear/scene/util/SGDebugDrawCallback.hxx>
 
 #include "leaf.hxx"
 
@@ -49,8 +56,9 @@ typedef int_list::iterator int_list_iterator;
 typedef int_list::const_iterator int_point_list_iterator;
 
 
-static void random_pt_inside_tri( float *res,
-                                  float *n1, float *n2, float *n3 )
+static inline
+osg::Vec3 random_pt_inside_tri(const osg::Vec3& n1, const osg::Vec3& n2,
+                               const osg::Vec3& n3 )
 {
     double a = sg_random();
     double b = sg_random();
@@ -60,60 +68,45 @@ static void random_pt_inside_tri( float *res,
     }
     double c = 1 - a - b;
 
-    res[0] = n1[0]*a + n2[0]*b + n3[0]*c;
-    res[1] = n1[1]*a + n2[1]*b + n3[1]*c;
-    res[2] = n1[2]*a + n2[2]*b + n3[2]*c;
+    return n1*a + n2*b + n3*c;
 }
 
-
-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<SGRandomSurfacePointsFill> triangleFunctor;
+  triangleFunctor.lights = lights;
+  triangleFunctor.factor = factor;
+  leaf->accept(triangleFunctor);
 }
 
 
@@ -121,7 +114,7 @@ ssgVertexArray *sgGenRandomSurfacePoints( ssgLeaf *leaf, double factor ) {
 // Scenery loaders.
 ////////////////////////////////////////////////////////////////////////
 
-ssgLeaf *sgMakeLeaf( const string& path,
+osg::Node* SGMakeLeaf( const string& path,
                      const GLenum ty, 
                      SGMaterialLib *matlib, const string& material,
                      const point_list& nodes, const point_list& normals,
@@ -129,10 +122,10 @@ ssgLeaf *sgMakeLeaf( const string& path,
                      const int_list& node_index,
                      const int_list& normal_index,
                      const int_list& tex_index,
-                     const bool calc_lights, ssgVertexArray *lights )
+                     const bool calc_lights, osg::Vec3Array *lights )
 {
     double tex_width = 1000.0, tex_height = 1000.0;
-    ssgSimpleState *state = NULL;
+    osg::StateSet *state = 0;
     float coverage = -1;
 
     SGMaterial *mat = matlib->find( material );
@@ -173,9 +166,6 @@ ssgLeaf *sgMakeLeaf( const string& path,
         coverage = -1;
     }
 
-    sgVec2 tmp2;
-    sgVec3 tmp3;
-    sgVec4 tmp4;
     int i;
 
     // vertices
@@ -184,74 +174,81 @@ ssgLeaf *sgMakeLeaf( const string& path,
         SG_LOG( SG_TERRAIN, SG_ALERT, "Woh! node list size < 1" );
         exit(-1);
     }
-    ssgVertexArray *vl = new ssgVertexArray( size );
-    Point3D node;
+    osg::Vec3Array* vl = new osg::Vec3Array;
+    vl->reserve(size);
     for ( i = 0; i < size; ++i ) {
-        node = nodes[ node_index[i] ];
-        sgSetVec3( tmp3, node[0], node[1], node[2] );
-        vl -> add( tmp3 );
+        Point3D node = nodes[ node_index[i] ];
+        vl->push_back(osg::Vec3(node[0], node[1], node[2]));
     }
 
     // normals
-    Point3D normal;
-    ssgNormalArray *nl = new ssgNormalArray( size );
+    osg::Vec3Array* nl = new osg::Vec3Array;
+    nl->reserve(size);
     if ( normal_index.size() ) {
         // object file specifies normal indices (i.e. normal indices
         // aren't 'implied'
         for ( i = 0; i < size; ++i ) {
-            normal = normals[ normal_index[i] ];
-            sgSetVec3( tmp3, normal[0], normal[1], normal[2] );
-            nl -> add( tmp3 );
+            Point3D normal = normals[ normal_index[i] ];
+            nl->push_back(osg::Vec3(normal[0], normal[1], normal[2]));
         }
     } else {
         // use implied normal indices.  normal index = vertex index.
         for ( i = 0; i < size; ++i ) {
-            normal = normals[ node_index[i] ];
-            sgSetVec3( tmp3, normal[0], normal[1], normal[2] );
-            nl -> add( tmp3 );
+            Point3D normal = normals[ node_index[i] ];
+            nl->push_back(osg::Vec3(normal[0], normal[1], normal[2]));
         }
     }
 
     // colors
-    ssgColourArray *cl = new ssgColourArray( 1 );
-    sgSetVec4( tmp4, 1.0, 1.0, 1.0, 1.0 );
-    cl->add( tmp4 );
+    osg::Vec4Array* cl = new osg::Vec4Array;
+    cl->push_back(osg::Vec4(1, 1, 1, 1));
 
     // texture coordinates
     size = tex_index.size();
     Point3D texcoord;
-    ssgTexCoordArray *tl = new ssgTexCoordArray( size );
+    osg::Vec2Array* tl = new osg::Vec2Array;
+    tl->reserve(size);
     if ( size == 1 ) {
-        texcoord = texcoords[ tex_index[0] ];
-        sgSetVec2( tmp2, texcoord[0], texcoord[1] );
-        //sgSetVec2( tmp2, texcoord[0], texcoord[1] );
+        Point3D texcoord = texcoords[ tex_index[0] ];
+        osg::Vec2 tmp2(texcoord[0], texcoord[1]);
         if ( tex_width > 0 ) {
             tmp2[0] *= (1000.0 / tex_width);
         }
         if ( tex_height > 0 ) {
             tmp2[1] *= (1000.0 / tex_height);
         }
-        tl -> add( tmp2 );
+        tl -> push_back( tmp2 );
     } else if ( size > 1 ) {
         for ( i = 0; i < size; ++i ) {
-            texcoord = texcoords[ tex_index[i] ];
-            sgSetVec2( tmp2, texcoord[0], texcoord[1] );
+            Point3D texcoord = texcoords[ tex_index[i] ];
+            osg::Vec2 tmp2(texcoord[0], texcoord[1]);
             if ( tex_width > 0 ) {
                 tmp2[0] *= (1000.0 / tex_width);
             }
             if ( tex_height > 0 ) {
                 tmp2[1] *= (1000.0 / tex_height);
             }
-            tl -> add( tmp2 );
+            tl -> push_back( tmp2 );
         }
     }
 
-    ssgLeaf *leaf = new ssgVtxTable ( ty, vl, nl, tl, cl );
 
-    // 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;
 }
index 779e67406cad0448a5a7ce0d8cc33b8c3bcc08e9..eb4e663dd26fad6f229363fb83e75861ddb381a1 100644 (file)
@@ -34,7 +34,8 @@
 
 #include STL_STRING
 
-#include <plib/ssg.h>           // plib include
+#include <osg/Array>
+#include <osg/Node>
 
 #include <simgear/math/sg_types.hxx>
 
@@ -45,7 +46,7 @@ class SGMaterialLib;            // forward declaration.
 
 
 // Create a ssg leaf
-ssgLeaf *sgMakeLeaf( const string& path,
+osg::Node* SGMakeLeaf( const string& path,
                      const GLenum ty,
                      SGMaterialLib *matlib, const string& material,
                      const point_list& nodes, const point_list& normals,
@@ -53,17 +54,6 @@ ssgLeaf *sgMakeLeaf( const string& path,
                      const int_list& node_index,
                      const int_list& normal_index,
                      const int_list& tex_index,
-                     const bool calc_lights, ssgVertexArray *lights );
-
-
-// return a newly created list of points randomly spread across the
-// specified leaf.  "factor" specifies density ... on average there
-// will be one object per the area specified by "factor" in m^2 A
-// larger factor will mean fewer objects.
-ssgVertexArray *sgGenRandomSurfacePoints( ssgLeaf *leaf, double factor );
-
-// Another varient of the same routine.
-void sgGenRandomSurfacePoints( ssgLeaf *leaf, double factor, 
-                               ssgVertexArray *lights );
+                     const bool calc_lights, osg::Vec3Array *lights );
 
 #endif // _SG_LEAF_HXX
index c0bf8d0fbec8c043d03fdb481ec70f046187ce01..a5bfcda9b346694155499e469e0c0e0786e09e38 100644 (file)
 
 #include STL_STRING
 
+#include <osg/StateSet>
+#include <osg/Geode>
+#include <osg/Geometry>
+#include <osg/Group>
+#include <osg/LOD>
+
 #include <simgear/bucket/newbucket.hxx>
 #include <simgear/io/sg_binobj.hxx>
 #include <simgear/math/sg_geodesy.hxx>
@@ -55,13 +61,11 @@ struct Leaf {
 
 
 // Generate an ocean tile
-bool sgGenTile( const string& path, SGBucket b,
+bool SGGenTile( const string& path, SGBucket b,
                 Point3D *center, double *bounding_radius,
-                SGMaterialLib *matlib, ssgBranch* geometry )
+                SGMaterialLib *matlib, osg::Group* group )
 {
-    ssgSimpleState *state = NULL;
-
-    geometry->setName( (char *)path.c_str() );
+    osg::StateSet *state = 0;
 
     double tex_width = 1000.0;
     // double tex_height;
@@ -142,43 +146,30 @@ bool sgGenTile( const string& path, SGBucket b,
                                        1000.0 / tex_width );
 
     // Allocate ssg structure
-    ssgVertexArray   *vl = new ssgVertexArray( 4 );
-    ssgNormalArray   *nl = new ssgNormalArray( 4 );
-    ssgTexCoordArray *tl = new ssgTexCoordArray( 4 );
-    ssgColourArray   *cl = new ssgColourArray( 1 );
-
-    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<string,list<Leaf> > LeafMap;
@@ -443,7 +436,7 @@ bool sgBinObjLoad( const string& path, const bool is_base,
             Leaf &leaf = *li;
             int ind = leaf.index;
             if ( leaf.type == GL_TRIANGLES ) {
-                ssgLeaf *leaf = sgMakeLeaf( path, GL_TRIANGLES, matlib,
+                osg::Node *leaf = SGMakeLeaf( path, GL_TRIANGLES, matlib,
                                             tri_materials[ind],
                                             nodes, normals, texcoords,
                                             tris_v[ind], tris_n[ind], tris_tc[ind],
@@ -459,9 +452,9 @@ bool sgBinObjLoad( const string& path, const bool is_base,
                                                     center, mat );
                     }
                 }
-                local_terrain->addKid( leaf );
+                local_terrain->addChild( leaf );
             } else if ( leaf.type == GL_TRIANGLE_STRIP ) {
-                ssgLeaf *leaf = sgMakeLeaf( path, GL_TRIANGLE_STRIP,
+                osg::Node *leaf = SGMakeLeaf( path, GL_TRIANGLE_STRIP,
                                             matlib, strip_materials[ind],
                                             nodes, normals, texcoords,
                                             strips_v[ind], strips_n[ind], strips_tc[ind],
@@ -477,9 +470,9 @@ bool sgBinObjLoad( const string& path, const bool is_base,
                                                     center, mat );
                     }
                 }
-                local_terrain->addKid( leaf );
+                local_terrain->addChild( leaf );
             } else {
-                ssgLeaf *leaf = sgMakeLeaf( path, GL_TRIANGLE_FAN,
+                osg::Node *leaf = SGMakeLeaf( path, GL_TRIANGLE_FAN,
                                             matlib, fan_materials[ind],
                                             nodes, normals, texcoords,
                                             fans_v[ind], fans_n[ind], fans_tc[ind],
@@ -495,7 +488,7 @@ bool sgBinObjLoad( const string& path, const bool is_base,
                                                     center, mat );
                     }
                 }
-                local_terrain->addKid( leaf );
+                local_terrain->addChild( leaf );
             }
             ++li;
         }
index 883336ea1b8b8d17b331b027f0f64142a6a60786..5e3ae30a586bc1107aa10d25e25aa41dbf68dada 100644 (file)
@@ -35,7 +35,8 @@
 
 #include STL_STRING
 
-#include <plib/ssg.h>           // plib include
+#include <osg/Array>
+#include <osg/Group>
 
 #include <simgear/math/point3d.hxx>
 
@@ -46,21 +47,21 @@ class SGMaterialLib;
 
 
 // Load a Binary obj file
-bool sgBinObjLoad( const string& path, const bool is_base,
+bool SGBinObjLoad( const string& path, const bool is_base,
                    Point3D *center,
                    double *bounding_radius,
                    SGMaterialLib *matlib,
                    bool use_random_objects,
-                   ssgBranch *geometry,
-                   ssgBranch *vasi_lights,
-                   ssgBranch *rwy_lights,
-                   ssgBranch *taxi_lights,
-                   ssgVertexArray *ground_lights );
+                   osg::Group *geometry,
+                   osg::Group *vasi_lights,
+                   osg::Group *rwy_lights,
+                   osg::Group *taxi_lights,
+                   osg::Vec3Array *ground_lights );
 
 // Generate an ocean tile
-bool sgGenTile( const string& path, SGBucket b,
+bool SGGenTile( const string& path, SGBucket b,
                 Point3D *center, double *bounding_radius,
-                SGMaterialLib *matlib, ssgBranch *geometry );
+                SGMaterialLib *matlib, osg::Group *geometry );
 
 
 #endif // _SG_OBJ_HXX
index 21193f9c2edda23c5027a68bb0f853e7c0805661..6097d12d6a4f33bbc899a5ce6996c4b4079298c0 100644 (file)
 #  include <simgear_config.h>
 #endif
 
-#include <plib/sg.h>
-#include <plib/ssg.h>
+#include <osg/Array>
+#include <osg/Geometry>
+#include <osg/Geode>
+#include <osg/LOD>
+#include <osg/MatrixTransform>
+#include <osg/NodeCallback>
+#include <osg/NodeVisitor>
+#include <osg/Switch>
 
 #include <simgear/scene/material/mat.hxx>
 #include <simgear/screen/extensions.hxx>
+#include <simgear/math/sg_random.h>
 
 #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<osg::Switch*>(node));
+    osg::Switch* sw = static_cast<osg::Switch*>(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;
index de5240a3ef6b848e054ab444aff4cb1d7fa94c31..431233ceae776a8b81e74eba2cffbc698a26911a 100644 (file)
@@ -35,9 +35,6 @@
 #include STL_STRING
 #include <vector>              // STL
 
-#include <plib/sg.h>
-#include <plib/ssg.h>          // plib include
-
 #include <simgear/math/sg_types.hxx>
 #include <simgear/scene/material/matlib.hxx>
 
@@ -79,21 +76,18 @@ typedef int_list::const_iterator int_point_list_iterator;
 // Yes this get's to be long and convoluted.  If you can suggest a
 // simpler way, please do! :-)
 
-ssgLeaf *sgMakeDirectionalLight( sgVec3 pt, sgVec3 dir, sgVec3 up );
-
-
-ssgBranch *sgMakeDirectionalLights( const point_list &nodes,
+osg::Node *SGMakeDirectionalLights( const point_list &nodes,
                                     const point_list &normals,
                                     const int_list &pnt_i,
                                     const int_list &nml_i,
                                     SGMaterialLib *matlib,
                                     const string &material,
-                                    sgdVec3 dup );
+                                    const SGVec3d& dup );
 
 // Specify the way we want to draw directional point lights (assuming the
 // appropriate extensions are available.)
 
-void sgConfigureDirectionalLights( bool use_point_sprites,
+void SGConfigureDirectionalLights( bool use_point_sprites,
                                    bool enhanced_lighting,
                                    bool distance_attenuation );
 
index 9bb7c9c81a6f7ba504a764c8c0c686fbde97c05d..52f0a6f87726478b9712b069f88efb58b6416d20 100644 (file)
@@ -25,9 +25,6 @@
 #  include <simgear_config.h>
 #endif
 
-#include <plib/sg.h>
-#include <plib/ssg.h>
-
 #include <simgear/sg_inlines.h>
 #include <simgear/math/point3d.hxx>
 #include <simgear/math/sg_geodesy.hxx>
@@ -120,6 +117,8 @@ void SGTriUserData::add_object_to_triangle (SGMatModel * object)
     if (object->get_heading_type() == SGMatModel::HEADING_RANDOM)
         hdg_deg = sg_random() * 360;
 
+#if 0
+    // OSGFIXME
     sgMat4 mat;
     makeWorldMatrix(mat, hdg_deg);
 
@@ -132,45 +131,47 @@ void SGTriUserData::add_object_to_triangle (SGMatModel * object)
                                            root_props, sim_time_sec )
                  );
     branch->addKid(pos);
+#endif
 }
 
 void SGTriUserData::makeWorldMatrix (sgMat4 mat, double hdg_deg )
 {
-    if (hdg_deg == 0) {
-        mat[0][0] =  leafData->sin_lat * leafData->cos_lon;
-        mat[0][1] =  leafData->sin_lat * leafData->sin_lon;
-        mat[0][2] = -leafData->cos_lat;
-        mat[0][3] =  SG_ZERO;
-
-        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);
+//     }
 }
index dfb439035a1830bd682cd7e94fd9b7b52d5e7dd9..7001e9954eb396e8d7dca83227632eafd481b909 100644 (file)
 
 #include STL_STRING
 
-#include <plib/ssg.h>
+#include <plib/sg.h>
+
+#include <osg/Referenced>
+#include <osg/Geometry>
+#include <osg/Group>
 
 SG_USING_STD(string);
 
@@ -52,13 +56,13 @@ void sgUserDataInit( SGModelLib *m, const string &r,
 /**
  * User data for populating leaves when they come in range.
  */
-class SGLeafUserData : public ssgBase
+class SGLeafUserData : public osg::Referenced
 {
 public:
     bool is_filled_in;
-    ssgLeaf *leaf;
+    osg::Geometry *leaf;
     SGMaterial *mat;
-    ssgBranch *branch;
+    osg::Group *branch;
     float sin_lat;
     float cos_lat;
     float sin_lon;
@@ -71,17 +75,17 @@ public:
 /**
  * User data for populating triangles when they come in range.
  */
-class SGTriUserData : public ssgBase
+class SGTriUserData : public osg::Referenced
 {
 public:
     bool is_filled_in;
     float * p1;
     float * p2;
     float * p3;
-    sgVec3 center;
+    osg::Vec3 center;
     double area;
     SGMatModelGroup * object_group;
-    ssgBranch * branch;
+    osg::Group * branch;
     SGLeafUserData * leafData;
     unsigned int seed;
 
@@ -90,26 +94,4 @@ public:
     void makeWorldMatrix (sgMat4 ROT, double hdg_deg );
 };
 
-
-/**
- * ssgEntity with a dummy bounding sphere, to fool culling.
- *
- * This forces the in-range and out-of-range branches to be visited
- * when appropriate, even if they have no children.  It's ugly, but
- * it works and seems fairly efficient (since branches can still
- * be culled when they're out of the view frustum).
- */
-class SGDummyBSphereEntity : public ssgBranch
-{
-public:
-  SGDummyBSphereEntity (float radius)
-  {
-    bsphere.setCenter(0, 0, 0);
-    bsphere.setRadius(radius);
-  }
-  virtual ~SGDummyBSphereEntity () {}
-  virtual void recalcBSphere () { bsphere_is_invalid = false; }
-};
-
-
 #endif // _SG_USERDATA_HXX
index 10319d4fc7445ca8b119d665d3cc9ca153fea8ad..92a790cb0d1e64879f0e60f94ce674c65ae93de0 100644 (file)
 #ifndef _SG_VASI_HXX
 #define _SG_VASI_HXX
 
-
 #ifndef __cplusplus
 # error This library requires C++
 #endif
 
-
 #include <simgear/compiler.h>
 
-#include STL_STRING
-SG_USING_STD(string);
-
-#include <plib/ssg.h>          // plib include
-
-#include <simgear/math/sg_geodesy.hxx>
-
-
-class SGVASIUserData : public ssgBase
-{
-
-private:
-
-    sgdVec3 abs_pos;
-    double alt_m;
-    ssgLeaf *leaf;
-
+#include <osg/io_utils>
+#include <osg/ref_ptr>
+#include <osg/Array>
+#include <osg/NodeCallback>
+#include <osg/NodeVisitor>
+#include <osg/Vec3>
+
+/// Callback that updates the colors of a VASI according to the view direction
+/// Notet that we need the eyepoint which is only available during culling
+/// So this will be a cull callback ...
+class SGVasiUpdateCallback : public osg::NodeCallback {
 public:
-
-    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<osg::Vec4Array> 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 (file)
index 0000000..0241c3e
--- /dev/null
@@ -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 (file)
index 0000000..3754423
--- /dev/null
@@ -0,0 +1,164 @@
+/* -*-c++-*-
+ *
+ * Copyright (C) 2006 Mathias Froehlich 
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SG_SCENE_DEBUGDRAWCALLBACK_HXX
+#define SG_SCENE_DEBUGDRAWCALLBACK_HXX
+
+#include <iostream>
+#include <GL/gl.h>
+#include <osg/Drawable>
+#include <osg/State>
+
+struct SGDebugDrawCallback : public osg::Drawable::DrawCallback {
+  virtual void drawImplementation(osg::State& state,
+                                  const osg::Drawable* drawable) const
+  {
+//     state.dirtyColorPointer();
+    printState(std::cout, drawable);
+    drawable->drawImplementation(state);
+    printState(std::cout, drawable);
+//     state.dirtyColorPointer();
+  }
+
+  void printState(std::ostream& stream, const osg::Drawable* drawable) const
+  {
+    stream << "Drawable \"" << drawable->getName() << "\"";
+#ifdef ERROR_CHECK
+#undef ERROR_CHECK
+#endif
+
+#define ERROR_CHECK(msg)              \
+do {                                  \
+  GLenum errorNo = glGetError();      \
+  if (errorNo != GL_NO_ERROR)         \
+    stream << msg;                    \
+} while(0)
+
+#ifdef PRINT_STATE
+#undef PRINT_STATE
+#endif
+#define PRINT_STATE(flag)             \
+do {                                  \
+  if (glIsEnabled(flag))              \
+    stream << " " #flag;              \
+  ERROR_CHECK(" ERROR " #flag);       \
+} while(0)
+
+    PRINT_STATE(GL_COLOR_ARRAY);
+    PRINT_STATE(GL_EDGE_FLAG_ARRAY);
+    PRINT_STATE(GL_INDEX_ARRAY);
+    PRINT_STATE(GL_NORMAL_ARRAY);
+    PRINT_STATE(GL_TEXTURE_COORD_ARRAY);
+    PRINT_STATE(GL_VERTEX_ARRAY);
+
+    PRINT_STATE(GL_ALPHA_TEST);
+    PRINT_STATE(GL_AUTO_NORMAL);
+    PRINT_STATE(GL_BLEND);
+    PRINT_STATE(GL_CLIP_PLANE0);
+    PRINT_STATE(GL_CLIP_PLANE1);
+    PRINT_STATE(GL_CLIP_PLANE2);
+    PRINT_STATE(GL_CLIP_PLANE3);
+    PRINT_STATE(GL_CLIP_PLANE4);
+    PRINT_STATE(GL_CLIP_PLANE5);
+    PRINT_STATE(GL_COLOR_LOGIC_OP);
+//     PRINT_STATE(GL_COLOR_TABLE);
+//     PRINT_STATE(GL_CONVOLUTION_1D);
+//     PRINT_STATE(GL_CONVOLUTION_2D);
+    PRINT_STATE(GL_CULL_FACE);
+    PRINT_STATE(GL_DEPTH_TEST);
+    PRINT_STATE(GL_DITHER);
+    PRINT_STATE(GL_FOG);
+//     PRINT_STATE(GL_HISTOGRAM);
+    PRINT_STATE(GL_INDEX_LOGIC_OP);
+    PRINT_STATE(GL_LIGHT0);
+    PRINT_STATE(GL_LIGHT1);
+    PRINT_STATE(GL_LIGHT2);
+    PRINT_STATE(GL_LIGHT3);
+    PRINT_STATE(GL_LIGHT4);
+    PRINT_STATE(GL_LIGHT5);
+    PRINT_STATE(GL_LIGHT6);
+    PRINT_STATE(GL_LIGHT7);
+    PRINT_STATE(GL_LIGHTING);
+    PRINT_STATE(GL_LINE_SMOOTH);
+    PRINT_STATE(GL_LINE_STIPPLE);
+    PRINT_STATE(GL_MAP1_COLOR_4);
+    PRINT_STATE(GL_MAP1_INDEX);
+    PRINT_STATE(GL_MAP1_NORMAL);
+    PRINT_STATE(GL_MAP1_TEXTURE_COORD_1);
+    PRINT_STATE(GL_MAP1_TEXTURE_COORD_2);
+    PRINT_STATE(GL_MAP1_TEXTURE_COORD_3);
+    PRINT_STATE(GL_MAP1_TEXTURE_COORD_4);
+    PRINT_STATE(GL_MAP2_COLOR_4);
+    PRINT_STATE(GL_MAP2_INDEX);
+    PRINT_STATE(GL_MAP2_NORMAL);
+    PRINT_STATE(GL_MAP2_TEXTURE_COORD_1);
+    PRINT_STATE(GL_MAP2_TEXTURE_COORD_2);
+    PRINT_STATE(GL_MAP2_TEXTURE_COORD_3);
+    PRINT_STATE(GL_MAP2_TEXTURE_COORD_4);
+    PRINT_STATE(GL_MAP2_VERTEX_3);
+    PRINT_STATE(GL_MAP2_VERTEX_4);
+//     PRINT_STATE(GL_MINMAX);
+    PRINT_STATE(GL_NORMALIZE);
+    PRINT_STATE(GL_POINT_SMOOTH);
+    PRINT_STATE(GL_POLYGON_SMOOTH);
+    PRINT_STATE(GL_POLYGON_OFFSET_FILL);
+    PRINT_STATE(GL_POLYGON_OFFSET_LINE);
+    PRINT_STATE(GL_POLYGON_OFFSET_POINT);
+    PRINT_STATE(GL_POLYGON_STIPPLE);
+//     PRINT_STATE(GL_POST_COLOR_MATRIX_COLOR_TABLE);
+//     PRINT_STATE(GL_POST_CONVOLUTION_COLOR_TABLE);
+    PRINT_STATE(GL_RESCALE_NORMAL);
+    PRINT_STATE(GL_SCISSOR_TEST);
+//     PRINT_STATE(GL_SEPARABLE_2D);
+    PRINT_STATE(GL_STENCIL_TEST);
+    PRINT_STATE(GL_TEXTURE_1D);
+    PRINT_STATE(GL_TEXTURE_2D);
+    PRINT_STATE(GL_TEXTURE_3D);
+    PRINT_STATE(GL_TEXTURE_GEN_Q);
+    PRINT_STATE(GL_TEXTURE_GEN_R);
+    PRINT_STATE(GL_TEXTURE_GEN_S);
+    PRINT_STATE(GL_TEXTURE_GEN_T);
+#undef PRINT_STATE
+#undef ERROR_CHECK
+
+    if (glIsEnabled(GL_COLOR_MATERIAL)) {
+      stream << " GL_COLOR_MATERIAL(";
+      GLint value;
+      glGetIntegerv(GL_COLOR_MATERIAL_PARAMETER, &value);
+      if (value == GL_DIFFUSE)
+        stream << "GL_DIFFUSE";
+      if (value == GL_AMBIENT)
+        stream << "GL_AMBIENT";
+      if (value == GL_AMBIENT_AND_DIFFUSE)
+        stream << "GL_AMBIENT_AND_DIFFUSE";
+      if (value == GL_EMISSION)
+        stream << "GL_EMISSION";
+      if (value == GL_SPECULAR)
+        stream << "GL_SPECULAR";
+
+      stream << ")";
+    }
+
+    stream << "\n";
+  }
+};
+  
+#endif
diff --git a/simgear/scene/util/SGNodeMasks.hxx b/simgear/scene/util/SGNodeMasks.hxx
new file mode 100644 (file)
index 0000000..f89f7f2
--- /dev/null
@@ -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 (file)
index 0000000..cd38141
--- /dev/null
@@ -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 (file)
index 0000000..7458f85
--- /dev/null
@@ -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 (file)
index 0000000..7fdba11
--- /dev/null
@@ -0,0 +1,66 @@
+/* -*-c++-*-
+ *
+ * Copyright (C) 2006 Mathias Froehlich 
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SG_SCENE_UPDATEVISITOR_HXX
+#define SG_SCENE_UPDATEVISITOR_HXX
+
+#include <osg/NodeVisitor>
+#include <osgUtil/UpdateVisitor>
+
+#include <osg/io_utils>
+
+class SGUpdateVisitor : public osgUtil::UpdateVisitor {
+public:
+  SGUpdateVisitor()
+  {
+//     setTraversalMode(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN);
+  }
+//   virtual void apply(osg::Transform& transform)
+//   {
+//     osg::Matrix matrix = mModelViewMatrix;
+//     transform.computeLocalToWorldMatrix(mModelViewMatrix, this);
+
+//     handle_callbacks_and_traverse(transform);
+
+//     mModelViewMatrix = matrix;
+//   }
+
+//   virtual osg::Vec3 getEyePoint() const
+//   {
+//     osg::Matrix matrix;
+//     matrix.invert(mModelViewMatrix);
+//     return matrix.preMult(osg::Vec3(0, 0, 0));
+//   }
+
+// protected:
+//   osg::Matrix mModelViewMatrix;
+};
+
+// #include <osg/NodeCallback>
+
+// class SGNodeCallback : public osg::NodeCallback {
+// public:
+//   virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
+//   {
+//   }
+// };
+
+#endif
index 49621fe5a22f8a2a9fd4a50531ec139611aa08b6..a5160cfc17fd1ccf09479e1241ff10c3023b32f6 100644 (file)
@@ -25,8 +25,6 @@
 #  include <windows.h>
 #endif
 
-#include <plib/ssg.h>
-
 #include "jpgfactory.hxx"
    
 
@@ -42,6 +40,7 @@ static boolean empty_output_buffer (j_compress_ptr cinfo);
 }
 #endif
 
+// OSGFIME: offscreenrendering on osg - completely new context ...
 
 typedef struct {
     struct jpeg_destination_mgr pub; /* public fields */
@@ -238,7 +237,8 @@ int trJpgFactory::render()
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
 
-    sgFrustum *frustum = ssgGetFrustum();
+    // OSGFIXME
+//     sgFrustum *frustum = ssgGetFrustum();
     trFrustum(tr,
               frustum->getLeft(), frustum->getRight(),
               frustum->getBot(),  frustum->getTop(), 
diff --git a/simgear/screen/ssgEntityArray.cxx b/simgear/screen/ssgEntityArray.cxx
deleted file mode 100644 (file)
index bf1c12d..0000000
+++ /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 <simgear_config.h>
-#endif
-
-#include "ssgEntityArray.hxx"
-
-
-// Forward declaration of internal ssg stuff (for hot/isec/los/etc.)
-void _ssgPushPath ( ssgEntity *l ) ;
-void _ssgPopPath () ;
-
-
-void ssgEntityArray::copy_from ( ssgEntityArray *src, int clone_flags )
-{
-  ssgEntity::copy_from ( src, clone_flags ) ;
-
-  ssgEntity *k = src -> getModel ( ) ;
-  if ( k != NULL && ( clone_flags & SSG_CLONE_RECURSIVE ) )
-      setModel ( (ssgEntity *)( k -> clone ( clone_flags )) ) ;
-  else
-      setModel ( k ) ;
-
-  ssgTransform *t = src -> getPosTransform();
-  if ( t != NULL && ( clone_flags & SSG_CLONE_RECURSIVE ) )
-      pos = (ssgTransform *)( t -> clone ( clone_flags ) );
-  else
-      pos = t;
-
-  ssgVertexArray *v = src -> getLocations();
-  if ( v != NULL && ( clone_flags & SSG_CLONE_RECURSIVE ) )
-      locations = (ssgVertexArray *)( v -> clone ( clone_flags ) );
-  else
-      locations = v;
-
-  v = src -> getOrientations();
-  if ( v != NULL && ( clone_flags & SSG_CLONE_RECURSIVE ) )
-      orientations = (ssgVertexArray *)( v -> clone ( clone_flags ) );
-  else
-      orientations = v;
-}
-
-ssgBase *ssgEntityArray::clone ( int clone_flags )
-{
-  ssgEntityArray *b = new ssgEntityArray ;
-  b -> copy_from ( this, clone_flags ) ;
-  return b ;
-}
-
-
-
-ssgEntityArray::ssgEntityArray (void)
-{
-    type = ssgTypeBranch () ;
-    pos = new ssgTransform;
-    locations = new ssgVertexArray();
-    orientations = new ssgVertexArray();
-}
-
-
-ssgEntityArray::~ssgEntityArray (void)
-{
-    removeModel() ;
-    ssgDeRefDelete( pos );
-    locations->removeAll();
-    orientations->removeAll();
-
-    delete orientations;
-    delete locations;
-    delete pos;
-}
-
-
-void ssgEntityArray::zeroSpareRecursive ()
-{
-  zeroSpare () ;
-
-  model -> zeroSpareRecursive () ;
-  pos -> zeroSpareRecursive () ;
-  locations -> zeroSpareRecursive () ;
-  orientations -> zeroSpareRecursive () ;
-}
-
-
-void ssgEntityArray::recalcBSphere (void)
-{
-  emptyBSphere () ;
-
-  pos->removeAllKids();
-  pos->addKid( model );
-
-  for ( int i = 0; i < locations->getNum(); ++i ) {
-      sgCoord c;
-      sgSetCoord( &c, locations->get(i), orientations->get(i) );
-      pos->setTransform( &c );
-      extendBSphere( pos->getBSphere() );
-  }
-
-  pos->removeAllKids();
-
-  /* FIXME: Traverse placement list
-  for ( ssgEntity *k = getKid ( 0 ) ; k != NULL ; k = getNextKid () )
-    extendBSphere ( k -> getBSphere () ) ;
-  */
-
-  bsphere_is_invalid = FALSE ;
-}
-
-
-void ssgEntityArray::removeModel ()
-{
-    model->deadBeefCheck () ;
-    ssgDeRefDelete ( model ) ;
-}
-
-
-void ssgEntityArray::replaceModel ( ssgEntity *new_entity )
-{
-    removeModel();
-    setModel( new_entity );
-}
-
-
-void ssgEntityArray::addPlacement ( sgVec3 loc, sgVec3 orient )
-{
-    locations->add( loc ) ;
-    orientations->add( orient ) ;
-    dirtyBSphere () ;
-}
-
-
-void ssgEntityArray::removeAllPlacements()
-{
-    locations->removeAll();
-    orientations->removeAll();
-    dirtyBSphere () ;
-}
-
-
-void ssgEntityArray::print ( FILE *fd, char *indent, int how_much )
-{
-  ssgEntity::print ( fd, indent, how_much ) ;
-  fprintf ( fd, "%s  Num Kids=%d\n", indent, getNumKids() ) ;
-
-  if ( getNumParents() != getRef() )
-    ulSetError ( UL_WARNING, "Ref count doesn't tally with parent count" ) ;
-
-       if ( how_much > 1 )
-  {    if ( bsphere.isEmpty() )
-                       fprintf ( fd, "%s  BSphere is Empty.\n", indent ) ;
-               else
-                       fprintf ( fd, "%s  BSphere  R=%g, C=(%g,%g,%g)\n", indent,
-                               bsphere.getRadius(), bsphere.getCenter()[0], bsphere.getCenter()[1], bsphere.getCenter()[2] ) ;
-       }
-
-  char in [ 100 ] ;
-  sprintf ( in, "%s  ", indent ) ;
-
-  model -> print ( fd, in, how_much ) ;
-}
-
-
-#ifdef HAVE_PLIB_PSL
-void ssgEntityArray::getStats ( int *num_branches, int *num_leaves, int *num_tris, int *num_verts )
-{
-  int nb, nl, nt, nv ;
-
-  *num_branches = 1 ;   /* this! */
-  *num_leaves   = 0 ;
-  *num_tris     = 0 ;
-  *num_verts    = 0 ;
-
-  model -> getStats ( & nb, & nl, & nt, & nv ) ;
-  *num_branches += nb * locations->getNum() ;
-  *num_leaves   += nl * locations->getNum() ;
-  *num_tris     += nt * locations->getNum() ;
-  *num_verts    += nv * locations->getNum() ;
-}
-#endif
-
-
-void ssgEntityArray::cull ( sgFrustum *f, sgMat4 m, int test_needed )
-{
-  if ( ! preTravTests ( &test_needed, SSGTRAV_CULL ) )
-    return ;
-
-  int cull_result = cull_test ( f, m, test_needed ) ;
-
-  if ( cull_result == SSG_OUTSIDE )
-    return ;
-
-  pos->removeAllKids();
-  pos->addKid( model );
-
-  for ( int i = 0; i < locations->getNum(); ++i ) {
-      sgCoord c;
-      sgSetCoord( &c, locations->get(i), orientations->get(i) );
-      pos->setTransform( &c );
-      pos->cull( f, m, cull_result != SSG_INSIDE );
-  }
-
-  pos->removeAllKids();
-
-  postTravTests ( SSGTRAV_CULL ) ; 
-}
-
-
-
-void ssgEntityArray::hot ( sgVec3 s, sgMat4 m, int test_needed )
-{
-  if ( ! preTravTests ( &test_needed, SSGTRAV_HOT ) )
-    return ;
-
-  int hot_result = hot_test ( s, m, test_needed ) ;
-
-  if ( hot_result == SSG_OUTSIDE )
-    return ;
-
-  _ssgPushPath ( this ) ;
-
-  pos->removeAllKids();
-  pos->addKid( model );
-
-  for ( int i = 0; i < locations->getNum(); ++i ) {
-      sgCoord c;
-      sgSetCoord( &c, locations->get(i), orientations->get(i) );
-      pos->setTransform( &c );
-      pos->hot ( s, m, hot_result != SSG_INSIDE );
-  }
-
-  pos->removeAllKids();
-
-  _ssgPopPath () ;
-
-  postTravTests ( SSGTRAV_HOT ) ;
-}
-
-
-
-void ssgEntityArray::los ( sgVec3 s, sgMat4 m, int test_needed )
-{
-  if ( ! preTravTests ( &test_needed, SSGTRAV_LOS ) )
-    return ;
-
-  int los_result = los_test ( s, m, test_needed ) ;
-
-  if ( los_result == SSG_OUTSIDE )
-    return ;
-
-  _ssgPushPath ( this ) ;
-
-  pos->removeAllKids();
-  pos->addKid( model );
-
-  for ( int i = 0; i < locations->getNum(); ++i ) {
-      sgCoord c;
-      sgSetCoord( &c, locations->get(i), orientations->get(i) );
-      pos->setTransform( &c );
-      pos->los ( s, m, los_result != SSG_INSIDE ) ;
-  }
-
-  pos->removeAllKids();
-
-  _ssgPopPath () ;
-
-  postTravTests ( SSGTRAV_LOS) ;
-}
-
-
-void ssgEntityArray::isect ( sgSphere *s, sgMat4 m, int test_needed )
-{
-  if ( ! preTravTests ( &test_needed, SSGTRAV_ISECT ) )
-    return ;
-
-  int isect_result = isect_test ( s, m, test_needed ) ;
-
-  if ( isect_result == SSG_OUTSIDE )
-    return ;
-
-  _ssgPushPath ( this ) ;
-
-  pos->removeAllKids();
-  pos->addKid( model );
-
-  for ( int i = 0; i < locations->getNum(); ++i ) {
-      sgCoord c;
-      sgSetCoord( &c, locations->get(i), orientations->get(i) );
-      pos->setTransform( &c );
-      pos->isect ( s, m, isect_result != SSG_INSIDE ) ;
-  }
-
-  pos->removeAllKids();
-
-  _ssgPopPath () ;
-
-  postTravTests ( SSGTRAV_ISECT ) ; 
-}
-
-
-#if 0
-int ssgEntityArray::load ( FILE *fd )
-{
-  int nkids ;
-
-  _ssgReadInt ( fd, & nkids ) ;
-
-  if ( ! ssgEntity::load ( fd ) )
-    return FALSE ;
-
-  for ( int i = 0 ; i < nkids ; i++ )
-  {
-    ssgEntity *kid ;
-
-    if ( ! _ssgLoadObject ( fd, (ssgBase **) &kid, ssgTypeEntity () ) )
-      return FALSE ;
-
-    addKid ( kid ) ;
-  }
-
-  return TRUE ;
-}
-
-
-int ssgEntityArray::save ( FILE *fd )
-{
-  _ssgWriteInt ( fd, getNumKids() ) ;
-
-  if ( ! ssgEntity::save ( fd ) )
-    return FALSE ;
-
-  for ( int i = 0 ; i < getNumKids() ; i++ )
-  {
-    if ( ! _ssgSaveObject ( fd, getKid ( i ) ) )
-       return FALSE ;
-  }
-
-  return TRUE ;
-}
-#endif
-
diff --git a/simgear/screen/ssgEntityArray.hxx b/simgear/screen/ssgEntityArray.hxx
deleted file mode 100644 (file)
index 3b0c65c..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef _SSG_ENTITY_ARRAY_HXX
-#define _SSG_ENTITY_ARRAY_HXX
-
-#ifdef HAVE_CONFIG_H
-#  include <simgear_config.h>
-#endif
-
-#include <plib/ssg.h>
-
-
-class ssgEntityArray : public ssgEntity
-{
-    // The replicated child
-    ssgEntity *model ;
-
-    // The one transformation node
-    ssgTransform *pos;
-
-    // The list of locations and orientations
-    ssgVertexArray *locations;
-    ssgVertexArray *orientations;
-
-protected:
-
-    virtual void copy_from ( ssgEntityArray *src, int clone_flags ) ;
-
-public:
-
-    virtual void zeroSpareRecursive ();
-
-    virtual ssgBase *clone ( int clone_flags = 0 ) ;
-    ssgEntityArray (void) ;
-    virtual ~ssgEntityArray (void) ;
-
-    ssgEntity *getModel () const { return model ; }
-    void setModel        ( ssgEntity *entity ) { model = entity; }
-    void removeModel     () ;
-    void replaceModel    ( ssgEntity *new_entity ) ;
-
-    ssgVertexArray *getLocations () const { return locations; }
-    ssgVertexArray *getOrientations () const { return orientations; }
-
-    float *getLocation ( int i ) const { return locations->get( i ); }
-    float *getOrientation ( int i ) const { return orientations->get( i ); }
-    void addPlacement ( sgVec3 loc, sgVec3 orient );
-    virtual int getNumPlacements() const { return locations->getNum(); }
-    void removeAllPlacements();
-
-    ssgTransform *getPosTransform() { return pos; }
-
-    virtual const char *getTypeName(void) ;
-    virtual void cull          ( sgFrustum *f, sgMat4 m, int test_needed ) ;
-    virtual void isect         ( sgSphere  *s, sgMat4 m, int test_needed ) ;
-    virtual void hot           ( sgVec3     s, sgMat4 m, int test_needed ) ;
-    virtual void los           ( sgVec3     s, sgMat4 m, int test_needed ) ;
-    virtual void print         ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
-#ifdef HAVE_PLIB_PSL
-    virtual void getStats ( int *num_branches, int *num_leaves, int *num_tris, int *num_vertices ) ;
-#endif
-    virtual int load ( FILE *fd ) ;
-    virtual int save ( FILE *fd ) ;
-    virtual void recalcBSphere () ;
-} ;
-
-
-#endif // _SSG_ENTITY_ARRAY_HXX
index 53e1bf820d24a0625a77ea0778854379cff1650d..85e9f3a8acc16914bd915b83e5e92d3fec6d1a72 100644 (file)
@@ -2,7 +2,65 @@
 
 /*
  * $Log$
- * Revision 1.3  2006/02/21 10:47:21  ehofman
+ * Revision 1.4  2006/10/29 19:27:11  frohlich
+ * Modified Files:
+ *     configure.ac simgear/environment/visual_enviro.cxx
+ *     simgear/ephemeris/ephemeris.cxx
+ *     simgear/ephemeris/ephemeris.hxx simgear/ephemeris/stardata.cxx
+ *     simgear/ephemeris/stardata.hxx simgear/math/SGMatrix.hxx
+ *     simgear/math/SGQuat.hxx simgear/math/SGVec3.hxx
+ *     simgear/math/SGVec4.hxx simgear/scene/Makefile.am
+ *     simgear/scene/material/mat.cxx simgear/scene/material/mat.hxx
+ *     simgear/scene/material/matlib.cxx
+ *     simgear/scene/material/matlib.hxx
+ *     simgear/scene/material/matmodel.cxx
+ *     simgear/scene/material/matmodel.hxx
+ *     simgear/scene/model/Makefile.am
+ *     simgear/scene/model/animation.cxx
+ *     simgear/scene/model/animation.hxx
+ *     simgear/scene/model/custtrans.hxx
+ *     simgear/scene/model/model.cxx simgear/scene/model/model.hxx
+ *     simgear/scene/model/modellib.cxx
+ *     simgear/scene/model/modellib.hxx
+ *     simgear/scene/model/personality.cxx
+ *     simgear/scene/model/personality.hxx
+ *     simgear/scene/model/placement.cxx
+ *     simgear/scene/model/placement.hxx
+ *     simgear/scene/model/placementtrans.cxx
+ *     simgear/scene/model/placementtrans.hxx
+ *     simgear/scene/model/shadanim.cxx
+ *     simgear/scene/model/shadowvolume.hxx
+ *     simgear/scene/sky/cloud.cxx simgear/scene/sky/cloud.hxx
+ *     simgear/scene/sky/cloudfield.cxx simgear/scene/sky/dome.cxx
+ *     simgear/scene/sky/dome.hxx simgear/scene/sky/moon.cxx
+ *     simgear/scene/sky/moon.hxx simgear/scene/sky/newcloud.cxx
+ *     simgear/scene/sky/oursun.cxx simgear/scene/sky/oursun.hxx
+ *     simgear/scene/sky/sky.cxx simgear/scene/sky/sky.hxx
+ *     simgear/scene/sky/sphere.cxx simgear/scene/sky/sphere.hxx
+ *     simgear/scene/sky/stars.cxx simgear/scene/sky/stars.hxx
+ *     simgear/scene/tgdb/apt_signs.cxx
+ *     simgear/scene/tgdb/apt_signs.hxx simgear/scene/tgdb/leaf.cxx
+ *     simgear/scene/tgdb/leaf.hxx simgear/scene/tgdb/obj.cxx
+ *     simgear/scene/tgdb/obj.hxx simgear/scene/tgdb/pt_lights.cxx
+ *     simgear/scene/tgdb/pt_lights.hxx
+ *     simgear/scene/tgdb/userdata.cxx
+ *     simgear/scene/tgdb/userdata.hxx simgear/scene/tgdb/vasi.hxx
+ *     simgear/screen/jpgfactory.cxx simgear/screen/tr.cxx
+ *     simgear/structure/Makefile.am simgear/threads/SGThread.hxx
+ * Added Files:
+ *     simgear/scene/util/Makefile.am
+ *     simgear/scene/util/SGDebugDrawCallback.hxx
+ *     simgear/scene/util/SGNodeMasks.hxx
+ *     simgear/scene/util/SGStateAttributeVisitor.hxx
+ *     simgear/scene/util/SGTextureStateAttributeVisitor.hxx
+ *     simgear/scene/util/SGUpdateVisitor.hxx
+ * Removed Files:
+ *     simgear/screen/ssgEntityArray.cxx
+ *     simgear/screen/ssgEntityArray.hxx
+ *     simgear/structure/ssgSharedPtr.hxx
+ *     Big BLOB on the way to OSG.
+ *
+ * Revision 1.3  2006-02-21 10:47:21  ehofman
  * Back out the previous patch.
  *
  * Revision 1.2  2004/11/18 19:10:34  curt
 
 #include SG_GLU_H
 
-#include <plib/ssg.h>
 #include "tr.h"
 
 
@@ -395,7 +452,8 @@ void trBeginTile(TRcontext *tr)
           * (tr->CurrentRow * tr->TileHeightNB - border) / tr->ImageHeight;
    top = bottom + (tr->Top - tr->Bottom) * tileHeight / tr->ImageHeight;
 
-   ssgSetFrustum ( left, right, bottom, top, tr->Near, tr->Far );
+   // OSGFIXME
+//    ssgSetFrustum ( left, right, bottom, top, tr->Near, tr->Far );
 
    /* restore user's matrix mode */
    glMatrixMode( (GLenum)matrixMode );
index e7d361ae5bf94406e880b20f23f50688367763a3..6324da1747b1fe496b3220335a7481c5fb95f9e1 100644 (file)
@@ -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 (file)
index 44471af..0000000
+++ /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<typename T>
-class ssgSharedPtr {
-public:
-  ssgSharedPtr(void) : _ptr(0)
-  {}
-  ssgSharedPtr(T* ptr) : _ptr(ptr)
-  { get(_ptr); }
-  ssgSharedPtr(const ssgSharedPtr& p) : _ptr(p.ptr())
-  { get(_ptr); }
-  template<typename U>
-  ssgSharedPtr(const ssgSharedPtr<U>& p) : _ptr(p.ptr())
-  { get(_ptr); }
-  ~ssgSharedPtr(void)
-  { put(); }
-  
-  ssgSharedPtr& operator=(const ssgSharedPtr& p)
-  { assign(p.ptr()); return *this; }
-  template<typename U>
-  ssgSharedPtr& operator=(const ssgSharedPtr<U>& p)
-  { assign(p.ptr()); return *this; }
-  template<typename U>
-  ssgSharedPtr& operator=(U* p)
-  { assign(p); return *this; }
-
-  T* operator->(void) const
-  { return _ptr; }
-  T& operator*(void) const
-  { return *_ptr; }
-  operator T*(void) const
-  { return _ptr; }
-  T* ptr(void) const
-  { return _ptr; }
-
-  bool isShared(void) const
-  { if (_ptr) return 1 < _ptr->getRef(); else return false; }
-  unsigned getNumRefs(void) const
-  { if (_ptr) return _ptr->getRef(); else return 0; }
-
-  bool valid(void) const
-  { return _ptr; }
-
-private:
-  void assign(T* p)
-  { get(p); put(); _ptr = p; }
-
-  static void get(T* p)
-  { if (p) p->ref(); }
-  void put(void)
-  {
-    if (!_ptr)
-      return;
-
-    assert(0 < _ptr->getRef());
-    _ptr->deRef();
-    if (_ptr->getRef() == 0) {
-      delete _ptr;
-      _ptr = 0;
-    }
-  }
-  
-  // The reference itself.
-  T* _ptr;
-};
-
-#endif
index d04d60af15431f310d8fa540f11b733f9efcde1d..5179ab80cb02f01715c5bfe2604180fce68637a1 100644 (file)
@@ -136,6 +136,7 @@ SGThread::start( unsigned cpu )
 {
     int status = pthread_create( &tid, 0, start_handler, this );
     assert( status == 0 );
+    (void)status;
 #if defined( sgi )
     if ( !status && !cpu )
         pthread_setrunon_np( cpu );
@@ -148,6 +149,7 @@ SGThread::join()
 {
     int status = pthread_join( tid, 0 );
     assert( status == 0 );
+    (void)status;
 }
 
 inline void
@@ -155,6 +157,7 @@ SGThread::cancel()
 {
     int status = pthread_cancel( tid );
     assert( status == 0 );
+    (void)status;
 }
 
 /**
@@ -219,24 +222,28 @@ inline SGMutex::SGMutex()
 {
     int status = pthread_mutex_init( &mutex, 0 );
     assert( status == 0 );
+    (void)status;
 }
 
 inline SGMutex::~SGMutex()
 {
     int status = pthread_mutex_destroy( &mutex );
     assert( status == 0 );
+    (void)status;
 }
 
 inline void SGMutex::lock()
 {
     int status = pthread_mutex_lock( &mutex );
     assert( status == 0 );
+    (void)status;
 }
 
 inline void SGMutex::unlock()
 {
     int status = pthread_mutex_unlock( &mutex );
     assert( status == 0 );
+    (void)status;
 }
 
 /**
@@ -307,30 +314,35 @@ inline SGPthreadCond::SGPthreadCond()
 {
     int status = pthread_cond_init( &cond, 0 );
     assert( status == 0 );
+    (void)status;
 }
 
 inline SGPthreadCond::~SGPthreadCond()
 {
     int status = pthread_cond_destroy( &cond );
     assert( status == 0 );
+    (void)status;
 }
 
 inline void SGPthreadCond::signal()
 {
     int status = pthread_cond_signal( &cond );
     assert( status == 0 );
+    (void)status;
 }
 
 inline void SGPthreadCond::broadcast()
 {
     int status = pthread_cond_broadcast( &cond );
     assert( status == 0 );
+    (void)status;
 }
 
 inline void SGPthreadCond::wait( SGMutex& mutex )
 {
     int status = pthread_cond_wait( &cond, &mutex.mutex );
     assert( status == 0 );
+    (void)status;
 }
 
 #endif /* SGTHREAD_HXX_INCLUDED */