]> git.mxchange.org Git - flightgear.git/commitdiff
Modified Files:
authorfrohlich <frohlich>
Sun, 29 Oct 2006 19:30:21 +0000 (19:30 +0000)
committerfrohlich <frohlich>
Sun, 29 Oct 2006 19:30:21 +0000 (19:30 +0000)
  configure.ac src/AIModel/AIAircraft.cxx src/AIModel/AIBase.cxx
  src/AIModel/AIBase.hxx src/AIModel/AICarrier.cxx
  src/AIModel/AICarrier.hxx src/AIModel/AIManager.cxx
  src/AIModel/AIManager.hxx src/ATC/AIEntity.cxx
  src/ATC/AIEntity.hxx src/ATC/AIMgr.cxx src/ATC/AIMgr.hxx
  src/ATC/ATCdisplay.cxx src/ATC/ATCdisplay.hxx
  src/Cockpit/cockpit.cxx src/Cockpit/cockpit.hxx
  src/Cockpit/hud.cxx src/Cockpit/hud.hxx
  src/Cockpit/hud_rwy.cxx src/Cockpit/panel.cxx
  src/Cockpit/panel.hxx src/Cockpit/built_in/FGMagRibbon.cxx
  src/Cockpit/built_in/FGMagRibbon.hxx src/FDM/flight.cxx
  src/FDM/groundcache.cxx src/FDM/groundcache.hxx
  src/GUI/gui_funcs.cxx src/Input/input.cxx
  src/Instrumentation/od_gauge.cxx
  src/Instrumentation/od_gauge.hxx
  src/Instrumentation/render_area_2d.cxx
  src/Instrumentation/render_area_2d.hxx
  src/Instrumentation/wxradar.cxx
  src/Instrumentation/wxradar.hxx
  src/Instrumentation/HUD/HUD.cxx
  src/Instrumentation/HUD/HUD.hxx
  src/Instrumentation/HUD/HUD_runway.cxx src/Main/Makefile.am
  src/Main/main.cxx src/Main/renderer.cxx src/Main/renderer.hxx
  src/Main/viewmgr.cxx src/Model/acmodel.cxx
  src/Model/acmodel.hxx src/Model/model_panel.cxx
  src/Model/model_panel.hxx src/Model/modelmgr.cxx
  src/Model/modelmgr.hxx src/Model/panelnode.cxx
  src/Model/panelnode.hxx src/Navaids/awynet.cxx
  src/Scenery/Makefile.am src/Scenery/hitlist.cxx
  src/Scenery/hitlist.hxx src/Scenery/newcache.cxx
  src/Scenery/scenery.cxx src/Scenery/scenery.hxx
  src/Scenery/tileentry.cxx src/Scenery/tileentry.hxx
  src/Scenery/tilemgr.cxx src/Scripting/NasalSys.cxx
  src/Scripting/NasalSys.hxx src/Time/light.cxx
Big BLOB on the way to OSG.

63 files changed:
configure.ac
src/AIModel/AIAircraft.cxx
src/AIModel/AIBase.cxx
src/AIModel/AIBase.hxx
src/AIModel/AICarrier.cxx
src/AIModel/AICarrier.hxx
src/AIModel/AIManager.cxx
src/AIModel/AIManager.hxx
src/ATC/AIEntity.cxx
src/ATC/AIEntity.hxx
src/ATC/AIMgr.cxx
src/ATC/AIMgr.hxx
src/ATC/ATCdisplay.cxx
src/ATC/ATCdisplay.hxx
src/Cockpit/built_in/FGMagRibbon.cxx
src/Cockpit/built_in/FGMagRibbon.hxx
src/Cockpit/cockpit.cxx
src/Cockpit/cockpit.hxx
src/Cockpit/hud.cxx
src/Cockpit/hud.hxx
src/Cockpit/hud_rwy.cxx
src/Cockpit/panel.cxx
src/Cockpit/panel.hxx
src/FDM/flight.cxx
src/FDM/groundcache.cxx
src/FDM/groundcache.hxx
src/GUI/gui_funcs.cxx
src/Input/input.cxx
src/Instrumentation/HUD/HUD.cxx
src/Instrumentation/HUD/HUD.hxx
src/Instrumentation/HUD/HUD_runway.cxx
src/Instrumentation/od_gauge.cxx
src/Instrumentation/od_gauge.hxx
src/Instrumentation/render_area_2d.cxx
src/Instrumentation/render_area_2d.hxx
src/Instrumentation/wxradar.cxx
src/Instrumentation/wxradar.hxx
src/Main/Makefile.am
src/Main/main.cxx
src/Main/renderer.cxx
src/Main/renderer.hxx
src/Main/viewmgr.cxx
src/Model/acmodel.cxx
src/Model/acmodel.hxx
src/Model/model_panel.cxx
src/Model/model_panel.hxx
src/Model/modelmgr.cxx
src/Model/modelmgr.hxx
src/Model/panelnode.cxx
src/Model/panelnode.hxx
src/Navaids/awynet.cxx
src/Scenery/Makefile.am
src/Scenery/hitlist.cxx
src/Scenery/hitlist.hxx
src/Scenery/newcache.cxx
src/Scenery/scenery.cxx
src/Scenery/scenery.hxx
src/Scenery/tileentry.cxx
src/Scenery/tileentry.hxx
src/Scenery/tilemgr.cxx
src/Scripting/NasalSys.cxx
src/Scripting/NasalSys.hxx
src/Time/light.cxx

index 6f828eac79f967abc190685879a9265c17e921cd..0afede1a48ed68220a57e6b9d6bc75ae836de932 100644 (file)
@@ -38,6 +38,14 @@ if test "x$with_plib" != "x" ; then
     EXTRA_DIRS="${EXTRA_DIRS} $with_plib"
 fi
 
+# specify the osg location
+AC_ARG_WITH(osg, [  --with-osg=PREFIX       Specify the prefix path to osg])
+
+if test "x$with_osg" != "x" ; then
+    echo "osg prefix is $with_osg"
+    EXTRA_DIRS="${EXTRA_DIRS} $with_osg"
+fi
+
 dnl Determine an extra directories to add to include/lib search paths
 case "${host}" in
 *-apple-darwin* | *-*-mingw32*)
index c6450677a107775dea685da53ced19fec389c1a5..315bbdf6ad3a9db285261d75f7d396b0b3b0c354 100644 (file)
@@ -82,6 +82,11 @@ FGAIAircraft::FGAIAircraft(FGAISchedule *ref) :
     use_perf_vs = true;
     isTanker = false;
 
+    no_roll = false;
+    tgt_speed = 0;
+    speed = 0;
+    groundTargetSpeed = 0;
+
     // set heading and altitude locks
     hdg_lock = false;
     alt_lock = false;
index 2c274cd37a39345ec77fc4a8f91b1d7b0658c057..11a3877d2bdd2535f30d6f0d7598cf5cc3a55dcb 100644 (file)
@@ -26,8 +26,8 @@
 
 #include STL_STRING
 
-#include <plib/sg.h>
-#include <plib/ssg.h>
+#include <osg/ref_ptr>
+#include <osg/Node>
 
 #include <simgear/math/point3d.hxx>
 #include <simgear/math/polar3d.hxx>
@@ -73,7 +73,7 @@ FGAIBase::~FGAIBase() {
     // Unregister that one at the scenery manager
     if (globals->get_scenery()) {
         globals->get_scenery()->unregister_placement_transform(aip.getTransform());
-        globals->get_scenery()->get_scene_graph()->removeKid(aip.getSceneGraph());
+        globals->get_scenery()->get_scene_graph()->removeChild(aip.getSceneGraph());
     }
     if (props) {
         SGPropertyNode* parent = props->getParent();
@@ -135,11 +135,11 @@ bool FGAIBase::init() {
        model = NULL;
      }
    }
-   if (model) {
-     aip.init( model );
+   if (model.get()) {
+     aip.init( model.get() );
      aip.setVisible(true);
      invisible = false;
-     globals->get_scenery()->get_scene_graph()->addKid(aip.getSceneGraph());
+     globals->get_scenery()->get_scene_graph()->addChild(aip.getSceneGraph());
      // Register that one at the scenery manager
      globals->get_scenery()->register_placement_transform(aip.getTransform());
      fgSetString("/ai/models/model-added", props->getPath());
@@ -155,15 +155,16 @@ bool FGAIBase::init() {
 }
 
 
-ssgBranch * FGAIBase::load3DModel(const string& fg_root,
-                                  const string &path,
-                                  SGPropertyNode *prop_root,
-                                  double sim_time_sec)
+osg::Node*
+FGAIBase::load3DModel(const string& fg_root,
+                      const string &path,
+                      SGPropertyNode *prop_root,
+                      double sim_time_sec)
 {
   // some more code here to check whether a model with this name has already been loaded
   // if not load it, otherwise, get the memory pointer and do something like
   // SetModel as in ATC/AIEntity.cxx
-  ssgBranch *personality_branch = new SGPersonalityBranch;
+  osg::Group* personality_branch = new SGPersonalityBranch;
 
   model = manager->getModel(path);
   if (!(model)) {
@@ -171,9 +172,9 @@ ssgBranch * FGAIBase::load3DModel(const string& fg_root,
                             path,
                             prop_root,
                             sim_time_sec);
-      manager->setModel(path, model);
+      manager->setModel(path, model.get());
   }
-  personality_branch->addKid( model );
+  personality_branch->addChild( model.get() );
 
   return personality_branch;
   //return model;
index 5fd191c8713d2dd885f782c3298f872ce421e738..83d7e2a2024a876f645cf9029de440c6ec23c2a2 100644 (file)
@@ -118,7 +118,7 @@ protected:
     double ht_diff;             // value used by radar display instrument
 
     string model_path;    //Path to the 3D model
-    ssgSharedPtr<ssgBranch> model; //The 3D model object
+    osg::ref_ptr<osg::Node> model; //The 3D model object
     SGModelPlacement aip;
     bool delete_me;
     bool invisible;
@@ -173,7 +173,7 @@ public:
     static const double lbs_to_slugs;
 
     inline double _getRange() { return range; };
-    ssgBranch * load3DModel(const string& fg_root,
+    osg::Node* load3DModel(const string& fg_root,
                             const string &path,
                             SGPropertyNode *prop_root,
                             double sim_time_sec);
index 7fa08422b20fcc86864bacfb678d3e250982de03..0ec684609330c0ac19211bcacc7e62e6b9aa493a 100644 (file)
 #  include <config.h>
 #endif
 
+#include <algorithm>
 #include <string>
 #include <vector>
 
+#include <osg/NodeVisitor>
+
 #include <simgear/math/SGMath.hxx>
-#include <simgear/math/point3d.hxx>
 #include <simgear/math/sg_geodesy.hxx>
+#include <simgear/scene/util/SGNodeMasks.hxx>
+
 #include <math.h>
 #include <Main/util.hxx>
 #include <Main/viewer.hxx>
 
 #include "AICarrier.hxx"
 
-/** Value of earth radius (meters) */
-#define RADIUS_M   SG_EQUATORIAL_RADIUS_M
+class FGCarrierVisitor : public osg::NodeVisitor {
+public:
+  FGCarrierVisitor(FGAICarrier* carrier,
+                   const std::list<std::string>& wireObjects,
+                   const std::list<std::string>& catapultObjects,
+                   const std::list<std::string>& solidObjects) :
+    osg::NodeVisitor(osg::NodeVisitor::NODE_VISITOR,
+                     osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
+    mWireObjects(wireObjects),
+    mCatapultObjects(catapultObjects),
+    mSolidObjects(solidObjects),
+    mFoundHot(false),
+    mCarrier(carrier)
+  { }
+  virtual void apply(osg::Node& node)
+  {
+    osg::ref_ptr<osg::Referenced> oldUserData = mUserData;
+    bool oldFoundHot = mFoundHot;
+    mFoundHot = false;
+
+    if (std::find(mWireObjects.begin(), mWireObjects.end(), node.getName())
+        != mWireObjects.end()) {
+      mFoundHot = true;
+      mUserData = FGAICarrierHardware::newWire(mCarrier);
+    }
+    if (std::find(mCatapultObjects.begin(), mCatapultObjects.end(), node.getName())
+        != mCatapultObjects.end()) {
+      mFoundHot = true;
+      mUserData = FGAICarrierHardware::newCatapult(mCarrier);
+    }
+    if (std::find(mSolidObjects.begin(), mSolidObjects.end(), node.getName())
+        != mSolidObjects.end()) {
+      mFoundHot = true;
+      mUserData = FGAICarrierHardware::newSolid(mCarrier);
+    }
+    node.setUserData(mUserData.get());
 
+    traverse(node);
 
+    mFoundHot = oldFoundHot || mFoundHot;
+
+    if (mFoundHot) {
+      node.setNodeMask(node.getNodeMask() | SG_NODEMASK_TERRAIN_BIT);
+    } else
+      node.setNodeMask(node.getNodeMask() & ~SG_NODEMASK_TERRAIN_BIT);
+
+    mUserData = oldUserData;
+  }
+  
+private:
+  std::list<std::string> mWireObjects;
+  std::list<std::string> mCatapultObjects;
+  std::list<std::string> mSolidObjects;
+  bool mFoundHot;
+  FGAICarrier* mCarrier;
+  osg::ref_ptr<osg::Referenced> mUserData;
+};
 
 FGAICarrier::FGAICarrier() : FGAIShip(otCarrier) {
 }
@@ -140,10 +197,10 @@ void FGAICarrier::setTACANChannelID(const string& id) {
     TACAN_channel_id = id;
 }
 
-void FGAICarrier::getVelocityWrtEarth(sgdVec3& v, sgdVec3& omega, sgdVec3& pivot) {
-    sgdCopyVec3(v, vel_wrt_earth.sg() );
-    sgdCopyVec3(omega, rot_wrt_earth.sg() );
-    sgdCopyVec3(pivot, rot_pivot_wrt_earth.sg() );
+void FGAICarrier::getVelocityWrtEarth(SGVec3d& v, SGVec3d& omega, SGVec3d& pivot) {
+    v = vel_wrt_earth;
+    omega = rot_wrt_earth;
+    pivot = rot_pivot_wrt_earth;
 }
 
 void FGAICarrier::update(double dt) {
@@ -263,14 +320,12 @@ bool FGAICarrier::init() {
     // To avoid that every detail in a carrier 3D model will end into
     // the aircraft local cache, only set the HOT traversal bit on
     // selected objects.
-    ssgEntity *sel = aip.getSceneGraph();
+    osg::Node* sel = aip.getSceneGraph();
     // Clear the HOT traversal flag
-    mark_nohot(sel);
     // Selectively set that flag again for wires/cats/solid objects.
     // Attach a pointer to this carrier class to those objects.
-    mark_wires(sel, wire_objects);
-    mark_cat(sel, catapult_objects);
-    mark_solid(sel, solid_objects);
+    FGCarrierVisitor carrierVisitor(this, wire_objects, catapult_objects, solid_objects);
+    sel->accept(carrierVisitor);
 
     _longitude_node = fgGetNode("/position/longitude-deg", true);
     _latitude_node = fgGetNode("/position/latitude-deg", true);
@@ -416,187 +471,6 @@ bool FGAICarrier::getParkPosition(const string& id, SGGeod& geodPos,
     return false;
 }
 
-
-void FGAICarrier::mark_nohot(ssgEntity* e) {
-    if (e->isAKindOf(ssgTypeBranch())) {
-        ssgBranch* br = (ssgBranch*)e;
-        ssgEntity* kid;
-        for ( kid = br->getKid(0); kid != NULL ; kid = br->getNextKid() )
-            mark_nohot(kid);
-
-        br->clrTraversalMaskBits(SSGTRAV_HOT);
-
-    } else if (e->isAKindOf(ssgTypeLeaf())) {
-
-        e->clrTraversalMaskBits(SSGTRAV_HOT);
-    }
-}
-
-
-bool FGAICarrier::mark_wires(ssgEntity* e, const list<string>& wire_objects, bool mark) {
-    bool found = false;
-    if (e->isAKindOf(ssgTypeBranch())) {
-        ssgBranch* br = (ssgBranch*)e;
-        ssgEntity* kid;
-
-        list<string>::const_iterator it;
-        for (it = wire_objects.begin(); it != wire_objects.end(); ++it)
-            mark = mark || (e->getName() && (*it) == e->getName());
-
-        for ( kid = br->getKid(0); kid != NULL ; kid = br->getNextKid() )
-            found = mark_wires(kid, wire_objects, mark) || found;
-
-        if (found)
-            br->setTraversalMaskBits(SSGTRAV_HOT);
-
-    } else if (e->isAKindOf(ssgTypeLeaf())) {
-        list<string>::const_iterator it;
-        for (it = wire_objects.begin(); it != wire_objects.end(); ++it) {
-            if (mark || (e->getName() && (*it) == e->getName())) {
-                e->setTraversalMaskBits(SSGTRAV_HOT);
-                ssgBase* ud = e->getUserData();
-                if (ud) {
-                    FGAICarrierHardware* ch = dynamic_cast<FGAICarrierHardware*>(ud);
-                    if (ch) {
-                        SG_LOG(SG_GENERAL, SG_WARN,
-                                "AICarrier: Carrier hardware gets marked twice!\n"
-                                "           You have probably a whole branch marked as"
-                                " a wire which also includes other carrier hardware.");
-                    } else {
-                        SG_LOG(SG_GENERAL, SG_ALERT,
-                                "AICarrier: Found user data attached to a leaf node which "
-                                "should be marked as a wire!\n    ****Skipping!****");
-                    }
-                } else {
-                    e->setUserData( FGAICarrierHardware::newWire( this ) );
-                    ssgLeaf *l = (ssgLeaf*)e;
-                    if ( l->getNumLines() != 1 ) {
-                        SG_LOG(SG_GENERAL, SG_ALERT,
-                                "AICarrier: Found wires not modeled with exactly one line!");
-                    }
-                    found = true;
-                }
-            }
-        }
-    }
-    return found;
-}
-
-
-bool FGAICarrier::mark_solid(ssgEntity* e, const list<string>& solid_objects, bool mark) {
-    bool found = false;
-    if (e->isAKindOf(ssgTypeBranch())) {
-        ssgBranch* br = (ssgBranch*)e;
-        ssgEntity* kid;
-
-        list<string>::const_iterator it;
-        for (it = solid_objects.begin(); it != solid_objects.end(); ++it)
-            mark = mark || (e->getName() && (*it) == e->getName());
-
-        for ( kid = br->getKid(0); kid != NULL ; kid = br->getNextKid() )
-            found = mark_solid(kid, solid_objects, mark) || found;
-
-        if (found)
-            br->setTraversalMaskBits(SSGTRAV_HOT);
-
-    } else if (e->isAKindOf(ssgTypeLeaf())) {
-        list<string>::const_iterator it;
-        for (it = solid_objects.begin(); it != solid_objects.end(); ++it) {
-            if (mark || (e->getName() && (*it) == e->getName())) {
-                e->setTraversalMaskBits(SSGTRAV_HOT);
-                ssgBase* ud = e->getUserData();
-
-                if (ud) {
-                    FGAICarrierHardware* ch = dynamic_cast<FGAICarrierHardware*>(ud);
-                    if (ch) {
-                        SG_LOG(SG_GENERAL, SG_WARN,
-                                "AICarrier: Carrier hardware gets marked twice!\n"
-                                "           You have probably a whole branch marked solid"
-                                " which also includes other carrier hardware.");
-                    } else {
-                        SG_LOG(SG_GENERAL, SG_ALERT,
-                                "AICarrier: Found user data attached to a leaf node which "
-                                "should be marked solid!\n    ****Skipping!****");
-                    }
-                } else {
-                    e->setUserData( FGAICarrierHardware::newSolid( this ) );
-                    found = true;
-                }
-            }
-        }
-    }
-    return found;
-}
-
-
-bool FGAICarrier::mark_cat(ssgEntity* e, const list<string>& cat_objects, bool mark) {
-    bool found = false;
-    if (e->isAKindOf(ssgTypeBranch())) {
-        ssgBranch* br = (ssgBranch*)e;
-        ssgEntity* kid;
-
-        list<string>::const_iterator it;
-        for (it = cat_objects.begin(); it != cat_objects.end(); ++it)
-            mark = mark || (e->getName() && (*it) == e->getName());
-
-        for ( kid = br->getKid(0); kid != NULL ; kid = br->getNextKid() )
-            found = mark_cat(kid, cat_objects, mark) || found;
-
-        if (found)
-            br->setTraversalMaskBits(SSGTRAV_HOT);
-
-    } else if (e->isAKindOf(ssgTypeLeaf())) {
-        list<string>::const_iterator it;
-        for (it = cat_objects.begin(); it != cat_objects.end(); ++it) {
-            if (mark || (e->getName() && (*it) == e->getName())) {
-                e->setTraversalMaskBits(SSGTRAV_HOT);
-                ssgBase* ud = e->getUserData();
-                if (ud) {
-                    FGAICarrierHardware* ch = dynamic_cast<FGAICarrierHardware*>(ud);
-                    if (ch) {
-                        SG_LOG(SG_GENERAL, SG_WARN,
-                                "AICarrier: Carrier hardware gets marked twice!\n"
-                                "You have probably a whole branch marked as"
-                                "a catapult which also includes other carrier hardware.");
-                    } else {
-                        SG_LOG(SG_GENERAL, SG_ALERT,
-                                "AICarrier: Found user data attached to a leaf node which "
-                                "should be marked as a catapult!\n    ****Skipping!****");
-                    }
-                } else {
-                    e->setUserData( FGAICarrierHardware::newCatapult( this ) );
-                    ssgLeaf *l = (ssgLeaf*)e;
-                    if ( l->getNumLines() != 1 ) {
-                        SG_LOG(SG_GENERAL, SG_ALERT,
-                                "AICarrier: Found a cat not modeled with exactly "
-                                "one line!");
-                    } else {
-                        // Now some special code to make sure the cat points in the right
-                        // direction. The 0 index must be the backward end, the 1 index
-                        // the forward end.
-                        // Forward is positive x-direction in our 3D model, also the model
-                        // as such is flattened when it is loaded, so we do not need to
-                        // care for transforms ...
-                        short v[2];
-                        l->getLine(0, v, v+1 );
-                        SGVec3f ends[2];
-                        for (int k=0; k<2; ++k)
-                            sgCopyVec3( ends[k].sg(), l->getVertex( v[k] ) );
-
-                        // When the 1 end is behind the 0 end, swap the coordinates.
-                        if (ends[0][0] < ends[1][0]) {
-                            sgCopyVec3( l->getVertex( v[0] ), ends[1].sg() );
-                            sgCopyVec3( l->getVertex( v[1] ), ends[0].sg() );
-                        }
-                        found = true;
-                    }
-                }
-            }
-        }
-    }
-    return found;
-}
-
 // find relative wind
 void FGAICarrier::UpdateWind( double dt) {
 
@@ -746,12 +620,6 @@ bool FGAICarrier::OutsideBox() { //returns true if the carrier is outside operat
 } // end OutsideBox
 
 
-// return the distance to the horizon, given the altitude and the radius of the earth
-float FGAICarrier::Horizon(float h) {
-    return RADIUS_M * acos(RADIUS_M / (RADIUS_M + h));
-}
-
-
 bool FGAICarrier::InToWind() {
     if ( fabs(rel_wind) < 5 )
         return true;
index 9a3d52f416861b57e109fabf41e5cd25d67c3d27..d76e1ed0eae8525aac7bac9a608bcdabae1b384a 100644 (file)
 
 #include <string>
 #include <list>
-#include <plib/ssg.h>
+
+#include <osg/Referenced>
+#include <osg/Node>
+
 #include <simgear/compiler.h>
 
 SG_USING_STD(string);
@@ -37,7 +40,7 @@ SG_USING_STD(list);
 class FGAIManager;
 class FGAICarrier;
 
-class FGAICarrierHardware : public ssgBase {
+class FGAICarrierHardware : public osg::Referenced {
 public:
 
     enum Type { Catapult, Wire, Solid };
@@ -84,7 +87,7 @@ public:
     void setSign(const string& );
     void setTACANChannelID(const string &);
 
-    void getVelocityWrtEarth(sgdVec3& v, sgdVec3& omega, sgdVec3& pivot);
+    void getVelocityWrtEarth(SGVec3d& v, SGVec3d& omega, SGVec3d& pivot);
     virtual void bind();
     virtual void unbind();
     void UpdateWind ( double dt );
@@ -97,7 +100,6 @@ public:
     void TurnToLaunch();
     void TurnToBase();
     void ReturnToBox();
-    float Horizon(float h);
     bool OutsideBox();
 
     bool init();
@@ -124,11 +126,6 @@ private:
 
 
     void update(double dt);
-    void mark_nohot(ssgEntity*);
-
-    bool mark_wires(ssgEntity*, const list<string>&, bool = false);
-    bool mark_cat(ssgEntity*, const list<string>&, bool = false);
-    bool mark_solid(ssgEntity*, const list<string>&, bool = false);
     double wind_from_east;  // fps
     double wind_from_north; // fps
     double rel_wind_speed_kts;
index bdf9f5b36dc1bb852aba2cf963b57bca8b47fedb..c5decd5e35c2924b31ef1686e06d55b7aea50c2b 100644 (file)
@@ -259,7 +259,7 @@ FGAIManager::loadScenarioFile(const std::string& filename)
 // This code keeps track of models that have already been loaded
 // Eventually we'd prbably need to find a way to keep track of models
 // that are unloaded again
-ssgBranch * FGAIManager::getModel(const string& path)
+osg::Node* FGAIManager::getModel(const string& path)
 {
   ModelVecIterator i = loadedModels.begin();  
   //cerr << "Reference count summary " << endl;
@@ -291,7 +291,7 @@ ssgBranch * FGAIManager::getModel(const string& path)
   return 0;
 }
 
-void FGAIManager::setModel(const string& path, ssgBranch *model)
+void FGAIManager::setModel(const string& path, osg::Node *model)
 {
   loadedModels.push_back(FGModelID(path,model));
 }
index 42b279bf20cc1fce05708e3b2eedbde1fe767e96..4b6d4ef085fc2e05151877772dffb1d91f0e2d20 100644 (file)
@@ -26,7 +26,6 @@
 #include <list>
 
 #include <simgear/structure/subsystem_mgr.hxx>
-#include <simgear/structure/ssgSharedPtr.hxx>
 #include <simgear/structure/SGSharedPtr.hxx>
 
 #include <Main/fg_props.hxx>
@@ -43,13 +42,13 @@ SG_USING_STD(vector);
 class FGModelID
 {
 private:
-  ssgSharedPtr<ssgBranch> model;
+  osg::ref_ptr<osg::Node> model;
   string path;
 public:
-  FGModelID(const string& pth, ssgBranch * mdl) { path =pth; model=mdl;};
-  ssgBranch * const getModelId() const { return model;};
+  FGModelID(const string& pth, osg::Node* mdl) { path =pth; model=mdl;};
+  osg::Node* const getModelId() const { return model.get();};
   const string & getPath() const { return path;};
-  int getNumRefs() const { return model.getNumRefs(); };
+  int getNumRefs() const { return model->referenceCount(); };
 };
 
 typedef vector<FGModelID> ModelVec;
@@ -100,8 +99,8 @@ public:
 
     void processScenario( const string &filename );
 
-  ssgBranch * getModel(const string& path);
-  void setModel(const string& path, ssgBranch *model);
+  osg::Node* getModel(const string& path);
+  void setModel(const string& path, osg::Node *model);
 
   static SGPropertyNode_ptr loadScenarioFile(const std::string& filename);
 
index f4d58cd1d657f73ff79b024c2827b8599d6b62a3..7afbef1ba9c93be699d3e8a15bc705918bb96f07 100644 (file)
@@ -46,18 +46,18 @@ FGAIEntity::FGAIEntity() {
 FGAIEntity::~FGAIEntity() {
        //cout << "FGAIEntity dtor called..." << endl;
        //cout << "Removing model from scene graph..." << endl;
-       globals->get_scenery()->get_scene_graph()->removeKid(_aip.getSceneGraph());
+       globals->get_scenery()->get_scene_graph()->removeChild(_aip.getSceneGraph());
         // Unregister that one at the scenery manager
         globals->get_scenery()->unregister_placement_transform(_aip.getTransform());
 
        //cout << "Done!" << endl;
 }
 
-void FGAIEntity::SetModel(ssgBranch* model) {
+void FGAIEntity::SetModel(osg::Node* model) {
        _model = model;
-       _aip.init(_model);
+       _aip.init(_model.get());
        _aip.setVisible(false);
-       globals->get_scenery()->get_scene_graph()->addKid(_aip.getSceneGraph());
+       globals->get_scenery()->get_scene_graph()->addChild(_aip.getSceneGraph());
         // Register that one at the scenery manager
         globals->get_scenery()->register_placement_transform(_aip.getTransform());
 
index 5c7f276bf09e8dadc6387f57ac0526b617592784..dc9070b8bfebc3e4bd1c52387c62231b65b96e64 100644 (file)
 #include <simgear/math/point3d.hxx>
 #include <simgear/scene/model/model.hxx>
 #include <simgear/scene/model/placement.hxx>
-#include <simgear/structure/ssgSharedPtr.hxx>
-
-
-class ssgBase;
 
 
 /*****************************************************************
@@ -46,7 +42,7 @@ public:
     virtual ~FGAIEntity();
        
        // Set the 3D model to use (Must be called)
-       void SetModel(ssgBranch* model);
+  void SetModel(osg::Node* model);
 
     // Run the internal calculations
     virtual void Update(double dt)=0;
@@ -67,7 +63,7 @@ protected:
     double _pitch;     //degrees
 
     char* _model_path; //Path to the 3D model
-    ssgSharedPtr<ssgBranch> _model;    // Pointer to the model
+    osg::ref_ptr<osg::Node> _model;    // Pointer to the model
     SGModelPlacement _aip;
 
     void Transform();
index 34527a79f016b2c216c6d8617c6f30cb57be8eca..60519cc69a6651b063a9476380e5ba8d41fe1a2b 100644 (file)
@@ -306,7 +306,7 @@ void FGAIMgr::ActivateAirport(const string& ident) {
        ATC->AIRegisterAirport(ident);
        // TODO - need to start the traffic more randomly
        FGAILocalTraffic* local_traffic = new FGAILocalTraffic;
-       local_traffic->SetModel(_defaultModel); // currently hardwired to cessna.
+       local_traffic->SetModel(_defaultModel.get());   // currently hardwired to cessna.
        //local_traffic->Init(ident, IN_PATTERN, TAKEOFF_ROLL);
        local_traffic->Init(GenerateShortForm(GenerateUniqueCallsign()), ident);
        local_traffic->FlyCircuits(1, true);    // Fly 2 circuits with touch & go in between
@@ -469,7 +469,7 @@ void FGAIMgr::GenerateSimpleAirportTraffic(const string& ident, double min_dist)
                        else cessna = true;
                        string s = GenerateShortForm(GenerateUniqueCallsign(), (cessna ? "Cessna-" : "Piper-"));
                        FGAIGAVFRTraffic* t = new FGAIGAVFRTraffic();
-                       t->SetModel(cessna ? _defaultModel : (_havePiperModel ? _piperModel : _defaultModel));
+                       t->SetModel(cessna ? _defaultModel.get() : (_havePiperModel ? _piperModel.get() : _defaultModel.get()));
                        //cout << "Generating VFR traffic " << s << " inbound to " << ident << " " << ad << " meters out from " << dir << " degrees\n";
                        Point3D tpos = dclUpdatePosition(aptpos, dir, 6.0, ad);
                        if(tpos.elev() > (aptpos.elev() + 3000.0)) tpos.setelev(aptpos.elev() + 3000.0);        // FEET yuk :-(
index a1e3e61159949faac942d992584a799612a68a06..6bc81a10b9afd33da00cf5366e2415469d24d2d9 100644 (file)
@@ -23,7 +23,6 @@
 #define _FG_AIMGR_HXX
 
 #include <simgear/structure/subsystem_mgr.hxx>
-#include <simgear/structure/ssgSharedPtr.hxx>
 
 #include <Main/fg_props.hxx>
 
@@ -110,8 +109,8 @@ public:
 
 private:
        
-       ssgSharedPtr<ssgBranch> _defaultModel;  // Cessna 172!
-       ssgSharedPtr<ssgBranch> _piperModel;    // pa28-161
+        osg::ref_ptr<osg::Node> _defaultModel;  // Cessna 172!
+       osg::ref_ptr<osg::Node> _piperModel;    // pa28-161
 
        bool initDone;  // Hack - guard against update getting called before init
 
index 89588e0006f0967708853a3f4600016f2a9792c2..e554a4d78ab71ba19bc6c5833147bbb991efa238 100644 (file)
@@ -61,8 +61,13 @@ void FGATCDisplay::bind() {
 void FGATCDisplay::unbind() {
 }
 
+void FGATCDisplay::update(double dt)
+{
+  std::cout << "OSGFIXME" << std::endl;
+}
+
 // update - this actually draws the visuals and should be called from the main Flightgear rendering loop.
-void FGATCDisplay::update(double dt) {
+void FGATCDisplay::update(double dt, osg::State& state) {
        
        // These strings are used for temporary storage of the transmission string in order
        // that the string we view only changes when the next repetition starts scrolling
index cc3818de9583a998b62d27c36bfa22b0c6b68046..bf94d0acd0a3100cdab9c10fc225a5b9d9927194 100644 (file)
@@ -27,6 +27,7 @@
 #  include <config.h>
 #endif
 
+#include <osg/State>
 #include <simgear/structure/subsystem_mgr.hxx>
 
 #include <vector>
@@ -72,6 +73,7 @@ public:
     void unbind();
 
     // Display any registered messages
+    void update(double dt, osg::State&);
     void update(double dt);
 
     // Register a single message for display after a delay of delay seconds
index 7f3f8ceb1175861196bff20b64c6d1d0c593b189..a05db18ae50db9f671a41d3ea44f2fe08117cb74 100644 (file)
@@ -36,7 +36,7 @@ FGMagRibbon::FGMagRibbon (int w, int h)
 }
 
 void
-FGMagRibbon::draw ()
+FGMagRibbon::draw (osg::State& state)
 {
   double heading = _magcompass_node->getDoubleValue();
   double xoffset, yoffset;
@@ -71,10 +71,16 @@ FGMagRibbon::draw ()
   FGCroppedTexture *t = getTexture();
   t->setCrop(xoffset, yoffset, xoffset + 0.5, yoffset + 0.25);
 
-  glPushAttrib(GL_DEPTH_BUFFER_BIT);
-  glEnable(GL_DEPTH_TEST);
-  FGTexturedLayer::draw();
-  glPopAttrib();
+  static osg::ref_ptr<osg::StateSet> stateSet = new osg::StateSet;
+  stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
+
+  state.pushStateSet(stateSet.get());
+  state.apply();
+
+  FGTexturedLayer::draw(state);
+
+  state.popStateSet();
+  state.apply();
 }
 
 // end of FGMagRibbon.cxx
index a430c61783152f820ce2fab1492076d1227c0635..39c320df3e5250b36a1cf7cf6ec41603163b2d9f 100644 (file)
@@ -34,7 +34,7 @@ public:
     FGMagRibbon (int w, int h);
     virtual ~FGMagRibbon () {}
 
-    virtual void draw ();
+    virtual void draw (osg::State& state);
 
 private:
     SGPropertyNode_ptr _magcompass_node;
index 74c1bde9a500d4696932252002f660804f236a2f..e746f854f506dc5e40e0b7d5db99ae45eaeeabb5 100644 (file)
@@ -550,7 +550,7 @@ bool fgCockpitInit( fgAIRCRAFT *cur_aircraft )
     return true;
 }
 
-void fgCockpitUpdate( void ) {
+void fgCockpitUpdate( osg::State* state ) {
 
     SG_LOG( SG_COCKPIT, SG_DEBUG,
             "Cockpit: code " << ac_cockpit->code() << " status "
@@ -568,7 +568,7 @@ void fgCockpitUpdate( void ) {
     if ( hud_visibility_node->getBoolValue() ) {
         // This will check the global hud linked list pointer.
         // If there is anything to draw it will.
-        fgUpdateHUD();
+        fgUpdateHUD( state );
     }
 
     glViewport( 0, 0, iwidth, iheight );
index b3d7b420eb317abc2f2f194d8d679b88aa26a602..5b8b7e6326c9acc21ce92a2322c4fbc1ca6d5cd6 100644 (file)
@@ -31,8 +31,9 @@
 # error This library requires C++
 #endif
 
+#include <osg/State>
 
-#include <Aircraft/aircraft.hxx>
+#include "Aircraft/aircraft.hxx"
 #include "panel.hxx"
 
 // Class fg_Cockpit          This class is a holder for the heads up display
@@ -53,7 +54,7 @@ class fg_Cockpit  {
 typedef fg_Cockpit * pCockpit;
 
 bool fgCockpitInit( fgAIRCRAFT *cur_aircraft );
-void fgCockpitUpdate( void );
+void fgCockpitUpdate( osg::State* );
 
 
 #endif /* _COCKPIT_HXX */
index 0d016b873e93f02648ffcd5ee257a0aaecd63242..88597d5dc3376484fe73fe227427190f99b36958 100644 (file)
@@ -79,8 +79,8 @@ float HUD_matrix[16];
 int readHud( istream &input );
 int readInstrument ( const SGPropertyNode * node);
 
-static void drawHUD();
-static void fgUpdateHUDVirtual();
+static void drawHUD(osg::State*);
+static void fgUpdateHUDVirtual(osg::State*);
 
 
 class locRECT {
@@ -255,8 +255,6 @@ int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ )
         input.close();
     }
 
-    fgHUDReshape();
-
     if ( HUDtext ) {
         // this chunk of code is not necessarily thread safe if the
         // compiler optimizer reorders these statements.  Note that
@@ -314,39 +312,17 @@ int fgHUDInit2( fgAIRCRAFT * /* current_aircraft */ )
 //$$$ End - added, Neetha, 28 Nov 2k
 
 
-void fgHUDReshape(void) {
-#if 0
-    if ( HUDtext ) {
-        // this chunk of code is not necessarily thread safe if the
-        // compiler optimizer reorders these statements.  Note that
-        // "delete ptr" does not set "ptr = NULL".  We have to do that
-        // ourselves.
-        fntRenderer *tmp = HUDtext;
-        HUDtext = NULL;
-        delete tmp;
-    }
-
-    HUD_TextSize = fgGetInt("/sim/startup/xsize") / 60;
-    HUD_TextSize = 10;
-    HUDtext = new fntRenderer();
-    HUDtext -> setFont      ( guiFntHandle ) ;
-    HUDtext -> setPointSize ( HUD_TextSize ) ;
-    HUD_TextList.setFont( HUDtext );
-#endif
-}
-
-
 // fgUpdateHUD
 //
 // Performs a once around the list of calls to instruments installed in
 // the HUD object with requests for redraw. Kinda. It will when this is
 // all C++.
 //
-void fgUpdateHUD( void ) {
+void fgUpdateHUD( osg::State* state ) {
 
     static const SGPropertyNode *enable3d_node = fgGetNode("/sim/hud/enable3d");
     if ( HUD_style == 1 && enable3d_node->getBoolValue() ) {
-        fgUpdateHUDVirtual();
+        fgUpdateHUDVirtual(state);
         return;
     }
 
@@ -356,15 +332,15 @@ void fgUpdateHUD( void ) {
     if ( current_aspect > normal_aspect ) {
         float aspect_adjust = current_aspect / normal_aspect;
         float adjust = 320.0f*aspect_adjust - 320.0f;
-        fgUpdateHUD( -adjust, 0.0f, 640.0f+adjust, 480.0f );
+        fgUpdateHUD( state, -adjust, 0.0f, 640.0f+adjust, 480.0f );
     } else {
         float aspect_adjust = normal_aspect / current_aspect;
         float adjust = 240.0f*aspect_adjust - 240.0f;
-        fgUpdateHUD( 0.0f, -adjust, 640.0f, 480.0f+adjust );
+        fgUpdateHUD( state, 0.0f, -adjust, 640.0f, 480.0f+adjust );
     }
 }
 
-void fgUpdateHUDVirtual()
+void fgUpdateHUDVirtual(osg::State* state)
 {
     FGViewer* view = globals->get_current_view();
 
@@ -406,7 +382,7 @@ void fgUpdateHUDVirtual()
     glTranslatef(-320, -240, -1);
 
     // Do the deed
-    drawHUD();
+    drawHUD(state);
 
     // Clean up our mess
     glMatrixMode(GL_PROJECTION);
@@ -416,7 +392,7 @@ void fgUpdateHUDVirtual()
 }
 
 
-void fgUpdateHUD( GLfloat x_start, GLfloat y_start,
+void fgUpdateHUD( osg::State* state, GLfloat x_start, GLfloat y_start,
                   GLfloat x_end, GLfloat y_end )
 {
     glMatrixMode(GL_PROJECTION);
@@ -428,7 +404,7 @@ void fgUpdateHUD( GLfloat x_start, GLfloat y_start,
     glPushMatrix();
     glLoadIdentity();
 
-    drawHUD();
+    drawHUD(state);
 
     glMatrixMode(GL_PROJECTION);
     glPopMatrix();
@@ -437,7 +413,7 @@ void fgUpdateHUD( GLfloat x_start, GLfloat y_start,
 }
 
 
-void drawHUD()
+void drawHUD(osg::State* state)
 {
     if ( !HUD_deque.size() ) // Trust everyone, but ALWAYS cut the cards!
         return;
index 3964bacd579aada857c548899ff0e6e06d348635..8556e4b240f21120beea04d35ab2c6aed2c7a753 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
-//#ifdef HAVE_VALUES_H
-//#  include <values.h>  // for MAXINT
-//#endif
-
 #include <algorithm>    // for_each()
 #include <vector>       // STL vector
 #include <deque>        // STL double ended queue
 #include STL_FSTREAM
 
+#include <osg/State>
+
 #include <simgear/math/SGMath.hxx>
 #include <simgear/constants.h>
 
@@ -106,32 +104,6 @@ enum fgLabelJust{ LEFT_JUST, CENTER_JUST, RIGHT_JUST } ;
 #define HUDS_DECITICS            0x0040
 #define HUDS_NOTEXT              0x0080
 
-// Ladder orientaion
-// #define HUD_VERTICAL        1
-// #define HUD_HORIZONTAL       2
-// #define HUD_FREEFLOAT        3
-
-// Ladder orientation modes
-// #define HUD_LEFT         1
-// #define HUD_RIGHT            2
-// #define HUD_TOP              1
-// #define HUD_BOTTOM           2
-// #define HUD_V_LEFT           1
-// #define HUD_V_RIGHT          2
-// #define HUD_H_TOP            1
-// #define HUD_H_BOTTOM         2
-
-
-// Ladder sub-types
-// #define HUD_LIM              1
-// #define HUD_NOLIM            2
-// #define HUD_CIRC         3
-
-// #define HUD_INSTR_LADDER 1
-// #define HUD_INSTR_CLADDER    2
-// #define HUD_INSTR_HORIZON    3
-// #define HUD_INSTR_LABEL      4
-
 // in cockpit.cxx
 extern float get_throttleval ( void );
 extern float get_aileronval  ( void );
@@ -161,10 +133,8 @@ extern float get_climb_rate  ( void );
 extern float get_mach( void );
 extern char *coord_format_lat(float);
 extern char *coord_format_lon(float);
-//extern char *coord_format_latlon(float latitude, float longitude);  // cockpit.cxx
 
 // $$$ begin - added, VS Renganathan, 13 Oct 2K
-// #define FIGHTER_HUD
 extern float get_anzg (void);
 extern float get_Vx (void);
 extern float get_Vy (void);
@@ -205,7 +175,6 @@ extern float get_aux18(void);
 // $$$ end - added, VS Renganathan, 13 Oct 2K
 
 extern char *get_formated_gmt_time( void );
-extern void fgHUDReshape(void);
 
 enum  hudinstype{ HUDno_instr,
                   HUDscale,
@@ -522,9 +491,7 @@ class HUDdraw {
 };
 
 
-extern deque< instr_item *> HUD_deque;
 extern int HUD_style;
-//extern hud_deque_type HUD_deque;
 
 // instr_item           This class has no other purpose than to maintain
 //                      a linked list of instrument and derived class
@@ -788,27 +755,12 @@ public:
 };
 
 
-//using namespace std;
-//deque <instr_item>  * Hdeque_ptr;
-
 extern int  fgHUDInit( fgAIRCRAFT * /* current_aircraft */ );
 extern int  fgHUDInit2( fgAIRCRAFT * /* current_aircraft */ );
-extern void fgUpdateHUD( void );
-extern void fgUpdateHUD( GLfloat x_start, GLfloat y_start,
+extern void fgUpdateHUD( osg::State* );
+extern void fgUpdateHUD( osg::State*, GLfloat x_start, GLfloat y_start,
                          GLfloat x_end, GLfloat y_end );
 
-/*
-bool AddHUDInstrument( instr_item *pBlackBox );
-void DrawHUD ( void );
-bool DamageInstrument( INSTR_HANDLE unit );
-bool RepairInstrument( INSTR_HANDLE unit );
-
-
-void fgUpdateHUD ( Hptr hud );
-void fgUpdateHUD2( Hptr hud ); // Future use?
-void fgHUDSetTimeMode( Hptr hud, int time_of_day );
-*/
-
 
 
 
index bb3e78c59b7350499d82affc575957b04cc9bd62..aac5e26e0ca29274626b70a935981fe894489fba 100644 (file)
@@ -105,13 +105,16 @@ void runway_instr::draw()
             globals->get_viewmgr()->copyToCurrent();
         }
         //Set the camera to the cockpit view to get the view of the runway from the cockpit
-        ssgSetCamera((sgVec4 *)cockpit_view->get_VIEW());
+        // OSGFIXME
+//         ssgSetCamera((sgVec4 *)cockpit_view->get_VIEW());
         get_rwy_points(points3d);
         //Get the current project matrix
-        ssgGetProjectionMatrix(projMat);
+        // OSGFIXME
+//         ssgGetProjectionMatrix(projMat);
 //        const sgVec4 *viewMat = globals->get_current_view()->get_VIEW();
         //Get the current model view matrix (cockpit view)
-        ssgGetModelviewMatrix(modelView);
+        // OSGFIXME
+//         ssgGetModelviewMatrix(modelView);
         //Create a rotation matrix to correct for any offsets (other than default offsets) to the model view matrix
         sgMat4 xy; //rotation about the Rxy, negate the sin's on Ry
         xy[0][0] = cYaw;         xy[1][0] = 0.0f;   xy[2][0] = -sYaw;        xy[3][0] = 0.0f;
@@ -164,7 +167,8 @@ void runway_instr::draw()
             curr_view->setGoalPitchOffset_deg(gpo);
         }
         //Set the camera back to the current view
-        ssgSetCamera((sgVec4 *)curr_view);
+        // OSGFIXME
+//         ssgSetCamera((sgVec4 *)curr_view);
         glPopAttrib();
     }//if not broken
 }
index 90c5e200025eff066d6994636140a5f043089da4..b0f6db745a2f159c466a1081cd9a88b6dbffe70f 100644 (file)
 #include <stdio.h>     // sprintf
 #include <string.h>
 
+#include <osg/CullFace>
+#include <osg/Depth>
+#include <osg/Material>
+#include <osg/TexEnv>
+#include <osg/PolygonOffset>
+
 #include <simgear/compiler.h>
 
 #include SG_GLU_H
 
-#include <plib/ssg.h>
 #include <plib/fnt.h>
 
 #include <simgear/debug/logstream.hxx>
 #include <simgear/misc/sg_path.hxx>
+#include <simgear/scene/model/model.hxx>
 
 #include <Main/globals.hxx>
 #include <Main/fg_props.hxx>
@@ -109,23 +115,24 @@ fgPanelVisible ()
 // Implementation of FGTextureManager.
 ////////////////////////////////////////////////////////////////////////
 
-map<string,ssgTexture *> FGTextureManager::_textureMap;
+map<string,osg::ref_ptr<osg::Texture2D> > FGTextureManager::_textureMap;
 
-ssgTexture *
+osg::Texture2D*
 FGTextureManager::createTexture (const string &relativePath)
 {
-  ssgTexture * texture = _textureMap[relativePath];
+  osg::Texture2D* texture = _textureMap[relativePath].get();
   if (texture == 0) {
     SG_LOG( SG_COCKPIT, SG_DEBUG,
             "Texture " << relativePath << " does not yet exist" );
     SGPath tpath(globals->get_fg_root());
     tpath.append(relativePath);
-    texture = new ssgTexture((char *)tpath.c_str(), false, false);
+
+    texture = SGLoadTexture2D(tpath);
+
     _textureMap[relativePath] = texture;
-    if (_textureMap[relativePath] == 0
+    if (!_textureMap[relativePath].valid()
       SG_LOG( SG_COCKPIT, SG_ALERT, "Texture *still* doesn't exist" );
-    SG_LOG( SG_COCKPIT, SG_DEBUG, "Created texture " << relativePath
-            << " handle=" << texture->getHandle() );
+    SG_LOG( SG_COCKPIT, SG_DEBUG, "Created texture " << relativePath );
   }
 
   return texture;
@@ -160,13 +167,16 @@ FGCroppedTexture::~FGCroppedTexture ()
 }
 
 
-ssgTexture *
+osg::StateSet*
 FGCroppedTexture::getTexture ()
 {
   if (_texture == 0) {
-    _texture = FGTextureManager::createTexture(_path);
+    _texture = new osg::StateSet;
+    _texture->setTextureAttribute(0, FGTextureManager::createTexture(_path));
+    _texture->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON);
+    _texture->setTextureAttribute(0, new osg::TexEnv(osg::TexEnv::MODULATE));
   }
-  return _texture;
+  return _texture.get();
 }
 
 
@@ -254,11 +264,52 @@ FGPanel::unbind ()
 }
 
 
+void
+FGPanel::update (double dt)
+{
+  std::cout << "OSGFIXME" << std::endl;
+}
+
+void
+FGPanel::update (osg::State& state, GLfloat winx, GLfloat winw, GLfloat winy, GLfloat winh)
+{
+                               // Calculate accelerations
+                               // and jiggle the panel accordingly
+                               // The factors and bounds are just
+                               // initial guesses; using sqrt smooths
+                               // out the spikes.
+  double x_offset = _x_offset->getIntValue();
+  double y_offset = _y_offset->getIntValue();
+
+
+  glMatrixMode(GL_PROJECTION);
+  glPushMatrix();
+  glLoadIdentity();
+  if ( _flipx->getBoolValue() ) {
+    gluOrtho2D(winx + winw, winx, winy + winh, winy); /* up side down */
+  } else {
+    gluOrtho2D(winx, winx + winw, winy, winy + winh); /* right side up */
+  }
+  
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glLoadIdentity();
+  
+  glTranslated(x_offset, y_offset, 0);
+  
+  draw(state);
+
+  glMatrixMode(GL_PROJECTION);
+  glPopMatrix();
+  glMatrixMode(GL_MODELVIEW);
+  glPopMatrix();
+}
+
 /**
  * Update the panel.
  */
 void
-FGPanel::update (double dt)
+FGPanel::update (osg::State& state)
 {
                                // Do nothing if the panel isn't visible.
     if ( !fgPanelVisible() ) {
@@ -271,9 +322,9 @@ FGPanel::update (double dt)
     float aspect_adjust = get_aspect_adjust(_xsize_node->getIntValue(),
                                             _ysize_node->getIntValue());
     if (aspect_adjust <1.0)
-        update(WIN_X, int(WIN_W * aspect_adjust), WIN_Y, WIN_H);
+        update(state, WIN_X, int(WIN_W * aspect_adjust), WIN_Y, WIN_H);
     else
-        update(WIN_X, WIN_W, WIN_Y, int(WIN_H / aspect_adjust));
+        update(state, WIN_X, WIN_W, WIN_Y, int(WIN_H / aspect_adjust));
 }
 
 /**
@@ -294,87 +345,39 @@ void FGPanel::updateMouseDelay()
 
 
 void
-FGPanel::update (GLfloat winx, GLfloat winw, GLfloat winy, GLfloat winh)
-{
-                               // Calculate accelerations
-                               // and jiggle the panel accordingly
-                               // The factors and bounds are just
-                               // initial guesses; using sqrt smooths
-                               // out the spikes.
-  double x_offset = _x_offset->getIntValue();
-  double y_offset = _y_offset->getIntValue();
-
-#if 0
-  if (_jitter->getFloatValue() != 0.0) {
-    double a_x_pilot = current_aircraft.fdm_state->get_A_X_pilot();
-    double a_y_pilot = current_aircraft.fdm_state->get_A_Y_pilot();
-    double a_z_pilot = current_aircraft.fdm_state->get_A_Z_pilot();
-
-    double a_zx_pilot = a_z_pilot - a_x_pilot;
-    
-    int x_adjust = int(sqrt(fabs(a_y_pilot) * _jitter->getFloatValue())) *
-                  (a_y_pilot < 0 ? -1 : 1);
-    int y_adjust = int(sqrt(fabs(a_zx_pilot) * _jitter->getFloatValue())) *
-                  (a_zx_pilot < 0 ? -1 : 1);
-
-                               // adjustments in screen coordinates
-    x_offset += x_adjust;
-    y_offset += y_adjust;
-  }
-#endif
-
-  glMatrixMode(GL_PROJECTION);
-  glPushMatrix();
-  glLoadIdentity();
-  if ( _flipx->getBoolValue() ) {
-    gluOrtho2D(winx + winw, winx, winy + winh, winy); /* up side down */
-  } else {
-    gluOrtho2D(winx, winx + winw, winy, winy + winh); /* right side up */
-  }
-  
-  glMatrixMode(GL_MODELVIEW);
-  glPushMatrix();
-  glLoadIdentity();
-  
-  glTranslated(x_offset, y_offset, 0);
-  
-  draw();
-
-  glMatrixMode(GL_PROJECTION);
-  glPopMatrix();
-  glMatrixMode(GL_MODELVIEW);
-  glPopMatrix();
-
-  ssgForceBasicState();
-  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-}
-
-void
-FGPanel::draw()
+FGPanel::draw(osg::State& state)
 {
   // In 3D mode, it's possible that we are being drawn exactly on top
   // of an existing polygon.  Use an offset to prevent z-fighting.  In
   // 2D mode, this is a no-op.
-  glEnable(GL_POLYGON_OFFSET_FILL);
-  glPolygonOffset(-1, -POFF_UNITS);
-
-  // save some state
-  glPushAttrib( GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_LIGHTING_BIT
-                | GL_TEXTURE_BIT | GL_PIXEL_MODE_BIT | GL_CULL_FACE 
-                | GL_DEPTH_BUFFER_BIT );
-
-  // Draw the background
-  glEnable(GL_TEXTURE_2D);
-  glDisable(GL_LIGHTING);
-  glEnable(GL_BLEND);
-  glEnable(GL_ALPHA_TEST);
-  glEnable(GL_COLOR_MATERIAL);
-  glEnable(GL_CULL_FACE);
-  glCullFace(GL_BACK);
-  if ( _enable_depth_test )
-      glDepthFunc(GL_ALWAYS);
-  else
-    glDisable(GL_DEPTH_TEST);
+  static osg::ref_ptr<osg::StateSet> panelStateSet;
+  if (!panelStateSet.valid()) {
+    panelStateSet = new osg::StateSet;
+    panelStateSet->setAttributeAndModes(new osg::PolygonOffset(-1, -POFF_UNITS));
+    panelStateSet->setTextureAttribute(0, new osg::TexEnv);
+
+    // Draw the background
+    panelStateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON);
+    panelStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
+    panelStateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
+    panelStateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON);
+    osg::Material* material = new osg::Material;
+    material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
+    material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(1, 1, 1, 1));
+    material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(1, 1, 1, 1));
+    material->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1));
+    material->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 0, 1));
+    panelStateSet->setAttribute(material);
+    panelStateSet->setMode(GL_COLOR_MATERIAL, osg::StateAttribute::ON);
+    panelStateSet->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
+    panelStateSet->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK));
+    if ( _enable_depth_test )
+      panelStateSet->setAttributeAndModes(new osg::Depth(osg::Depth::ALWAYS));
+    else
+      panelStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
+  }
+  state.pushStateSet(panelStateSet.get());
+  state.apply();
 
   FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
   sgCopyVec4( panel_color, l->scene_diffuse());
@@ -385,36 +388,40 @@ FGPanel::draw()
   }
   glColor4fv( panel_color );
   if (_bg != 0) {
-    glBindTexture(GL_TEXTURE_2D, _bg->getHandle());
-    // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-    // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+    state.pushStateSet(_bg.get());
+    state.apply();
     glBegin(GL_POLYGON);
     glTexCoord2f(0.0, 0.0); glVertex2f(WIN_X, WIN_Y);
     glTexCoord2f(1.0, 0.0); glVertex2f(WIN_X + _width, WIN_Y);
     glTexCoord2f(1.0, 1.0); glVertex2f(WIN_X + _width, WIN_Y + _height);
     glTexCoord2f(0.0, 1.0); glVertex2f(WIN_X, WIN_Y + _height);
     glEnd();
+    state.popStateSet();
+    state.apply();
   } else {
     for (int i = 0; i < 4; i ++) {
       // top row of textures...(1,3,5,7)
-      glBindTexture(GL_TEXTURE_2D, _mbg[i*2]->getHandle());
-      glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+      state.pushStateSet(_mbg[i*2].get());
+      state.apply();
       glBegin(GL_POLYGON);
       glTexCoord2f(0.0, 0.0); glVertex2f(WIN_X + (_width/4) * i, WIN_Y + (_height/2));
       glTexCoord2f(1.0, 0.0); glVertex2f(WIN_X + (_width/4) * (i+1), WIN_Y + (_height/2));
       glTexCoord2f(1.0, 1.0); glVertex2f(WIN_X + (_width/4) * (i+1), WIN_Y + _height);
       glTexCoord2f(0.0, 1.0); glVertex2f(WIN_X + (_width/4) * i, WIN_Y + _height);
       glEnd();
+      state.popStateSet();
+      state.apply();
       // bottom row of textures...(2,4,6,8)
-      glBindTexture(GL_TEXTURE_2D, _mbg[(i*2)+1]->getHandle());
-      glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+      state.pushStateSet(_mbg[i*2+1].get());
+      state.apply();
       glBegin(GL_POLYGON);
       glTexCoord2f(0.0, 0.0); glVertex2f(WIN_X + (_width/4) * i, WIN_Y);
       glTexCoord2f(1.0, 0.0); glVertex2f(WIN_X + (_width/4) * (i+1), WIN_Y);
       glTexCoord2f(1.0, 1.0); glVertex2f(WIN_X + (_width/4) * (i+1), WIN_Y + (_height/2));
       glTexCoord2f(0.0, 1.0); glVertex2f(WIN_X + (_width/4) * i, WIN_Y + (_height/2));
       glEnd();
+      state.popStateSet();
+      state.apply();
     }
   }
 
@@ -448,7 +455,7 @@ FGPanel::draw()
     glEnable(GL_CLIP_PLANE2);
     glEnable(GL_CLIP_PLANE3);
     glPopMatrix();
-    instr->draw();
+    instr->draw(state);
 
     glPopMatrix();
   }
@@ -458,24 +465,24 @@ FGPanel::draw()
   glDisable(GL_CLIP_PLANE2);
   glDisable(GL_CLIP_PLANE3);
 
+  state.popStateSet();
+  state.apply();
 
   // Draw yellow "hotspots" if directed to.  This is a panel authoring
   // feature; not intended to be high performance or to look good.
   if ( fgGetBool("/sim/panel-hotspots") ) {
-    glDisable(GL_TEXTURE_2D);
+    static osg::ref_ptr<osg::StateSet> hotspotStateSet = new osg::StateSet;
+    hotspotStateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::OFF);
+    state.pushStateSet(hotspotStateSet.get());
+    state.apply();
+  
     glColor3f(1, 1, 0);
     
     for ( unsigned int i = 0; i < _instruments.size(); i++ )
-      _instruments[i]->drawHotspots();
+      _instruments[i]->drawHotspots(state);
+    state.popStateSet();
+    state.apply();
   }
-
-
-  // restore some original state
-  if ( _enable_depth_test )
-    glDepthFunc(GL_LESS);
-  glPopAttrib();
-  glPolygonOffset(0, 0);
-  glDisable(GL_POLYGON_OFFSET_FILL);
 }
 
 /**
@@ -502,19 +509,28 @@ FGPanel::getVisibility () const
  * Set the panel's background texture.
  */
 void
-FGPanel::setBackground (ssgTexture * texture)
+FGPanel::setBackground (osg::Texture2D* texture)
 {
-  _bg = texture;
+  osg::StateSet* stateSet = new osg::StateSet;
+  stateSet->setTextureAttribute(0, texture);
+  stateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON);
+  stateSet->setTextureAttribute(0, new osg::TexEnv(osg::TexEnv::MODULATE));
+  _bg = stateSet;
 }
 
 /**
  * Set the panel's multiple background textures.
  */
 void
-FGPanel::setMultiBackground (ssgTexture * texture, int idx)
+FGPanel::setMultiBackground (osg::Texture2D* texture, int idx)
 {
   _bg = 0;
-  _mbg[idx] = texture;
+
+  osg::StateSet* stateSet = new osg::StateSet;
+  stateSet->setTextureAttribute(0, texture);
+  stateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON);
+  stateSet->setTextureAttribute(0, new osg::TexEnv(osg::TexEnv::MODULATE));
+  _mbg[idx] = stateSet;
 }
 
 /**
@@ -702,7 +718,7 @@ FGPanelInstrument::~FGPanelInstrument ()
 }
 
 void
-FGPanelInstrument::drawHotspots()
+FGPanelInstrument::drawHotspots(osg::State& state)
 {
   for ( unsigned int i = 0; i < _actions.size(); i++ ) {
     FGPanelAction* a = _actions[i];
@@ -800,14 +816,14 @@ FGLayeredInstrument::~FGLayeredInstrument ()
 }
 
 void
-FGLayeredInstrument::draw ()
+FGLayeredInstrument::draw (osg::State& state)
 {
   if (!test())
     return;
   
   for (int i = 0; i < (int)_layers.size(); i++) {
     glPushMatrix();
-    _layers[i]->draw();
+    _layers[i]->draw(state);
     glPopMatrix();
   }
 }
@@ -857,7 +873,7 @@ FGSpecialInstrument::~FGSpecialInstrument ()
 }
 
 void
-FGSpecialInstrument::draw ()
+FGSpecialInstrument::draw (osg::State& state)
 {
   complex->draw();
 }
@@ -947,13 +963,13 @@ FGGroupLayer::~FGGroupLayer ()
 }
 
 void
-FGGroupLayer::draw ()
+FGGroupLayer::draw (osg::State& state)
 {
   if (test()) {
     transform();
     int nLayers = _layers.size();
     for (int i = 0; i < nLayers; i++)
-      _layers[i]->draw();
+      _layers[i]->draw(state);
   }
 }
 
@@ -984,14 +1000,15 @@ FGTexturedLayer::~FGTexturedLayer ()
 
 
 void
-FGTexturedLayer::draw ()
+FGTexturedLayer::draw (osg::State& state)
 {
   if (test()) {
     int w2 = _w / 2;
     int h2 = _h / 2;
     
     transform();
-    glBindTexture(GL_TEXTURE_2D, _texture.getTexture()->getHandle());
+    state.pushStateSet(_texture.getTexture());
+    state.apply();
     glBegin(GL_POLYGON);
 
     if (_emissive) {
@@ -1007,6 +1024,8 @@ FGTexturedLayer::draw ()
     glTexCoord2f(_texture.getMaxX(), _texture.getMaxY()); glVertex2f(w2, h2);
     glTexCoord2f(_texture.getMinX(), _texture.getMaxY()); glVertex2f(-w2, h2);
     glEnd();
+    state.popStateSet();
+    state.apply();
   }
 }
 
@@ -1034,7 +1053,7 @@ FGTextLayer::~FGTextLayer ()
 }
 
 void
-FGTextLayer::draw ()
+FGTextLayer::draw (osg::State& state)
 {
   if (test()) {
     glColor4fv(_color);
@@ -1187,14 +1206,14 @@ FGSwitchLayer::FGSwitchLayer ()
 }
 
 void
-FGSwitchLayer::draw ()
+FGSwitchLayer::draw (osg::State& state)
 {
   if (test()) {
     transform();
     int nLayers = _layers.size();
     for (int i = 0; i < nLayers; i++) {
       if (_layers[i]->test()) {
-          _layers[i]->draw();
+          _layers[i]->draw(state);
           return;
       }
     }
index 6be0dbfd792eff54c941420c3a3a76e18845f153..81f7bc3a83c59dfe7171671db5cf9cda2e17e35c 100644 (file)
 #  include <windows.h>
 #endif
 
+#include <osg/ref_ptr>
+#include <osg/StateSet>
+#include <osg/Texture2D>
+
 #include <plib/fnt.h>
 
 #include <simgear/compiler.h>
@@ -54,7 +58,6 @@ SG_USING_STD(vector);
 SG_USING_STD(map);
 
 
-class ssgTexture;
 class FGPanelInstrument;
 
 
@@ -72,9 +75,9 @@ class FGPanelInstrument;
 class FGTextureManager
 {
 public:
-  static ssgTexture * createTexture(const string &relativePath);
+  static osg::Texture2D* createTexture(const string &relativePath);
 private:
-  static map<string,ssgTexture *> _textureMap;
+  static map<string,osg::ref_ptr<osg::Texture2D> > _textureMap;
 };
 
 
@@ -97,7 +100,7 @@ public:
 
   virtual const string &getPath () const { return _path; }
 
-  virtual ssgTexture * getTexture ();
+  virtual osg::StateSet* getTexture ();
 
   virtual void setCrop (float minX, float minY, float maxX, float maxY) {
     _minX = minX; _minY = minY; _maxX = maxX; _maxY = maxY;
@@ -111,7 +114,7 @@ public:
 
 private:
   string _path;
-  ssgTexture * _texture;
+  osg::ref_ptr<osg::StateSet> _texture;
   float _minX, _minY, _maxX, _maxY;
 };
 
@@ -141,9 +144,10 @@ public:
   virtual void init ();
   virtual void bind ();
   virtual void unbind ();
-  virtual void draw ();
-  virtual void update (double dt);
-  virtual void update (GLfloat winx, GLfloat winw, GLfloat winy, GLfloat winh);
+  virtual void draw (osg::State& state);
+  virtual void update (double);
+  void update (osg::State& state);
+  virtual void update (osg::State& state, GLfloat winx, GLfloat winw, GLfloat winy, GLfloat winh);
 
   virtual void updateMouseDelay();
 
@@ -151,10 +155,10 @@ public:
   virtual void addInstrument (FGPanelInstrument * instrument);
 
                                // Background texture.
-  virtual void setBackground (ssgTexture * texture);
+  virtual void setBackground (osg::Texture2D* texture);
 
                                // Background multiple textures.
-  virtual void setMultiBackground (ssgTexture * texture, int idx);
+  virtual void setMultiBackground (osg::Texture2D* texture, int idx);
 
                                // Make the panel visible or invisible.
   virtual bool getVisibility () const;
@@ -208,8 +212,8 @@ private:
   SGConstPropertyNode_ptr _xsize_node;
   SGConstPropertyNode_ptr _ysize_node;
   
-  ssgTexture * _bg;
-  ssgTexture * _mbg[8];
+  osg::ref_ptr<osg::StateSet> _bg;
+  osg::ref_ptr<osg::StateSet> _mbg[8];
                                // List of instruments in panel.
   instrument_list_type _instruments;
   bool _enable_depth_test;
@@ -335,7 +339,7 @@ public:
   FGInstrumentLayer (int w = -1, int h = -1);
   virtual ~FGInstrumentLayer ();
 
-  virtual void draw () = 0;
+  virtual void draw (osg::State& state) = 0;
   virtual void transform () const;
 
   virtual int getWidth () const { return _w; }
@@ -377,8 +381,8 @@ public:
   FGPanelInstrument (int x, int y, int w, int h);
   virtual ~FGPanelInstrument ();
 
-  virtual void draw () = 0;
-  virtual void drawHotspots();
+  virtual void draw (osg::State& state) = 0;
+  virtual void drawHotspots(osg::State& state);
 
   virtual void setPosition(int x, int y);
   virtual void setSize(int w, int h);
@@ -414,7 +418,7 @@ public:
   FGLayeredInstrument (int x, int y, int w, int h);
   virtual ~FGLayeredInstrument ();
 
-  virtual void draw ();
+  virtual void draw (osg::State& state);
 
                                // Transfer pointer ownership!!
   virtual int addLayer (FGInstrumentLayer *layer);
@@ -444,7 +448,7 @@ public:
   //FGSpecialInstrument (int x, int y, int w, int h);
   virtual ~FGSpecialInstrument ();
 
-  virtual void draw ();
+  virtual void draw (osg::State& state);
   
 protected:
   DCLGPS* complex;
@@ -463,7 +467,7 @@ class FGGroupLayer : public FGInstrumentLayer
 public:
   FGGroupLayer ();
   virtual ~FGGroupLayer ();
-  virtual void draw ();
+  virtual void draw (osg::State& state);
                                // transfer pointer ownership
   virtual void addLayer (FGInstrumentLayer * layer);
 protected:
@@ -485,7 +489,7 @@ public:
   FGTexturedLayer (const FGCroppedTexture &texture, int w = -1, int h = -1);
   virtual ~FGTexturedLayer ();
 
-  virtual void draw ();
+  virtual void draw (osg::State& state);
 
   virtual void setTexture (const FGCroppedTexture &texture) {
     _texture = texture;
@@ -540,7 +544,7 @@ public:
   FGTextLayer (int w = -1, int h = -1);
   virtual ~FGTextLayer ();
 
-  virtual void draw ();
+  virtual void draw (osg::State& state);
 
                                // Transfer pointer!!
   virtual void addChunk (Chunk * chunk);
@@ -576,7 +580,7 @@ class FGSwitchLayer : public FGGroupLayer
 public:
                                // Transfer pointers!!
   FGSwitchLayer ();
-  virtual void draw ();
+  virtual void draw (osg::State& state);
 
 };
 
index fd09210b70446807fcd318c4ac1680dd1a51a93e..08aa8fae79bcf8a882ecaaf17dffcae807979e0a 100644 (file)
@@ -800,29 +800,32 @@ bool
 FGInterface::prepare_ground_cache_m(double ref_time, const double pt[3],
                                     double rad)
 {
-  return ground_cache.prepare_ground_cache(ref_time, pt, rad);
+  return ground_cache.prepare_ground_cache(ref_time, SGVec3d(pt), rad);
 }
 
 bool FGInterface::prepare_ground_cache_ft(double ref_time, const double pt[3],
                                           double rad)
 {
   // Convert units and do the real work.
-  sgdVec3 pt_ft;
-  sgdScaleVec3( pt_ft, pt, SG_FEET_TO_METER );
+  SGVec3d pt_ft = SG_FEET_TO_METER*SGVec3d(pt);
   return ground_cache.prepare_ground_cache(ref_time, pt_ft, rad*SG_FEET_TO_METER);
 }
 
 bool
 FGInterface::is_valid_m(double *ref_time, double pt[3], double *rad)
 {
-  return ground_cache.is_valid(ref_time, pt, rad);
+  SGVec3d _pt;
+  bool valid = ground_cache.is_valid(*ref_time, _pt, *rad);
+  sgdCopyVec3(pt, _pt.data());
+  return valid;
 }
 
 bool FGInterface::is_valid_ft(double *ref_time, double pt[3], double *rad)
 {
   // Convert units and do the real work.
-  bool found_ground = ground_cache.is_valid(ref_time, pt, rad);
-  sgdScaleVec3(pt, SG_METER_TO_FEET);
+  SGVec3d _pt;
+  bool found_ground = ground_cache.is_valid(*ref_time, _pt, *rad);
+  sgdScaleVec3(pt, _pt.data(), SG_METER_TO_FEET);
   *rad *= SG_METER_TO_FEET;
   return found_ground;
 }
@@ -831,7 +834,13 @@ double
 FGInterface::get_cat_m(double t, const double pt[3],
                        double end[2][3], double vel[2][3])
 {
-  return ground_cache.get_cat(t, pt, end, vel);
+  SGVec3d _end[2], _vel[2];
+  double dist = ground_cache.get_cat(t, SGVec3d(pt), _end, _vel);
+  for (int k=0; k<2; ++k) {
+    sgdCopyVec3( end[k], _end[k].data() );
+    sgdCopyVec3( vel[k], _vel[k].data() );
+  }
+  return dist;
 }
 
 double
@@ -839,12 +848,12 @@ FGInterface::get_cat_ft(double t, const double pt[3],
                         double end[2][3], double vel[2][3])
 {
   // Convert units and do the real work.
-  sgdVec3 pt_m;
-  sgdScaleVec3( pt_m, pt, SG_FEET_TO_METER );
-  double dist = ground_cache.get_cat(t, pt_m, end, vel);
+  SGVec3d pt_m = SG_FEET_TO_METER*SGVec3d(pt);
+  SGVec3d _end[2], _vel[2];
+  double dist = ground_cache.get_cat(t, pt_m, _end, _vel);
   for (int k=0; k<2; ++k) {
-    sgdScaleVec3( end[k], SG_METER_TO_FEET );
-    sgdScaleVec3( vel[k], SG_METER_TO_FEET );
+    sgdScaleVec3( end[k], _end[k].data(), SG_METER_TO_FEET );
+    sgdScaleVec3( vel[k], _vel[k].data(), SG_METER_TO_FEET );
   }
   return dist*SG_METER_TO_FEET;
 }
@@ -857,8 +866,12 @@ FGInterface::get_agl_m(double t, const double pt[3],
                        double *frictionFactor, double *agl)
 {
   const SGMaterial* material;
-  bool ret = ground_cache.get_agl(t, pt, 2.0, contact, normal, vel, type,
-                                  &material, agl);
+  SGVec3d _contact, _normal, _vel;
+  bool ret = ground_cache.get_agl(t, SGVec3d(pt), 2.0, _contact, _normal,
+                                  _vel, type, &material, agl);
+  sgdCopyVec3(contact, _contact.data());
+  sgdCopyVec3(normal, _normal.data());
+  sgdCopyVec3(vel, _vel.data());
   if (material) {
     *loadCapacity = material->get_load_resistence();
     *frictionFactor = material->get_friction_factor();
@@ -878,15 +891,16 @@ FGInterface::get_agl_ft(double t, const double pt[3],
                         double *frictionFactor, double *agl)
 {
   // Convert units and do the real work.
-  sgdVec3 pt_m;
-  sgdScaleVec3( pt_m, pt, SG_FEET_TO_METER );
+  SGVec3d pt_m = SG_FEET_TO_METER*SGVec3d(pt);
 
   const SGMaterial* material;
-  bool ret = ground_cache.get_agl(t, pt_m, 2.0, contact, normal, vel,
+  SGVec3d _contact, _normal, _vel;
+  bool ret = ground_cache.get_agl(t, pt_m, 2.0, _contact, _normal, _vel,
                                   type, &material, agl);
   // Convert units back ...
-  sgdScaleVec3( contact, SG_METER_TO_FEET );
-  sgdScaleVec3( vel, SG_METER_TO_FEET );
+  sgdScaleVec3( contact, _contact.data(), SG_METER_TO_FEET );
+  sgdScaleVec3( vel, _vel.data(), SG_METER_TO_FEET );
+  sgdCopyVec3( normal, _normal.data() );
   *agl *= SG_METER_TO_FEET;
 
   // return material properties if available
@@ -906,8 +920,13 @@ FGInterface::get_agl_m(double t, const double pt[3], double max_altoff,
                        double contact[3], double normal[3], double vel[3],
                        int *type, const SGMaterial** material, double *agl)
 {
-  return ground_cache.get_agl(t, pt, max_altoff, contact, normal, vel, type,
-                              material, agl);
+  SGVec3d _contact, _normal, _vel;
+  bool found = ground_cache.get_agl(t, SGVec3d(pt), max_altoff, _contact,
+                                    _normal, _vel, type, material, agl);
+  sgdCopyVec3(contact, _contact.data());
+  sgdCopyVec3(normal, _normal.data());
+  sgdCopyVec3(vel, _vel.data());
+  return found;
 }
 
 bool
@@ -916,14 +935,15 @@ FGInterface::get_agl_ft(double t, const double pt[3], double max_altoff,
                         int *type, const SGMaterial** material, double *agl)
 {
   // Convert units and do the real work.
-  sgdVec3 pt_m;
-  sgdScaleVec3( pt_m, pt, SG_FEET_TO_METER );
+  SGVec3d pt_m = SG_FEET_TO_METER*SGVec3d(pt);
+  SGVec3d _contact, _normal, _vel;
   bool ret = ground_cache.get_agl(t, pt_m, SG_FEET_TO_METER * max_altoff,
-                                  contact, normal, vel,
+                                  _contact, _normal, _vel,
                                   type, material, agl);
   // Convert units back ...
-  sgdScaleVec3( contact, SG_METER_TO_FEET );
-  sgdScaleVec3( vel, SG_METER_TO_FEET );
+  sgdScaleVec3( contact, _contact.data(), SG_METER_TO_FEET );
+  sgdScaleVec3( vel, _vel.data(), SG_METER_TO_FEET );
+  sgdCopyVec3( normal, _normal.data() );
   *agl *= SG_METER_TO_FEET;
   return ret;
 }
@@ -932,37 +952,37 @@ FGInterface::get_agl_ft(double t, const double pt[3], double max_altoff,
 double
 FGInterface::get_groundlevel_m(double lat, double lon, double alt)
 {
-  sgdVec3 pos, cpos;
   // Compute the cartesian position of the given lat/lon/alt.
-  sgGeodToCart(lat, lon, alt, pos);
+  SGVec3d pos = SGVec3d::fromGeod(SGGeod::fromRadM(lon, lat, alt));
 
   // FIXME: how to handle t - ref_time differences ???
+  SGVec3d cpos;
   double ref_time, radius;
   // Prepare the ground cache for that position.
-  if (!is_valid_m(&ref_time, cpos, &radius)) {
-    bool ok = prepare_ground_cache_m(ref_time, pos, 10);
+  if (!is_valid_m(&ref_time, cpos.data(), &radius)) {
+    bool ok = prepare_ground_cache_m(ref_time, pos.data(), 10);
     /// This is most likely the case when the given altitude is
     /// too low, try with a new altitude of 10000m, that should be
     /// sufficient to find a ground level below everywhere on our planet
     if (!ok) {
-      sgGeodToCart(lat, lon, 10000, pos);
+      pos = SGVec3d::fromGeod(SGGeod::fromRadM(lon, lat, 10000));
       /// If there is still no ground, return sea level radius
-      if (!prepare_ground_cache_m(ref_time, pos, 10))
+      if (!prepare_ground_cache_m(ref_time, pos.data(), 10))
         return 0;
     }
-  } else if (radius*radius <= sgdDistanceSquaredVec3(pos, cpos)) {
+  } else if (radius*radius <= distSqr(pos, cpos)) {
     /// We reuse the old radius value, but only if it is at least 10 Meters ..
     if (!(10 < radius)) // Well this strange compare is nan safe
       radius = 10;
 
-    bool ok = prepare_ground_cache_m(ref_time, pos, radius);
+    bool ok = prepare_ground_cache_m(ref_time, pos.data(), radius);
     /// This is most likely the case when the given altitude is
     /// too low, try with a new altitude of 10000m, that should be
     /// sufficient to find a ground level below everywhere on our planet
     if (!ok) {
-      sgGeodToCart(lat, lon, 10000, pos);
+      pos = SGVec3d::fromGeod(SGGeod::fromRadM(lon, lat, 10000));
       /// If there is still no ground, return sea level radius
-      if (!prepare_ground_cache_m(ref_time, pos, radius))
+      if (!prepare_ground_cache_m(ref_time, pos.data(), radius))
         return 0;
     }
   }
@@ -973,24 +993,28 @@ FGInterface::get_groundlevel_m(double lat, double lon, double alt)
   // the returns stem from the groundcache or from the coarse
   // computations below the groundcache. The contact point is still something
   // valid, the normals and the other returns just contain some defaults.
-  get_agl_m(ref_time, pos, 2.0, contact, normal, vel, &type, 0, &agl);
-  Point3D geodPos = sgCartToGeod(Point3D(contact[0], contact[1], contact[2]));
-  return geodPos.elev();
+  get_agl_m(ref_time, pos.data(), 2.0, contact, normal, vel, &type, 0, &agl);
+  SGGeod geod = SGGeod::fromCart(SGVec3d(contact));
+  return geod.getElevationM();
 }
   
 bool
 FGInterface::caught_wire_m(double t, const double pt[4][3])
 {
-  return ground_cache.caught_wire(t, pt);
+  SGVec3d pt_m[4];
+  for (int i=0; i<4; ++i)
+    sgdCopyVec3(pt_m[i].data(), pt[i]);
+  
+  return ground_cache.caught_wire(t, pt_m);
 }
 
 bool
 FGInterface::caught_wire_ft(double t, const double pt[4][3])
 {
   // Convert units and do the real work.
-  double pt_m[4][3];
+  SGVec3d pt_m[4];
   for (int i=0; i<4; ++i)
-    sgdScaleVec3(pt_m[i], pt[i], SG_FEET_TO_METER);
+    sgdScaleVec3(pt_m[i].data(), pt[i], SG_FEET_TO_METER);
     
   return ground_cache.caught_wire(t, pt_m);
 }
@@ -998,17 +1022,24 @@ FGInterface::caught_wire_ft(double t, const double pt[4][3])
 bool
 FGInterface::get_wire_ends_m(double t, double end[2][3], double vel[2][3])
 {
-  return ground_cache.get_wire_ends(t, end, vel);
+  SGVec3d _end[2], _vel[2];
+  bool ret = ground_cache.get_wire_ends(t, _end, _vel);
+  for (int k=0; k<2; ++k) {
+    sgdCopyVec3( end[k], _end[k].data() );
+    sgdCopyVec3( vel[k], _vel[k].data() );
+  }
+  return ret;
 }
 
 bool
 FGInterface::get_wire_ends_ft(double t, double end[2][3], double vel[2][3])
 {
   // Convert units and do the real work.
-  bool ret = ground_cache.get_wire_ends(t, end, vel);
+  SGVec3d _end[2], _vel[2];
+  bool ret = ground_cache.get_wire_ends(t, _end, _vel);
   for (int k=0; k<2; ++k) {
-    sgdScaleVec3( end[k], SG_METER_TO_FEET );
-    sgdScaleVec3( vel[k], SG_METER_TO_FEET );
+    sgdScaleVec3( end[k], _end[k].data(), SG_METER_TO_FEET );
+    sgdScaleVec3( vel[k], _vel[k].data(), SG_METER_TO_FEET );
   }
   return ret;
 }
index dac41d515680363a913fc32fdbe08272f661e770..2a9cde89c102de4e3e8bd8c2fef99e2a92e889c1 100644 (file)
 #include <float.h>
 
 #include <plib/sg.h>
+#include <osg/CullFace>
+#include <osg/Drawable>
+#include <osg/Geode>
+#include <osg/Geometry>
+#include <osg/TriangleFunctor>
 
 #include <simgear/sg_inlines.h>
 #include <simgear/constants.h>
@@ -34,6 +39,7 @@
 #include <simgear/math/sg_geodesy.hxx>
 #include <simgear/scene/material/mat.hxx>
 #include <simgear/scene/material/matlib.hxx>
+#include <simgear/scene/util/SGNodeMasks.hxx>
 
 #include <Main/globals.hxx>
 #include <Scenery/scenery.hxx>
 #include "flight.hxx"
 #include "groundcache.hxx"
 
-// Specialized version of sgMultMat4 needed because of mixed matrix
-// types
-static inline void fgMultMat4(sgdMat4 dst, sgdMat4 m1, sgMat4 m2) {
-    for ( int j = 0 ; j < 4 ; j++ ) {
-        dst[0][j] = m2[0][0] * m1[0][j] +
-                    m2[0][1] * m1[1][j] +
-                    m2[0][2] * m1[2][j] +
-                    m2[0][3] * m1[3][j] ;
-
-        dst[1][j] = m2[1][0] * m1[0][j] +
-                    m2[1][1] * m1[1][j] +
-                    m2[1][2] * m1[2][j] +
-                    m2[1][3] * m1[3][j] ;
-
-        dst[2][j] = m2[2][0] * m1[0][j] +
-                    m2[2][1] * m1[1][j] +
-                    m2[2][2] * m1[2][j] +
-                    m2[2][3] * m1[3][j] ;
-
-        dst[3][j] = m2[3][0] * m1[0][j] +
-                    m2[3][1] * m1[1][j] +
-                    m2[3][2] * m1[2][j] +
-                    m2[3][3] * m1[3][j] ;
-    }
-}
-
-static inline bool fgdPointInTriangle( sgdVec3 point, sgdVec3 tri[3] )
+static inline bool
+fgdPointInTriangle( const SGVec3d& point, const SGVec3d tri[3] )
 {
-    sgdVec3 dif;
+    SGVec3d dif;
 
     // Some tolerance in meters we accept a point to be outside of the triangle
     // and still return that it is inside.
@@ -172,51 +153,160 @@ static inline bool fgdPointInTriangle( sgdVec3 point, sgdVec3 tri[3] )
 // line direction dir intersects the sphere sp.
 // Adapted from plib.
 static inline bool
-fgdIsectSphereInfLine(const sgdSphere& sp,
-                      const sgdVec3 pt_on_line, const sgdVec3 dir)
+fgdIsectSphereInfLine(const SGVec3d& sphereCenter, double radius,
+                      const SGVec3d& pt_on_line, const SGVec3d& dir)
 {
-  sgdVec3 r;
-  sgdSubVec3( r, sp.getCenter(), pt_on_line ) ;
-
-  SGDfloat projectedDistance = sgdScalarProductVec3(r, dir);
-  SGDfloat dist = sgdScalarProductVec3 ( r, r ) -
-    projectedDistance * projectedDistance;
-
-  SGDfloat radius = sp.getRadius();
+  SGVec3d r = sphereCenter - pt_on_line;
+  double projectedDistance = dot(r, dir);
+  double dist = dot(r, r) - projectedDistance * projectedDistance;
   return dist < radius*radius;
 }
 
-FGGroundCache::FGGroundCache()
-{
-  sgdSetVec3(cache_center, 0.0, 0.0, 0.0);
-  ground_radius = 0.0;
-  cache_ref_time = 0.0;
-  wire_id = 0;
-  sgdSetVec3(reference_wgs84_point, 0.0, 0.0, 0.0);
-  reference_vehicle_radius = 0.0;
-  found_ground = false;
-}
-
-FGGroundCache::~FGGroundCache()
-{
-}
+template<typename T>
+class SGExtendedTriangleFunctor : public osg::TriangleFunctor<T> {
+public:
+  // Ok, to be complete we should also implement the indexed variants
+  // For now this one appears to be enough ...
+  void drawArrays(GLenum mode, GLint first, GLsizei count)
+  {
+    if (_vertexArrayPtr==0 || count==0) return;
+
+    const osg::Vec3* vlast;
+    const osg::Vec3* vptr;
+    switch(mode) {
+    case(GL_LINES):
+      vlast = &_vertexArrayPtr[first+count];
+      for(vptr=&_vertexArrayPtr[first];vptr<vlast;vptr+=2)
+        this->operator()(*(vptr),*(vptr+1),_treatVertexDataAsTemporary);
+      break;
+    case(GL_LINE_STRIP):
+      vlast = &_vertexArrayPtr[first+count-1];
+      for(vptr=&_vertexArrayPtr[first];vptr<vlast;++vptr)
+        this->operator()(*(vptr),*(vptr+1),_treatVertexDataAsTemporary);
+      break;
+    case(GL_LINE_LOOP):
+      vlast = &_vertexArrayPtr[first+count-1];
+      for(vptr=&_vertexArrayPtr[first];vptr<vlast;++vptr)
+        this->operator()(*(vptr),*(vptr+1),_treatVertexDataAsTemporary);
+      this->operator()(_vertexArrayPtr[first+count-1],
+                       _vertexArrayPtr[first],_treatVertexDataAsTemporary);
+      break;
+    default:
+      osg::TriangleFunctor<T>::drawArrays(mode, first, count);
+      break;
+    }
+  }
+protected:
+  using osg::TriangleFunctor<T>::_vertexArrayPtr;
+  using osg::TriangleFunctor<T>::_treatVertexDataAsTemporary;
+};
 
-FGGroundCache::GroundProperty
-FGGroundCache::extractGroundProperty( ssgLeaf* l )
-{
-  // FIXME: Do more ...
-  // Idea: have a get_globals() function which knows about that stuff.
-  // Or most probably read that from a configuration file,
-  // from property tree or whatever ...
+class GroundCacheFillVisitor : public osg::NodeVisitor {
+public:
   
-  // Get ground dependent data.
-  GroundProperty gp;
-  gp.wire_id = -1;
-  
-  FGAICarrierHardware *ud =
-    dynamic_cast<FGAICarrierHardware*>(l->getUserData());
-  if (ud) {
+  /// class to just redirect triangles to the GroundCacheFillVisitor
+  class GroundCacheFill {
+  public:
+    void setGroundCacheFillVisitor(GroundCacheFillVisitor* gcfv)
+    { mGroundCacheFillVisitor = gcfv; }
+    
+    void operator () (const osg::Vec3& v1, const osg::Vec3& v2,
+                      const osg::Vec3& v3, bool)
+    { mGroundCacheFillVisitor->addTriangle(v1, v2, v3); }
+
+    void operator () (const osg::Vec3& v1, const osg::Vec3& v2, bool)
+    { mGroundCacheFillVisitor->addLine(v1, v2); }
+    
+  private:
+    GroundCacheFillVisitor* mGroundCacheFillVisitor;
+  };
+
+
+  GroundCacheFillVisitor(FGGroundCache* groundCache,
+                         const SGVec3d& down, 
+                         const SGVec3d& cacheReference,
+                         double cacheRadius,
+                         double wireCacheRadius) :
+    osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN),
+    mGroundCache(groundCache)
+  {
+    setTraversalMask(SG_NODEMASK_TERRAIN_BIT);
+    mDown = down;
+    sphIsec = true;
+    mBackfaceCulling = false;
+    mCacheReference = cacheReference;
+    mCacheRadius = cacheRadius;
+    mWireCacheRadius = wireCacheRadius;
+
+    mTriangleFunctor.setGroundCacheFillVisitor(this);
+
+    mGroundProperty.wire_id = -1;
+    mGroundProperty.vel = SGVec3d(0, 0, 0);
+    mGroundProperty.rot = SGVec3d(0, 0, 0);
+    mGroundProperty.pivot = SGVec3d(0, 0, 0);
+  }
+
+  void updateCullMode(osg::StateSet* stateSet)
+  {
+    if (!stateSet)
+      return;
+
+    osg::StateAttribute* stateAttribute;
+    stateAttribute = stateSet->getAttribute(osg::StateAttribute::CULLFACE);
+    if (!stateAttribute)
+      return;
+    osg::CullFace* cullFace = static_cast<osg::CullFace*>(stateAttribute);
+    mBackfaceCulling = cullFace->getMode() == osg::CullFace::BACK;
+  }
+
+  bool enterBoundingSphere(const osg::BoundingSphere& bs)
+  {
+    if (!bs.valid())
+      return false;
+
+    SGVec3d cntr(osg::Vec3d(bs.center())*mLocalToGlobal);
+    double rc = bs.radius() + mCacheRadius;
+    // Ok, this node might intersect the cache. Visit it in depth.
+    double centerDist2 = distSqr(mCacheReference, cntr);
+    if (centerDist2 < rc*rc) {
+      sphIsec = true;
+    } else {
+      // Check if the down direction touches the bounding sphere of the node
+      // if so, do at least croase agl computations.
+      // Ther other thing is that we must check if we are in range of
+      // cats or wires
+      double rw = bs.radius() + mWireCacheRadius;
+      if (rw*rw < centerDist2 &&
+          !fgdIsectSphereInfLine(cntr, bs.radius(), mCacheReference, mDown))
+        return false;
+      sphIsec = false;
+    }
+
+    return true;
+  }
+
+  bool enterNode(osg::Node& node)
+  {
+    if (!enterBoundingSphere(node.getBound()))
+      return false;
+
+    updateCullMode(node.getStateSet());
+
+    FGGroundCache::GroundProperty& gp = mGroundProperty;
+    // get some material information for use in the gear model
+    gp.material = globals->get_matlib()->findMaterial(&node);
+    if (gp.material) {
+      gp.type = gp.material->get_solid() ? FGInterface::Solid : FGInterface::Water;
+      return true;
+    }
+    osg::Referenced* base = node.getUserData();
+    if (!base)
+      return true;
+    FGAICarrierHardware *ud =
+      dynamic_cast<FGAICarrierHardware*>(base);
+    if (!ud)
+      return true;
+
     switch (ud->type) {
     case FGAICarrierHardware::Wire:
       gp.type = FGInterface::Wire;
@@ -229,137 +319,199 @@ FGGroundCache::extractGroundProperty( ssgLeaf* l )
       gp.type = FGInterface::Solid;
       break;
     }
-
     // Copy the velocity from the carrier class.
     ud->carrier->getVelocityWrtEarth( gp.vel, gp.rot, gp.pivot );
+  
+    return true;
   }
 
-  else {
-    // Initialize velocity field.
-    sgdSetVec3( gp.vel, 0.0, 0.0, 0.0 );
-    sgdSetVec3( gp.rot, 0.0, 0.0, 0.0 );
-    sgdSetVec3( gp.pivot, 0.0, 0.0, 0.0 );
+  void fillWith(osg::Drawable* drawable)
+  {
+    bool oldSphIsec = sphIsec;
+    if (!enterBoundingSphere(drawable->getBound()))
+      return;
 
-    // get some material information for use in the gear model
-    gp.material = globals->get_matlib()->findMaterial(l);
-    if (gp.material)
-      gp.type = gp.material->get_solid() ? FGInterface::Solid : FGInterface::Water;
+    bool oldBackfaceCulling = mBackfaceCulling;
+    updateCullMode(drawable->getStateSet());
+
+    drawable->accept(mTriangleFunctor);
+
+    mBackfaceCulling = oldBackfaceCulling;
+    sphIsec = oldSphIsec;
   }
-  
-  return gp;
-}
 
-void
-FGGroundCache::putLineLeafIntoCache(const sgdSphere *wsp, const sgdMat4 xform,
-                                    ssgLeaf *l)
-{
-  GroundProperty gp = extractGroundProperty(l);
-
-  // Lines must have special meanings.
-  // Wires and catapults are done with lines.
-  int nl = l->getNumLines();
-  for (int i = 0; i < nl; ++i) {
-    sgdSphere sphere;
-    sphere.empty();
-    sgdVec3 ends[2];
-    short v[2];
-    l->getLine(i, v, v+1 );
-    for (int k=0; k<2; ++k) {
-      sgdSetVec3(ends[k], l->getVertex(v[k]));
-      sgdXformPnt3(ends[k], xform);
-      sphere.extend(ends[k]);
-    }
+  virtual void apply(osg::Geode& geode)
+  {
+    bool oldBackfaceCulling = mBackfaceCulling;
+    bool oldSphIsec = sphIsec;
+    FGGroundCache::GroundProperty oldGp = mGroundProperty;
+    if (!enterNode(geode))
+      return;
+
+    for(unsigned i = 0; i < geode.getNumDrawables(); ++i)
+      fillWith(geode.getDrawable(i));
+    sphIsec = oldSphIsec;
+    mGroundProperty = oldGp;
+    mBackfaceCulling = oldBackfaceCulling;
+  }
 
-    if (wsp->intersects( &sphere )) {
-      if (gp.type == FGInterface::Wire) {
-        Wire wire;
-        sgdCopyVec3(wire.ends[0], ends[0]);
-        sgdCopyVec3(wire.ends[1], ends[1]);
-        sgdCopyVec3(wire.velocity, gp.vel);
-        sgdCopyVec3(wire.rotation, gp.rot);
-        sgdSubVec3(wire.rotation_pivot, gp.pivot, cache_center);
-        wire.wire_id = gp.wire_id;
-
-        wires.push_back(wire);
-      }
-      if (gp.type == FGInterface::Catapult) {
-        Catapult cat;
-        sgdCopyVec3(cat.start, ends[0]);
-        sgdCopyVec3(cat.end, ends[1]);
-        sgdCopyVec3(cat.velocity, gp.vel);
-        sgdCopyVec3(cat.rotation, gp.rot);
-        sgdSubVec3(cat.rotation_pivot, gp.pivot, cache_center);
-
-        catapults.push_back(cat);
-      }
-    }
+  virtual void apply(osg::Group& group)
+  {
+    bool oldBackfaceCulling = mBackfaceCulling;
+    bool oldSphIsec = sphIsec;
+    FGGroundCache::GroundProperty oldGp = mGroundProperty;
+    if (!enterNode(group))
+      return;
+    traverse(group);
+    sphIsec = oldSphIsec;
+    mBackfaceCulling = oldBackfaceCulling;
+    mGroundProperty = oldGp;
   }
-}
 
-void
-FGGroundCache::putSurfaceLeafIntoCache(const sgdSphere *sp,
-                                       const sgdMat4 xform, bool sphIsec,
-                                       sgdVec3 down, ssgLeaf *l)
-{
-  GroundProperty gp = extractGroundProperty(l);
-
-  int nt = l->getNumTriangles();
-  for (int i = 0; i < nt; ++i) {
-    Triangle t;
-    t.sphere.empty();
-    t.material = gp.material;
-    short v[3];
-    l->getTriangle(i, &v[0], &v[1], &v[2]);
-    for (int k = 0; k < 3; ++k) {
-      sgdSetVec3(t.vertices[k], l->getVertex(v[k]));
-      sgdXformPnt3(t.vertices[k], xform);
-      t.sphere.extend(t.vertices[k]);
-    }
+  virtual void apply(osg::Transform& transform)
+  {
+    /// transform the caches center to local coords
+    osg::Matrix oldLocalToGlobal = mLocalToGlobal;
+    transform.computeLocalToWorldMatrix(mLocalToGlobal, this);
+
+    // walk the children
+    apply((osg::Group&)transform);
 
-    sgdMakePlane(t.plane, t.vertices[0], t.vertices[1], t.vertices[2]);
-    SGDfloat dot = sgdScalarProductVec3(down, t.plane);
-    if (dot > 0) {
-      if (!l->getCullFace()) {
+    // Restore that one
+    mLocalToGlobal = oldLocalToGlobal;
+  }
+
+  void addTriangle(const osg::Vec3& v1, const osg::Vec3& v2,
+                   const osg::Vec3& v3)
+  {
+    FGGroundCache::Triangle t;
+    osg::Vec3d gv1 = osg::Vec3d(v1)*mLocalToGlobal;
+    osg::Vec3d gv2 = osg::Vec3d(v2)*mLocalToGlobal;
+    osg::Vec3d gv3 = osg::Vec3d(v3)*mLocalToGlobal;
+    for (unsigned i = 0; i < 3; ++i) {
+      t.vertices[0][i] = gv1[i];
+      t.vertices[1][i] = gv2[i];
+      t.vertices[2][i] = gv3[i];
+    }
+    // FIXME: can do better ...
+    t.boundCenter = (1.0/3)*(t.vertices[0] + t.vertices[1] + t.vertices[2]);
+    t.boundRadius = std::max(length(t.vertices[0] - t.boundCenter),
+                             length(t.vertices[1] - t.boundCenter));
+    t.boundRadius = std::max(t.boundRadius,
+                             length(t.vertices[2] - t.boundCenter));
+
+    sgdMakePlane(t.plane.sg(), t.vertices[0].sg(), t.vertices[1].sg(),
+                 t.vertices[2].sg());
+    double d = sgdScalarProductVec3(mDown.sg(), t.plane.sg());
+    if (d > 0) {
+      if (mBackfaceCulling) {
         // Surface points downwards, ignore for altitude computations.
-        continue;
+        return;
       } else
-        sgdScaleVec4( t.plane, -1 );
+        t.plane = -t.plane;
     }
 
     // Check if the sphere around the vehicle intersects the sphere
     // around that triangle. If so, put that triangle into the cache.
-    if (sphIsec && sp->intersects(&t.sphere)) {
-      sgdCopyVec3(t.velocity, gp.vel);
-      sgdCopyVec3(t.rotation, gp.rot);
-      sgdSubVec3(t.rotation_pivot, gp.pivot, cache_center);
-      t.type = gp.type;
-      triangles.push_back(t);
+    if (sphIsec &&
+        distSqr(t.boundCenter, mCacheReference)
+        < (t.boundRadius + mCacheRadius)*(t.boundRadius + mCacheRadius) ) {
+      t.velocity = mGroundProperty.vel;
+      t.rotation = mGroundProperty.rot;
+      t.rotation_pivot = mGroundProperty.pivot - mGroundCache->cache_center;
+      t.type = mGroundProperty.type;
+      mGroundCache->triangles.push_back(t);
     }
     
     // In case the cache is empty, we still provide agl computations.
     // But then we use the old way of having a fixed elevation value for
     // the whole lifetime of this cache.
-    if ( fgdIsectSphereInfLine(t.sphere, sp->getCenter(), down) ) {
-      sgdVec3 tmp;
-      sgdSetVec3(tmp, sp->center[0], sp->center[1], sp->center[2]);
-      sgdVec3 isectpoint;
-      if ( sgdIsectInfLinePlane( isectpoint, tmp, down, t.plane ) &&
+    if ( fgdIsectSphereInfLine(t.boundCenter, t.boundRadius,
+                               mCacheReference, mDown) ) {
+      SGVec3d isectpoint;
+      if ( sgdIsectInfLinePlane( isectpoint.sg(), mCacheReference.sg(),
+                                 mDown.sg(), t.plane.sg() ) &&
            fgdPointInTriangle( isectpoint, t.vertices ) ) {
-        // Compute the offset to the ground cache midpoint
-        sgdVec3 off;
-        sgdSubVec3(off, isectpoint, tmp);
         // Only accept the altitude if the intersection point is below the
         // ground cache midpoint
-        if (0 < sgdScalarProductVec3( off, down )) {
-          found_ground = true;
-          sgdAddVec3(isectpoint, cache_center);
-          double this_radius = sgdLengthVec3(isectpoint);
-          if (ground_radius < this_radius)
-            ground_radius = this_radius;
+        if (0 < dot(isectpoint - mCacheReference, mDown)) {
+          mGroundCache->found_ground = true;
+          isectpoint += mGroundCache->cache_center;
+          double this_radius = length(isectpoint);
+          if (mGroundCache->ground_radius < this_radius)
+            mGroundCache->ground_radius = this_radius;
         }
       }
     }
   }
+  void addLine(const osg::Vec3& v1, const osg::Vec3& v2)
+  {
+    SGVec3d gv1 = SGVec3d(osg::Vec3d(v1)*mLocalToGlobal);
+    SGVec3d gv2 = SGVec3d(osg::Vec3d(v2)*mLocalToGlobal);
+
+    SGVec3d boundCenter = 0.5*(gv1 + gv2);
+    double boundRadius = length(gv1 - boundCenter);
+
+    if (distSqr(boundCenter, mCacheReference)
+        < (boundRadius + mWireCacheRadius)*(boundRadius + mWireCacheRadius) ) {
+      if (mGroundProperty.type == FGInterface::Wire) {
+        FGGroundCache::Wire wire;
+        wire.ends[0] = gv1;
+        wire.ends[1] = gv2;
+        wire.velocity = mGroundProperty.vel;
+        wire.rotation = mGroundProperty.rot;
+        wire.rotation_pivot = mGroundProperty.pivot - mGroundCache->cache_center;
+        wire.wire_id = mGroundProperty.wire_id;
+
+        mGroundCache->wires.push_back(wire);
+      }
+      if (mGroundProperty.type == FGInterface::Catapult) {
+        FGGroundCache::Catapult cat;
+        // Trick to get the ends in the right order.
+        // Use the x axis in the original coordinate system. Choose the
+        // most negative x-axis as the one pointing forward
+        if (v1[0] < v2[0]) {
+          cat.start = gv1;
+          cat.end = gv2;
+        } else {
+          cat.start = gv2;
+          cat.end = gv1;
+        }
+        cat.velocity = mGroundProperty.vel;
+        cat.rotation = mGroundProperty.rot;
+        cat.rotation_pivot = mGroundProperty.pivot - mGroundCache->cache_center;
+
+        mGroundCache->catapults.push_back(cat);
+      }
+    }
+  }
+
+  SGExtendedTriangleFunctor<GroundCacheFill> mTriangleFunctor;
+  FGGroundCache* mGroundCache;
+  SGVec3d mCacheReference;
+  double mCacheRadius;
+  double mWireCacheRadius;
+  osg::Matrix mLocalToGlobal;
+  SGVec3d mDown;
+  bool sphIsec;
+  bool mBackfaceCulling;
+  FGGroundCache::GroundProperty mGroundProperty;
+};
+
+FGGroundCache::FGGroundCache()
+{
+  cache_center = SGVec3d(0, 0, 0);
+  ground_radius = 0.0;
+  cache_ref_time = 0.0;
+  wire_id = 0;
+  reference_wgs84_point = SGVec3d(0, 0, 0);
+  reference_vehicle_radius = 0.0;
+  found_ground = false;
+}
+
+FGGroundCache::~FGGroundCache()
+{
 }
 
 inline void
@@ -367,104 +519,27 @@ FGGroundCache::velocityTransformTriangle(double dt,
                                          FGGroundCache::Triangle& dst,
                                          const FGGroundCache::Triangle& src)
 {
-  sgdCopyVec3(dst.vertices[0], src.vertices[0]);
-  sgdCopyVec3(dst.vertices[1], src.vertices[1]);
-  sgdCopyVec3(dst.vertices[2], src.vertices[2]);
+  dst = src;
 
-  sgdCopyVec4(dst.plane, src.plane);
-  
-  sgdCopyVec3(dst.sphere.center, src.sphere.center);
-  dst.sphere.radius = src.sphere.radius;
-
-  sgdCopyVec3(dst.velocity, src.velocity);
-  sgdCopyVec3(dst.rotation, src.rotation);
-  sgdCopyVec3(dst.rotation_pivot, src.rotation_pivot);
-
-  dst.type = src.type;
-  dst.material = src.material;
-
-  if (dt*sgdLengthSquaredVec3(src.velocity) != 0) {
-    sgdVec3 pivotoff, vel;
-    for (int i = 0; i < 3; ++i) {
-      sgdSubVec3(pivotoff, src.vertices[i], src.rotation_pivot);
-      sgdVectorProductVec3(vel, src.rotation, pivotoff);
-      sgdAddVec3(vel, src.velocity);
-      sgdAddScaledVec3(dst.vertices[i], vel, dt);
-    }
-    
-    // Transform the plane equation
-    sgdSubVec3(pivotoff, dst.plane, src.rotation_pivot);
-    sgdVectorProductVec3(vel, src.rotation, pivotoff);
-    sgdAddVec3(vel, src.velocity);
-    dst.plane[3] += dt*sgdScalarProductVec3(dst.plane, vel);
+  if (fabs(dt*dot(src.velocity, src.velocity)) < SGLimitsd::epsilon())
+    return;
 
-    sgdAddScaledVec3(dst.sphere.center, src.velocity, dt);
-  }
-}
-
-void
-FGGroundCache::cache_fill(ssgBranch *branch, sgdMat4 xform,
-                          sgdSphere* sp, sgdVec3 down, sgdSphere* wsp)
-{
-  // Travel through all kids.
-  ssgEntity *e;
-  for ( e = branch->getKid(0); e != NULL ; e = branch->getNextKid() ) {
-    if ( !(e->getTraversalMask() & SSGTRAV_HOT) )
-      continue;
-    if ( e->getBSphere()->isEmpty() )
-      continue;
-    
-    // We need to check further if either the sphere around the branch
-    // intersects the sphere around the aircraft or the line downwards from
-    // the aircraft intersects the branchs sphere.
-    sgdSphere esphere;
-    sgdSetVec3(esphere.center, e->getBSphere()->center);
-    esphere.radius = e->getBSphere()->radius;
-    esphere.orthoXform(xform);
-    bool wspIsec = wsp->intersects(&esphere);
-    bool downIsec = fgdIsectSphereInfLine(esphere, sp->getCenter(), down);
-    if (!wspIsec && !downIsec)
-      continue;
-
-    // For branches collect up the transforms to reach that branch and
-    // call cache_fill recursively.
-    if ( e->isAKindOf( ssgTypeBranch() ) ) {
-      ssgBranch *b = (ssgBranch *)e;
-      if ( b->isAKindOf( ssgTypeTransform() ) ) {
-        // Collect up the transforms required to reach that part of
-        // the branch.
-        sgMat4 xform2;
-        sgMakeIdentMat4( xform2 );
-        ssgTransform *t = (ssgTransform*)b;
-        t->getTransform( xform2 );
-        sgdMat4 xform3;
-        fgMultMat4(xform3, xform, xform2);
-        cache_fill( b, xform3, sp, down, wsp );
-      } else
-        cache_fill( b, xform, sp, down, wsp );
-    }
-   
-    // For leafs, check each triangle for intersection.
-    // This will minimize the number of vertices/triangles in the cache.
-    else if (e->isAKindOf(ssgTypeLeaf())) {
-      // Since we reach that leaf if we have an intersection with the
-      // most probably bigger wire/catapult cache sphere, we need to check
-      // that here, if the smaller cache for the surface has a chance for hits.
-      // Also, if the spheres do not intersect compute a coarse agl value
-      // by following the line downwards originating at the aircraft.
-      bool spIsec = sp->intersects(&esphere);
-      putSurfaceLeafIntoCache(sp, xform, spIsec, down, (ssgLeaf *)e);
-
-      // If we are here, we need to put all special hardware here into
-      // the cache.
-      if (wspIsec)
-        putLineLeafIntoCache(wsp, xform, (ssgLeaf *)e);
-    }
+  for (int i = 0; i < 3; ++i) {
+    SGVec3d pivotoff = src.vertices[i] - src.rotation_pivot;
+    dst.vertices[i] += dt*(src.velocity + cross(src.rotation, pivotoff));
   }
+  
+  // Transform the plane equation
+  SGVec3d pivotoff, vel;
+  sgdSubVec3(pivotoff.sg(), dst.plane.sg(), src.rotation_pivot.sg());
+  vel = src.velocity + cross(src.rotation, pivotoff);
+  dst.plane[3] += dt*sgdScalarProductVec3(dst.plane.sg(), vel.sg());
+  
+  dst.boundCenter += dt*src.velocity;
 }
 
 bool
-FGGroundCache::prepare_ground_cache(double ref_time, const double pt[3],
+FGGroundCache::prepare_ground_cache(double ref_time, const SGVec3d& pt,
                                     double rad)
 {
   // Empty cache.
@@ -475,14 +550,18 @@ FGGroundCache::prepare_ground_cache(double ref_time, const double pt[3],
   wires.resize(0);
 
   // Store the parameters we used to build up that cache.
-  sgdCopyVec3(reference_wgs84_point, pt);
+  reference_wgs84_point = pt;
   reference_vehicle_radius = rad;
   // Store the time reference used to compute movements of moving triangles.
   cache_ref_time = ref_time;
 
+  // Get a normalized down vector valid for the whole cache
+  SGQuatd hlToEc = SGQuatd::fromLonLat(SGGeod::fromCart(pt));
+  down = hlToEc.rotate(SGVec3d(0, 0, 1));
+
   // Decide where we put the scenery center.
   SGVec3d old_cntr = globals->get_scenery()->get_center();
-  SGVec3d cntr(pt[0], pt[1], pt[2]);
+  SGVec3d cntr(pt);
   // Only move the cache center if it is unacceptable far away.
   if (40*40 < distSqr(old_cntr, cntr))
     globals->get_scenery()->set_center(cntr);
@@ -490,43 +569,21 @@ FGGroundCache::prepare_ground_cache(double ref_time, const double pt[3],
     cntr = old_cntr;
 
   // The center of the cache.
-  sgdSetVec3(cache_center, cntr[0], cntr[1], cntr[2]);
+  cache_center = cntr;
   
-  sgdVec3 ptoff;
-  sgdSubVec3(ptoff, pt, cache_center);
   // Prepare sphere around the aircraft.
-  sgdSphere acSphere;
-  acSphere.setRadius(rad);
-  acSphere.setCenter(ptoff);
+  SGVec3d ptoff = pt - cache_center;
+  double cacheRadius = rad;
 
   // Prepare bigger sphere around the aircraft.
   // This one is required for reliably finding wires we have caught but
   // have already left the hopefully smaller sphere for the ground reactions.
   const double max_wire_dist = 300.0;
-  sgdSphere wireSphere;
-  wireSphere.setRadius(max_wire_dist < rad ? rad : max_wire_dist);
-  wireSphere.setCenter(ptoff);
-
-  // Down vector. Is used for croase agl computations when we are far enough
-  // from ground that we have an empty cache.
-  sgdVec3 down;
-  sgdSetVec3(down, -pt[0], -pt[1], -pt[2]);
-  sgdNormalizeVec3(down);
-
-  // We collapse all transforms we need to reach a particular leaf.
-  // The leafs itself will be then transformed later.
-  // So our cache is just flat.
-  // For leafs which are moving (carriers surface, etc ...)
-  // we will later store a speed in the GroundType class. We can then apply
-  // some translations to that nodes according to the time which has passed
-  // compared to that snapshot.
-  sgdMat4 xform;
-  sgdMakeIdentMat4( xform );
-
+  double wireCacheRadius = max_wire_dist < rad ? rad : max_wire_dist;
 
   // Walk the scene graph and extract solid ground triangles and carrier data.
-  ssgBranch *terrain = globals->get_scenery()->get_scene_graph();
-  cache_fill(terrain, xform, &acSphere, down, &wireSphere);
+  GroundCacheFillVisitor gcfv(this, down, ptoff, cacheRadius, wireCacheRadius);
+  globals->get_scenery()->get_scene_graph()->accept(gcfv);
 
   // some stats
   SG_LOG(SG_FLIGHT,SG_DEBUG, "prepare_ground_cache(): ac radius = " << rad
@@ -549,17 +606,17 @@ FGGroundCache::prepare_ground_cache(double ref_time, const double pt[3],
 }
 
 bool
-FGGroundCache::is_valid(double *ref_time, double pt[3], double *rad)
+FGGroundCache::is_valid(double& ref_time, SGVec3d& pt, double& rad)
 {
-  sgdCopyVec3(pt, reference_wgs84_point);
-  *rad = reference_vehicle_radius;
-  *ref_time = cache_ref_time;
+  pt = reference_wgs84_point;
+  rad = reference_vehicle_radius;
+  ref_time = cache_ref_time;
   return found_ground;
 }
 
 double
-FGGroundCache::get_cat(double t, const double dpt[3],
-                       double end[2][3], double vel[2][3])
+FGGroundCache::get_cat(double t, const SGVec3d& dpt,
+                       SGVec3d end[2], SGVec3d vel[2])
 {
   // start with a distance of 1e10 meters...
   double dist = 1e10;
@@ -569,35 +626,30 @@ FGGroundCache::get_cat(double t, const double dpt[3],
 
   size_t sz = catapults.size();
   for (size_t i = 0; i < sz; ++i) {
-    sgdVec3 pivotoff, rvel[2];
-    sgdLineSegment3 ls;
-    sgdCopyVec3(ls.a, catapults[i].start);
-    sgdCopyVec3(ls.b, catapults[i].end);
+    SGVec3d pivotoff, rvel[2];
+    pivotoff = catapults[i].start - catapults[i].rotation_pivot;
+    rvel[0] = catapults[i].velocity + cross(catapults[i].rotation, pivotoff);
+    pivotoff = catapults[i].end - catapults[i].rotation_pivot;
+    rvel[1] = catapults[i].velocity + cross(catapults[i].rotation, pivotoff);
 
-    sgdSubVec3(pivotoff, ls.a, catapults[i].rotation_pivot);
-    sgdVectorProductVec3(rvel[0], catapults[i].rotation, pivotoff);
-    sgdAddVec3(rvel[0], catapults[i].velocity);
-    sgdSubVec3(pivotoff, ls.b, catapults[i].rotation_pivot);
-    sgdVectorProductVec3(rvel[1], catapults[i].rotation, pivotoff);
-    sgdAddVec3(rvel[1], catapults[i].velocity);
+    SGVec3d thisEnd[2];
+    thisEnd[0] = cache_center + catapults[i].start + t*rvel[0];
+    thisEnd[1] = cache_center + catapults[i].end + t*rvel[1];
 
-    sgdAddVec3(ls.a, cache_center);
-    sgdAddVec3(ls.b, cache_center);
+    sgdLineSegment3 ls;
+    sgdCopyVec3(ls.a, thisEnd[0].sg());
+    sgdCopyVec3(ls.b, thisEnd[1].sg());
+    double this_dist = sgdDistSquaredToLineSegmentVec3( ls, dpt.sg() );
 
-    sgdAddScaledVec3(ls.a, rvel[0], t);
-    sgdAddScaledVec3(ls.b, rvel[1], t);
-    
-    double this_dist = sgdDistSquaredToLineSegmentVec3( ls, dpt );
     if (this_dist < dist) {
       SG_LOG(SG_FLIGHT,SG_INFO, "Found catapult "
              << this_dist << " meters away");
       dist = this_dist;
         
-      // The carrier code takes care of that ordering.
-      sgdCopyVec3( end[0], ls.a );
-      sgdCopyVec3( end[1], ls.b );
-      sgdCopyVec3( vel[0], rvel[0] );
-      sgdCopyVec3( vel[1], rvel[1] );
+      end[0] = thisEnd[0];
+      end[1] = thisEnd[1];
+      vel[0] = rvel[0];
+      vel[1] = rvel[1];
     }
   }
 
@@ -606,8 +658,8 @@ FGGroundCache::get_cat(double t, const double dpt[3],
 }
 
 bool
-FGGroundCache::get_agl(double t, const double dpt[3], double max_altoff,
-                       double contact[3], double normal[3], double vel[3],
+FGGroundCache::get_agl(double t, const SGVec3d& dpt, double max_altoff,
+                       SGVec3d& contact, SGVec3d& normal, SGVec3d& vel,
                        int *type, const SGMaterial** material, double *agl)
 {
   bool ret = false;
@@ -616,21 +668,15 @@ FGGroundCache::get_agl(double t, const double dpt[3], double max_altoff,
 //   *agl = 0.0;
   if (material)
     *material = 0;
-  sgdSetVec3( vel, 0.0, 0.0, 0.0 );
-  sgdSetVec3( contact, 0.0, 0.0, 0.0 );
-  sgdSetVec3( normal, 0.0, 0.0, 0.0 );
+  vel = SGVec3d(0, 0, 0);
+  contact = SGVec3d(0, 0, 0);
+  normal = SGVec3d(0, 0, 0);
 
   // Time difference to th reference time.
   t -= cache_ref_time;
 
   // The double valued point we start to search for intersection.
-  sgdVec3 pt;
-  sgdSubVec3( pt, dpt, cache_center );
-
-  // The search direction
-  sgdVec3 dir;
-  sgdSetVec3( dir, -dpt[0], -dpt[1], -dpt[2] );
-  sgdNormaliseVec3( dir );
+  SGVec3d pt = dpt - cache_center;
 
   // Initialize to something sensible
   double current_radius = 0.0;
@@ -639,39 +685,34 @@ FGGroundCache::get_agl(double t, const double dpt[3], double max_altoff,
   for (size_t i = 0; i < sz; ++i) {
     Triangle triangle;
     velocityTransformTriangle(t, triangle, triangles[i]);
-    if (!fgdIsectSphereInfLine(triangle.sphere, pt, dir))
+    if (!fgdIsectSphereInfLine(triangle.boundCenter, triangle.boundRadius, pt, down))
       continue;
 
     // Check for intersection.
-    sgdVec3 isecpoint;
-    if ( sgdIsectInfLinePlane( isecpoint, pt, dir, triangle.plane ) &&
-         sgdPointInTriangle( isecpoint, triangle.vertices ) ) {
+    SGVec3d isecpoint;
+    if ( sgdIsectInfLinePlane( isecpoint.sg(), pt.sg(), down.sg(), triangle.plane.sg() ) &&
+         fgdPointInTriangle( isecpoint, triangle.vertices ) ) {
       // Compute the vector from pt to the intersection point ...
-      sgdVec3 off;
-      sgdSubVec3(off, isecpoint, pt);
+      SGVec3d off = isecpoint - pt;
       // ... and check if it is too high or not
-      if (-max_altoff < sgdScalarProductVec3( off, dir )) {
+      if (-max_altoff < dot(off, down)) {
         // Transform to the wgs system
-        sgdAddVec3( isecpoint, cache_center );
+        isecpoint += cache_center;
         // compute the radius, good enough approximation to take the geocentric radius
-        SGDfloat radius = sgdLengthSquaredVec3(isecpoint);
+        double radius = dot(isecpoint, isecpoint);
         if (current_radius < radius) {
           current_radius = radius;
           ret = true;
           // Save the new potential intersection point.
-          sgdCopyVec3( contact, isecpoint );
+          contact = isecpoint;
           // The first three values in the vector are the plane normal.
-          sgdCopyVec3( normal, triangle.plane );
+          sgdCopyVec3( normal.sg(), triangle.plane.sg() );
           // The velocity wrt earth.
-          sgdVec3 pivotoff;
-          sgdSubVec3(pivotoff, pt, triangle.rotation_pivot);
-          sgdVectorProductVec3(vel, triangle.rotation, pivotoff);
-          sgdAddVec3(vel, triangle.velocity);
+          SGVec3d pivotoff = pt - triangle.rotation_pivot;
+          vel = triangle.velocity + cross(triangle.rotation, pivotoff);
           // Save the ground type.
           *type = triangle.type;
-          sgdVec3 dstToContact;
-          sgdSubVec3(dstToContact, contact, dpt);
-          *agl = sgdScalarProductVec3(dir, dstToContact);
+          *agl = dot(down, contact - dpt);
           if (material)
             *material = triangle.material;
         }
@@ -685,24 +726,21 @@ FGGroundCache::get_agl(double t, const double dpt[3], double max_altoff,
   // Whenever we did not have a ground triangle for the requested point,
   // take the ground level we found during the current cache build.
   // This is as good as what we had before for agl.
-  double r = sgdLengthVec3( dpt );
-  sgdCopyVec3( contact, dpt );
-  sgdScaleVec3( contact, ground_radius/r );
-  sgdCopyVec3( normal, dpt );
-  sgdNormaliseVec3( normal );
-  sgdSetVec3( vel, 0.0, 0.0, 0.0 );
+  double r = length(dpt);
+  contact = dpt;
+  contact *= ground_radius/r;
+  normal = -down;
+  vel = SGVec3d(0, 0, 0);
   
   // The altitude is the distance of the requested point from the
   // contact point.
-  sgdVec3 dstToContact;
-  sgdSubVec3(dstToContact, contact, dpt);
-  *agl = sgdScalarProductVec3(dir, dstToContact);
+  *agl = dot(down, contact - dpt);
   *type = FGInterface::Unknown;
 
   return ret;
 }
 
-bool FGGroundCache::caught_wire(double t, const double pt[4][3])
+bool FGGroundCache::caught_wire(double t, const SGVec3d pt[4])
 {
   size_t sz = wires.size();
   if (sz == 0)
@@ -713,36 +751,34 @@ bool FGGroundCache::caught_wire(double t, const double pt[4][3])
 
   // Build the two triangles spanning the area where the hook has moved
   // during the past step.
-  sgdVec4 plane[2];
-  sgdVec3 tri[2][3];
-  sgdMakePlane( plane[0], pt[0], pt[1], pt[2] );
-  sgdCopyVec3( tri[0][0], pt[0] );
-  sgdCopyVec3( tri[0][1], pt[1] );
-  sgdCopyVec3( tri[0][2], pt[2] );
-  sgdMakePlane( plane[1], pt[0], pt[2], pt[3] );
-  sgdCopyVec3( tri[1][0], pt[0] );
-  sgdCopyVec3( tri[1][1], pt[2] );
-  sgdCopyVec3( tri[1][2], pt[3] );
+  SGVec4d plane[2];
+  SGVec3d tri[2][3];
+  sgdMakePlane( plane[0].sg(), pt[0].sg(), pt[1].sg(), pt[2].sg() );
+  tri[0][0] = pt[0];
+  tri[0][1] = pt[1];
+  tri[0][2] = pt[2];
+  sgdMakePlane( plane[1].sg(), pt[0].sg(), pt[2].sg(), pt[3].sg() );
+  tri[1][0] = pt[0];
+  tri[1][1] = pt[2];
+  tri[1][2] = pt[3];
 
   // Intersect the wire lines with each of these triangles.
   // You have caught a wire if they intersect.
   for (size_t i = 0; i < sz; ++i) {
-    sgdVec3 le[2];
+    SGVec3d le[2];
     for (int k = 0; k < 2; ++k) {
-      sgdVec3 pivotoff, vel;
-      sgdCopyVec3(le[k], wires[i].ends[k]);
-      sgdSubVec3(pivotoff, le[k], wires[i].rotation_pivot);
-      sgdVectorProductVec3(vel, wires[i].rotation, pivotoff);
-      sgdAddVec3(vel, wires[i].velocity);
-      sgdAddScaledVec3(le[k], vel, t);
-      sgdAddVec3(le[k], cache_center);
+      le[k] = wires[i].ends[k];
+      SGVec3d pivotoff = le[k] - wires[i].rotation_pivot;
+      SGVec3d vel = wires[i].velocity + cross(wires[i].rotation, pivotoff);
+      le[k] += t*vel + cache_center;
     }
     
     for (int k=0; k<2; ++k) {
-      sgdVec3 isecpoint;
-      double isecval = sgdIsectLinesegPlane(isecpoint, le[0], le[1], plane[k]);
+      SGVec3d isecpoint;
+      double isecval = sgdIsectLinesegPlane(isecpoint.sg(), le[0].sg(),
+                                            le[1].sg(), plane[k].sg());
       if ( 0.0 <= isecval && isecval <= 1.0 &&
-           sgdPointInTriangle( isecpoint, tri[k] ) ) {
+           fgdPointInTriangle( isecpoint, tri[k] ) ) {
         SG_LOG(SG_FLIGHT,SG_INFO, "Caught wire");
         // Store the wire id.
         wire_id = wires[i].wire_id;
@@ -754,7 +790,7 @@ bool FGGroundCache::caught_wire(double t, const double pt[4][3])
   return false;
 }
 
-bool FGGroundCache::get_wire_ends(double t, double end[2][3], double vel[2][3])
+bool FGGroundCache::get_wire_ends(double t, SGVec3d end[2], SGVec3d vel[2])
 {
   // Fast return if we do not have an active wire.
   if (wire_id < 0)
@@ -768,13 +804,9 @@ bool FGGroundCache::get_wire_ends(double t, double end[2][3], double vel[2][3])
   for (size_t i = 0; i < sz; ++i) {
     if (wires[i].wire_id == wire_id) {
       for (size_t k = 0; k < 2; ++k) {
-        sgdVec3 pivotoff;
-        sgdCopyVec3(end[k], wires[i].ends[k]);
-        sgdSubVec3(pivotoff, end[k], wires[i].rotation_pivot);
-        sgdVectorProductVec3(vel[k], wires[i].rotation, pivotoff);
-        sgdAddVec3(vel[k], wires[i].velocity);
-        sgdAddScaledVec3(end[k], vel[k], t);
-        sgdAddVec3(end[k], cache_center);
+        SGVec3d pivotoff = end[k] - wires[i].rotation_pivot;
+        vel[k] = wires[i].velocity + cross(wires[i].rotation, pivotoff);
+        end[k] = cache_center + wires[i].ends[k] + t*vel[k];
       }
       return true;
     }
index e91534a63f1ba532e7845e3e6392383fab6ee5dc..754d539215154eba647a8aa2c8571ac20427dcf9 100644 (file)
 #ifndef _GROUNDCACHE_HXX
 #define _GROUNDCACHE_HXX
 
-#include <plib/sg.h>
-#include <plib/ssg.h>
 #include <simgear/compiler.h>
 #include <simgear/constants.h>
+#include <simgear/math/SGMath.hxx>
 
 class SGMaterial;
+class GroundCacheFillVisitor;
 
 class FGGroundCache {
 public:
@@ -42,19 +42,18 @@ public:
     // Prepare the ground cache for the wgs84 position pt_*.
     // That is take all vertices in the ball with radius rad around the
     // position given by the pt_* and store them in a local scene graph.
-    bool prepare_ground_cache(double ref_time, const double pt[3],
+    bool prepare_ground_cache(double ref_time, const SGVec3d& pt,
                               double rad);
 
     // Returns true if the cache is valid.
     // Also the reference time, point and radius values where the cache
     // is valid for are returned.
-    bool is_valid(double *ref_time, double pt[3], double *rad);
-      
+    bool is_valid(double& ref_time, SGVec3d& pt, double& rad);
 
     // Return the nearest catapult to the given point
     // pt in wgs84 coordinates.
-    double get_cat(double t, const double pt[3],
-                   double end[2][3], double vel[2][3]);
+    double get_cat(double t, const SGVec3d& pt,
+                   SGVec3d end[2], SGVec3d vel[2]);
   
 
     // Return the altitude above ground below the wgs84 point pt
@@ -63,8 +62,8 @@ public:
     // this kind kind of ground can carry, the friction factor between
     // 0 and 1 which can be used to model lower friction with wet runways
     // and finally the altitude above ground.
-    bool get_agl(double t, const double pt[3], double max_altoff,
-                 double contact[3], double normal[3], double vel[3],
+    bool get_agl(double t, const SGVec3d& pt, double max_altoff,
+                 SGVec3d& contact, SGVec3d& normal, SGVec3d& vel,
                  int *type, const SGMaterial** material, double *agl);
 
     // Return 1 if the hook intersects with a wire.
@@ -72,51 +71,54 @@ public:
     // intersects with the line representing the wire.
     // If the wire is caught, the cache will trace this wires endpoints until
     // the FDM calls release_wire().
-    bool caught_wire(double t, const double pt[4][3]);
+    bool caught_wire(double t, const SGVec3d pt[4]);
   
     // Return the location and speed of the wire endpoints.
-    bool get_wire_ends(double t, double end[2][3], double vel[2][3]);
+    bool get_wire_ends(double t, SGVec3d end[2], SGVec3d vel[2]);
 
     // Tell the cache code that it does no longer need to care for
     // the wire end position.
     void release_wire(void);
 
 private:
+    friend class GroundCacheFillVisitor;
+
     struct Triangle {
       Triangle() : material(0) {}
       // The edge vertices.
-      sgdVec3 vertices[3];
+      SGVec3d vertices[3];
       // The surface normal.
-      sgdVec4 plane;
+      SGVec4d plane;
       // The bounding shpere.
-      sgdSphere sphere;
+      SGVec3d boundCenter;
+      double boundRadius;
       // The linear and angular velocity.
-      sgdVec3 velocity;
-      sgdVec3 rotation;
-      sgdVec3 rotation_pivot;
+      SGVec3d velocity;
+      SGVec3d rotation;
+      SGVec3d rotation_pivot;
       // Ground type
       int type;
       // the simgear material reference, contains friction coeficients ...
       const SGMaterial* material;
     };
     struct Catapult {
-      sgdVec3 start;
-      sgdVec3 end;
-      sgdVec3 velocity;
-      sgdVec3 rotation;
-      sgdVec3 rotation_pivot;
+      SGVec3d start;
+      SGVec3d end;
+      SGVec3d velocity;
+      SGVec3d rotation;
+      SGVec3d rotation_pivot;
     };
     struct Wire {
-      sgdVec3 ends[2];
-      sgdVec3 velocity;
-      sgdVec3 rotation;
-      sgdVec3 rotation_pivot;
+      SGVec3d ends[2];
+      SGVec3d velocity;
+      SGVec3d rotation;
+      SGVec3d rotation_pivot;
       int wire_id;
     };
 
 
     // The center of the cache.
-    sgdVec3 cache_center;
+    SGVec3d cache_center;
     // Approximate ground radius.
     // In case the aircraft is too high above ground.
     double ground_radius;
@@ -133,37 +135,23 @@ private:
 
     // The point and radius where the cache is built around.
     // That are the arguments that were given to prepare_ground_cache.
-    sgdVec3 reference_wgs84_point;
+    SGVec3d reference_wgs84_point;
     double reference_vehicle_radius;
+    SGVec3d down;
     bool found_ground;
 
 
-    // Fills the environment cache with everything inside the sphere sp.
-    void cache_fill(ssgBranch *branch, sgdMat4 xform,
-                    sgdSphere* sp, sgdVec3 down, sgdSphere* wsp);
-
-    // compute the ground property of this leaf.
-    void putSurfaceLeafIntoCache(const sgdSphere *sp, const sgdMat4 xform,
-                                 bool sphIsec, sgdVec3 down, ssgLeaf *l);
-
-    void putLineLeafIntoCache(const sgdSphere *wsp, const sgdMat4 xform,
-                              ssgLeaf *l);
-
     // Helper class to hold some properties of the ground triangle.
     struct GroundProperty {
       GroundProperty() : type(0), material(0) {}
       int type;
       int wire_id;
-      sgdVec3 vel;
-      sgdVec3 rot;
-      sgdVec3 pivot;
+      SGVec3d vel;
+      SGVec3d rot;
+      SGVec3d pivot;
       const SGMaterial* material;
     };
 
-    // compute the ground property of this leaf.
-    static GroundProperty extractGroundProperty( ssgLeaf* leaf );
-
-
     static void velocityTransformTriangle(double dt, Triangle& dst,
                                           const Triangle& src);
 };
index 8765aa017cf57350df9152fbba19e78dc0e6a215..03b042aaefa3122cb8cd2e15e11033ad4ff390b8 100644 (file)
@@ -60,8 +60,6 @@
 # endif
 #endif
 
-#include <plib/ssg.h>
-
 #include <simgear/constants.h>
 #include <simgear/debug/logstream.hxx>
 #include <simgear/misc/sg_path.hxx>
@@ -283,7 +281,7 @@ void fgHiResDump()
     }
 
     FGRenderer *renderer = globals->get_renderer();
-    renderer->init();
+//     renderer->init();
     renderer->resize( fgGetInt("/sim/startup/xsize"),
                       fgGetInt("/sim/startup/ysize") );
 
@@ -325,11 +323,12 @@ void fgHiResDump()
     trTileBuffer(tr, GL_RGB, GL_UNSIGNED_BYTE, tile);
     trImageSize(tr, imageWidth, imageHeight);
     trRowOrder(tr, TR_TOP_TO_BOTTOM);
-    sgFrustum *frustum = ssgGetFrustum();
-    trFrustum(tr,
-              frustum->getLeft(), frustum->getRight(),
-              frustum->getBot(),  frustum->getTop(), 
-              frustum->getNear(), frustum->getFar());
+    // OSGFIXME
+//     sgFrustum *frustum = ssgGetFrustum();
+//     trFrustum(tr,
+//               frustum->getLeft(), frustum->getRight(),
+//               frustum->getBot(),  frustum->getTop(), 
+//               frustum->getNear(), frustum->getFar());
        
     /* Prepare ppm output file */
     while (count < 1000) {
@@ -380,13 +379,15 @@ void fgHiResDump()
         int curRow =  trGet(tr, TR_CURRENT_ROW);
 
         renderer->update( false );
-        if ( do_hud )
-            fgUpdateHUD( curColumn*hud_col_step,      curRow*hud_row_step,
-                         (curColumn+1)*hud_col_step, (curRow+1)*hud_row_step );
-        if (do_panel)
-            globals->get_current_panel()->update(
-                                   curColumn*panel_col_step, panel_col_step,
-                                   curRow*panel_row_step,    panel_row_step );
+        // OSGFIXME
+//         if ( do_hud )
+//             fgUpdateHUD( curColumn*hud_col_step,      curRow*hud_row_step,
+//                          (curColumn+1)*hud_col_step, (curRow+1)*hud_row_step );
+        // OSGFIXME
+//         if (do_panel)
+//             globals->get_current_panel()->update(
+//                                    curColumn*panel_col_step, panel_col_step,
+//                                    curRow*panel_row_step,    panel_row_step );
         more = trEndTile(tr);
 
         /* save tile into tile row buffer*/
@@ -472,7 +473,7 @@ GLubyte *hiResScreenCapture( int multiplier )
     float fov = oldfov / multiplier;
     FGViewer *v = globals->get_current_view();
     fgSetDouble("/sim/current-view/field-of-view", fov);
-    globals->get_renderer()->init();
+//     globals->get_renderer()->init();
     int cur_width = fgGetInt("/sim/startup/xsize");
     int cur_height = fgGetInt("/sim/startup/ysize");
     delete( b1 );
@@ -554,7 +555,7 @@ void fgDumpSnapShot () {
     fgSetBool("/sim/signals/screenshot", true);
 
     FGRenderer *renderer = globals->get_renderer();
-    renderer->init();
+//     renderer->init();
     renderer->resize( fgGetInt("/sim/startup/xsize"),
                         fgGetInt("/sim/startup/ysize") );
 
index d1b170f89d91bdc07adf3ded92b47918dd941333..30639bc19dada40f29f3f40d5dab90ab5fcc2dbe 100644 (file)
@@ -59,7 +59,6 @@
 
 #include <Scenery/scenery.hxx>
 #include <Main/renderer.hxx>
-#include <plib/ssg.h>
 #include <simgear/math/sg_geodesy.hxx>
 
 SG_USING_STD(ifstream);
index a5b6a4f530286852a923b94c394345f06bd1c68c..45e59754db26f8d6058808bbff5c927cd1e43412 100644 (file)
@@ -144,7 +144,7 @@ void HUD::update(double dt)
 }
 
 
-void HUD::draw()
+void HUD::draw(osg::State&)
 {
     if (!isVisible())
         return;
index bb0db7500416a8f13e73fa74d5dd0f1115247d0f..d1d987dbb55424396d574336daeb36225944a29f 100644 (file)
@@ -36,6 +36,8 @@ SG_USING_STD(deque);
 SG_USING_STD(vector);
 SG_USING_NAMESPACE(std);
 
+#include <osg/State>
+
 #include <plib/sg.h>
 
 #include <simgear/math/SGLimits.hxx>
@@ -134,7 +136,7 @@ public:
     void update(double);
 
     // called from Main/renderer.cxx to draw 2D and 3D HUD
-    void draw();
+    void draw(osg::State&);
 
     // listener callback to read various HUD related properties
     void valueChanged(SGPropertyNode *);
index 5c525abd9b7906435e5f1b0ed71ac961f989a648..c2555eba94695e79ae8bb34acdb28951dab8a17e 100644 (file)
@@ -98,13 +98,16 @@ void HUD::Runway::draw()
         globals->get_viewmgr()->copyToCurrent();
     }
     //Set the camera to the cockpit view to get the view of the runway from the cockpit
-    ssgSetCamera((sgVec4 *)_cockpit_view->get_VIEW());
+    // OSGFIXME
+//     ssgSetCamera((sgVec4 *)_cockpit_view->get_VIEW());
     get_rwy_points(_points3d);
     //Get the current project matrix
-    ssgGetProjectionMatrix(projMat);
+    // OSGFIXME
+//     ssgGetProjectionMatrix(projMat);
 //    const sgVec4 *viewMat = globals->get_current_view()->get_VIEW();
     //Get the current model view matrix (cockpit view)
-    ssgGetModelviewMatrix(modelView);
+    // OSGFIXME
+//     ssgGetModelviewMatrix(modelView);
     //Create a rotation matrix to correct for any offsets (other than default offsets) to the model view matrix
     sgMat4 xy; //rotation about the Rxy, negate the sin's on Ry
     xy[0][0] = cYaw,         xy[1][0] = 0.0f,   xy[2][0] = -sYaw,        xy[3][0] = 0.0f;
@@ -157,7 +160,8 @@ void HUD::Runway::draw()
         curr_view->setGoalPitchOffset_deg(gpo);
     }
     //Set the camera back to the current view
-    ssgSetCamera((sgVec4 *)curr_view);
+    // OSGFIXME
+//     ssgSetCamera((sgVec4 *)curr_view);
     glPopAttrib();
 }
 
index d02cc354d0fdf5127336c980e8ff4b9ea26d7cea..31607aa9c633f5f4e01f6a8b0fecc12c3ca0ac61 100644 (file)
@@ -24,7 +24,6 @@
 #  include "config.h"
 #endif
 
-#include <plib/ssg.h>
 #include <simgear/screen/extensions.hxx>
 #include <simgear/screen/RenderTexture.h>
 #include <simgear/debug/logstream.hxx>
@@ -35,8 +34,8 @@
 #include "od_gauge.hxx"
 
 FGODGauge::FGODGauge() :
-    rtAvailable( false ),
-    rt( 0 )
+    rtAvailable( false )// ,
+//     rt( 0 )
 {
 }
 
@@ -44,49 +43,49 @@ FGODGauge::FGODGauge() :
 // never used
 void FGODGauge::allocRT () {
     GLint colorBits = 0;
-    glGetIntegerv( GL_BLUE_BITS, &colorBits );
+//     glGetIntegerv( GL_BLUE_BITS, &colorBits );
     textureWH = 256;
-    rt = new RenderTexture();
-    if( colorBits < 8 )
-        rt->Reset("rgba=5,5,5,1 ctt");
-    else
-        rt->Reset("rgba ctt");
-
-    if( rt->Initialize(256, 256, true) ) {
-        SG_LOG(SG_ALL, SG_INFO, "FGODGauge:Initialize sucessfull");
-        if (rt->BeginCapture())
-        {
-            SG_LOG(SG_ALL, SG_INFO, "FGODGauge:BeginCapture sucessfull, RTT available");
-            rtAvailable = true;
-            glViewport(0, 0, textureWH, textureWH);
-            glMatrixMode(GL_PROJECTION);
-            glLoadIdentity();
-            gluOrtho2D( -256.0, 256.0, -256.0, 256.0 );
-            glMatrixMode(GL_MODELVIEW);
-            glLoadIdentity();
-            glDisable(GL_LIGHTING);
-            glEnable(GL_COLOR_MATERIAL);
-            glDisable(GL_CULL_FACE);
-            glDisable(GL_FOG);
-            glDisable(GL_DEPTH_TEST);
-            glClearColor(0.0, 0.0, 0.0, 0.0);
-            glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-            glBindTexture(GL_TEXTURE_2D, 0);
-            glEnable(GL_TEXTURE_2D);
-            glEnable(GL_ALPHA_TEST);
-            glAlphaFunc(GL_GREATER, 0.0f);
-            glDisable(GL_SMOOTH);
-            glEnable(GL_BLEND);
-            glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
-            rt->EndCapture();
-        } else
-            SG_LOG(SG_ALL, SG_WARN, "FGODGauge:BeginCapture failed, RTT not available, using backbuffer");
-    } else
-        SG_LOG(SG_ALL, SG_WARN, "FGODGauge:Initialize failed, RTT not available, using backbuffer");
+//     rt = new RenderTexture();
+//     if( colorBits < 8 )
+//         rt->Reset("rgba=5,5,5,1 ctt");
+//     else
+//         rt->Reset("rgba ctt");
+
+//     if( rt->Initialize(256, 256, true) ) {
+//         SG_LOG(SG_ALL, SG_INFO, "FGODGauge:Initialize sucessfull");
+//         if (rt->BeginCapture())
+//         {
+//             SG_LOG(SG_ALL, SG_INFO, "FGODGauge:BeginCapture sucessfull, RTT available");
+//             rtAvailable = true;
+//             glViewport(0, 0, textureWH, textureWH);
+//             glMatrixMode(GL_PROJECTION);
+//             glLoadIdentity();
+//             gluOrtho2D( -256.0, 256.0, -256.0, 256.0 );
+//             glMatrixMode(GL_MODELVIEW);
+//             glLoadIdentity();
+//             glDisable(GL_LIGHTING);
+//             glEnable(GL_COLOR_MATERIAL);
+//             glDisable(GL_CULL_FACE);
+//             glDisable(GL_FOG);
+//             glDisable(GL_DEPTH_TEST);
+//             glClearColor(0.0, 0.0, 0.0, 0.0);
+//             glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+//             glBindTexture(GL_TEXTURE_2D, 0);
+//             glEnable(GL_TEXTURE_2D);
+//             glEnable(GL_ALPHA_TEST);
+//             glAlphaFunc(GL_GREATER, 0.0f);
+//             glDisable(GL_SMOOTH);
+//             glEnable(GL_BLEND);
+//             glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
+//             rt->EndCapture();
+//         } else
+//             SG_LOG(SG_ALL, SG_WARN, "FGODGauge:BeginCapture failed, RTT not available, using backbuffer");
+//     } else
+//         SG_LOG(SG_ALL, SG_WARN, "FGODGauge:Initialize failed, RTT not available, using backbuffer");
 }
 
 FGODGauge::~FGODGauge() {
-    delete rt;
+//     delete rt;
 }
 
 void FGODGauge::init () {
@@ -96,58 +95,59 @@ void FGODGauge::update (double dt) {
 }
 
 void FGODGauge::beginCapture(int viewSize) {
-    if( ! rt )
-        allocRT();
-    if(rtAvailable) {
-        rt->BeginCapture();
-    }
-    else
-        set2D();
-     textureWH = viewSize;
-    glViewport(0, 0, textureWH, textureWH);
+//     if( ! rt )
+//         allocRT();
+//     if(rtAvailable) {
+//         rt->BeginCapture();
+//     }
+//     else
+//         set2D();
+//      textureWH = viewSize;
+//     glViewport(0, 0, textureWH, textureWH);
 }
 
 void FGODGauge::beginCapture(void) {
-    if( ! rt )
-        allocRT();
-    if(rtAvailable) {
-        rt->BeginCapture();
-    }
-    else
-        set2D();
+//     if( ! rt )
+//         allocRT();
+//     if(rtAvailable) {
+//         rt->BeginCapture();
+//     }
+//     else
+//         set2D();
 }
 
 void FGODGauge::Clear(void) {
-    if(rtAvailable) {
-        glClear(GL_COLOR_BUFFER_BIT);
-    }
-    else {
-        glDisable(GL_BLEND);
-        glDisable(GL_ALPHA_TEST);
-          glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
-        glRectf(-256.0, -256.0, 256.0, 256.0);
-        glEnable(GL_BLEND);
-        glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
-        glEnable(GL_ALPHA_TEST);
-    }
-}
-
-void FGODGauge::endCapture(GLuint texID) {
-    glBindTexture(GL_TEXTURE_2D, texID);
-    // don't use mimaps if we don't update them
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-
-    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, textureWH, textureWH);
-    if(rtAvailable)
-        rt->EndCapture();
-    else
-        set3D();
-    glBindTexture(GL_TEXTURE_2D, 0);
+//     if(rtAvailable) {
+//         glClear(GL_COLOR_BUFFER_BIT);
+//     }
+//     else {
+//         glDisable(GL_BLEND);
+//         glDisable(GL_ALPHA_TEST);
+//           glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
+//         glRectf(-256.0, -256.0, 256.0, 256.0);
+//         glEnable(GL_BLEND);
+//         glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
+//         glEnable(GL_ALPHA_TEST);
+//     }
+}
+
+void FGODGauge::endCapture(osg::Texture2D* texID) {
+  // OSGFIXME
+//     glBindTexture(GL_TEXTURE_2D, texID);
+//     // don't use mimaps if we don't update them
+//     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+//     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, textureWH, textureWH);
+//     if(rtAvailable)
+//         rt->EndCapture();
+//     else
+//         set3D();
+//     glBindTexture(GL_TEXTURE_2D, 0);
 }
 
 void FGODGauge::setSize(int viewSize) {
     textureWH = viewSize;
-    glViewport(0, 0, textureWH, textureWH);
+//     glViewport(0, 0, textureWH, textureWH);
 }
 
 bool FGODGauge::serviceable(void) {
@@ -168,9 +168,11 @@ static const char *strip_path(const char *name) {
     return fn ;
 }
 
-static ssgSimpleState *
-find_texture_node (ssgEntity * node, const char * name)
+// OSGFIXME
+static osg::StateSet*
+find_texture_node(osg::Node* node, const char * name)
 {
+#if 0
   if( node->isAKindOf( ssgTypeLeaf() ) ) {
     ssgLeaf *leaf = (ssgLeaf *) node;
     ssgSimpleState *state = (ssgSimpleState *) leaf->getState();
@@ -195,49 +197,51 @@ find_texture_node (ssgEntity * node, const char * name)
         return result;
     }
   } 
+#endif
   return 0;
 }
 
-void FGODGauge::set_texture(const char * name, GLuint new_texture) {
-    ssgEntity * root = globals->get_scenery()->get_aircraft_branch();
+void FGODGauge::set_texture(const char * name, osg::Texture2D* new_texture) {
+    osg::Group* root = globals->get_scenery()->get_aircraft_branch();
     name = strip_path( name );
-    ssgSimpleState * node = find_texture_node( root, name );
-    if( node )
-        node->setTexture( new_texture );
+    // OSGFIXME
+//     osg::StateSet* node = find_texture_node( root, name );
+//     if( node )
+//         node->setTexture( new_texture );
 }
 
 void FGODGauge::set2D() {
-    glPushAttrib ( GL_ENABLE_BIT | GL_VIEWPORT_BIT  | GL_TRANSFORM_BIT | GL_LIGHTING_BIT ) ;
+//     glPushAttrib ( GL_ENABLE_BIT | GL_VIEWPORT_BIT  | GL_TRANSFORM_BIT | GL_LIGHTING_BIT ) ;
 
-    glDisable(GL_LIGHTING);
-    glEnable(GL_COLOR_MATERIAL);
-    glDisable(GL_CULL_FACE);
-    glDisable(GL_FOG);
-    glDisable(GL_DEPTH_TEST);
-    glClearColor(0.0, 0.0, 0.0, 0.0);
-    glEnable(GL_TEXTURE_2D);
-    glDisable(GL_SMOOTH);
-    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-    glBindTexture(GL_TEXTURE_2D, 0);
+//     glDisable(GL_LIGHTING);
+//     glEnable(GL_COLOR_MATERIAL);
+//     glDisable(GL_CULL_FACE);
+//     glDisable(GL_FOG);
+//     glDisable(GL_DEPTH_TEST);
+//     glClearColor(0.0, 0.0, 0.0, 0.0);
+//     glEnable(GL_TEXTURE_2D);
+//     glDisable(GL_SMOOTH);
+//     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+//     glBindTexture(GL_TEXTURE_2D, 0);
 
-    glViewport ( 0, 0, textureWH, textureWH ) ;
-    glMatrixMode   ( GL_PROJECTION ) ;
-    glPushMatrix   () ;
-    glLoadIdentity () ;
-    gluOrtho2D( -256.0, 256.0, -256.0, 256.0 );
-    glMatrixMode   ( GL_MODELVIEW ) ;
-    glPushMatrix   () ;
-    glLoadIdentity () ;
+//     glViewport ( 0, 0, textureWH, textureWH ) ;
+//     glMatrixMode   ( GL_PROJECTION ) ;
+//     glPushMatrix   () ;
+//     glLoadIdentity () ;
+//     gluOrtho2D( -256.0, 256.0, -256.0, 256.0 );
+//     glMatrixMode   ( GL_MODELVIEW ) ;
+//     glPushMatrix   () ;
+//     glLoadIdentity () ;
 
-    glAlphaFunc(GL_GREATER, 0.0f);
+//     glAlphaFunc(GL_GREATER, 0.0f);
 
 }
 
 void FGODGauge::set3D() {
-    glMatrixMode   ( GL_PROJECTION ) ;
-    glPopMatrix    () ;
-    glMatrixMode   ( GL_MODELVIEW ) ;
-    glPopMatrix    () ;
-    glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
-    glPopAttrib    () ;
+//     glMatrixMode   ( GL_PROJECTION ) ;
+//     glPopMatrix    () ;
+//     glMatrixMode   ( GL_MODELVIEW ) ;
+//     glPopMatrix    () ;
+//     glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
+//     glPopAttrib    () ;
 }
index f8a5f0e0addcb156e793d7951c64d702a7e3456c..caf18a41a77bc1bc8e061eb2d5dd3c936eecd957 100644 (file)
 #ifndef _OD_GAUGE_HXX
 #define _OD_GAUGE_HXX
 
+#include <osg/Texture2D>
 
-#include <plib/ssg.h>
 #include <simgear/structure/subsystem_mgr.hxx>
 
-class RenderTexture;
-
 /**
  * Owner Drawn Gauge helper class.
  */
@@ -58,7 +56,7 @@ public:
      * Finish rendering and save the buffer to a texture.
      * @param texID name of a gl texture
      */
-    void endCapture(GLuint texID);
+    void endCapture(osg::Texture2D*);
     /**
      * Set the size of the destination texture.
      * @param viewSize size of the destination texture 
@@ -75,11 +73,10 @@ public:
      * @param name texture filename
      * @param new_texture dynamic texture to replace the old one
      */
-    void set_texture(const char * name, GLuint new_texture);
+    void set_texture(const char * name, osg::Texture2D* new_texture);
 
 private:
     int textureWH;
-    RenderTexture *rt;
     bool rtAvailable;
 
     void allocRT(void);
index 6338e3082cdcc843a896cce4dc16536715a4d337..e1ebbeda4543184899b49f9e8e4f3d17f6786078 100644 (file)
 //
 // $Id$
 
-#include "render_area_2d.hxx"
-//#include <iostream>
 
-#include <plib/ssg.h>
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#ifdef HAVE_WINDOWS_H
+#   include <windows.h>
+#endif
 
-//using namespace std;
+#include <GL/gl.h>
 
+#include "render_area_2d.hxx"
 
 
 static const float dummy_normals[][3] = {{0.0f, 0.0f, 0.0f},
@@ -65,6 +70,7 @@ RenderArea2D::RenderArea2D(int logx, int logy, int sizex, int sizey, int posx, i
 }
 
 void RenderArea2D::draw() {
+#if 0
     glDisable(GL_TEXTURE_2D);
        /*
     glColor3f(1, 1, 0);
@@ -103,6 +109,7 @@ void RenderArea2D::draw() {
        }
        
        glEnable(GL_TEXTURE_2D);
+#endif
 }
 
 // Set clipping region in logical units
@@ -336,25 +343,34 @@ void RenderArea2D::Flush() {
 // -----------------------------------------
 
 void RenderArea2D::doSetColor( const float *rgba ) {
+  //OSGFIXME
+#if 0
   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, rgba);
   glColor4fv( rgba );
+#endif
 }
 
 void RenderArea2D::doDrawQuad( const sgVec2 *p, const sgVec3 *normals ) {
        //cout << "doDrawQuad: " << *p[0] << ", " << *(p[0]+1) << ", " << *p[1] << ", " << *(p[1]+1) << ", " << *p[2] << ", " << *p([2]+1) << ", " << *p[3] << ", " << *p([3]+1) <<'\n';
+  //OSGFIXME
+#if 0
   glBegin(GL_QUADS);
   glNormal3fv( normals[0] ); glVertex2fv( p[0] );
   glNormal3fv( normals[1] ); glVertex2fv( p[1] );
   glNormal3fv( normals[2] ); glVertex2fv( p[2] );
   glNormal3fv( normals[3] ); glVertex2fv( p[3] );
   glEnd();
+#endif
 }
 
 void RenderArea2D::doDrawQuad( const sgVec2 *p, const sgVec3 *normals, const sgVec4 *color ) {
+  //OSGFIXME
+#if 0
   glBegin(GL_QUADS);
     glColor4fv( color[0] );glNormal3fv( normals[0] ); glVertex2fv( p[0] );
     glColor4fv( color[1] );glNormal3fv( normals[1] ); glVertex2fv( p[1] );
     glColor4fv( color[2] );glNormal3fv( normals[2] ); glVertex2fv( p[2] );
     glColor4fv( color[3] );glNormal3fv( normals[3] ); glVertex2fv( p[3] );
   glEnd();
+#endif
 }
index 4b3b0593890c9e8d3472f22c84037f375b0dd675..de41798d05b2deb94ff8b3f577619506d9b1c657 100644 (file)
@@ -28,9 +28,9 @@
 #  include <config.h>
 #endif
 
+#include <plib/sg.h>
 #include <simgear/compiler.h>
 
-#include <plib/ssg.h>
 #include <vector>
 
 SG_USING_STD(vector);
index 11aa71050b2842516fff817262f16d909153e24f..1a879ed5f019b3aa93f1bf46021326f8c5920112 100644 (file)
@@ -87,7 +87,10 @@ wxRadarBg::init ()
     SGPath tpath(globals->get_fg_root());
     tpath.append("Aircraft/Instruments/Textures/wxecho.rgb");
     // no mipmap or else alpha will mix with pixels on the border of shapes, ruining the effect
-    wxEcho = new ssgTexture( tpath.c_str(), false, false, false);
+
+    // OSGFIXME
+//     wxEcho = new ssgTexture( tpath.c_str(), false, false, false);
+    wxEcho = new osg::Texture2D;
 
     _Instrument->setFloatValue("trk", 0.0);
     _Instrument->setFloatValue("tilt", 0.0);
@@ -110,6 +113,8 @@ wxRadarBg::init ()
 void
 wxRadarBg::update (double delta_time_sec)
 {
+  //OSGFIXME
+#if 0
     if ( ! sim_init_done ) {
         if ( ! fgGetBool("sim/sceneryloaded", false) )
             return;
@@ -130,7 +135,7 @@ wxRadarBg::update (double delta_time_sec)
         // we must locate them and replace their handle by hand
         // only do that when the instrument is turned on
         if ( last_switchKnob == "off" )
-            odg->set_texture( odgauge_name, resultTexture->getHandle());
+            odg->set_texture( odgauge_name, resultTexture.get());
         last_switchKnob = switchKnob;
     }
     FGViewer *current__view = globals->get_current_view();
@@ -189,7 +194,8 @@ wxRadarBg::update (double delta_time_sec)
         const float symbolSize = 1.0f / 8.0f ;
         // draw the radar echo, we do that in 3 passes, one for each color level
         // this is to 'merge' same colors together
-        glBindTexture(GL_TEXTURE_2D, wxEcho->getHandle() );
+        // OSGFIXME
+//         glBindTexture(GL_TEXTURE_2D, wxEcho->getHandle() );
         glColor3f(1.0f, 1.0f, 1.0f);
         glBegin( GL_QUADS );
 
@@ -335,5 +341,6 @@ wxRadarBg::update (double delta_time_sec)
         glEnable(GL_ALPHA_TEST);
     }
     glPopMatrix();
-    odg->endCapture( resultTexture->getHandle() );
+    odg->endCapture( resultTexture.get() );
+#endif
 }
index b2f7139f8f77ca458231c5ce1d3a9511eae40df7..acaa6680b1f501870fb54e73180af008775eeab7 100644 (file)
 #ifndef _INST_WXRADAR_HXX
 #define _INST_WXRADAR_HXX
 
-#include <plib/ssg.h>
+#include <osg/ref_ptr>
+#include <osg/Texture2D>
 
 #include <simgear/props/props.hxx>
 #include <simgear/structure/subsystem_mgr.hxx>
 #include <simgear/environment/visual_enviro.hxx>
-#include <simgear/structure/ssgSharedPtr.hxx>
 
-class ssgTexture;
 class FGODGauge;
 
 class wxRadarBg : public SGSubsystem {
@@ -52,8 +51,8 @@ private:
 
     SGPropertyNode_ptr _serviceable_node;
     SGPropertyNode_ptr _Instrument;
-    ssgSharedPtr<ssgTexture> resultTexture;
-    ssgSharedPtr<ssgTexture> wxEcho;
+    osg::ref_ptr<osg::Texture2D> resultTexture;
+    osg::ref_ptr<osg::Texture2D> wxEcho;
     string last_switchKnob;
     bool sim_init_done;
     FGODGauge *odg;
index 5ac0cf0b9ccd6278cc5d907a4c01b511712a3a92..d8448015ba5e2e4c2e9946dd499bafe883d32f7f 100644 (file)
@@ -78,8 +78,8 @@ fgfs_LDADD = \
        $(top_builddir)/src/Autopilot/libAutopilot.a \
        $(top_builddir)/src/Input/libInput.a \
        $(top_builddir)/src/Instrumentation/KLN89/libKLN89.a \
-       $(top_builddir)/src/Instrumentation/HUD/libHUD.a \
        $(top_builddir)/src/Instrumentation/libInstrumentation.a \
+       $(top_builddir)/src/Instrumentation/HUD/libHUD.a \
        $(top_builddir)/src/Model/libModel.a \
        $(top_builddir)/src/Network/libNetwork.a \
        $(top_builddir)/src/Navaids/libNavaids.a \
@@ -97,13 +97,17 @@ fgfs_LDADD = \
        -lsgtiming -lsgio -lsgscreen -lsgmath -lsgbucket -lsgprops -lsgdebug \
        -lsgmagvar -lsgmisc -lsgnasal -lsgxml -lsgsound -lsgserial \
        -lsgstructure -lsgenvironment \
+       -lplibpuaux -lplibpu -lplibfnt -lplibjs -lplibnet \
+       -lplibsg -lplibul \
+       -losgUtil -losgDB -losgSim -losg -lOpenThreads \
        $(THREAD_LIBS) \
-       -lplibpuaux -lplibpu -lplibfnt -lplibjs -lplibnet -lplibssgaux -lplibssg -lplibsg -lplibul \
        $(network_LIBS) \
        -lz \
        $(opengl_LIBS) \
        $(openal_LIBS)
 
+# -lplibssgaux -lplibssg
+
 metar_SOURCES = metar_main.cxx
 
 metar_LDADD = \
index 03ba1711cc57daff5cfa8bbf94b433ee48acaa91..6f82ad88325577c99943110c739ead0720584a2c 100644 (file)
@@ -614,13 +614,12 @@ static void fgMainLoop( void ) {
         globals->get_soundmgr()->set_volume(init_volume);
     }
 
-    if (fgGetBool("/sim/rendering/specular-highlight")) {
-        glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
-       // glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
-    } else {
-        glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
-        // glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
-    }
+    // OSGFIXME: with osg>1.2 remove this, osg::LightModel does the trick...
+//     if (fgGetBool("/sim/rendering/specular-highlight")) {
+//         glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
+//     } else {
+//         glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
+//     }
 
     fgRequestRedraw();
 
@@ -665,10 +664,6 @@ static void fgIdleFunction ( void ) {
         general.set_glDepthBits( tmp );
         SG_LOG ( SG_GENERAL, SG_INFO, "Depth buffer bits = " << tmp );
 
-        // Initialize ssg (from plib).  Needs to come before we do any
-        // other ssg stuff, but after opengl has been initialized.
-        ssgInit();
-
         // Initialize the user interface (we need to do this before
         // passing off control to the OS main loop and before
         // fgInitGeneral to get our fonts !!!
@@ -682,21 +677,21 @@ static void fgIdleFunction ( void ) {
         fgReadAircraft();
 
         // 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;
-        }
+//         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;
+//         }
         fgSplashProgress("reading airport & navigation data");
 
 
@@ -838,7 +833,6 @@ static void fgIdleFunction ( void ) {
         // lighting->addKid( airport );
 
         // build our custom render states
-        globals->get_renderer()->build_states();
         fgSplashProgress("initializing subsystems");
 
 
@@ -993,7 +987,8 @@ bool fgMainInit( int argc, char **argv ) {
         exit(-1);
     }
 
-    sgUseDisplayList = fgGetBool( "/sim/rendering/use-display-list", true );
+    //OSGFIXME
+//     sgUseDisplayList = fgGetBool( "/sim/rendering/use-display-list", true );
 
     // Load the configuration parameters.  (Command line options
     // override config file options.  Config file options override
index 0a6077bf9af5b7921e0a5d0ec2cb271379e7cbc8..21c66f26014c96f7686dd9d9150cbe6aee7b22d7 100644 (file)
 #  include <windows.h>
 #endif
 
-#include <plib/ssg.h>
-#include <plib/netSocket.h>
-
+#include <osg/ref_ptr>
+#include <osg/AlphaFunc>
+#include <osg/BlendFunc>
+#include <osg/CameraNode>
+#include <osg/CameraView>
+#include <osg/CullFace>
+#include <osg/Depth>
+#include <osg/Fog>
+#include <osg/Group>
+#include <osg/LightModel>
+#include <osg/NodeCallback>
+#include <osg/Notify>
+#include <osg/MatrixTransform>
+#include <osg/Multisample>
+#include <osg/Point>
+#include <osg/PolygonMode>
+#include <osg/ShadeModel>
+#include <osg/TexEnv>
+#include <osg/TexGen>
+#include <osg/TexMat>
+#include <osg/ColorMatrix>
+
+#include <osgUtil/SceneView>
+#include <osgUtil/UpdateVisitor>
+
+#include <osg/io_utils>
+#include <osgDB/WriteFile>
+#include <osgDB/ReadFile>
+#include <sstream>
+
+#include <simgear/math/SGMath.hxx>
 #include <simgear/screen/extensions.hxx>
 #include <simgear/scene/material/matlib.hxx>
 #include <simgear/scene/model/animation.hxx>
 #include <simgear/scene/model/model.hxx>
 #include <simgear/scene/model/modellib.hxx>
 #include <simgear/scene/model/placement.hxx>
+#include <simgear/scene/util/SGUpdateVisitor.hxx>
 #include <simgear/scene/tgdb/pt_lights.hxx>
 #include <simgear/props/props.hxx>
 #include <simgear/timing/sg_time.hxx>
 
 #include <simgear/environment/visual_enviro.hxx>
 
-#include <simgear/scene/model/shadowvolume.hxx>
-
 #include <Scenery/tileentry.hxx>
 #include <Time/light.hxx>
 #include <Time/light.hxx>
 #include <Aircraft/aircraft.hxx>
-// #include <Aircraft/replay.hxx>
 #include <Cockpit/panel.hxx>
 #include <Cockpit/cockpit.hxx>
 #include <Cockpit/hud.hxx>
 #include "main.hxx"
 
 
-extern void sgShaderFrameInit(double delta_time_sec);
-
-float default_attenuation[3] = {1.0, 0.0, 0.0};
-
-// Clip plane settings...
-float scene_nearplane = 0.5f;
-float scene_farplane = 120000.0f;
-
-glPointParameterfProc glPointParameterfPtr = 0;
-glPointParameterfvProc glPointParameterfvPtr = 0;
-bool glPointParameterIsSupported = false;
-bool glPointSpriteIsSupported = false;
+class FGSunLightUpdateCallback : public osg::StateAttribute::Callback {
+public:
+  virtual void operator()(osg::StateAttribute* stateAttribute,
+                          osg::NodeVisitor*)
+  {
+    assert(dynamic_cast<osg::Light*>(stateAttribute));
+    osg::Light* light = static_cast<osg::Light*>(stateAttribute);
+
+    FGLight *l = static_cast<FGLight*>(globals->get_subsystem("lighting"));
+    SGVec4f ambient(l->scene_ambient());
+    light->setAmbient(ambient.osg());
+    SGVec4f diffuse(l->scene_diffuse());
+    light->setDiffuse(diffuse.osg());
+    SGVec4f specular(l->scene_specular());
+    light->setSpecular(specular.osg());
+    SGVec4f position(l->sun_vec()[0], l->sun_vec()[1], l->sun_vec()[2], 0);
+    light->setPosition(position.osg());
+
+    light->setDirection(osg::Vec3(0, 0, -1));
+    light->setSpotExponent(0);
+    light->setSpotCutoff(180);
+    light->setConstantAttenuation(1);
+    light->setLinearAttenuation(0);
+    light->setQuadraticAttenuation(0);
+  }
+};
+
+class FGWireFrameModeUpdateCallback : public osg::StateAttribute::Callback {
+public:
+  FGWireFrameModeUpdateCallback() :
+    mWireframe(fgGetNode("/sim/rendering/wireframe"))
+  { }
+  virtual void operator()(osg::StateAttribute* stateAttribute,
+                          osg::NodeVisitor*)
+  {
+    assert(dynamic_cast<osg::PolygonMode*>(stateAttribute));
+    osg::PolygonMode* polygonMode;
+    polygonMode = static_cast<osg::PolygonMode*>(stateAttribute);
+
+    if (mWireframe->getBoolValue())
+      polygonMode->setMode(osg::PolygonMode::FRONT_AND_BACK,
+                           osg::PolygonMode::LINE);
+    else
+      polygonMode->setMode(osg::PolygonMode::FRONT_AND_BACK,
+                           osg::PolygonMode::FILL);
+  }
+private:
+  SGSharedPtr<SGPropertyNode> mWireframe;
+};
+
+class FGLightModelUpdateCallback : public osg::StateAttribute::Callback {
+public:
+  FGLightModelUpdateCallback() :
+    mHighlights(fgGetNode("/sim/rendering/specular-highlight"))
+  { }
+  virtual void operator()(osg::StateAttribute* stateAttribute,
+                          osg::NodeVisitor*)
+  {
+    assert(dynamic_cast<osg::LightModel*>(stateAttribute));
+    osg::LightModel* lightModel;
+    lightModel = static_cast<osg::LightModel*>(stateAttribute);
+
+#if 0
+    FGLight *l = static_cast<FGLight*>(globals->get_subsystem("lighting"));
+    SGVec4f ambient(l->scene_ambient());
+    lightModel->setAmbientIntensity(ambient.osg());
+#else
+    lightModel->setAmbientIntensity(osg::Vec4(0, 0, 0, 1));
+#endif
+    lightModel->setTwoSided(true);
 
+    if (mHighlights->getBoolValue()) {
+      lightModel->setColorControl(osg::LightModel::SEPARATE_SPECULAR_COLOR);
+      lightModel->setLocalViewer(true);
+    } else {
+      lightModel->setColorControl(osg::LightModel::SINGLE_COLOR);
+      lightModel->setLocalViewer(false);
+    }
+  }
+private:
+  SGSharedPtr<SGPropertyNode> mHighlights;
+};
+
+class FGFogEnableUpdateCallback : public osg::StateSet::Callback {
+public:
+  FGFogEnableUpdateCallback() :
+    mFogEnabled(fgGetNode("/sim/rendering/fog"))
+  { }
+  virtual void operator()(osg::StateSet* stateSet, osg::NodeVisitor*)
+  {
+    if (strcmp(mFogEnabled->getStringValue(), "disabled") == 0) {
+      stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
+    } else {
+      stateSet->setMode(GL_FOG, osg::StateAttribute::ON);
+    }
+  }
+private:
+  SGSharedPtr<SGPropertyNode> mFogEnabled;
+};
 
 // fog constants.  I'm a little nervous about putting actual code out
 // here but it seems to work (?)
@@ -104,11 +216,19 @@ static GLfloat ground_exp2_punch_through;
 // Sky structures
 SGSky *thesky;
 
-ssgSharedPtr<ssgSimpleState> default_state;
-ssgSharedPtr<ssgSimpleState> hud_and_panel;
-ssgSharedPtr<ssgSimpleState> menus;
+static osg::ref_ptr<osgUtil::SceneView> sceneView = new osgUtil::SceneView;
+static osg::ref_ptr<osg::FrameStamp> mFrameStamp = new osg::FrameStamp;
+
+static osg::ref_ptr<osg::Group> mRoot = new osg::Group;
 
-SGShadowVolume *shadows;
+static osg::ref_ptr<osg::CameraView> mCameraView = new osg::CameraView;
+static osg::ref_ptr<osg::CameraNode> mBackGroundCamera = new osg::CameraNode;
+static osg::ref_ptr<osg::CameraNode> mSceneCamera = new osg::CameraNode;
+
+static osg::ref_ptr<osg::Fog> mFog = new osg::Fog;
+static osg::ref_ptr<osg::Fog> mRunwayLightingFog = new osg::Fog;
+static osg::ref_ptr<osg::Fog> mTaxiLightingFog = new osg::Fog;
+static osg::ref_ptr<osg::Fog> mGroundLightingFog = new osg::Fog;
 
 FGRenderer::FGRenderer()
 {
@@ -124,63 +244,16 @@ FGRenderer::~FGRenderer()
 #endif
 }
 
-
-void
-FGRenderer::build_states( void ) {
-    default_state = new ssgSimpleState;
-    default_state->disable( GL_TEXTURE_2D );
-    default_state->enable( GL_CULL_FACE );
-    default_state->enable( GL_COLOR_MATERIAL );
-    default_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
-    default_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
-    default_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
-    default_state->disable( GL_BLEND );
-    default_state->disable( GL_ALPHA_TEST );
-    default_state->disable( GL_LIGHTING );
-
-    hud_and_panel = new ssgSimpleState;
-    hud_and_panel->disable( GL_CULL_FACE );
-    hud_and_panel->disable( GL_TEXTURE_2D );
-    hud_and_panel->disable( GL_LIGHTING );
-    hud_and_panel->enable( GL_BLEND );
-
-    menus = new ssgSimpleState;
-    menus->disable( GL_CULL_FACE );
-    menus->disable( GL_TEXTURE_2D );
-    menus->enable( GL_BLEND );
-
-    shadows = new SGShadowVolume( globals->get_scenery()->get_scene_graph() );
-    shadows->init( fgGetNode("/sim/rendering", true) );
-    shadows->addOccluder( globals->get_scenery()->get_aircraft_branch(), SGShadowVolume::occluderTypeAircraft );
-
-}
-
-
 // Initialize various GL/view parameters
 void
 FGRenderer::init( void ) {
 
-    FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
+    osg::initNotifyLevel();
 
     // Go full screen if requested ...
-    if ( fgGetBool("/sim/startup/fullscreen") ) {
+    if ( fgGetBool("/sim/startup/fullscreen") )
         fgOSFullScreen();
-    }
-
-    // If enabled, normal vectors specified with glNormal are scaled
-    // to unit length after transformation.  Enabling this has
-    // performance implications.  See the docs for glNormal.
-    // glEnable( GL_NORMALIZE );
-
-    glEnable( GL_LIGHTING );
-    glEnable( GL_LIGHT0 );
-    // glLightfv( GL_LIGHT0, GL_POSITION, l->sun_vec );  // done later with ssg
 
-    sgVec3 sunpos;
-    sgSetVec3( sunpos, l->sun_vec()[0], l->sun_vec()[1], l->sun_vec()[2] );
-    ssgGetLight( 0 ) -> setPosition( sunpos );
-
-    glFogi (GL_FOG_MODE, GL_EXP2);
     if ( (!strcmp(fgGetString("/sim/rendering/fog"), "disabled")) || 
          (!fgGetBool("/sim/rendering/shading"))) {
         // if fastest fog requested, or if flat shading force fastest
@@ -188,38 +261,141 @@ FGRenderer::init( void ) {
     } else if ( !strcmp(fgGetString("/sim/rendering/fog"), "nicest") ) {
         glHint ( GL_FOG_HINT, GL_DONT_CARE );
     }
-    if ( fgGetBool("/sim/rendering/wireframe") ) {
-        // draw wire frame
-        glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
-    }
 
-    // This is the default anyways, but it can't hurt
-    glFrontFace ( GL_CCW );
-
-    // Just testing ...
-    if ( SGIsOpenGLExtensionSupported("GL_ARB_point_sprite") ||
-         SGIsOpenGLExtensionSupported("GL_NV_point_sprite") )
-    {
-        GLuint handle = thesky->get_sun_texture_id();
-        glBindTexture ( GL_TEXTURE_2D, handle ) ;
-        glTexEnvf(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
-        glEnable(GL_POINT_SPRITE);
-        // glEnable(GL_POINT_SMOOTH);
-        glPointSpriteIsSupported = true;
-    }
-    glEnable(GL_LINE_SMOOTH);
-    // glEnable(GL_POLYGON_SMOOTH);      
     glHint(GL_POLYGON_SMOOTH_HINT, GL_DONT_CARE);
     glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
     glHint(GL_POINT_SMOOTH_HINT, GL_DONT_CARE);
-}
 
+    sceneView->setDefaults(osgUtil::SceneView::COMPILE_GLOBJECTS_AT_INIT);
+
+    mFog->setMode(osg::Fog::EXP2);
+    mRunwayLightingFog->setMode(osg::Fog::EXP2);
+    mTaxiLightingFog->setMode(osg::Fog::EXP2);
+    mGroundLightingFog->setMode(osg::Fog::EXP2);
+
+    sceneView->setFrameStamp(mFrameStamp.get());
+
+    sceneView->setUpdateVisitor(new SGUpdateVisitor);
+
+    sceneView->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
+    sceneView->getCamera()->setClearMask(0);
+
+    osg::StateSet* stateSet = mRoot->getOrCreateStateSet();
+
+    stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
+    
+    stateSet->setAttribute(new osg::Depth(osg::Depth::LEQUAL));
+    stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
+
+    stateSet->setAttribute(new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.01));
+    stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::OFF);
+    stateSet->setAttribute(new osg::BlendFunc);
+    stateSet->setMode(GL_BLEND, osg::StateAttribute::OFF);
+
+    stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
+    
+//     osg::Material* material = new osg::Material;
+//     stateSet->setAttribute(material);
+    
+//     stateSet->setAttribute(new osg::CullFace(osg::CullFace::BACK));
+//     stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
+
+
+    // need to update the light on every frame
+    osg::Light* sunLight = new osg::Light;
+    sunLight->setLightNum(0);
+    sunLight->setUpdateCallback(new FGSunLightUpdateCallback);
+    stateSet->setAttributeAndModes(sunLight, osg::StateAttribute::ON);
+    osg::LightModel* lightModel = new osg::LightModel;
+    lightModel->setUpdateCallback(new FGLightModelUpdateCallback);
+    stateSet->setAttributeAndModes(lightModel, osg::StateAttribute::ON);
+
+    // this is the topmost scenegraph node for osg
+    mBackGroundCamera->addChild(thesky->getPreRoot());
+    mBackGroundCamera->setClearMask(GL_COLOR_BUFFER_BIT);
+
+    GLbitfield inheritanceMask = osg::CullSettings::ALL_VARIABLES;
+    inheritanceMask &= ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE;
+    inheritanceMask &= ~osg::CullSettings::NEAR_FAR_RATIO;
+    inheritanceMask &= ~osg::CullSettings::CULLING_MODE;
+    mBackGroundCamera->setInheritanceMask(inheritanceMask);
+    mBackGroundCamera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
+    mBackGroundCamera->setCullingMode(osg::CullSettings::NO_CULLING);
+
+    mBackGroundCamera->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
+
+    mRoot->addChild(mBackGroundCamera.get());
+
+
+    sceneView->getCamera()->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
+
+    mSceneCamera->setClearMask(GL_DEPTH_BUFFER_BIT);
+    inheritanceMask = osg::CullSettings::ALL_VARIABLES;
+    inheritanceMask &= ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE;
+    inheritanceMask &= ~osg::CullSettings::CULLING_MODE;
+    mSceneCamera->setInheritanceMask(inheritanceMask);
+    mSceneCamera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
+    mSceneCamera->setCullingMode(osg::CullSettings::DEFAULT_CULLING);
+
+
+    stateSet = globals->get_scenery()->get_scene_graph()->getOrCreateStateSet();
+    stateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
+    stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON);
+    stateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON);
+    stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
+
+    // switch to enable wireframe
+    osg::PolygonMode* polygonMode = new osg::PolygonMode;
+    polygonMode->setUpdateCallback(new FGWireFrameModeUpdateCallback);
+    stateSet->setAttributeAndModes(polygonMode);
+
+    // scene fog handling
+    stateSet->setAttributeAndModes(mFog.get());
+    stateSet->setUpdateCallback(new FGFogEnableUpdateCallback);
+
+    mRoot->addChild(mSceneCamera.get());
+
+    mSceneCamera->addChild(globals->get_scenery()->get_scene_graph());
+
+    stateSet = mSceneCamera->getOrCreateStateSet();
+    stateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
+    stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
+
+    // this one contains all lights, here we set the light states we did
+    // in the plib case with plain OpenGL
+    osg::Group* lightGroup = new osg::Group;
+    mSceneCamera->addChild(lightGroup);
+    lightGroup->addChild(globals->get_scenery()->get_gnd_lights_root());
+    lightGroup->addChild(globals->get_scenery()->get_vasi_lights_root());
+    lightGroup->addChild(globals->get_scenery()->get_rwy_lights_root());
+    lightGroup->addChild(globals->get_scenery()->get_taxi_lights_root());
+
+    stateSet = globals->get_scenery()->get_gnd_lights_root()->getOrCreateStateSet();
+    stateSet->setAttributeAndModes(mFog.get());
+    stateSet->setUpdateCallback(new FGFogEnableUpdateCallback);
+    stateSet = globals->get_scenery()->get_vasi_lights_root()->getOrCreateStateSet();
+    stateSet->setAttributeAndModes(mRunwayLightingFog.get());
+    stateSet->setUpdateCallback(new FGFogEnableUpdateCallback);
+    stateSet = globals->get_scenery()->get_rwy_lights_root()->getOrCreateStateSet();
+    stateSet->setAttributeAndModes(mRunwayLightingFog.get());
+    stateSet->setUpdateCallback(new FGFogEnableUpdateCallback);
+    stateSet = globals->get_scenery()->get_taxi_lights_root()->getOrCreateStateSet();
+    stateSet->setAttributeAndModes(mTaxiLightingFog.get());
+    stateSet->setUpdateCallback(new FGFogEnableUpdateCallback);
+
+    mCameraView->addChild(mRoot.get());
+    sceneView->setSceneData(mCameraView.get());
+
+    mSceneCamera->addChild(thesky->getCloudRoot());
+
+//  sceneView->getState()->setCheckForGLErrors(osg::State::ONCE_PER_ATTRIBUTE);
+}
 
 
 // Update all Visuals (redraws anything graphics related)
 void
 FGRenderer::update( bool refresh_camera_settings ) {
-    bool scenery_loaded = fgGetBool("sim/sceneryloaded") \
+    bool scenery_loaded = fgGetBool("sim/sceneryloaded")
                           || fgGetBool("sim/sceneryloaded-override");
 
     if ( idle_state < 1000 || !scenery_loaded ) {
@@ -232,38 +408,18 @@ FGRenderer::update( bool refresh_camera_settings ) {
         return;
     }
 
-    bool draw_otw = fgGetBool("/sim/rendering/draw-otw");
     bool skyblend = fgGetBool("/sim/rendering/skyblend");
     bool use_point_sprites = fgGetBool("/sim/rendering/point-sprites");
     bool enhanced_lighting = fgGetBool("/sim/rendering/enhanced-lighting");
     bool distance_attenuation
         = fgGetBool("/sim/rendering/distance-attenuation");
-    sgConfigureDirectionalLights( use_point_sprites, enhanced_lighting,
+    SGConfigureDirectionalLights( use_point_sprites, enhanced_lighting,
                                   distance_attenuation );
-    bool volumetric_clouds = sgEnviro.get_clouds_enable_state();
-#ifdef FG_ENABLE_MULTIPASS_CLOUDS
-    bool multi_pass_clouds = fgGetBool("/sim/rendering/multi-pass-clouds") && 
-                                !volumetric_clouds &&
-                                !SGCloudLayer::enable_bump_mapping;  // ugly artefact now
-#else
-    bool multi_pass_clouds = false;
-#endif
-    bool draw_clouds = fgGetBool("/environment/clouds/status");
-
-    GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
-    GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
 
-    // static const SGPropertyNode *longitude
-    //     = fgGetNode("/position/longitude-deg");
-    // static const SGPropertyNode *latitude
-    //     = fgGetNode("/position/latitude-deg");
-    // static const SGPropertyNode *altitude
-    //     = fgGetNode("/position/altitude-ft");
     static const SGPropertyNode *groundlevel_nearplane
         = fgGetNode("/sim/current-view/ground-level-nearplane-m");
 
-    FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
-    static double last_visibility = -9999;
+    FGLight *l = static_cast<FGLight*>(globals->get_subsystem("lighting"));
 
     // update fog params
     double actual_visibility;
@@ -273,11 +429,7 @@ FGRenderer::update( bool refresh_camera_settings ) {
         actual_visibility = fgGetDouble("/environment/visibility-m");
     }
 
-        // TODO:TEST only, don't commit that !!
-//      sgFXperFrameInit();
-
-    sgShaderFrameInit(delta_time_sec);
-
+    static double last_visibility = -9999;
     if ( actual_visibility != last_visibility ) {
         last_visibility = actual_visibility;
 
@@ -291,15 +443,12 @@ FGRenderer::update( bool refresh_camera_settings ) {
             rwy_exp2_punch_through = sqrt_m_log01 / ( 8000 * 2.5 );
             taxi_exp2_punch_through = sqrt_m_log01 / ( 8000 * 1.5 );
         }
+        mFog->setDensity(fog_exp2_density);
+        mRunwayLightingFog->setDensity(rwy_exp2_punch_through);
+        mTaxiLightingFog->setDensity(taxi_exp2_punch_through);
+        mGroundLightingFog->setDensity(ground_exp2_punch_through);
     }
 
-    // double angle;
-    // GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
-    // GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
-    // GLfloat terrain_color[4] = { 0.54, 0.44, 0.29, 1.0 };
-    // GLfloat mat_shininess[] = { 10.0 };
-    GLbitfield clear_mask;
-
     // idle_state is now 1000 meaning we've finished all our
     // initializations and are running the main loop, so this will
     // now work without seg faulting the system.
@@ -313,37 +462,37 @@ FGRenderer::update( bool refresh_camera_settings ) {
         resize( fgGetInt("/sim/startup/xsize"),
                 fgGetInt("/sim/startup/ysize") );
 
-        // Tell GL we are switching to model view parameters
-        glMatrixMode(GL_MODELVIEW);
-        glLoadIdentity();
-        ssgSetCamera( (sgVec4 *)current__view->get_VIEW() );
-    }
+        // OSGFXME: compute the view directly without indirection through ssg
+        sgMat4 viewmat;
+        sgTransposeNegateMat4(viewmat, (sgVec4 *)current__view->get_VIEW());
+        sgMat4 cameraMatrix = {
+          {  1.0f,  0.0f,  0.0f,  0.0f },
+          {  0.0f,  0.0f, -1.0f,  0.0f },
+          {  0.0f,  1.0f,  0.0f,  0.0f },
+          {  0.0f,  0.0f,  0.0f,  1.0f }
+        };
+        sgPreMultMat4(cameraMatrix, viewmat);
+
+        osg::Matrixd m;
+        for (unsigned i = 0; i < 4; ++i)
+          for (unsigned j = 0; j < 4; ++j)
+            m(i, j) = cameraMatrix[i][j];
 
-    clear_mask = GL_DEPTH_BUFFER_BIT;
-    if ( fgGetBool("/sim/rendering/wireframe") ) {
-        clear_mask |= GL_COLOR_BUFFER_BIT;
+        osg::Quat attitude;
+        attitude.set(m);
+        mCameraView->setPosition(osg::Vec3d(m(3,0), m(3,1), m(3,2)));
+        mCameraView->setAttitude(attitude);
     }
 
     if ( skyblend ) {
         if ( fgGetBool("/sim/rendering/textures") ) {
-        // glClearColor(black[0], black[1], black[2], black[3]);
-        glClearColor(l->adj_fog_color()[0], l->adj_fog_color()[1],
-                     l->adj_fog_color()[2], l->adj_fog_color()[3]);
-        clear_mask |= GL_COLOR_BUFFER_BIT;
+            SGVec4f clearColor(l->adj_fog_color());
+            mBackGroundCamera->setClearColor(clearColor.osg());
         }
     } else {
-        glClearColor(l->sky_color()[0], l->sky_color()[1],
-                     l->sky_color()[2], l->sky_color()[3]);
-        clear_mask |= GL_COLOR_BUFFER_BIT;
+        SGVec4f clearColor(l->sky_color());
+        mBackGroundCamera->setClearColor(clearColor.osg());
     }
-    if ( multi_pass_clouds && draw_clouds ) {
-        glClearStencil( 0 );
-        clear_mask |= GL_STENCIL_BUFFER_BIT;
-    }
-    glClear( clear_mask );
-
-    // set the opengl state to known default values
-    default_state->force();
 
     // update fog params if visibility has changed
     double visibility_meters = fgGetDouble("/environment/visibility-m");
@@ -353,9 +502,6 @@ FGRenderer::update( bool refresh_camera_settings ) {
                         ( global_multi_loop * fgGetInt("/sim/speed-up") )
                         / (double)fgGetInt("/sim/model-hz") );
 
-    // Set correct opengl fog density
-    glFogf (GL_FOG_DENSITY, fog_exp2_density);
-
     // update the sky dome
     if ( skyblend ) {
 
@@ -375,9 +521,9 @@ FGRenderer::update( bool refresh_camera_settings ) {
 
         static SGSkyState sstate;
 
-        sstate.view_pos  = current__view->get_view_pos();
-        sstate.zero_elev = current__view->get_zero_elev();
-        sstate.view_up   = current__view->get_world_up();
+        sstate.view_pos  = SGVec3f(current__view->get_view_pos());
+        sstate.zero_elev = SGVec3f(current__view->get_zero_elev());
+        sstate.view_up   = SGVec3f(current__view->get_world_up());
         sstate.lon       = current__view->getLongitude_deg()
                             * SGD_DEGREES_TO_RADIANS;
         sstate.lat       = current__view->getLatitude_deg()
@@ -412,11 +558,10 @@ FGRenderer::update( bool refresh_camera_settings ) {
         */
 
         static SGSkyColor scolor;
-//        FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
 
-        scolor.sky_color   = l->sky_color();
-        scolor.fog_color   = l->adj_fog_color();
-        scolor.cloud_color = l->cloud_color();
+        scolor.sky_color   = SGVec3f(l->sky_color());
+        scolor.fog_color   = SGVec3f(l->adj_fog_color());
+        scolor.cloud_color = SGVec3f(l->cloud_color());
         scolor.sun_angle   = l->get_sun_angle();
         scolor.moon_angle  = l->get_moon_angle();
         scolor.nplanets    = globals->get_ephem()->getNumPlanets();
@@ -446,47 +591,35 @@ FGRenderer::update( bool refresh_camera_settings ) {
           << " moon dec = " << globals->get_ephem()->getMoonDeclination() );
         */
 
-        shadows->setupShadows(
-          current__view->getLongitude_deg(),
-          current__view->getLatitude_deg(),
-          globals->get_time_params()->getGst(),
-          globals->get_ephem()->getSunRightAscension(),
-          globals->get_ephem()->getSunDeclination(),
-          l->get_sun_angle());
+        //OSGFIXME
+//         shadows->setupShadows(
+//           current__view->getLongitude_deg(),
+//           current__view->getLatitude_deg(),
+//           globals->get_time_params()->getGst(),
+//           globals->get_ephem()->getSunRightAscension(),
+//           globals->get_ephem()->getSunDeclination(),
+//           l->get_sun_angle());
 
     }
 
-    glEnable( GL_DEPTH_TEST );
     if ( strcmp(fgGetString("/sim/rendering/fog"), "disabled") ) {
-        glEnable( GL_FOG );
-        glFogi( GL_FOG_MODE, GL_EXP2 );
-        glFogfv( GL_FOG_COLOR, l->adj_fog_color() );
-    } else
-        glDisable( GL_FOG ); 
-
-    // set sun/lighting parameters
-    ssgGetLight( 0 ) -> setPosition( l->sun_vec() );
-
-    // GL_LIGHT_MODEL_AMBIENT has a default non-zero value so if
-    // we only update GL_AMBIENT for our lights we will never get
-    // a completely dark scene.  So, we set GL_LIGHT_MODEL_AMBIENT
-    // explicitely to black.
-    glLightModelfv( GL_LIGHT_MODEL_AMBIENT, black );
+        SGVec4f color(l->adj_fog_color());
+        mFog->setColor(color.osg());
+        mRunwayLightingFog->setColor(color.osg());
+        mTaxiLightingFog->setColor(color.osg());
+        mGroundLightingFog->setColor(color.osg());
+    }
 
-    ssgGetLight( 0 ) -> setColour( GL_AMBIENT, l->scene_ambient() );
-    ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, l->scene_diffuse() );
-    ssgGetLight( 0 ) -> setColour( GL_SPECULAR, l->scene_specular() );
 
-    sgEnviro.setLight(l->adj_fog_color());
+//     sgEnviro.setLight(l->adj_fog_color());
 
     // texture parameters
-    // glEnable( GL_TEXTURE_2D );
-    glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ;
-    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ) ;
+    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
 
     double agl = current__view->getAltitudeASL_ft()*SG_FEET_TO_METER
       - current__view->getSGLocation()->get_cur_elev_m();
 
+    float scene_nearplane, scene_farplane;
     if ( agl > 10.0 ) {
         scene_nearplane = 10.0f;
         scene_farplane = 120000.0f;
@@ -497,279 +630,84 @@ FGRenderer::update( bool refresh_camera_settings ) {
 
     setNearFar( scene_nearplane, scene_farplane );
 
-    sgEnviro.startOfFrame(current__view->get_view_pos(), 
-        current__view->get_world_up(),
-        current__view->getLongitude_deg(),
-        current__view->getLatitude_deg(),
-        current__view->getAltitudeASL_ft() * SG_FEET_TO_METER,
-        delta_time_sec);
-
-    if ( draw_otw && skyblend ) {
-        // draw the sky backdrop
-
-        // we need a white diffuse light for the phase of the moon
-        ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, white );
-        thesky->preDraw( cur_fdm_state->get_Altitude() * SG_FEET_TO_METER,
-                         fog_exp2_density );
-        // return to the desired diffuse color
-        ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, l->scene_diffuse() );
-    }
-
-    // draw the ssg scene
-    glEnable( GL_DEPTH_TEST );
-
-    if ( fgGetBool("/sim/rendering/wireframe") ) {
-        // draw wire frame
-        glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
-    }
-    if ( draw_otw ) {
-        if ( draw_clouds ) {
-
-            // Draw the terrain
-            FGTileMgr::set_tile_filter( true );
-            sgSetModelFilter( false );
-            globals->get_aircraft_model()->select( false );
-            ssgCullAndDraw( globals->get_scenery()->get_scene_graph() );
-
-            // Disable depth buffer update, draw the clouds
-            glDepthMask( GL_FALSE );
-            if( !volumetric_clouds )
-                thesky->drawUpperClouds();
-            if ( multi_pass_clouds ) {
-                thesky->drawLowerClouds();
-            }
-            glDepthMask( GL_TRUE );
-
-            if ( multi_pass_clouds ) {
-                // Draw the objects except the aircraft
-                //  and update the stencil buffer with 1
-                glEnable( GL_STENCIL_TEST );
-                glStencilFunc( GL_ALWAYS, 1, 1 );
-                glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
-            }
-            FGTileMgr::set_tile_filter( false );
-            sgSetModelFilter( true );
-            ssgCullAndDraw( globals->get_scenery()->get_scene_graph() );
-        } else {
-            FGTileMgr::set_tile_filter( true );
-            sgSetModelFilter( true );
-            globals->get_aircraft_model()->select( false );
-            ssgCullAndDraw( globals->get_scenery()->get_scene_graph() );
-        }
-    }
-
-    // This is a bit kludgy.  Every 200 frames, do an extra
-    // traversal of the scene graph without drawing anything, but
-    // with the field-of-view set to 360x360 degrees.  This
-    // ensures that out-of-range random objects that are not in
-    // the current view frustum will still be freed properly.
-    static int counter = 0;
-    counter++;
-    if (counter >= 200) {
-        sgFrustum f;
-        f.setFOV(360, 360);
-                // No need to put the near plane too close;
-                // this way, at least the aircraft can be
-                // culled.
-        f.setNearFar(1000, 1000000);
-        sgMat4 m;
-        ssgGetModelviewMatrix(m);
-        FGTileMgr::set_tile_filter( true );
-        sgSetModelFilter( true );
-        globals->get_scenery()->get_scene_graph()->cull(&f, m, true);
-        counter = 0;
-    }
-
-    // change state for lighting here
-
-    // draw runway lighting
-    glFogf (GL_FOG_DENSITY, rwy_exp2_punch_through);
-
-    // CLO - 02/25/2005 - DO WE NEED THIS extra fgSetNearFar()?
-    // fgSetNearFar( scene_nearplane, scene_farplane );
-
-    if ( use_point_sprites ) {
-        glEnable(GL_POINT_SPRITE);
-    } else {
-        glDisable(GL_POINT_SPRITE);
-    }
-
-    if ( enhanced_lighting ) {
-
-        // Enable states for drawing points with GL_extension
-        glEnable(GL_POINT_SMOOTH);
-
-        if ( distance_attenuation && glPointParameterIsSupported )
-        {
-            // Enable states for drawing points with GL_extension
-            glEnable(GL_POINT_SMOOTH);
-
-            float quadratic[3] = {1.0, 0.001, 0.0000001};
-            // makes the points fade as they move away
-            glPointParameterfvPtr(GL_DISTANCE_ATTENUATION_EXT, quadratic);
-            // glPointParameterfPtr(GL_POINT_SIZE_MIN_EXT, 1.0); 
-        }
-
-        glPointSize(4.0);
-
-        // blending function for runway lights
-        glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
-    }
-
-    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);
-    glPolygonMode(GL_FRONT, GL_POINT);
-
-    // draw runway lighting
-    if ( draw_otw ) {
-        ssgCullAndDraw( globals->get_scenery()->get_vasi_lights_root() );
-        ssgCullAndDraw( globals->get_scenery()->get_rwy_lights_root() );
-    }
+//     sgEnviro.startOfFrame(current__view->get_view_pos(), 
+//         current__view->get_world_up(),
+//         current__view->getLongitude_deg(),
+//         current__view->getLatitude_deg(),
+//         current__view->getAltitudeASL_ft() * SG_FEET_TO_METER,
+//         delta_time_sec);
 
-    // change punch through and then draw taxi lighting
-    glFogf ( GL_FOG_DENSITY, fog_exp2_density );
-    // sgVec3 taxi_fog;
-    // sgSetVec3( taxi_fog, 0.0, 0.0, 0.0 );
-    // glFogfv ( GL_FOG_COLOR, taxi_fog );
-    if ( draw_otw ) {
-        ssgCullAndDraw( globals->get_scenery()->get_taxi_lights_root() );
-    }
-
-    // clean up lighting
-    glPolygonMode(GL_FRONT, GL_FILL);
-    glDisable(GL_TEXTURE_GEN_S);
-    glDisable(GL_TEXTURE_GEN_T);
-
-    //static int _frame_count = 0;
-    //if (_frame_count % 30 == 0) {
-    //  printf("SSG: %s\n", ssgShowStats());
-    //}
-    //else {
-    //  ssgShowStats();
-    //}
-    //_frame_count++;
-
-
-    if ( enhanced_lighting ) {
-        if ( distance_attenuation && glPointParameterIsSupported ) {
-            glPointParameterfvPtr(GL_DISTANCE_ATTENUATION_EXT,
-                                  default_attenuation);
-        }
-
-        glPointSize(1.0);
-        glDisable(GL_POINT_SMOOTH);
-    }
-
-    // draw ground lighting
-    glFogf (GL_FOG_DENSITY, ground_exp2_punch_through);
-    if ( draw_otw ) {
-        ssgCullAndDraw( globals->get_scenery()->get_gnd_lights_root() );
-    }
+    // OSGFIXME
+//     sgEnviro.drawLightning();
 
-    sgEnviro.drawLightning();
-
-    if ( draw_otw && draw_clouds ) {
-        if ( multi_pass_clouds ) {
-            // Disable depth buffer update, draw the clouds where the
-            //  objects overwrite the already drawn clouds, by testing
-            //  the stencil buffer against 1
-            glDepthMask( GL_FALSE );
-            glStencilFunc( GL_EQUAL, 1, 1 );
-            glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
-            thesky->drawUpperClouds();
-            thesky->drawLowerClouds();
-            glDepthMask( GL_TRUE );
-            glDisable( GL_STENCIL_TEST );
-        } else {
-            glDepthMask( GL_FALSE );
-            if( volumetric_clouds )
-                thesky->drawUpperClouds();
-            thesky->drawLowerClouds();
-            glDepthMask( GL_TRUE );
-        }
-    }
-       double current_view_origin_airspeed_horiz_kt =
-        fgGetDouble("/velocities/airspeed-kt", 0.0)
-                       * cos( fgGetDouble("/orientation/pitch-deg", 0.0)
-                               * SGD_DEGREES_TO_RADIANS);
+//        double current_view_origin_airspeed_horiz_kt =
+//         fgGetDouble("/velocities/airspeed-kt", 0.0)
+//                        * cos( fgGetDouble("/orientation/pitch-deg", 0.0)
+//                                * SGD_DEGREES_TO_RADIANS);
        // TODO:find the real view speed, not the AC one
-    sgEnviro.drawPrecipitation(
-        fgGetDouble("/environment/metar/rain-norm", 0.0),
-        fgGetDouble("/environment/metar/snow-norm", 0.0),
-        fgGetDouble("/environment/metar/hail-norm", 0.0),
-        current__view->getPitch_deg() + current__view->getPitchOffset_deg(),
-        current__view->getRoll_deg() + current__view->getRollOffset_deg(),
-        - current__view->getHeadingOffset_deg(),
-               current_view_origin_airspeed_horiz_kt
-               );
-
-    // compute shadows and project them on screen
-    bool is_internal = globals->get_current_view()->getInternal();
-    // draw before ac because ac internal rendering clear the depth buffer
-
-       globals->get_aircraft_model()->select( true );
-    if( is_internal )
-        shadows->endOfFrame();
-
-    if ( draw_otw ) {
-        FGTileMgr::set_tile_filter( false );
-        sgSetModelFilter( false );
-        globals->get_aircraft_model()->select( true );
-        globals->get_model_mgr()->draw();
-        globals->get_aircraft_model()->draw();
-
-        FGTileMgr::set_tile_filter( true );
-        sgSetModelFilter( true );
-        globals->get_aircraft_model()->select( true );
-    }
-       // in 'external' view the ac can be culled, so shadows have not been draw in the
-       // posttrav callback, this would be a rare case if the getInternal was acting
-       // as expected (ie in internal view, getExternal returns false)
-       if( !is_internal )
-               shadows->endOfFrame();
+//     sgEnviro.drawPrecipitation(
+//         fgGetDouble("/environment/metar/rain-norm", 0.0),
+//         fgGetDouble("/environment/metar/snow-norm", 0.0),
+//         fgGetDouble("/environment/metar/hail-norm", 0.0),
+//         current__view->getPitch_deg() + current__view->getPitchOffset_deg(),
+//         current__view->getRoll_deg() + current__view->getRollOffset_deg(),
+//         - current__view->getHeadingOffset_deg(),
+//                current_view_origin_airspeed_horiz_kt
+//                );
+
+    // OSGFIXME
+//     if( is_internal )
+//         shadows->endOfFrame();
+
+    // need to call the update visitor once
+    globals->get_aircraft_model()->select( true );
+    FGTileMgr::set_tile_filter( true );
+    mFrameStamp->setReferenceTime(globals->get_sim_time_sec());
+    mFrameStamp->setFrameNumber(1+mFrameStamp->getFrameNumber());
+    mFrameStamp->setCalendarTime(*globals->get_time_params()->getGmt());
+    sceneView->update();
+    sceneView->cull();
+    sceneView->draw();
+
+    glPushAttrib(GL_ALL_ATTRIB_BITS);
+    glPushClientAttrib(~0u);
 
     // display HUD && Panel
     glDisable( GL_FOG );
     glDisable( GL_DEPTH_TEST );
-    // glDisable( GL_CULL_FACE );
-    // glDisable( GL_TEXTURE_2D );
-
-    // update the controls subsystem
-    globals->get_controls()->update(delta_time_sec);
-
-    hud_and_panel->apply();
-    fgCockpitUpdate();
 
-    FGInstrumentMgr *instr = static_cast<FGInstrumentMgr *>(globals->get_subsystem("instrumentation"));
-    HUD *hud = static_cast<HUD *>(instr->get_subsystem("hud"));
-    hud->draw();
+    fgCockpitUpdate(sceneView->getState());
 
-    // Use the hud_and_panel ssgSimpleState for rendering the ATC output
-    // This only works properly if called before the panel call
-    if((fgGetBool("/sim/atc/enabled")) || (fgGetBool("/sim/ai-traffic/enabled")))
-        globals->get_ATC_display()->update(delta_time_sec);
+    FGInstrumentMgr *instr = static_cast<FGInstrumentMgr*>(globals->get_subsystem("instrumentation"));
+    HUD *hud = static_cast<HUD*>(instr->get_subsystem("hud"));
+    hud->draw(*sceneView->getState());
 
     // update the panel subsystem
-    if ( globals->get_current_panel() != NULL ) {
-        globals->get_current_panel()->update(delta_time_sec);
-    }
+    if ( globals->get_current_panel() != NULL )
+        globals->get_current_panel()->update(*sceneView->getState());
+    // We don't need a state here - can be safely removed when we can pick
+    // correctly
     fgUpdate3DPanels();
 
+    if((fgGetBool("/sim/atc/enabled"))
+       || (fgGetBool("/sim/ai-traffic/enabled")))
+      globals->get_ATC_display()->update(delta_time_sec,
+                                         *sceneView->getState());
+
     // We can do translucent menus, so why not. :-)
-    menus->apply();
-    glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
+    glDisable( GL_TEXTURE_2D ) ;
+    glDisable( GL_CULL_FACE ) ;
+    glEnable( GL_BLEND ) ;
+    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
     puDisplay();
-    // glDisable ( GL_BLEND ) ;
-
-    glEnable( GL_DEPTH_TEST );
-    glEnable( GL_FOG );
 
     // Fade out the splash screen over the first three seconds.
     double t = globals->get_sim_time_sec();
     if (t <= 2.5)
         fgSplashUpdate((2.5 - t) / 2.5);
+
+    glPopClientAttrib();
+    glPopAttrib();
 }
 
 
@@ -788,7 +726,7 @@ FGRenderer::resize( int width, int height ) {
         view_h = height;
     }
 
-    glViewport( 0, (GLint)(height - view_h), (GLint)(width), (GLint)(view_h) );
+    sceneView->getViewport()->setViewport(0, height - view_h, width, view_h);
 
     static int lastwidth = 0;
     static int lastheight = 0;
@@ -812,11 +750,7 @@ FGRenderer::resize( int width, int height ) {
       // cout << "setFOV(" << viewmgr->get_current_view()->get_h_fov()
       //      << ", " << viewmgr->get_current_view()->get_v_fov() << ")"
       //      << endl;
-
     }
-
-    fgHUDReshape();
-
 }
 
 
@@ -844,8 +778,10 @@ static void fgHackFrustum() {
     static SGPropertyNode *top_pct
         = fgGetNode("/sim/current-view/frustum-top-pct");
 
-    sgFrustum *f = ssgGetFrustum();
-
+    double left, right;
+    double bottom, top;
+    double zNear, zFar;
+    sceneView->getProjectionMatrixAsFrustum(left, right, bottom, top, zNear, zFar);
     // cout << " l = " << f->getLeft()
     //      << " r = " << f->getRight()
     //      << " b = " << f->getBot()
@@ -854,36 +790,36 @@ static void fgHackFrustum() {
     //      << " f = " << f->getFar()
     //      << endl;
 
-    double width = f->getRight() - f->getLeft();
-    double height = f->getTop() - f->getBot();
+    double width = right - left;
+    double height = top - bottom;
 
     double l, r, t, b;
 
     if ( left_pct != NULL ) {
-        l = f->getLeft() + width * left_pct->getDoubleValue();
+        l = left + width * left_pct->getDoubleValue();
     } else {
-        l = f->getLeft();
+        l = left;
     }
 
     if ( right_pct != NULL ) {
-        r = f->getLeft() + width * right_pct->getDoubleValue();
+        r = left + width * right_pct->getDoubleValue();
     } else {
-        r = f->getRight();
+        r = right;
     }
 
     if ( bottom_pct != NULL ) {
-        b = f->getBot() + height * bottom_pct->getDoubleValue();
+        b = bottom + height * bottom_pct->getDoubleValue();
     } else {
-        b = f->getBot();
+        b = bottom;
     }
 
     if ( top_pct != NULL ) {
-        t = f->getBot() + height * top_pct->getDoubleValue();
+        t = bottom + height * top_pct->getDoubleValue();
     } else {
-        t = f->getTop();
+        t = top;
     }
 
-    ssgSetFrustum(l, r, b, t, f->getNear(), f->getFar());
+    sceneView->setProjectionMatrixAsFrustum(l, r, b, t, zNear, zFar);
 }
 
 
@@ -906,12 +842,13 @@ void FGRenderer::setFOV( float w, float h ) {
     fov_width = w;
     fov_height = h;
 
+    sceneView->setProjectionMatrixAsPerspective(fov_height,
+                                                fov_width/fov_height,
+                                                fov_near, fov_far);
     // fully specify the view frustum before hacking it (so we don't
     // accumulate hacked effects
-    ssgSetFOV( w, h );
-    ssgSetNearFar( fov_near, fov_far );
     fgHackFrustum();
-    sgEnviro.setFOV( w, h );
+//     sgEnviro.setFOV( w, h );
 }
 
 
@@ -919,14 +856,20 @@ void FGRenderer::setFOV( float w, float h ) {
  *  planes rather than calling the ssg routine directly
  */
 void FGRenderer::setNearFar( float n, float f ) {
+// OSGFIXME: we have currently too much z-buffer fights
+n = 0.2;
     fov_near = n;
     fov_far = f;
 
+    sceneView->setProjectionMatrixAsPerspective(fov_height,
+                                                fov_width/fov_height,
+                                                fov_near, fov_far);
+
+    sceneView->getCamera()->setNearFarRatio(fov_near/fov_far);
+    mSceneCamera->setNearFarRatio(fov_near/fov_far);
+
     // fully specify the view frustum before hacking it (so we don't
     // accumulate hacked effects
-    ssgSetNearFar( n, f );
-    ssgSetFOV( fov_width, fov_height );
-
     fgHackFrustum();
 }
 
@@ -935,16 +878,20 @@ bool FGRenderer::getPickInfo( SGVec3d& pt, SGVec3d& dir,
 {
   // Get the matrices involved in the transform from global to screen
   // coordinates.
-  sgMat4 pm;
-  ssgGetProjectionMatrix(pm);
-  sgMat4 mv;
-  ssgGetModelviewMatrix(mv);
+  osg::Matrix pm = sceneView->getCamera()->getProjectionMatrix();
+
+  osg::Matrix mv;
+  osg::NodePathList paths;
+  paths = globals->get_scenery()->get_scene_graph()->getParentalNodePaths();
+  if (!paths.empty()) {
+    // Ok, we know that this should not have multiple parents ...
+    // FIXME: is this allways true?
+    mv = osg::computeLocalToEye(sceneView->getCamera()->getViewMatrix(),
+                                paths.front(), false);
+  }
   
-  // Compose ...
-  sgMat4 m;
-  sgMultMat4(m, pm, mv);
-  // ... and invert
-  sgInvertMat4(m);
+  // Compose and invert
+  osg::Matrix m = osg::Matrix::inverse(mv*pm);
   
   // Get the width and height of the display to be able to normalize the
   // mouse coordinate
@@ -954,24 +901,25 @@ bool FGRenderer::getPickInfo( SGVec3d& pt, SGVec3d& dir,
   // Compute some coordinates of in the line from the eyepoint to the
   // mouse click coodinates.
   // First build the normalized projection coordinates
-  sgVec4 normPt;
-  sgSetVec4(normPt, (2*x - width)/width, -(2*y - height)/height, 1, 1);
+  osg::Vec4 normPt((2*x - width)/width, -(2*y - height)/height, 1, 1);
   // Transform them into the real world
-  sgVec4 worldPt;
-  sgXformPnt4(worldPt, normPt, m);
-  if (worldPt[3] == 0)
+  osg::Vec4 worldPt4 = m.preMult(normPt);
+  if (fabs(worldPt4[3]) < SGLimitsf::min())
     return false;
-  sgScaleVec3(worldPt, 1/worldPt[3]);
+  SGVec3f worldPt(worldPt4[0]/worldPt4[3],
+                  worldPt4[1]/worldPt4[3],
+                  worldPt4[2]/worldPt4[3]);
 
   // Now build a direction from the point
   FGViewer* view = globals->get_current_view();
-  sgVec4 fDir;
-  sgSubVec3(fDir, worldPt, view->get_view_pos());
-  sgdSetVec3(dir.sg(), fDir);
-  sgdNormalizeVec3(dir.sg());
+  dir = normalize(toVec3d(worldPt - SGVec3f(view->get_view_pos())));
 
   // Copy the start point
-  sgdCopyVec3(pt.sg(), view->get_absolute_view_pos());
+  pt = SGVec3d(view->get_absolute_view_pos());
+
+  // OSGFIXME: ist this sufficient??? especially the precision problems here??
+// bool mSceneView->projectWindowXYIntoObject(int x,int y,osg::Vec3& near_point,osg::Vec3& far_point) const;
+
 
   return true;
 }
index 7cfbfd354c57f2d0494d9f67a1c0270b77199120..83faba51ba7ea2d15a8f8361efa29ae260ee21e6 100644 (file)
@@ -25,7 +25,6 @@ public:
 
     void init();
 
-    void build_states();
     static void resize(int width, int height );
 
     // calling update( refresh_camera_settings = false ) will not
index a9cea38d27c3ec458650a559fb6ed64276e42ef2..e1ba8432536b8107d4eab2780113100638481521 100644 (file)
@@ -28,7 +28,6 @@
 #include <string.h>            // strcmp
 
 #include <plib/sg.h>
-#include <plib/ssg.h>
 
 #include <simgear/compiler.h>
 
index 7e4f7cbd94e785e4fcc65967b500155f71e1a27f..4b0a87841251bbec8e29d8e438708b77c74acc84 100644 (file)
@@ -9,15 +9,12 @@
 
 #include <string.h>            // for strcmp()
 
-#include <plib/sg.h>
-#include <plib/ssg.h>
-
 #include <simgear/compiler.h>
 #include <simgear/debug/logstream.hxx>
 #include <simgear/structure/exception.hxx>
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/scene/model/placement.hxx>
-#include <simgear/scene/model/shadowvolume.hxx>
+#include <simgear/scene/util/SGNodeMasks.hxx>
 
 #include <Main/globals.hxx>
 #include <Main/fg_props.hxx>
 
 #include "acmodel.hxx"
 
-
-class fgLoaderOptions : ssgLoaderOptions {
-
-public:
-    virtual void makeTexturePath ( char* path, const char *fname ) const ;
-    string livery_path;
-
-};
-
-void fgLoaderOptions::makeTexturePath ( char *path, const char *fname ) const
-{
-  /* Remove all leading path information. */
-  const char* seps = "\\/" ;
-  const char* fn = & fname [ strlen ( fname ) - 1 ] ;
-  for ( ; fn != fname && strchr(seps,*fn) == NULL ; fn-- )
-    /* Search back for a seperator */ ;
-  if ( strchr(seps,*fn) != NULL )
-    fn++ ;
-  fname = fn ;
-  // if we have a livery path and the texture is found there then we use that
-  // path in priority, if the texture was not found or we add no additional 
-  // livery path then we use the current model path or model/texture-path
-  if( livery_path.size() ) {
-      make_path( path, livery_path.c_str(), fname );
-      if( ulFileExists( path ) )
-          return;
-  }
-  make_path ( path, texture_dir, fname ) ;
-}
-
-static fgLoaderOptions _fgLoaderOptions;
-
 \f
 ////////////////////////////////////////////////////////////////////////
 // Implementation of FGAircraftModel
@@ -69,8 +34,8 @@ static fgLoaderOptions _fgLoaderOptions;
 
 FGAircraftModel::FGAircraftModel ()
   : _aircraft(0),
-    _selector(new ssgSelector),
-    _scene(new ssgRoot),
+    _selector(new osg::Switch),
+    _scene(new osg::Group),
     _nearplane(0.10f),
     _farplane(1000.0f)
 {
@@ -84,14 +49,13 @@ FGAircraftModel::~FGAircraftModel ()
 
   delete _aircraft;
                                // SSG will delete it
-  globals->get_scenery()->get_aircraft_branch()->removeKid(_selector);
+  globals->get_scenery()->get_aircraft_branch()->removeChild(_selector.get());
 }
 
 void 
 FGAircraftModel::init ()
 {
-  ssgLoaderOptions *currLoaderOptions = ssgGetCurrentOptions();
-  ssgSetCurrentOptions( (ssgLoaderOptions*)&_fgLoaderOptions );
+  SGPath liveryPath;
   _aircraft = new SGModelPlacement;
   string path = fgGetString("/sim/model/path", "Models/Geometry/glider.ac");
   string texture_path = fgGetString("/sim/model/texture-path");
@@ -101,41 +65,44 @@ FGAircraftModel::init ()
           temp_path = globals->get_fg_root();
           temp_path.append( SGPath( path ).dir() );
           temp_path.append( texture_path );
-          _fgLoaderOptions.livery_path = temp_path.str();
+          liveryPath = temp_path;
       } else
-          _fgLoaderOptions.livery_path = texture_path;
+          liveryPath = texture_path;
   }
   try {
-    ssgBranch *model = fgLoad3DModelPanel( globals->get_fg_root(),
+    osg::Node *model = fgLoad3DModelPanel( globals->get_fg_root(),
                                            path,
                                            globals->get_props(),
-                                           globals->get_sim_time_sec() );
+                                           globals->get_sim_time_sec(),
+                                           liveryPath);
     _aircraft->init( model );
   } catch (const sg_exception &ex) {
     SG_LOG(SG_GENERAL, SG_ALERT, "Failed to load aircraft from " << path);
     SG_LOG(SG_GENERAL, SG_ALERT, "(Falling back to glider.ac.)");
-    ssgBranch *model = fgLoad3DModelPanel( globals->get_fg_root(),
+    osg::Node *model = fgLoad3DModelPanel( globals->get_fg_root(),
                                            "Models/Geometry/glider.ac",
                                            globals->get_props(),
-                                           globals->get_sim_time_sec() );
+                                           globals->get_sim_time_sec(),
+                                           liveryPath);
     _aircraft->init( model );
   }
-  _scene->addKid(_aircraft->getSceneGraph());
-  _selector->addKid(_aircraft->getSceneGraph());
-  globals->get_scenery()->get_aircraft_branch()->addKid(_selector);
+  _scene->addChild(_aircraft->getSceneGraph());
+  _selector->addChild(_aircraft->getSceneGraph());
+  // Do not do altitude computations with that model
+  _selector->setNodeMask(~SG_NODEMASK_TERRAIN_BIT);
+  globals->get_scenery()->get_aircraft_branch()->addChild(_selector.get());
 
   // Register that one at the scenery manager
   globals->get_scenery()->register_placement_transform(_aircraft->getTransform());
-  ssgSetCurrentOptions( currLoaderOptions );
 }
 
-void 
+void
 FGAircraftModel::bind ()
 {
   // No-op
 }
 
-void 
+void
 FGAircraftModel::unbind ()
 {
   // No-op
@@ -162,27 +129,5 @@ FGAircraftModel::update (double dt)
   _aircraft->update();
 }
 
-void
-FGAircraftModel::draw ()
-{
-                               // OK, now adjust the clip planes and draw
-                               // FIXME: view number shouldn't be 
-                               // hard-coded.
-  bool is_internal = globals->get_current_view()->getInternal();
-  if (_aircraft->getVisible() && is_internal) {
-    glClearDepth(1);
-    glClear(GL_DEPTH_BUFFER_BIT);
-    FGRenderer::setNearFar(_nearplane, _farplane);
-    ssgCullAndDraw(_scene);
-    _selector->select(0);
-  } else {
-    _selector->select(1);
-    // in external view the shadows are drawn before the transparent parts of the ac
-    _scene->setTravCallback( SSG_CALLBACK_POSTTRAV, SGShadowVolume::ACpostTravCB);
-    ssgCullAndDraw(_scene);
-    _scene->setTravCallback( SSG_CALLBACK_POSTTRAV, 0);
-  }
-
-}
 
 // end of model.cxx
index bee322e8bbaa6ca0b3f5e0ea282794f4e15dcd3a..9f248acfec4dcb39c84f70d7b2e456ecd31fafb6 100644 (file)
@@ -1,4 +1,4 @@
-// model.hxx - manage a 3D aircraft model.
+#// model.hxx - manage a 3D aircraft model.
 // Written by David Megginson, started 2002.
 //
 // This file is in the Public Domain, and comes with no warranty.
 SG_USING_STD(string);
 SG_USING_STD(vector);
 
+#include <osg/ref_ptr>
+#include <osg/Group>
+#include <osg/Switch>
+
 #include <simgear/structure/subsystem_mgr.hxx> // for SGSubsystem
-#include <simgear/structure/ssgSharedPtr.hxx>
 
 
 // Don't pull in the headers, since we don't need them here.
-class ssgRoot;
-class ssgSelector;
 class SGModelPlacement;
 
 
@@ -37,15 +38,14 @@ public:
   virtual void bind ();
   virtual void unbind ();
   virtual void update (double dt);
-  virtual void draw ();
   virtual SGModelPlacement * get3DModel() { return _aircraft; }
-  void select( bool s ) { _selector->select( s ? 0xffffffff : 0 ); }
+  void select( bool s ) { _selector->setValue( 0, s ); }
 
 private:
 
   SGModelPlacement * _aircraft;
-  ssgSharedPtr<ssgSelector> _selector;
-  ssgSharedPtr<ssgRoot> _scene;
+  osg::ref_ptr<osg::Switch> _selector;
+  osg::ref_ptr<osg::Group> _scene;
   float _nearplane;
   float _farplane;
 
index 732e0691a534ab293781ce0e37c57f0a33ec206c..ef98544793cc2d39c2c844fc3766baf400d9d952 100644 (file)
@@ -9,10 +9,11 @@
 
 #include <simgear/compiler.h>
 
-#include <plib/ssg.h>
+#include <osg/Geode>
 
 #include <simgear/props/props.hxx>
 #include <simgear/scene/model/model.hxx>
+#include <simgear/scene/util/SGNodeMasks.hxx>
 
 #include "panelnode.hxx"
 
 SG_USING_STD(vector);
 
 static
-ssgEntity *load_panel(SGPropertyNode *n)
+osg::Node* load_panel(SGPropertyNode *n)
 {
-  return new FGPanelNode(n);
+  osg::Geode* geode = new osg::Geode;
+  geode->addDrawable(new FGPanelNode(n));
+  return geode;
 }
+
 \f
 ////////////////////////////////////////////////////////////////////////
 // Global functions.
 ////////////////////////////////////////////////////////////////////////
 
-ssgBranch *
+osg::Node *
 fgLoad3DModelPanel( const string &fg_root, const string &path,
                     SGPropertyNode *prop_root,
-                    double sim_time_sec )
+                    double sim_time_sec, const SGPath& livery )
 {
-  return sgLoad3DModel( fg_root, path, prop_root, sim_time_sec, load_panel );
+  osg::Node* node = sgLoad3DModel( fg_root, path, prop_root, sim_time_sec,
+                                   load_panel, 0, livery );
+  node->setNodeMask(~SG_NODEMASK_TERRAIN_BIT);
+  return node;
 }
 
 
index ba6abf74198227956c5ea4ed8fe349c1bbc5d663..0c1c34a14739ee80fdf4328a89064c334ce00f35 100644 (file)
@@ -19,11 +19,6 @@ SG_USING_STD(vector);
 
 
 // Don't pull in the headers, since we don't need them here.
-class ssgBranch;
-class ssgEntity;
-class ssgRangeSelector;
-class ssgSelector;
-class ssgTransform;
 
 class SGInterpTable;
 class FGCondition;
@@ -51,9 +46,9 @@ class FGLocation;
  * Subsystems should not normally invoke this function directly;
  * instead, they should use the SGModelLoader declared in loader.hxx.
  */
-ssgBranch *fgLoad3DModelPanel( const string& fg_root, const string &path,
+osg::Node *fgLoad3DModelPanel( const string& fg_root, const string &path,
                                SGPropertyNode *prop_root,
-                               double sim_time_sec );
+                               double sim_time_sec, const SGPath& livery );
 
 
 #endif // __MODEL_HXX
index 7be7e4e474568de031087410fe37a25047dc6b31..561f3df8a3db27083cf504953b668542fcdeb24d 100644 (file)
 
 #include <vector>
 
-#include <plib/ssg.h>
-
 #include <simgear/scene/model/placement.hxx>
 #include <simgear/scene/model/modellib.hxx>
-#include <simgear/scene/model/shadowvolume.hxx>
 #include <simgear/structure/exception.hxx>
 
 #include <Main/fg_props.hxx>
@@ -26,7 +23,8 @@
 
 SG_USING_STD(vector);
 
-extern SGShadowVolume *shadows;
+// OSGFIXME
+// extern SGShadowVolume *shadows;
 
 
 FGModelMgr::FGModelMgr ()
@@ -43,7 +41,7 @@ FGModelMgr::~FGModelMgr ()
 
   for (unsigned int i = 0; i < _instances.size(); i++) {
     globals->get_scenery()->get_scene_graph()
-      ->removeKid(_instances[i]->model->getSceneGraph());
+      ->removeChild(_instances[i]->model->getSceneGraph());
     delete _instances[i];
   }
 }
@@ -72,7 +70,7 @@ FGModelMgr::add_model (SGPropertyNode * node)
   instance->model = model;
   instance->node = node;
   SGModelLib *model_lib = globals->get_model_lib();
-  ssgBranch *object = (ssgBranch *)model_lib->load_model(
+  osg::Node *object = model_lib->load_model(
       globals->get_fg_root(),
       node->getStringValue("path",
                            "Models/Geometry/glider.ac"),
@@ -121,7 +119,7 @@ FGModelMgr::add_model (SGPropertyNode * node)
     model->setHeadingDeg(node->getDoubleValue("heading-deg"));
 
                        // Add this model to the global scene graph
-  globals->get_scenery()->get_scene_graph()->addKid(model->getSceneGraph());
+  globals->get_scenery()->get_scene_graph()->addChild(model->getSceneGraph());
 
   // Register that one at the scenery manager
   globals->get_scenery()->register_placement_transform(model->getTransform());
@@ -166,11 +164,12 @@ FGModelMgr::update (double dt)
 
     instance->model->update();
 
-    if (shadows && !instance->shadow) {
-      ssgBranch *branch = (ssgBranch *)instance->model->getSceneGraph();
-      shadows->addOccluder(branch, SGShadowVolume::occluderTypeTileObject);
-      instance->shadow = true;
-    }
+    // OSGFIXME
+//     if (shadows && !instance->shadow) {
+//       osg::Node *branch = instance->model->getSceneGraph();
+//       shadows->addOccluder(branch, SGShadowVolume::occluderTypeTileObject);
+//       instance->shadow = true;
+//     }
   }
 }
 
@@ -193,14 +192,6 @@ FGModelMgr::remove_instance (Instance * instance)
     }
 }
 
-void
-FGModelMgr::draw ()
-{
-//   ssgSetNearFar(_nearplane, _farplane);
-//   ssgCullAndDraw(_scene);
-}
-
-
 \f
 ////////////////////////////////////////////////////////////////////////
 // Implementation of FGModelMgr::Instance
@@ -262,10 +253,11 @@ FGModelMgr::Listener::childRemoved(SGPropertyNode * parent, SGPropertyNode * chi
       continue;
 
     _mgr->_instances.erase(it);
-    ssgBranch *branch = (ssgBranch *)instance->model->getSceneGraph();
-    if (shadows && instance->shadow)
-        shadows->deleteOccluder(branch);
-    globals->get_scenery()->get_scene_graph()->removeKid(branch);
+    osg::Node *branch = instance->model->getSceneGraph();
+    // OSGFIXME
+//     if (shadows && instance->shadow)
+//         shadows->deleteOccluder(branch);
+    globals->get_scenery()->get_scene_graph()->removeChild(branch);
 
     delete instance;
     break;
index a2d2676453e9f8f83584c471d7709f120187e90e..b26bc05e39215b0c626f40721e4f42aa4b7a432e 100644 (file)
@@ -87,9 +87,6 @@ public:
    */
   virtual void remove_instance (Instance * instance);
 
-  virtual void draw ();
-
-
 
 private:
   /**
index bf553e2033b2231571cf1f0f1bc04175c38f28cb..29b4d0e725a4a1d29222be9db25c3995c56ad925 100644 (file)
@@ -14,8 +14,9 @@
 SG_USING_STD(vector);
 
 
-// Static (!) handling for all 3D panels in the program.  Very
-// clumsy.  Replace with per-aircraft handling.
+// Static (!) handling for all 3D panels in the program.
+// OSGFIXME: Put the panel as different elements in the scenegraph.
+// Then just pick in that scenegraph.
 vector<FGPanelNode*> all_3d_panels;
 bool fgHandle3DPanelMouseEvent( int button, int updown, int x, int y )
 {
@@ -45,17 +46,11 @@ FGPanelNode::FGPanelNode(SGPropertyNode* props)
     // Never mind.  We *have* to call init to make sure the static
     // state is initialized (it's not, if there aren't any 2D
     // panels).  This is a memory leak and should be fixed!`
+    // FIXME
     _panel->init();
 
     _panel->setDepthTest( props->getBoolValue("depth-test") );
 
-    // Initialize the matrices to the identity.  PLib prints warnings
-    // when trying to invert singular matrices (e.g. when not using a
-    // 3D panel).
-    for(i=0; i<4; i++)
-        for(int j=0; j<4; j++)
-            _lastModelview[4*i+j] = _lastProjection[4*i+j] = i==j ? 1 : 0;
-
     // Read out the pixel-space info
     _xmax = _panel->getWidth();
     _ymax = _panel->getHeight();
@@ -80,44 +75,38 @@ FGPanelNode::FGPanelNode(SGPropertyNode* props)
     // "a", "b", and "c" as our corners and "m" as the matrix. The
     // vector u goes from a to b, v from a to c, and w is a
     // perpendicular cross product.
-    float *a = _bottomLeft, *b = _bottomRight, *c = _topLeft, *m = _xform;
-    float u[3], v[3], w[3];
-    for(i=0; i<3; i++) u[i] = b[i] - a[i]; // U = B - A
-    for(i=0; i<3; i++) v[i] = c[i] - a[i]; // V = C - A
-
-    w[0] = u[1]*v[2] - v[1]*u[2];          // W = U x V
-    w[1] = u[2]*v[0] - v[2]*u[0];
-    w[2] = u[0]*v[1] - v[0]*u[1];
-
+    osg::Vec3 a = _bottomLeft;
+    osg::Vec3 b = _bottomRight;
+    osg::Vec3 c = _topLeft;
+    osg::Vec3 u = b - a;
+    osg::Vec3 v = c - a;
+    osg::Vec3 w = u^v;
+
+    osg::Matrix& m = _xform;
     // Now generate a trivial basis transformation matrix.  If we want
     // to map the three unit vectors to three arbitrary vectors U, V,
     // and W, then those just become the columns of the 3x3 matrix.
-    m[0] = u[0]; m[4] = v[0]; m[8]  = w[0]; m[12] = a[0]; //     |Ux Vx Wx|
-    m[1] = u[1]; m[5] = v[1]; m[9]  = w[1]; m[13] = a[1]; // m = |Uy Vy Wy|
-    m[2] = u[2]; m[6] = v[2]; m[10] = w[2]; m[14] = a[2]; //     |Uz Vz Wz|
-    m[3] = 0;    m[7] = 0;    m[11] = 0;    m[15] = 1;
+    m(0,0) = u[0]; m(1,0) = v[0]; m(2,0) = w[0]; m(3,0) = a[0];//    |Ux Vx Wx|
+    m(0,1) = u[1]; m(1,1) = v[1]; m(2,1) = w[1]; m(3,1) = a[1];//m = |Uy Vy Wy|
+    m(0,2) = u[2]; m(1,2) = v[2]; m(2,2) = w[2]; m(3,2) = a[2];//    |Uz Vz Wz|
+    m(0,3) = 0;    m(1,3) = 0;    m(2,3) = 0;    m(3,3) = 1;
 
     // The above matrix maps the unit (!) square to the panel
     // rectangle.  Postmultiply scaling factors that match the
     // pixel-space size of the panel.
-    for(i=0; i<4; i++) {
-        m[0+i] *= 1.0/_xmax;
-        m[4+i] *= 1.0/_ymax;
+    for(i=0; i<4; ++i) {
+        m(0,i) *= 1.0/_xmax;
+        m(1,i) *= 1.0/_ymax;
     }
 
-    // Now plib initialization.  The bounding sphere is defined nicely
-    // by our corner points:
-    float cx = (b[0]+c[0])/2;
-    float cy = (b[1]+c[1])/2;
-    float cz = (b[2]+c[2])/2;
-    float r = sqrt((cx-a[0])*(cx-a[0]) +
-                   (cy-a[1])*(cy-a[1]) +
-                   (cz-a[2])*(cz-a[2]));
-    bsphere.setCenter(cx, cy, cz);
-    bsphere.setRadius(r);
+    dirtyBound();
 
     // All done.  Add us to the list
     all_3d_panels.push_back(this);
+
+    setUseDisplayList(false);
+    getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
+    getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
 }
 
 FGPanelNode::~FGPanelNode()
@@ -125,29 +114,35 @@ FGPanelNode::~FGPanelNode()
     delete _panel;
 }
 
-void FGPanelNode::draw()
+void
+FGPanelNode::drawImplementation(osg::State& state) const
 {
-    // What's the difference?
-    draw_geometry();
+  osg::ref_ptr<osg::RefMatrix> mv = new osg::RefMatrix;
+  mv->set(_xform*state.getModelViewMatrix());
+  state.applyModelViewMatrix(mv.get());
+  
+  // Grab the matrix state, so that we can get back from screen
+  // coordinates to panel coordinates when the user clicks the
+  // mouse.
+  // OSGFIXME: we don't need that when we can really pick
+  const_cast<osg::Matrix&>(_lastModelview) = state.getModelViewMatrix();
+  const_cast<osg::Matrix&>(_lastProjection) = state.getProjectionMatrix();
+  state.getCurrentViewport()->getViewport(const_cast<int&>(_lastViewport[0]),
+                                          const_cast<int&>(_lastViewport[1]),
+                                          const_cast<int&>(_lastViewport[2]),
+                                          const_cast<int&>(_lastViewport[3]));
+  
+  _panel->draw(state);
 }
 
-void FGPanelNode::draw_geometry()
+osg::BoundingBox
+FGPanelNode::computeBound() const
 {
-    glMatrixMode(GL_MODELVIEW);
-    glPushMatrix();
-    glMultMatrixf(_xform);
-
-    // Grab the matrix state, so that we can get back from screen
-    // coordinates to panel coordinates when the user clicks the
-    // mouse.
-    glGetFloatv(GL_MODELVIEW_MATRIX, _lastModelview);
-    glGetFloatv(GL_PROJECTION_MATRIX, _lastProjection);
-    glGetIntegerv(GL_VIEWPORT, _lastViewport);
-
-    _panel->draw();
-
-
-    glPopMatrix();
+    osg::BoundingBox bb;
+    bb.expandBy(_bottomLeft);
+    bb.expandBy(_bottomRight);
+    bb.expandBy(_topLeft);
+    return bb;
 }
 
 bool FGPanelNode::doMouseAction(int button, int updown, int x, int y)
@@ -162,7 +157,7 @@ bool FGPanelNode::doMouseAction(int button, int updown, int x, int y)
 
     // Make two vectors in post-projection coordinates at the given
     // screen, one in the near field and one in the far field.
-    sgVec3 a, b;
+    osg::Vec3 a, b;
     a[0] = b[0] = vx;
     a[1] = b[1] = vy;
     a[2] =  0.75; // "Near" Z value
@@ -170,12 +165,11 @@ bool FGPanelNode::doMouseAction(int button, int updown, int x, int y)
 
     // Run both vectors "backwards" through the OpenGL matrix
     // transformation.  Remember to w-normalize the vectors!
-    sgMat4 m;
-    sgMultMat4(m, *(sgMat4*)_lastProjection, *(sgMat4*)_lastModelview);
-    sgInvertMat4(m);
+    osg::Matrix m = _lastModelview*_lastProjection;
+    m = osg::Matrix::inverse(m);
 
-    sgFullXformPnt3(a, m);
-    sgFullXformPnt3(b, m);
+    a = m.preMult(a);
+    b = m.preMult(b);
 
     // And find their intersection on the z=0 plane.  The resulting X
     // and Y coordinates are the hit location in panel coordinates.
@@ -187,9 +181,3 @@ bool FGPanelNode::doMouseAction(int button, int updown, int x, int y)
     return _panel->doLocalMouseAction(button, updown, panelX, panelY);
 }
 
-void FGPanelNode::die()
-{
-    SG_LOG(SG_ALL,SG_ALERT,"Unimplemented function called on FGPanelNode");
-    exit(1);
-}
-
index 78139bf329b8f24ff6bb9ccc3960b8dfbca165db..85f83a0d3b24fa56e5abdf9a58ac7d4e9b2df632 100644 (file)
@@ -1,8 +1,9 @@
 #ifndef FG_PANELNODE_HXX
 #define FG_PANELNODE_HXX
 
-
-#include <plib/ssg.h>
+#include <osg/Vec3>
+#include <osg/Matrix>
+#include <osg/Drawable>
 
 class FGPanel;
 class SGPropertyNode;
@@ -18,52 +19,28 @@ class SGPropertyNode;
 bool fgHandle3DPanelMouseEvent(int button, int updown, int x, int y);
 void fgUpdate3DPanels();
 
-class FGPanelNode : public ssgLeaf 
+class FGPanelNode : public osg::Drawable // OSGFIXME 
 {
-protected:
-    virtual void draw_geometry();
-
 public:
     FGPanelNode(SGPropertyNode* props);
     virtual ~FGPanelNode();
 
-    virtual void draw();
+    // OSGFIXME
+    virtual osg::Object* cloneType() const { return 0; }
+    virtual osg::Object* clone(const osg::CopyOp& copyop) const { return 0; }        
+
     bool doMouseAction(int button, int updown, int x, int y);
 
     FGPanel* getPanel() { return _panel; }
 
-    virtual void recalcBSphere() { bsphere_is_invalid = 0; }
-
-    //
-    // A bunch of Plib functions that aren't implemented.  I don't
-    // even know what many of them do, but they're pure virtual and
-    // require implementation.
-    //
-    virtual int getNumTriangles() { return 0; }
-    virtual void getTriangle(int n, short* v1, short* v2, short* v3) { die(); }
-    virtual int getNumLines() { die(); return 0; }
-    virtual void getLine(int n, short* v1, short* v2) { die(); }
-    
-    virtual void drawHighlight(sgVec4 colour) { die(); }
-    virtual void drawHighlight(sgVec4 colour, int i) { die(); }
-    virtual float* getVertex(int i) { die(); return 0; }
-    virtual float* getNormal(int i) { die(); return 0; }
-    virtual float* getColour(int i) { die(); return 0; }
-    virtual float* getTexCoord(int i) { die(); return 0; }
-    virtual void pick(int baseName) { die(); }
-    virtual void isect_triangles(sgSphere* s, sgMat4 m, int testNeeded) { die(); }
-    virtual void hot_triangles(sgVec3 s, sgMat4 m, int testNeeded) { die(); }
-    virtual void los_triangles(sgVec3 s, sgMat4 m, int testNeeded) { die(); }
-    virtual void transform(const sgMat4 m) { die(); }
+    virtual void drawImplementation(osg::State& state) const;
+    virtual osg::BoundingBox computeBound() const;
 
 private:
-    // Handler for all the unimplemented methods above
-    void die();
-
     FGPanel* _panel;
 
     // Panel corner coordinates
-    float _bottomLeft[3], _topLeft[3], _bottomRight[3];
+    osg::Vec3 _bottomLeft, _topLeft, _bottomRight;
 
     // The input range expected in the panel definition.  These x/y
     // coordinates will map to the right/top sides.
@@ -71,14 +48,14 @@ private:
     
     // The matrix that results, which transforms 2D x/y panel
     // coordinates into 3D coordinates of the panel quadrilateral.
-    GLfloat _xform[16];
+    osg::Matrix _xform;
 
     // The matrix transformation state that was active the last time
     // we were rendered.  Used by the mouse code to compute
     // intersections.
-    GLfloat _lastModelview[16];
-    GLfloat _lastProjection[16];
-    GLint   _lastViewport[4];
+    osg::Matrix _lastModelview;
+    osg::Matrix _lastProjection;
+    int   _lastViewport[4];
 };
 
 
index 5a76a521caae93df1b0974ef66151b02bd453dcd..564b4bfb78bc1feb8a280dc49c12e922bc48bfda 100755 (executable)
 #  include <config.h>
 #endif
 
-#ifdef _MSC_VER
-#  define _USE_MATH_DEFINES
-#endif
 #include <math.h>
 #include <algorithm>
 
 #include <simgear/compiler.h>
 
-//#include <plib/sg.h>
-//#include <plib/ul.h>
-
-//#include <Environment/environment_mgr.hxx>
-//#include <Environment/environment.hxx>
-//#include <simgear/misc/sg_path.hxx>
-//#include <simgear/props/props.hxx>
-//#include <simgear/structure/subsystem_mgr.hxx>
 #include <simgear/debug/logstream.hxx>
 #include <simgear/misc/sgstream.hxx>
 #include <simgear/route/waypoint.hxx>
-//#include <Main/globals.hxx>
-//#include <Main/fg_props.hxx>
-//#include <Airports/runways.hxx>
-
-//#include STL_STRING
 
 #include "awynet.hxx"
 
index 4caa7141f29d271748f64fca5043c1b383f24677..31e06048dadb3ce2f47ee403a582f39b39c1e12a 100644 (file)
@@ -2,7 +2,6 @@ noinst_LIBRARIES = libScenery.a
 
 libScenery_a_SOURCES = \
        FGTileLoader.cxx FGTileLoader.hxx \
-       hitlist.cxx hitlist.hxx \
        newcache.cxx newcache.hxx \
        scenery.cxx scenery.hxx \
        tileentry.cxx tileentry.hxx \
index afeb3bb1b68fa2b455755039552c29ef9f5ca672..8d38cee61cdf9cb326b9948ccb9e21de444f6393 100644 (file)
@@ -10,7 +10,6 @@
 #include <math.h>
 
 #include <plib/sg.h>
-#include <plib/ssg.h>
 
 #include <simgear/sg_inlines.h>
 #include <simgear/debug/logstream.hxx>
index cec41f967d72d7eb924a422c51d6384092725672..3fcce64b7bd4bea535706770180b435ccd775e8e 100644 (file)
 #include <vector>
 SG_USING_STD(vector);
 
-#include <plib/ssg.h>
-
 class ssgEntity;
 class ssgBranch;
+class ssgLeaf;
 
 class FGHitRec {
 
index 066ac321f2b50a8dddad895af79ba33b8618f785..70c7c55adca4a2a00d8f8df175a788034d830b09 100644 (file)
@@ -25,8 +25,6 @@
 #  include <config.h>
 #endif
 
-#include <plib/ssg.h>          // plib include
-
 #include <simgear/bucket/newbucket.hxx>
 #include <simgear/debug/logstream.hxx>
 #include <simgear/misc/sg_path.hxx>
@@ -246,7 +244,8 @@ void FGNewCache::clear_cache() {
     }
 
     // and ... just in case we missed something ... 
-    globals->get_scenery()->get_terrain_branch()->removeAllKids();
+    osg::Group* group = globals->get_scenery()->get_terrain_branch();
+    group->removeChildren(0, group->getNumChildren());
 }
 
 
index a94ae3434d8e8d27de2ba5f72940b0b12f61f773..1f04b6c1b24d771c20b9b62d7ec4a6687f2478ba 100644 (file)
 #include <stdio.h>
 #include <string.h>
 
+#include <osgUtil/IntersectVisitor>
+
 #include <simgear/debug/logstream.hxx>
 #include <simgear/scene/tgdb/userdata.hxx>
 #include <simgear/math/sg_geodesy.hxx>
 #include <simgear/scene/model/placementtrans.hxx>
 #include <simgear/scene/material/matlib.hxx>
+#include <simgear/scene/util/SGNodeMasks.hxx>
 
 #include <Main/fg_props.hxx>
 
-#include "hitlist.hxx"
 #include "scenery.hxx"
 
 
@@ -55,33 +57,33 @@ FGScenery::~FGScenery() {
 
 void FGScenery::init() {
     // Scene graph root
-    scene_graph = new ssgRoot;
+    scene_graph = new osg::Group;
     scene_graph->setName( "Scene" );
 
     // Terrain branch
-    terrain_branch = new ssgBranch;
+    terrain_branch = new osg::Group;
     terrain_branch->setName( "Terrain" );
-    scene_graph->addKid( terrain_branch );
+    scene_graph->addChild( terrain_branch.get() );
 
-    models_branch = new ssgBranch;
+    models_branch = new osg::Group;
     models_branch->setName( "Models" );
-    scene_graph->addKid( models_branch );
+    scene_graph->addChild( models_branch.get() );
 
-    aircraft_branch = new ssgBranch;
+    aircraft_branch = new osg::Group;
     aircraft_branch->setName( "Aircraft" );
-    scene_graph->addKid( aircraft_branch );
+    scene_graph->addChild( aircraft_branch.get() );
 
     // Lighting
-    gnd_lights_root = new ssgRoot;
+    gnd_lights_root = new osg::Group;
     gnd_lights_root->setName( "Ground Lighting Root" );
 
-    vasi_lights_root = new ssgRoot;
+    vasi_lights_root = new osg::Group;
     vasi_lights_root->setName( "VASI/PAPI Lighting Root" );
 
-    rwy_lights_root = new ssgRoot;
+    rwy_lights_root = new osg::Group;
     rwy_lights_root->setName( "Runway Lighting Root" );
 
-    taxi_lights_root = new ssgRoot;
+    taxi_lights_root = new osg::Group;
     taxi_lights_root->setName( "Taxi Lighting Root" );
 
     // Initials values needed by the draw-time object loader
@@ -107,17 +109,17 @@ void FGScenery::set_center( const SGVec3d& p ) {
     center = p;
     placement_list_type::iterator it = _placement_list.begin();
     while (it != _placement_list.end()) {
-        (*it)->setSceneryCenter(center.sg());
+        (*it)->setSceneryCenter(center);
         ++it;
     }
 }
 
-void FGScenery::register_placement_transform(ssgPlacementTransform *trans) {
+void FGScenery::register_placement_transform(SGPlacementTransform *trans) {
     _placement_list.push_back(trans);        
-    trans->setSceneryCenter(center.sg());
+    trans->setSceneryCenter(center);
 }
 
-void FGScenery::unregister_placement_transform(ssgPlacementTransform *trans) {
+void FGScenery::unregister_placement_transform(SGPlacementTransform *trans) {
     placement_list_type::iterator it = _placement_list.begin();
     while (it != _placement_list.end()) {
         if ((*it) == trans) {
@@ -154,29 +156,32 @@ FGScenery::get_cart_elevation_m(const SGVec3d& pos, double max_altoff,
     }
   }
 
-  // overridden with actual values if a terrain intersection is
-  // found
-  int this_hit;
-  double hit_radius = 0.0;
-  SGVec3d hit_normal(0, 0, 0);
+
+  SGVec3d start = pos + max_altoff*normalize(pos) - center;
+  SGVec3d end = - center;
   
-  SGVec3d sc = center;
-  SGVec3d ncpos = pos;
-
-  FGHitList hit_list;
-  // scenery center has been properly defined so any hit should
-  // be valid (and not just luck)
-  bool hit = fgCurrentElev(ncpos.sg(), max_altoff+length(pos), sc.sg(),
-                           get_scene_graph(), &hit_list, &alt,
-                           &hit_radius, hit_normal.sg(), this_hit);
-
-  if (material) {
-    *material = 0;
-    if (hit) {
-      ssgEntity *entity = hit_list.get_entity( this_hit );
-      if (entity && entity->isAKindOf(ssgTypeLeaf())) {
-        ssgLeaf* leaf = static_cast<ssgLeaf*>(entity);
-        *material = globals->get_matlib()->findMaterial(leaf);
+  osgUtil::IntersectVisitor intersectVisitor;
+  intersectVisitor.setTraversalMask(SG_NODEMASK_TERRAIN_BIT);
+  osg::ref_ptr<osg::LineSegment> lineSegment;
+  lineSegment = new osg::LineSegment(start.osg(), end.osg());
+  intersectVisitor.addLineSegment(lineSegment.get());
+  get_scene_graph()->accept(intersectVisitor);
+  bool hits = intersectVisitor.hits();
+  if (hits) {
+    int nHits = intersectVisitor.getNumHits(lineSegment.get());
+    alt = -SGLimitsd::max();
+    for (int i = 0; i < nHits; ++i) {
+      const osgUtil::Hit& hit
+        = intersectVisitor.getHitList(lineSegment.get())[i];
+      SGVec3d point;
+      point.osg() = hit.getWorldIntersectPoint();
+      point += center;
+      SGGeod geod = SGGeod::fromCart(point);
+      double elevation = geod.getElevationM();
+      if (alt < elevation) {
+        alt = elevation;
+        if (material)
+          *material = globals->get_matlib()->findMaterial(hit.getGeode());
       }
     }
   }
@@ -184,7 +189,7 @@ FGScenery::get_cart_elevation_m(const SGVec3d& pos, double max_altoff,
   if (replaced_center)
     set_center( saved_center );
   
-  return hit;
+  return hits;
 }
 
 bool
@@ -207,43 +212,37 @@ FGScenery::get_cart_ground_intersection(const SGVec3d& pos, const SGVec3d& dir,
     }
   }
 
-  // Not yet found any hit ...
-  bool result = false;
-
   // Make really sure the direction is normalized, is really cheap compared to
   // computation of ground intersection.
-  SGVec3d normalizedDir = normalize(dir);
-  SGVec3d relativePos = pos - center;
-
-  // At the moment only intersection with the terrain?
-  FGHitList hit_list;
-  hit_list.Intersect(globals->get_scenery()->get_terrain_branch(),
-                     relativePos.sg(), normalizedDir.sg());
-
-  double dist = DBL_MAX;
-  int hitcount = hit_list.num_hits();
-  for (int i = 0; i < hitcount; ++i) {
-    // Check for the nearest hit
-    SGVec3d diff = SGVec3d(hit_list.get_point(i)) - relativePos;
-    
-    // We only want hits in front of us ...
-    if (dot(normalizedDir, diff) < 0)
-      continue;
-
-    // find the nearest hit
-    double nDist = dot(diff, diff);
-    if (dist < nDist)
-      continue;
-
-    // Store the hit point
-    dist = nDist;
-    nearestHit = SGVec3d(hit_list.get_point(i)) + center;
-    result = true;
+  SGVec3d start = pos - center;
+  SGVec3d end = start + 1e5*dir;
+  
+  osgUtil::IntersectVisitor intersectVisitor;
+  intersectVisitor.setTraversalMask(SG_NODEMASK_TERRAIN_BIT);
+  osg::ref_ptr<osg::LineSegment> lineSegment;
+  lineSegment = new osg::LineSegment(start.osg(), end.osg());
+  intersectVisitor.addLineSegment(lineSegment.get());
+  get_scene_graph()->accept(intersectVisitor);
+  bool hits = intersectVisitor.hits();
+  if (hits) {
+    int nHits = intersectVisitor.getNumHits(lineSegment.get());
+    double dist = SGLimitsd::max();
+    for (int i = 0; i < nHits; ++i) {
+      const osgUtil::Hit& hit
+        = intersectVisitor.getHitList(lineSegment.get())[i];
+      SGVec3d point;
+      point.osg() = hit.getWorldIntersectPoint();
+      double newdist = length(start - point);
+      if (newdist < dist) {
+        dist = newdist;
+        nearestHit = point + center;
+      }
+    }
   }
 
   if (replaced_center)
     set_center( saved_center );
 
-  return result;
+  return hits;
 }
 
index cc363871a4c9ae6be8e19e28b5b016039015abbb..282bea2afc4c3ef146086fc4ef371f7367aec3de 100644 (file)
 
 #include <list>
 
-#include <plib/sg.h>
+#include <osg/ref_ptr>
+#include <osg/Group>
 
 #include <simgear/compiler.h>
 #include <simgear/structure/subsystem_mgr.hxx>
 #include <simgear/math/point3d.hxx>
 #include <simgear/scene/model/placementtrans.hxx>
-#include <simgear/structure/ssgSharedPtr.hxx>
 
 SG_USING_STD(list);
 
-class ssgRoot;
-class ssgBranch;
 class SGMaterial;
 
 
@@ -56,17 +54,17 @@ class FGScenery : public SGSubsystem {
     double sun_angle;
 
     // SSG scene graph
-    ssgSharedPtr<ssgRoot> scene_graph;
-    ssgSharedPtr<ssgBranch> terrain_branch;
-    ssgSharedPtr<ssgRoot> gnd_lights_root;
-    ssgSharedPtr<ssgRoot> vasi_lights_root;
-    ssgSharedPtr<ssgRoot> rwy_lights_root;
-    ssgSharedPtr<ssgRoot> taxi_lights_root;
-    ssgSharedPtr<ssgBranch> models_branch;
-    ssgSharedPtr<ssgBranch> aircraft_branch;
+    osg::ref_ptr<osg::Group> scene_graph;
+    osg::ref_ptr<osg::Group> terrain_branch;
+    osg::ref_ptr<osg::Group> gnd_lights_root;
+    osg::ref_ptr<osg::Group> vasi_lights_root;
+    osg::ref_ptr<osg::Group> rwy_lights_root;
+    osg::ref_ptr<osg::Group> taxi_lights_root;
+    osg::ref_ptr<osg::Group> models_branch;
+    osg::ref_ptr<osg::Group> aircraft_branch;
 
     // list of all placement transform, used to move the scenery center on the fly.
-    typedef list<ssgSharedPtr<ssgPlacementTransform> > placement_list_type;
+    typedef list<osg::ref_ptr<SGPlacementTransform> > placement_list_type;
     placement_list_type _placement_list;
 
 public:
@@ -120,56 +118,56 @@ public:
     const SGVec3d& get_center() const { return center; }
     void set_center( const SGVec3d& p );
 
-    inline ssgRoot *get_scene_graph () const { return scene_graph; }
-    inline void set_scene_graph (ssgRoot * s) { scene_graph = s; }
+    osg::Group *get_scene_graph () const { return scene_graph.get(); }
+    inline void set_scene_graph (osg::Group * s) { scene_graph = s; }
 
-    inline ssgBranch *get_terrain_branch () const { return terrain_branch; }
-    inline void set_terrain_branch (ssgBranch * t) { terrain_branch = t; }
+    osg::Group *get_terrain_branch () const { return terrain_branch.get(); }
+    inline void set_terrain_branch (osg::Group * t) { terrain_branch = t; }
 
-    inline ssgRoot *get_gnd_lights_root () const {
-        return gnd_lights_root;
+    inline osg::Group *get_gnd_lights_root () const {
+        return gnd_lights_root.get();
     }
-    inline void set_gnd_lights_root (ssgRoot *r) {
+    inline void set_gnd_lights_root (osg::Group *r) {
         gnd_lights_root = r;
     }
 
-    inline ssgRoot *get_vasi_lights_root () const {
-        return vasi_lights_root;
+    inline osg::Group *get_vasi_lights_root () const {
+        return vasi_lights_root.get();
     }
-    inline void set_vasi_lights_root (ssgRoot *r) {
+    inline void set_vasi_lights_root (osg::Group *r) {
         vasi_lights_root = r;
     }
 
-    inline ssgRoot *get_rwy_lights_root () const {
-        return rwy_lights_root;
+    inline osg::Group *get_rwy_lights_root () const {
+        return rwy_lights_root.get();
     }
-    inline void set_rwy_lights_root (ssgRoot *r) {
+    inline void set_rwy_lights_root (osg::Group *r) {
         rwy_lights_root = r;
     }
 
-    inline ssgRoot *get_taxi_lights_root () const {
-        return taxi_lights_root;
+    inline osg::Group *get_taxi_lights_root () const {
+        return taxi_lights_root.get();
     }
-    inline void set_taxi_lights_root (ssgRoot *r) {
+    inline void set_taxi_lights_root (osg::Group *r) {
         taxi_lights_root = r;
     }
 
-    inline ssgBranch *get_models_branch () const {
-        return models_branch;
+    inline osg::Group *get_models_branch () const {
+        return models_branch.get();
     }
-    inline void set_models_branch (ssgBranch *t) {
+    inline void set_models_branch (osg::Group *t) {
         models_branch = t;
     }
 
-    inline ssgBranch *get_aircraft_branch () const {
-        return aircraft_branch;
+    inline osg::Group *get_aircraft_branch () const {
+        return aircraft_branch.get();
     }
-    inline void set_aircraft_branch (ssgBranch *t) {
+    inline void set_aircraft_branch (osg::Group *t) {
         aircraft_branch = t;
     }
 
-    void register_placement_transform(ssgPlacementTransform *trans);
-    void unregister_placement_transform(ssgPlacementTransform *trans);
+    void register_placement_transform(SGPlacementTransform *trans);
+    void unregister_placement_transform(SGPlacementTransform *trans);
 };
 
 
index 7845bd0325772897c3de8c9b744ce76399c373a7..c6dda0ceca2d4cc5b1ecbd15f62b2d65aeb449d1 100644 (file)
 
 #include STL_STRING
 
+#include <osg/Array>
+#include <osg/Geometry>
+#include <osg/Geode>
+#include <osg/LOD>
+#include <osg/MatrixTransform>
+#include <osg/NodeCallback>
+#include <osg/Switch>
+
 #include <simgear/bucket/newbucket.hxx>
 #include <simgear/debug/logstream.hxx>
 #include <simgear/math/polar3d.hxx>
@@ -42,7 +50,6 @@
 #include <simgear/scene/material/matlib.hxx>
 #include <simgear/scene/tgdb/apt_signs.hxx>
 #include <simgear/scene/tgdb/obj.hxx>
-#include <simgear/scene/tgdb/vasi.hxx>
 #include <simgear/scene/model/placementtrans.hxx>
 
 #include <Aircraft/aircraft.hxx>
@@ -63,14 +70,14 @@ SG_USING_STD(string);
 FGTileEntry::FGTileEntry ( const SGBucket& b )
     : center( Point3D( 0.0 ) ),
       tile_bucket( b ),
-      terra_transform( new ssgPlacementTransform ),
-      vasi_lights_transform( new ssgPlacementTransform ),
-      rwy_lights_transform( new ssgPlacementTransform ),
-      taxi_lights_transform( new ssgPlacementTransform ),
-      terra_range( new ssgRangeSelector ),
-      vasi_lights_selector( new ssgSelector ),
-      rwy_lights_selector( new ssgSelector ),
-      taxi_lights_selector( new ssgSelector ),
+      terra_transform( new SGPlacementTransform ),
+      vasi_lights_transform( new SGPlacementTransform ),
+      rwy_lights_transform( new SGPlacementTransform ),
+      taxi_lights_transform( new SGPlacementTransform ),
+      terra_range( new osg::LOD ),
+      vasi_lights_selector( new osg::Switch ),
+      rwy_lights_selector( new osg::Switch ),
+      taxi_lights_selector( new osg::Switch ),
       loaded(false),
       pending_models(0),
       is_inner_ring(false),
@@ -92,47 +99,7 @@ FGTileEntry::~FGTileEntry () {
     // delete[] nodes;
 }
 
-
-#if 0
-// Please keep this for reference.  We use Norman's optimized routine,
-// but here is what the routine really is doing.
-void
-FGTileEntry::WorldCoordinate( sgCoord *obj_pos, Point3D center,
-                              double lat, double lon, double elev, double hdg)
-{
-    // setup transforms
-    Point3D geod( lon * SGD_DEGREES_TO_RADIANS,
-                  lat * SGD_DEGREES_TO_RADIANS,
-                  elev );
-        
-    Point3D world_pos = sgGeodToCart( geod );
-    Point3D offset = world_pos - center;
-        
-    sgMat4 POS;
-    sgMakeTransMat4( POS, offset.x(), offset.y(), offset.z() );
-
-    sgVec3 obj_rt, obj_up;
-    sgSetVec3( obj_rt, 0.0, 1.0, 0.0); // Y axis
-    sgSetVec3( obj_up, 0.0, 0.0, 1.0); // Z axis
-
-    sgMat4 ROT_lon, ROT_lat, ROT_hdg;
-    sgMakeRotMat4( ROT_lon, lon, obj_up );
-    sgMakeRotMat4( ROT_lat, 90 - lat, obj_rt );
-    sgMakeRotMat4( ROT_hdg, hdg, obj_up );
-
-    sgMat4 TUX;
-    sgCopyMat4( TUX, ROT_hdg );
-    sgPostMultMat4( TUX, ROT_lat );
-    sgPostMultMat4( TUX, ROT_lon );
-    sgPostMultMat4( TUX, POS );
-
-    sgSetCoord( obj_pos, TUX );
-}
-#endif
-
-
-// Norman's 'fast hack' for above
-static void WorldCoordinate( sgCoord *obj_pos, Point3D center, double lat,
+static void WorldCoordinate( osg::Matrix& obj_pos, Point3D center, double lat,
                              double lon, double elev, double hdg )
 {
     double lon_rad = lon * SGD_DEGREES_TO_RADIANS;
@@ -174,63 +141,57 @@ static void WorldCoordinate( sgCoord *obj_pos, Point3D center, double lat,
     mat[3][2] = offset.z();
     mat[3][3] = SG_ONE ;
 
-    sgSetCoord( obj_pos, mat );
+    for (unsigned i = 0; i < 4; ++i)
+      for (unsigned j = 0; j < 4; ++j)
+        obj_pos(i, j) = mat[i][j];
 }
 
 
-// recurse an ssg tree and call removeKid() on every node from the
+// recurse an ssg tree and call removeChild() on every node from the
 // bottom up.  Leaves the original branch in existance, but empty so
 // it can be removed by the calling routine.
-static void my_remove_branch( ssgBranch * branch ) {
-    for ( ssgEntity *k = branch->getKid( 0 );
-          k != NULL; 
-          k = branch->getNextKid() )
-    {
-        if ( k -> isAKindOf ( ssgTypeBranch() ) ) {
-            my_remove_branch( (ssgBranch *)k );
-            branch -> removeKid ( k );
-        } else if ( k -> isAKindOf ( ssgTypeLeaf() ) ) {
-            branch -> removeKid ( k ) ;
-        }
-    }
-}
+// static void my_remove_branch( osg::Group * branch ) {
+//     branch->removeChildren(0, branch->getNumChildren());
+// }
 
 
 // Free "n" leaf elements of an ssg tree.  returns the number of
 // elements freed.  An empty branch node is considered a leaf.  This
 // is intended to spread the load of freeing a complex tile out over
 // several frames.
-static int fgPartialFreeSSGtree( ssgBranch *b, int n ) {
+static int fgPartialFreeSSGtree( osg::Group *b, int n ) {
     int num_deletes = 0;
 
-    if ( n > 0 ) {
-        // we still have some delete budget left
-        // if ( b->getNumKids() > 100 ) {
-        //     cout << "large family = " << b->getNumKids() << endl;
-        // }
-        // deleting in reverse would help if my plib patch get's
-        // applied, but for now it will make things slower.
-        // for ( int i = b->getNumKids() - 1; i >= 0 ; --i ) {
-        for ( int i = 0; i < b->getNumKids(); ++i ) {
-            ssgEntity *kid = b->getKid(i);
-            if ( kid->isAKindOf( ssgTypeBranch() ) && kid->getRef() <= 1 ) {
-                int result = fgPartialFreeSSGtree( (ssgBranch *)kid, n );
-                num_deletes += result;
-                n -= result;
-                if ( n < 0 ) {
-                    break;
-                }
-            }
-            // remove the kid if (a) it is now empty -or- (b) it's ref
-            // count is > zero at which point we don't care if it's
-            // empty, we don't want to touch it's contents.
-            if ( kid->getNumKids() == 0 || kid->getRef() > 1 ) {
-                b->removeKid( kid );
-                num_deletes++;
-                n--;
-            }
-        }
-    }
+    b->removeChildren(0, b->getNumChildren());
+
+//     if ( n > 0 ) {
+//         // we still have some delete budget left
+//         // if ( b->getNumChilds() > 100 ) {
+//         //     cout << "large family = " << b->getNumChilds() << endl;
+//         // }
+//         // deleting in reverse would help if my plib patch get's
+//         // applied, but for now it will make things slower.
+//         // for ( int i = b->getNumChilds() - 1; i >= 0 ; --i ) {
+//         for ( int i = 0; i < b->getNumChildren(); ++i ) {
+//             ssgEntity *kid = b->getChild(i);
+//             if ( kid->isAKindOf( ssgTypeBranch() ) && kid->getRef() <= 1 ) {
+//                 int result = fgPartialFreeSSGtree( (osg::Group *)kid, n );
+//                 num_deletes += result;
+//                 n -= result;
+//                 if ( n < 0 ) {
+//                     break;
+//                 }
+//             }
+//             // remove the kid if (a) it is now empty -or- (b) it's ref
+//             // count is > zero at which point we don't care if it's
+//             // empty, we don't want to touch it's contents.
+//             if ( kid->getNumChildren() == 0 || kid->getRef() > 1 ) {
+//                 b->removeChild( kid );
+//                 num_deletes++;
+//                 n--;
+//             }
+//         }
+//     }
 
     return num_deletes;
 }
@@ -253,39 +214,39 @@ bool FGTileEntry::free_tile() {
         // delete the terrain branch (this should already have been
         // disconnected from the scene graph)
         SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING terra_transform" );
-        if ( fgPartialFreeSSGtree( terra_transform, delete_size ) == 0 ) {
+        if ( fgPartialFreeSSGtree( terra_transform.get(), delete_size ) == 0 ) {
             terra_transform = 0;
             free_tracker |= TERRA_NODE;
         }
-    } else if ( !(free_tracker & GROUND_LIGHTS) && gnd_lights_transform ) {
+    } else if ( !(free_tracker & GROUND_LIGHTS) && gnd_lights_transform.get() ) {
         // delete the terrain lighting branch (this should already have been
         // disconnected from the scene graph)
         SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING gnd_lights_transform" );
-        if ( fgPartialFreeSSGtree( gnd_lights_transform, delete_size ) == 0 ) {
+        if ( fgPartialFreeSSGtree( gnd_lights_transform.get(), delete_size ) == 0 ) {
             gnd_lights_transform = 0;
             free_tracker |= GROUND_LIGHTS;
         }
-    } else if ( !(free_tracker & VASI_LIGHTS) && vasi_lights_selector ) {
+    } else if ( !(free_tracker & VASI_LIGHTS) && vasi_lights_selector.get() ) {
         // delete the runway lighting branch (this should already have
         // been disconnected from the scene graph)
         SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING vasi_lights_selector" );
-        if ( fgPartialFreeSSGtree( vasi_lights_selector, delete_size ) == 0 ) {
+        if ( fgPartialFreeSSGtree( vasi_lights_selector.get(), delete_size ) == 0 ) {
             vasi_lights_selector = 0;
             free_tracker |= VASI_LIGHTS;
         }
-    } else if ( !(free_tracker & RWY_LIGHTS) && rwy_lights_selector ) {
+    } else if ( !(free_tracker & RWY_LIGHTS) && rwy_lights_selector.get() ) {
         // delete the runway lighting branch (this should already have
         // been disconnected from the scene graph)
         SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING rwy_lights_selector" );
-        if ( fgPartialFreeSSGtree( rwy_lights_selector, delete_size ) == 0 ) {
+        if ( fgPartialFreeSSGtree( rwy_lights_selector.get(), delete_size ) == 0 ) {
             rwy_lights_selector = 0;
             free_tracker |= RWY_LIGHTS;
         }
-    } else if ( !(free_tracker & TAXI_LIGHTS) && taxi_lights_selector ) {
+    } else if ( !(free_tracker & TAXI_LIGHTS) && taxi_lights_selector.get() ) {
         // delete the taxi lighting branch (this should already have been
         // disconnected from the scene graph)
         SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING taxi_lights_selector" );
-        if ( fgPartialFreeSSGtree( taxi_lights_selector, delete_size ) == 0 ) {
+        if ( fgPartialFreeSSGtree( taxi_lights_selector.get(), delete_size ) == 0 ) {
             taxi_lights_selector = 0;
             free_tracker |= TAXI_LIGHTS;
         }
@@ -309,19 +270,16 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) {
 
     // visibility can change from frame to frame so we update the
     // range selector cutoff's each time.
-    terra_range->setRange( 0, SG_ZERO );
-    terra_range->setRange( 1, vis + bounding_radius );
+    terra_range->setRange( 0, 0, vis + bounding_radius );
 
-    if ( gnd_lights_range ) {
-        gnd_lights_range->setRange( 0, SG_ZERO );
-        gnd_lights_range->setRange( 1, vis * 1.5 + bounding_radius );
+    if ( gnd_lights_range.get() ) {
+        gnd_lights_range->setRange( 0, 0, vis * 1.5 + bounding_radius );
     }
 
-    sgdVec3 sgdTrans;
-    sgdSetVec3( sgdTrans, center.x(), center.y(), center.z() );
+    SGVec3d lt_trans(center.x(), center.y(), center.z());
 
     FGLight *l = (FGLight *)(globals->get_subsystem("lighting"));
-    if ( gnd_lights_transform ) {
+    if ( gnd_lights_transform.get() ) {
         // we need to lift the lights above the terrain to avoid
         // z-buffer fighting.  We do this based on our altitude and
         // the distance this tile is away from scenery center.
@@ -329,9 +287,8 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) {
         // we expect 'up' to be a unit vector coming in, but since we
         // modify the value of lift_vec, we need to create a local
         // copy.
-        sgVec3 lift_vec;
-        sgCopyVec3( lift_vec, up );
-
+        SGVec3f lift_vec(up);
+  
         double agl;
         agl = globals->get_current_view()->getAltitudeASL_ft()*SG_FEET_TO_METER
           - globals->get_current_view()->getSGLocation()->get_cur_elev_m();
@@ -340,38 +297,31 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) {
         double dist = center.distance3D(p);
 
         if ( general.get_glDepthBits() > 16 ) {
-            sgScaleVec3( lift_vec, 10.0 + agl / 100.0 + dist / 10000 );
+            lift_vec *= 10.0 + agl / 100.0 + dist / 10000;
         } else {
-            sgScaleVec3( lift_vec, 10.0 + agl / 20.0 + dist / 5000 );
+            lift_vec *= 10.0 + agl / 20.0 + dist / 5000;
         }
 
-        sgdVec3 dlt_trans;
-        sgdCopyVec3( dlt_trans, sgdTrans );
-        sgdVec3 dlift_vec;
-        sgdSetVec3( dlift_vec, lift_vec );
-        sgdAddVec3( dlt_trans, dlift_vec );
-        gnd_lights_transform->setTransform( dlt_trans );
+        gnd_lights_transform->setTransform( lt_trans + toVec3d(lift_vec) );
 
         // select which set of lights based on sun angle
         float sun_angle = l->get_sun_angle() * SGD_RADIANS_TO_DEGREES;
         if ( sun_angle > 95 ) {
-            gnd_lights_brightness->select(0x04);
+            gnd_lights_brightness->setSingleChildOn(2);
         } else if ( sun_angle > 92 ) {
-            gnd_lights_brightness->select(0x02);
+            gnd_lights_brightness->setSingleChildOn(1);
         } else if ( sun_angle > 89 ) {
-            gnd_lights_brightness->select(0x01);
+            gnd_lights_brightness->setSingleChildOn(0);
         } else {
-            gnd_lights_brightness->select(0x00);
+            gnd_lights_brightness->setAllChildrenOff();
         }
     }
 
-    if ( vasi_lights_transform ) {
+    if ( vasi_lights_transform.get() ) {
         // we need to lift the lights above the terrain to avoid
         // z-buffer fighting.  We do this based on our altitude and
         // the distance this tile is away from scenery center.
-
-        sgVec3 lift_vec;
-        sgCopyVec3( lift_vec, up );
+        SGVec3f lift_vec(up);
 
         // we fudge agl by 30 meters so that the lifting function
         // doesn't phase in until we are > 30m agl.
@@ -384,29 +334,22 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) {
         }
         
         if ( general.get_glDepthBits() > 16 ) {
-            sgScaleVec3( lift_vec, 0.25 + agl / 400.0 + agl*agl / 5000000.0 );
+            lift_vec *= 0.25 + agl / 400.0 + agl*agl / 5000000.0;
         } else {
-            sgScaleVec3( lift_vec, 0.25 + agl / 150.0 );
+            lift_vec *= 0.25 + agl / 150.0;
         }
 
-        sgdVec3 dlt_trans;
-        sgdCopyVec3( dlt_trans, sgdTrans );
-        sgdVec3 dlift_vec;
-        sgdSetVec3( dlift_vec, lift_vec );
-        sgdAddVec3( dlt_trans, dlift_vec );
-        vasi_lights_transform->setTransform( dlt_trans );
+        vasi_lights_transform->setTransform( lt_trans + toVec3d(lift_vec) );
 
         // generally, vasi lights are always on
-        vasi_lights_selector->select(0x01);
+        vasi_lights_selector->setAllChildrenOn();
     }
 
-    if ( rwy_lights_transform ) {
+    if ( rwy_lights_transform.get() ) {
         // we need to lift the lights above the terrain to avoid
         // z-buffer fighting.  We do this based on our altitude and
         // the distance this tile is away from scenery center.
-
-        sgVec3 lift_vec;
-        sgCopyVec3( lift_vec, up );
+        SGVec3f lift_vec(up);
 
         // we fudge agl by 30 meters so that the lifting function
         // doesn't phase in until we are > 30m agl.
@@ -419,35 +362,28 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) {
         }
         
         if ( general.get_glDepthBits() > 16 ) {
-            sgScaleVec3( lift_vec, 0.01 + agl / 400.0 + agl*agl / 5000000.0 );
+            lift_vec *= 0.01 + agl / 400.0 + agl*agl / 5000000.0;
         } else {
-            sgScaleVec3( lift_vec, 0.25 + agl / 150.0 );
+            lift_vec *= 0.25 + agl / 150.0;
         }
 
-        sgdVec3 dlt_trans;
-        sgdCopyVec3( dlt_trans, sgdTrans );
-        sgdVec3 dlift_vec;
-        sgdSetVec3( dlift_vec, lift_vec );
-        sgdAddVec3( dlt_trans, dlift_vec );
-        rwy_lights_transform->setTransform( dlt_trans );
+        rwy_lights_transform->setTransform( lt_trans + toVec3d(lift_vec) );
 
         // turn runway lights on/off based on sun angle and visibility
         float sun_angle = l->get_sun_angle() * SGD_RADIANS_TO_DEGREES;
         if ( sun_angle > 85 ||
              (fgGetDouble("/environment/visibility-m") < 5000.0) ) {
-            rwy_lights_selector->select(0x01);
+            rwy_lights_selector->setAllChildrenOn();
         } else {
-            rwy_lights_selector->select(0x00);
+            rwy_lights_selector->setAllChildrenOff();
         }
     }
 
-    if ( taxi_lights_transform ) {
+    if ( taxi_lights_transform.get() ) {
         // we need to lift the lights above the terrain to avoid
         // z-buffer fighting.  We do this based on our altitude and
         // the distance this tile is away from scenery center.
-
-        sgVec3 lift_vec;
-        sgCopyVec3( lift_vec, up );
+        SGVec3f lift_vec(up);
 
         // we fudge agl by 30 meters so that the lifting function
         // doesn't phase in until we are > 30m agl.
@@ -460,172 +396,90 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) {
         }
         
         if ( general.get_glDepthBits() > 16 ) {
-            sgScaleVec3( lift_vec, 0.01 + agl / 400.0 + agl*agl / 5000000.0 );
+            lift_vec *= 0.01 + agl / 400.0 + agl*agl / 5000000.0;
         } else {
-            sgScaleVec3( lift_vec, 0.25 + agl / 150.0 );
+            lift_vec *= 0.25 + agl / 150.0;
         }
 
-        sgdVec3 dlt_trans;
-        sgdCopyVec3( dlt_trans, sgdTrans );
-        sgdVec3 dlift_vec;
-        sgdSetVec3( dlift_vec, lift_vec );
-        sgdAddVec3( dlt_trans, dlift_vec );
-        taxi_lights_transform->setTransform( dlt_trans );
+        taxi_lights_transform->setTransform( lt_trans + toVec3d(lift_vec) );
 
         // turn taxi lights on/off based on sun angle and visibility
         float sun_angle = l->get_sun_angle() * SGD_RADIANS_TO_DEGREES;
         if ( sun_angle > 85 ||
              (fgGetDouble("/environment/visibility-m") < 5000.0) ) {
-            taxi_lights_selector->select(0x01);
+            taxi_lights_selector->setAllChildrenOn();
         } else {
-            taxi_lights_selector->select(0x00);
-        }
-    }
-
-    if ( vasi_lights_transform && is_inner_ring ) {
-        // now we need to traverse the list of vasi lights and update
-        // their coloring (but only for the inner ring, no point in
-        // doing this extra work for tiles that are relatively far
-        // away.)
-        for ( int i = 0; i < vasi_lights_transform->getNumKids(); ++i ) {
-            // cout << "vasi root = " << i << endl;
-            ssgBranch *v = (ssgBranch *)vasi_lights_transform->getKid(i);
-            for ( int j = 0; j < v->getNumKids(); ++j ) {
-                // cout << "  vasi branch = " << j << endl;
-                ssgTransform *kid = (ssgTransform *)v->getKid(j);
-                SGVASIUserData *vasi = (SGVASIUserData *)kid->getUserData();
-
-                if ( vasi != NULL ) {
-                    sgdVec3 s;
-                    sgdCopyVec3( s, vasi->get_abs_pos() );
-                    Point3D start(s[0], s[1], s[2]);
-
-                    sgdVec3 d;
-                    sgdCopyVec3( d, globals->get_current_view()->get_absolute_view_pos() );
-
-                    double dist = sgdDistanceVec3( s, d );
-
-                    if ( dist < 10000 ) {
-                        double cur_alt
-                            = globals->get_current_view()->getAltitudeASL_ft()
-                            * SG_FEET_TO_METER;
-
-                        double y = cur_alt - vasi->get_alt_m();
-
-                        double angle;
-                        if ( dist != 0 ) {
-                            angle = asin( y / dist );
-                        } else {
-                            angle = 0.0;
-                        }
-
-                        vasi->set_color(angle * SG_RADIANS_TO_DEGREES);
-                    }
-                    // cout << "    dist = " << dist
-                    //      << " angle = " << angle * SG_RADIANS_TO_DEGREES
-                    //      << endl;
-                } else {
-                    SG_LOG( SG_TERRAIN, SG_ALERT, "no vasi data!" );
-                }
-            }
+            taxi_lights_selector->setAllChildrenOff();
         }
     }
 }
 
 
-// Set up lights rendering call backs
-static int fgLightsPredraw( ssgEntity *e ) {
-#if 0
-    if (glPointParameterIsSupported) {
-        static float quadratic[3] = {1.0, 0.01, 0.0001};
-        glPointParameterfvProc(GL_DISTANCE_ATTENUATION_EXT, quadratic);
-        glPointParameterfProc(GL_POINT_SIZE_MIN_EXT, 1.0); 
-        glPointSize(4.0);
-    }
-#endif
-    return true;
-}
-
-static int fgLightsPostdraw( ssgEntity *e ) {
-#if 0
-    if (glPointParameterIsSupported) {
-        static float default_attenuation[3] = {1.0, 0.0, 0.0};
-        glPointParameterfvProc(GL_DISTANCE_ATTENUATION_EXT,
-                              default_attenuation);
-        glPointSize(1.0);
-    }
-#endif
-    return true;
-}
-
-
-ssgLeaf* FGTileEntry::gen_lights( SGMaterialLib *matlib, ssgVertexArray *lights,
-                                  int inc, float bright )
+osg::Node*
+FGTileEntry::gen_lights( SGMaterialLib *matlib, osg::Vec3Array *lights,
+                         int inc, float bright )
 {
     // generate a repeatable random seed
-    float *p1 = lights->get( 0 );
-    unsigned int *seed = (unsigned int *)p1;
-    sg_srandom( *seed );
-
-    int size = lights->getNum() / inc;
+    sg_srandom( (unsigned)(*lights)[0][0] );
 
     // Allocate ssg structure
-    ssgVertexArray   *vl = new ssgVertexArray( size + 1 );
-    ssgNormalArray   *nl = NULL;
-    ssgTexCoordArray *tl = NULL;
-    ssgColourArray   *cl = new ssgColourArray( size + 1 );
+    osg::Vec3Array *vl = new osg::Vec3Array;
+    osg::Vec4Array *cl = new osg::Vec4Array;
 
-    sgVec4 color;
-    for ( int i = 0; i < lights->getNum(); ++i ) {
+    for ( unsigned i = 0; i < lights->size(); ++i ) {
         // this loop is slightly less efficient than it otherwise
         // could be, but we want a red light to always be red, and a
         // yellow light to always be yellow, etc. so we are trying to
         // preserve the random sequence.
         float zombie = sg_random();
         if ( i % inc == 0 ) {
-            vl->add( lights->get(i) );
+            vl->push_back( (*lights)[i] );
 
             // factor = sg_random() ^ 2, range = 0 .. 1 concentrated towards 0
             float factor = sg_random();
             factor *= factor;
 
+            osg::Vec4 color;
             if ( zombie > 0.5 ) {
                 // 50% chance of yellowish
-                sgSetVec4( color, 0.9, 0.9, 0.3, bright - factor * 0.2 );
+                color = osg::Vec4( 0.9, 0.9, 0.3, bright - factor * 0.2 );
             } else if ( zombie > 0.15 ) {
                 // 35% chance of whitish
-                sgSetVec4( color, 0.9, 0.9, 0.8, bright - factor * 0.2 );
+                color = osg::Vec4( 0.9, 0.9, 0.8, bright - factor * 0.2 );
             } else if ( zombie > 0.05 ) {
                 // 10% chance of orangish
-                sgSetVec4( color, 0.9, 0.6, 0.2, bright - factor * 0.2 );
+                color = osg::Vec4( 0.9, 0.6, 0.2, bright - factor * 0.2 );
             } else {
                 // 5% chance of redish
-                sgSetVec4( color, 0.9, 0.2, 0.2, bright - factor * 0.2 );
+                color = osg::Vec4( 0.9, 0.2, 0.2, bright - factor * 0.2 );
             }
-            cl->add( color );
+            cl->push_back( color );
         }
     }
 
     // create ssg leaf
-    ssgLeaf *leaf = 
-        new ssgVtxTable ( GL_POINTS, vl, nl, tl, cl );
+    osg::Geometry* geometry = new osg::Geometry;
+    geometry->setVertexArray(vl);
+    geometry->setColorArray(cl);
+    geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
+    geometry->addPrimitiveSet(new osg::DrawArrays(GL_POINTS, 0, vl->size()));
+    osg::Geode* geode = new osg::Geode;
+    geode->addDrawable(geometry);
 
     // assign state
     SGMaterial *mat = matlib->find( "GROUND_LIGHTS" );
-    leaf->setState( mat->get_state() );
-    leaf->setCallback( SSG_CALLBACK_PREDRAW, fgLightsPredraw );
-    leaf->setCallback( SSG_CALLBACK_POSTDRAW, fgLightsPostdraw );
+    geode->setStateSet(mat->get_state());
 
-    return leaf;
+    return geode;
 }
 
 
 bool FGTileEntry::obj_load( const string& path,
-                            ssgBranch *geometry,
-                            ssgBranch *vasi_lights,
-                            ssgBranch *rwy_lights,
-                            ssgBranch *taxi_lights,
-                            ssgVertexArray *ground_lights, bool is_base )
+                            osg::Group *geometry,
+                            osg::Group *vasi_lights,
+                            osg::Group *rwy_lights,
+                            osg::Group *taxi_lights,
+                            osg::Vec3Array *ground_lights, bool is_base )
 {
     Point3D c;                  // returned center point
     double br;                  // returned bounding radius
@@ -634,7 +488,7 @@ bool FGTileEntry::obj_load( const string& path,
         fgGetBool("/sim/rendering/random-objects", true);
 
     // try loading binary format
-    if ( sgBinObjLoad( path, is_base,
+    if ( SGBinObjLoad( path, is_base,
                        &c, &br, globals->get_matlib(), use_random_objects,
                        geometry, vasi_lights, rwy_lights, taxi_lights,
                        ground_lights ) )
@@ -782,32 +636,29 @@ FGTileEntry::load( const string_list &path_list, bool is_base )
 
 
     // obj_load() will generate ground lighting for us ...
-    ssgVertexArray *light_pts = new ssgVertexArray( 100 );
-    ssgBranch* new_tile = new ssgBranch;
+    osg::ref_ptr<osg::Vec3Array> light_pts = new osg::Vec3Array;
+    osg::Group* new_tile = new osg::Group;
 
 
     if (found_tile_base) {
         // load tile if found ...
-        ssgSharedPtr<ssgBranch> geometry = new ssgBranch;
-        if ( obj_load( object_base.str(), geometry,
-                       NULL, NULL, NULL, light_pts, true ) ) {
-            geometry->getKid( 0 )->setTravCallback(SSG_CALLBACK_PRETRAV,
-                    &FGTileMgr::tile_filter_cb);
-
-            new_tile -> addKid( geometry );
+        osg::ref_ptr<osg::Group> geometry = new osg::Group;
+        if ( obj_load( object_base.str(), geometry.get(),
+                       NULL, NULL, NULL, light_pts.get(), true ) ) {
+            new_tile -> addChild( geometry.get() );
         }
 
     } else {
         // ... or generate an ocean tile on the fly
         SG_LOG(SG_TERRAIN, SG_INFO, "  Generating ocean tile");
-        ssgSharedPtr<ssgBranch> geometry = new ssgBranch;
+        osg::ref_ptr<osg::Group> geometry = new osg::Group;
         Point3D c;
         double br;
-        if ( sgGenTile( path_list[0], tile_bucket, &c, &br,
-                        globals->get_matlib(), geometry ) ) {
+        if ( SGGenTile( path_list[0], tile_bucket, &c, &br,
+                        globals->get_matlib(), geometry.get() ) ) {
             center = c;
             bounding_radius = br;
-            new_tile -> addKid( geometry );
+            new_tile -> addChild( geometry.get() );
         } else {
             SG_LOG( SG_TERRAIN, SG_ALERT,
                     "Warning: failed to generate ocean tile!" );
@@ -823,30 +674,27 @@ FGTileEntry::load( const string_list &path_list, bool is_base )
             SGPath custom_path = obj->path;
             custom_path.append( obj->name );
 
-            ssgSharedPtr<ssgBranch> geometry = new ssgBranch;
-            ssgSharedPtr<ssgBranch> vasi_lights = new ssgBranch;
-            ssgSharedPtr<ssgBranch> rwy_lights = new ssgBranch;
-            ssgSharedPtr<ssgBranch> taxi_lights = new ssgBranch;
+            osg::ref_ptr<osg::Group> geometry = new osg::Group;
+            osg::ref_ptr<osg::Group> vasi_lights = new osg::Group;
+            osg::ref_ptr<osg::Group> rwy_lights = new osg::Group;
+            osg::ref_ptr<osg::Group> taxi_lights = new osg::Group;
 
             if ( obj_load( custom_path.str(),
-                           geometry, vasi_lights, rwy_lights,
-                           taxi_lights, NULL, false ) ) {
-
-                if ( geometry -> getNumKids() > 0 ) {
-                    geometry->getKid( 0 )->setTravCallback(
-                                                SSG_CALLBACK_PRETRAV,
-                                                &FGTileMgr::tile_filter_cb );
-                    new_tile -> addKid( geometry );
+                           geometry.get(), vasi_lights.get(), rwy_lights.get(),
+                           taxi_lights.get(), NULL, false ) ) {
+
+                if ( geometry -> getNumChildren() > 0 ) {
+                    new_tile -> addChild( geometry.get() );
                 }
 
-                if ( vasi_lights -> getNumKids() > 0 )
-                    vasi_lights_transform -> addKid( vasi_lights );
+                if ( vasi_lights -> getNumChildren() > 0 )
+                    vasi_lights_transform -> addChild( vasi_lights.get() );
 
-                if ( rwy_lights -> getNumKids() > 0 )
-                    rwy_lights_transform -> addKid( rwy_lights );
+                if ( rwy_lights -> getNumChildren() > 0 )
+                    rwy_lights_transform -> addChild( rwy_lights.get() );
 
-                if ( taxi_lights -> getNumKids() > 0 )
-                    taxi_lights_transform -> addKid( taxi_lights );
+                if ( taxi_lights -> getNumChildren() > 0 )
+                    taxi_lights_transform -> addChild( taxi_lights.get() );
             }
 
 
@@ -861,14 +709,14 @@ FGTileEntry::load( const string_list &path_list, bool is_base )
             }
             custom_path.append( obj->name );
 
-            sgCoord obj_pos;
-            WorldCoordinate( &obj_pos, center, obj->lat, obj->lon, obj->elev, obj->hdg );
+            osg::Matrix obj_pos;
+            WorldCoordinate( obj_pos, center, obj->lat, obj->lon, obj->elev, obj->hdg );
 
-            ssgTransform *obj_trans = new ssgTransform;
-            obj_trans->setTransform( &obj_pos );
+            osg::MatrixTransform *obj_trans = new osg::MatrixTransform;
+            obj_trans->setMatrix( obj_pos );
 
             // wire as much of the scene graph together as we can
-            new_tile->addKid( obj_trans );
+            new_tile->addChild( obj_trans );
             pending_models++;
 
             // push an entry onto the model load queue
@@ -882,27 +730,27 @@ FGTileEntry::load( const string_list &path_list, bool is_base )
 
 
         } else if (obj->type == OBJECT_SIGN || obj->type == OBJECT_RUNWAY_SIGN) {
-            ssgBranch *(*make_sign)(SGMaterialLib *, const string, const string);
-            make_sign = obj->type == OBJECT_SIGN ? sgMakeSign : sgMakeRunwaySign;
-
             // load the object itself
             SGPath custom_path = obj->path;
             custom_path.append( obj->name );
 
-            sgCoord obj_pos;
-            WorldCoordinate( &obj_pos, center, obj->lat, obj->lon, obj->elev, obj->hdg );
+            osg::Matrix obj_pos;
+            WorldCoordinate( obj_pos, center, obj->lat, obj->lon, obj->elev, obj->hdg );
 
-            ssgTransform *obj_trans = new ssgTransform;
-            obj_trans->setTransform( &obj_pos );
+            osg::MatrixTransform *obj_trans = new osg::MatrixTransform;
+            obj_trans->setMatrix( obj_pos );
 
-            ssgBranch *custom_obj
-                = (*make_sign)(globals->get_matlib(), custom_path.str(), obj->name);
+            osg::Node *custom_obj = 0;
+            if (obj->type == OBJECT_SIGN)
+                custom_obj = SGMakeSign(globals->get_matlib(), custom_path.str(), obj->name);
+            else
+                custom_obj = SGMakeRunwaySign(globals->get_matlib(), custom_path.str(), obj->name);
 
             // wire the pieces together
             if ( custom_obj != NULL ) {
-                obj_trans -> addKid( custom_obj );
+                obj_trans -> addChild( custom_obj );
             }
-            new_tile->addKid( obj_trans );
+            new_tile->addChild( obj_trans );
 
         }
         delete obj;
@@ -910,125 +758,102 @@ FGTileEntry::load( const string_list &path_list, bool is_base )
 
 
     if ( new_tile != NULL ) {
-        terra_range->addKid( new_tile );
+        terra_range->addChild( new_tile );
     }
 
-    terra_transform->addKid( terra_range );
+    terra_transform->addChild( terra_range.get() );
 
     // calculate initial tile offset
-    sgdVec3 sgdTrans;
-    sgdSetVec3( sgdTrans, center.x(), center.y(), center.z() );
+    SGVec3d sgdTrans(center.x(), center.y(), center.z());
     terra_transform->setTransform( sgdTrans );
 
     // Add ground lights to scene graph if any exist
     gnd_lights_transform = NULL;
     gnd_lights_range = NULL;
-    if ( light_pts->getNum() ) {
+    if ( light_pts->size() ) {
         SG_LOG( SG_TERRAIN, SG_DEBUG, "generating lights" );
-        gnd_lights_transform = new ssgPlacementTransform;
-        gnd_lights_range = new ssgRangeSelector;
-        gnd_lights_brightness = new ssgSelector;
-        ssgLeaf *lights;
+        gnd_lights_transform = new SGPlacementTransform;
+        gnd_lights_range = new osg::LOD;
+        gnd_lights_brightness = new osg::Switch;
+        osg::Node *lights;
 
-        lights = gen_lights( globals->get_matlib(), light_pts, 4, 0.7 );
-        gnd_lights_brightness->addKid( lights );
+        lights = gen_lights( globals->get_matlib(), light_pts.get(), 4, 0.7 );
+        gnd_lights_brightness->addChild( lights );
 
-        lights = gen_lights( globals->get_matlib(), light_pts, 2, 0.85 );
-        gnd_lights_brightness->addKid( lights );
+        lights = gen_lights( globals->get_matlib(), light_pts.get(), 2, 0.85 );
+        gnd_lights_brightness->addChild( lights );
 
-        lights = gen_lights( globals->get_matlib(), light_pts, 1, 1.0 );
-        gnd_lights_brightness->addKid( lights );
+        lights = gen_lights( globals->get_matlib(), light_pts.get(), 1, 1.0 );
+        gnd_lights_brightness->addChild( lights );
 
-        gnd_lights_range->addKid( gnd_lights_brightness );
-        gnd_lights_transform->addKid( gnd_lights_range );
+        gnd_lights_range->addChild( gnd_lights_brightness.get() );
+        gnd_lights_transform->addChild( gnd_lights_range.get() );
         gnd_lights_transform->setTransform( sgdTrans );
     }
 
     // Update vasi lights transform
-    if ( vasi_lights_transform->getNumKids() > 0 ) {
+    if ( vasi_lights_transform->getNumChildren() > 0 ) {
         vasi_lights_transform->setTransform( sgdTrans );
     }
 
     // Update runway lights transform
-    if ( rwy_lights_transform->getNumKids() > 0 ) {
+    if ( rwy_lights_transform->getNumChildren() > 0 ) {
         rwy_lights_transform->setTransform( sgdTrans );
     }
 
      // Update taxi lights transform
-    if ( taxi_lights_transform->getNumKids() > 0 ) {
+    if ( taxi_lights_transform->getNumChildren() > 0 ) {
         taxi_lights_transform->setTransform( sgdTrans );
     }
-
-    delete light_pts;
-}
-
-void
-FGTileEntry::makeDList( ssgBranch *b )
-{
-    int nb = b->getNumKids();
-    for (int i = 0; i<nb; i++) {
-        ssgEntity *e = b->getKid(i);
-        if (e->isAKindOf(ssgTypeLeaf())) {
-            ((ssgLeaf*)e)->makeDList();
-        } else if (e->isAKindOf(ssgTypeBranch())) {
-            makeDList( (ssgBranch*)e );
-        }
-    }
 }
 
 void
-FGTileEntry::add_ssg_nodes( ssgBranch *terrain_branch,
-                            ssgBranch *gnd_lights_branch,
-                            ssgBranch *vasi_lights_branch,
-                            ssgBranch *rwy_lights_branch,
-                            ssgBranch *taxi_lights_branch )
+FGTileEntry::add_ssg_nodes( osg::Group *terrain_branch,
+                            osg::Group *gnd_lights_branch,
+                            osg::Group *vasi_lights_branch,
+                            osg::Group *rwy_lights_branch,
+                            osg::Group *taxi_lights_branch )
 {
     // bump up the ref count so we can remove this later without
     // having ssg try to free the memory.
-#if PLIB_VERSION > 183
-    if ( fgGetBool( "/sim/rendering/use-display-list", true ) ) {
-        makeDList( terra_transform );
-    }
-#endif
-
-    terrain_branch->addKid( terra_transform );
-    globals->get_scenery()->register_placement_transform(terra_transform);
+    terrain_branch->addChild( terra_transform.get() );
+    globals->get_scenery()->register_placement_transform(terra_transform.get());
 
     SG_LOG( SG_TERRAIN, SG_DEBUG,
             "connected a tile into scene graph.  terra_transform = "
-            << terra_transform );
+            << terra_transform.get() );
     SG_LOG( SG_TERRAIN, SG_DEBUG, "num parents now = "
             << terra_transform->getNumParents() );
 
-    if ( gnd_lights_transform != NULL ) {
+    if ( gnd_lights_transform.get() != NULL ) {
         // bump up the ref count so we can remove this later without
         // having ssg try to free the memory.
-        gnd_lights_branch->addKid( gnd_lights_transform );
-        globals->get_scenery()->register_placement_transform(gnd_lights_transform);
+        gnd_lights_branch->addChild( gnd_lights_transform.get() );
+        globals->get_scenery()->register_placement_transform(gnd_lights_transform.get());
     }
 
-    if ( vasi_lights_transform != NULL ) {
+    if ( vasi_lights_transform.get() != NULL ) {
         // bump up the ref count so we can remove this later without
         // having ssg try to free the memory.
-        vasi_lights_selector->addKid( vasi_lights_transform );
-        globals->get_scenery()->register_placement_transform(vasi_lights_transform);
-        vasi_lights_branch->addKid( vasi_lights_selector );
+        vasi_lights_selector->addChild( vasi_lights_transform.get() );
+        globals->get_scenery()->register_placement_transform(vasi_lights_transform.get());
+        vasi_lights_branch->addChild( vasi_lights_selector.get() );
     }
 
-    if ( rwy_lights_transform != NULL ) {
+    if ( rwy_lights_transform.get() != NULL ) {
         // bump up the ref count so we can remove this later without
         // having ssg try to free the memory.
-        rwy_lights_selector->addKid( rwy_lights_transform );
-        globals->get_scenery()->register_placement_transform(rwy_lights_transform);
-        rwy_lights_branch->addKid( rwy_lights_selector );
+        rwy_lights_selector->addChild( rwy_lights_transform.get() );
+        globals->get_scenery()->register_placement_transform(rwy_lights_transform.get());
+        rwy_lights_branch->addChild( rwy_lights_selector.get() );
     }
 
-    if ( taxi_lights_transform != NULL ) {
+    if ( taxi_lights_transform.get() != NULL ) {
         // bump up the ref count so we can remove this later without
         // having ssg try to free the memory.
-        taxi_lights_selector->addKid( taxi_lights_transform );
-        globals->get_scenery()->register_placement_transform(taxi_lights_transform);
-        taxi_lights_branch->addKid( taxi_lights_selector );
+        taxi_lights_selector->addChild( taxi_lights_transform.get() );
+        globals->get_scenery()->register_placement_transform(taxi_lights_transform.get());
+        taxi_lights_branch->addChild( taxi_lights_selector.get() );
     }
 
     loaded = true;
@@ -1043,21 +868,21 @@ FGTileEntry::disconnect_ssg_nodes()
     if ( ! loaded ) {
         SG_LOG( SG_TERRAIN, SG_DEBUG, "removing a not-fully loaded tile!" );
     } else {
-        SG_LOG( SG_TERRAIN, SG_DEBUG, "removing a fully loaded tile!  terra_transform = " << terra_transform );
+        SG_LOG( SG_TERRAIN, SG_DEBUG, "removing a fully loaded tile!  terra_transform = " << terra_transform.get() );
     }
         
     // Unregister that one at the scenery manager
-    globals->get_scenery()->unregister_placement_transform(terra_transform);
+    globals->get_scenery()->unregister_placement_transform(terra_transform.get());
 
     // find the terrain branch parent
     int pcount = terra_transform->getNumParents();
     if ( pcount > 0 ) {
         // find the first parent (should only be one)
-        ssgBranch *parent = terra_transform->getParent( 0 ) ;
+        osg::Group *parent = terra_transform->getParent( 0 ) ;
         if( parent ) {
             // disconnect the tile (we previously ref()'d it so it
             // won't get freed now)
-            parent->removeKid( terra_transform );
+            parent->removeChild( terra_transform.get() );
         } else {
             SG_LOG( SG_TERRAIN, SG_ALERT,
                     "parent pointer is NULL!  Dying" );
@@ -1070,17 +895,17 @@ FGTileEntry::disconnect_ssg_nodes()
     }
 
     // find the ground lighting branch
-    if ( gnd_lights_transform ) {
+    if ( gnd_lights_transform.get() ) {
         // Unregister that one at the scenery manager
-        globals->get_scenery()->unregister_placement_transform(gnd_lights_transform);
+        globals->get_scenery()->unregister_placement_transform(gnd_lights_transform.get());
         pcount = gnd_lights_transform->getNumParents();
         if ( pcount > 0 ) {
             // find the first parent (should only be one)
-            ssgBranch *parent = gnd_lights_transform->getParent( 0 ) ;
+            osg::Group *parent = gnd_lights_transform->getParent( 0 ) ;
             if( parent ) {
                 // disconnect the light branch (we previously ref()'d
                 // it so it won't get freed now)
-                parent->removeKid( gnd_lights_transform );
+                parent->removeChild( gnd_lights_transform.get() );
             } else {
                 SG_LOG( SG_TERRAIN, SG_ALERT,
                         "parent pointer is NULL!  Dying" );
@@ -1094,17 +919,17 @@ FGTileEntry::disconnect_ssg_nodes()
     }
 
     // find the vasi lighting branch
-    if ( vasi_lights_transform ) {
+    if ( vasi_lights_transform.get() ) {
         // Unregister that one at the scenery manager
-        globals->get_scenery()->unregister_placement_transform(vasi_lights_transform);
+        globals->get_scenery()->unregister_placement_transform(vasi_lights_transform.get());
         pcount = vasi_lights_transform->getNumParents();
         if ( pcount > 0 ) {
             // find the first parent (should only be one)
-            ssgBranch *parent = vasi_lights_transform->getParent( 0 ) ;
+            osg::Group *parent = vasi_lights_transform->getParent( 0 ) ;
             if( parent ) {
                 // disconnect the light branch (we previously ref()'d
                 // it so it won't get freed now)
-                parent->removeKid( vasi_lights_transform );
+                parent->removeChild( vasi_lights_transform.get() );
             } else {
                 SG_LOG( SG_TERRAIN, SG_ALERT,
                         "parent pointer is NULL!  Dying" );
@@ -1118,17 +943,17 @@ FGTileEntry::disconnect_ssg_nodes()
     }
 
     // find the runway lighting branch
-    if ( rwy_lights_transform ) {
+    if ( rwy_lights_transform.get() ) {
         // Unregister that one at the scenery manager
-        globals->get_scenery()->unregister_placement_transform(rwy_lights_transform);
+        globals->get_scenery()->unregister_placement_transform(rwy_lights_transform.get());
         pcount = rwy_lights_transform->getNumParents();
         if ( pcount > 0 ) {
             // find the first parent (should only be one)
-            ssgBranch *parent = rwy_lights_transform->getParent( 0 ) ;
+            osg::Group *parent = rwy_lights_transform->getParent( 0 ) ;
             if( parent ) {
                 // disconnect the light branch (we previously ref()'d
                 // it so it won't get freed now)
-                parent->removeKid( rwy_lights_transform );
+                parent->removeChild( rwy_lights_transform.get() );
             } else {
                 SG_LOG( SG_TERRAIN, SG_ALERT,
                         "parent pointer is NULL!  Dying" );
@@ -1142,17 +967,17 @@ FGTileEntry::disconnect_ssg_nodes()
     }
 
     // find the taxi lighting branch
-    if ( taxi_lights_transform ) {
+    if ( taxi_lights_transform.get() ) {
         // Unregister that one at the scenery manager
-        globals->get_scenery()->unregister_placement_transform(taxi_lights_transform);
+        globals->get_scenery()->unregister_placement_transform(taxi_lights_transform.get());
         pcount = taxi_lights_transform->getNumParents();
         if ( pcount > 0 ) {
             // find the first parent (should only be one)
-            ssgBranch *parent = taxi_lights_transform->getParent( 0 ) ;
+            osg::Group *parent = taxi_lights_transform->getParent( 0 ) ;
             if( parent ) {
                 // disconnect the light branch (we previously ref()'d
                 // it so it won't get freed now)
-                parent->removeKid( taxi_lights_transform );
+                parent->removeChild( taxi_lights_transform.get() );
             } else {
                 SG_LOG( SG_TERRAIN, SG_ALERT,
                         "parent pointer is NULL!  Dying" );
index fee04866c4758a978c4a21f18edc458c337661f3..a2f3682243154d9ba2d49b56665a54dccfbfe8c5 100644 (file)
 #include <simgear/math/point3d.hxx>
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/scene/model/placementtrans.hxx>
-#include <simgear/structure/ssgSharedPtr.hxx>
+
+#include <osg/ref_ptr>
+#include <osg/Array>
+#include <osg/Group>
+#include <osg/LOD>
+#include <osg/MatrixTransform>
+#include <osg/Switch>
 
 #if defined( sgi )
 #include <strings.h>
@@ -57,12 +63,6 @@ typedef point_list::iterator point_list_iterator;
 typedef point_list::const_iterator const_point_list_iterator;
 
 
-class ssgLeaf;
-class ssgBranch;
-class ssgTransform;
-class ssgSelector;
-class ssgRangeSelector;
-class ssgVertexArray;
 class FGTileEntry;
 
 
@@ -76,7 +76,7 @@ private:
     string model_path;
     string texture_path;
     FGTileEntry *tile;
-    ssgSharedPtr<ssgTransform> obj_trans;
+    osg::ref_ptr<osg::MatrixTransform> obj_trans;
     SGBucket bucket;
     bool cache_obj;
 
@@ -85,7 +85,7 @@ public:
 
     inline FGDeferredModel() { }
     inline FGDeferredModel( const string& mp, const string& tp, SGBucket b,
-                    FGTileEntry *t, ssgTransform *ot, bool co )
+                            FGTileEntry *t, osg::MatrixTransform *ot, bool co )
     {
        model_path = mp;
        texture_path = tp;
@@ -100,7 +100,7 @@ public:
     inline const SGBucket& get_bucket() const { return bucket; }
     inline const bool get_cache_state() const { return cache_obj; }
     inline FGTileEntry *get_tile() const { return tile; }
-    inline ssgTransform *get_obj_trans() const { return obj_trans; }
+    inline osg::MatrixTransform *get_obj_trans() const { return obj_trans.get(); }
 };
 
 
@@ -121,10 +121,10 @@ public:
 private:
 
     // ssg tree structure for this tile is as follows:
-    // ssgRoot(scene)
-    //     - ssgBranch(terrain)
-    //        - ssgTransform(tile)
-    //           - ssgRangeSelector(tile)
+    // osg::Group(scene)
+    //     - osg::Group(terrain)
+    //        - SGPlacementTransform(tile)
+    //           - osg::LOD(tile)
     //              - ssgEntity(tile)
     //                 - kid1(fan)
     //                 - kid2(fan)
@@ -132,27 +132,27 @@ private:
     //                 - kidn(fan)
 
     // pointer to ssg transform for this tile
-    ssgSharedPtr<ssgPlacementTransform> terra_transform;
-    ssgSharedPtr<ssgPlacementTransform> vasi_lights_transform;
-    ssgSharedPtr<ssgPlacementTransform> rwy_lights_transform;
-    ssgSharedPtr<ssgPlacementTransform> taxi_lights_transform;
-    ssgSharedPtr<ssgPlacementTransform> gnd_lights_transform;
+    osg::ref_ptr<SGPlacementTransform> terra_transform;
+    osg::ref_ptr<SGPlacementTransform> vasi_lights_transform;
+    osg::ref_ptr<SGPlacementTransform> rwy_lights_transform;
+    osg::ref_ptr<SGPlacementTransform> taxi_lights_transform;
+    osg::ref_ptr<SGPlacementTransform> gnd_lights_transform;
 
     // pointer to ssg range selector for this tile
-    ssgSharedPtr<ssgRangeSelector> terra_range;
-    ssgSharedPtr<ssgRangeSelector> gnd_lights_range;
+    osg::ref_ptr<osg::LOD> terra_range;
+    osg::ref_ptr<osg::LOD> gnd_lights_range;
 
     // we create several preset brightness and can choose which one we
     // want based on lighting conditions.
-    ssgSharedPtr<ssgSelector> gnd_lights_brightness;
+    osg::ref_ptr<osg::Switch> gnd_lights_brightness;
 
     // we need to be able to turn runway lights on or off (doing this
     // via a call back would be nifty, but then the call back needs to
     // know about the higher level application's global state which is
     // a problem if we move the code into simgear.)
-    ssgSharedPtr<ssgSelector> vasi_lights_selector;
-    ssgSharedPtr<ssgSelector> rwy_lights_selector;
-    ssgSharedPtr<ssgSelector> taxi_lights_selector;
+    osg::ref_ptr<osg::Switch> vasi_lights_selector;
+    osg::ref_ptr<osg::Switch> rwy_lights_selector;
+    osg::ref_ptr<osg::Switch> taxi_lights_selector;
 
     /**
      * Indicates this tile has been loaded from a file and connected
@@ -169,15 +169,15 @@ private:
     volatile int pending_models;
 
     bool obj_load( const string& path,
-                   ssgBranch* geometry,
-                   ssgBranch* vasi_lights,
-                   ssgBranch* rwy_lights,
-                   ssgBranch* taxi_lights,
-                   ssgVertexArray* gound_lights,
+                   osg::Group* geometry,
+                   osg::Group* vasi_lights,
+                   osg::Group* rwy_lights,
+                   osg::Group* taxi_lights,
+                   osg::Vec3Array* gound_lights,
                    bool is_base );
 
-    ssgLeaf* gen_lights( SGMaterialLib *matlib, ssgVertexArray *lights,
-                         int inc, float bright );
+    osg::Node* gen_lights( SGMaterialLib *matlib, osg::Vec3Array *lights,
+                           int inc, float bright );
 
     double timestamp;
 
@@ -254,19 +254,14 @@ public:
      */
     inline const SGBucket& get_tile_bucket() const { return tile_bucket; }
 
-    /**
-     * Apply ssgLeaf::makeDList to all leaf of a branch
-     */
-    void makeDList( ssgBranch *b );
-
     /**
      * Add terrain mesh and ground lighting to scene graph.
      */
-    void add_ssg_nodes( ssgBranch *terrain_branch,
-                       ssgBranch *gnd_lights_branch,
-                        ssgBranch *vasi_lights_branch,
-                       ssgBranch *rwy_lights_branch,
-                       ssgBranch *taxi_lights_branch );
+    void add_ssg_nodes( osg::Group *terrain_branch,
+                       osg::Group *gnd_lights_branch,
+                        osg::Group *vasi_lights_branch,
+                       osg::Group *rwy_lights_branch,
+                       osg::Group *taxi_lights_branch );
 
     /**
      * disconnect terrain mesh and ground lighting nodes from scene
@@ -278,7 +273,7 @@ public:
     /**
      * return the SSG Transform node for the terrain
      */
-    inline ssgPlacementTransform *get_terra_transform() const { return terra_transform; }
+    inline SGPlacementTransform *get_terra_transform() const { return terra_transform.get(); }
 
     inline double get_timestamp() const { return timestamp; }
     inline void set_timestamp( double time_ms ) { timestamp = time_ms; }
index debc796fe9625e22343b975c5ef97c0f416a902a..baf830659a4649eba6f422f7b86016632933fb06 100644 (file)
@@ -25,8 +25,6 @@
 #  include <config.h>
 #endif
 
-#include <plib/ssg.h>
-
 #include <simgear/constants.h>
 #include <simgear/debug/logstream.hxx>
 #include <simgear/math/point3d.hxx>
@@ -35,7 +33,6 @@
 #include <simgear/math/vector.hxx>
 #include <simgear/structure/exception.hxx>
 #include <simgear/scene/model/modellib.hxx>
-#include <simgear/scene/model/shadowvolume.hxx>
 
 #include <Main/globals.hxx>
 #include <Main/fg_props.hxx>
@@ -59,8 +56,6 @@ queue<FGTileEntry *> FGTileMgr::delete_queue;
 
 bool FGTileMgr::tile_filter = true;
 
-extern SGShadowVolume *shadows;
-
 // Constructor
 FGTileMgr::FGTileMgr():
     state( Start ),
@@ -126,7 +121,8 @@ void FGTileMgr::sched_tile( const SGBucket& b, const bool is_inner_ring ) {
             long index = tile_cache.get_oldest_tile();
             if ( index >= 0 ) {
                 FGTileEntry *old = tile_cache.get_tile( index );
-                shadows->deleteOccluderFromTile( (ssgBranch *) old->get_terra_transform() );
+                // OSGFIXME
+//                 shadows->deleteOccluderFromTile( (ssgBranch *) old->get_terra_transform() );
                 old->disconnect_ssg_nodes();
                 delete_queue.push( old );
                 tile_cache.clear_entry( index );
@@ -310,9 +306,10 @@ void FGTileMgr::update_queues()
             // tile cache
             FGTileEntry *t = tile_cache.get_tile( dm->get_bucket() );
             if ( t != NULL ) {
-                ssgTexturePath( (char *)(dm->get_texture_path().c_str()) );
+              //OSGFIXME
+//                 ssgTexturePath( (char *)(dm->get_texture_path().c_str()) );
                 try {
-                    ssgEntity *obj_model =
+                    osg::Node *obj_model =
                         globals->get_model_lib()->load_model( ".",
                                                   dm->get_model_path(),
                                                   globals->get_props(),
@@ -320,10 +317,11 @@ void FGTileMgr::update_queues()
                                                   dm->get_cache_state(),
                                                   new FGNasalModelData );
                     if ( obj_model != NULL ) {
-                        dm->get_obj_trans()->addKid( obj_model );
-                        shadows->addOccluder( (ssgBranch *) obj_model->getParent(0),
-                            SGShadowVolume::occluderTypeTileObject,
-                            (ssgBranch *) dm->get_tile()->get_terra_transform());
+                        dm->get_obj_trans()->addChild( obj_model );
+              //OSGFIXME
+//                         shadows->addOccluder( (ssgBranch *) obj_model->getParent(0),
+//                             SGShadowVolume::occluderTypeTileObject,
+//                             (ssgBranch *) dm->get_tile()->get_terra_transform());
                     }
                 } catch (const sg_io_exception& exc) {
                                        string m(exc.getMessage());
index 7668a84eb6c99c474af58746ff50662e89da3b9b..437202e760349775eb4b8c034d925bc4bfe28aac 100644 (file)
@@ -740,7 +740,7 @@ void FGNasalListener::valueChanged(SGPropertyNode* node)
 // is removed from the scene graph.
 
 void FGNasalModelData::modelLoaded(const string& path, SGPropertyNode *prop,
-                                   ssgBranch *)
+                                   osg::Node *)
 {
     SGPropertyNode *n = prop->getNode("nasal"), *load;
     if (!n)
index cd26cc067ea45c68a347de04207727df184072a8..5e9b197d1991649a014591de608d4969ea9a6a21 100644 (file)
@@ -149,7 +149,7 @@ class FGNasalModelData : public SGModelData {
 public:
     FGNasalModelData() : _unload(0) {}
     ~FGNasalModelData();
-    void modelLoaded(const string& path, SGPropertyNode *prop, ssgBranch *);
+    void modelLoaded(const string& path, SGPropertyNode *prop, osg::Node *);
 
 private:
     string _module;
index 1bcc7ef8df84ea3d6ce4181b52a42e6d5bc62d5d..cd450433c3407b91368d65eece3e2c6aeffdaa80 100644 (file)
@@ -68,6 +68,8 @@ FGLight::FGLight ()
       _diffuse_tbl( NULL ),
       _specular_tbl( NULL ),
       _sky_tbl( NULL ),
+      _sun_angle(0),
+      _moon_angle(0),
       _prev_sun_angle(-9999.0),
       _sun_rotation( 0.0 ),
       _dt_total( 0.0 )
@@ -227,7 +229,7 @@ void FGLight::update_sky_color () {
     }
     gamma_correct_rgb( _cloud_color );
 
-    float *sun_color = thesky->get_sun_color();
+    SGVec4f sun_color = thesky->get_sun_color();
 
     _scene_ambient[0] = ((sun_color[0]*0.25 + _cloud_color[0]*0.75) + ambient) / 2;
     _scene_ambient[1] = ((sun_color[1]*0.25 + _cloud_color[1]*0.75) + ambient) / 2;
@@ -289,7 +291,7 @@ void FGLight::update_adj_fog_color () {
 
     // revert to unmodified values before usign them.
     //
-    float *sun_color = thesky->get_sun_color();
+    SGVec4f sun_color = thesky->get_sun_color();
 
     gamma_restore_rgb( _fog_color );