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*)
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;
#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>
// 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();
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());
}
-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)) {
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;
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;
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);
# 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) {
}
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) {
// 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);
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) {
} // 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;
#include <string>
#include <list>
-#include <plib/ssg.h>
+
+#include <osg/Referenced>
+#include <osg/Node>
+
#include <simgear/compiler.h>
SG_USING_STD(string);
class FGAIManager;
class FGAICarrier;
-class FGAICarrierHardware : public ssgBase {
+class FGAICarrierHardware : public osg::Referenced {
public:
enum Type { Catapult, Wire, Solid };
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 );
void TurnToLaunch();
void TurnToBase();
void ReturnToBox();
- float Horizon(float h);
bool OutsideBox();
bool init();
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;
// 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;
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));
}
#include <list>
#include <simgear/structure/subsystem_mgr.hxx>
-#include <simgear/structure/ssgSharedPtr.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
#include <Main/fg_props.hxx>
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;
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);
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());
#include <simgear/math/point3d.hxx>
#include <simgear/scene/model/model.hxx>
#include <simgear/scene/model/placement.hxx>
-#include <simgear/structure/ssgSharedPtr.hxx>
-
-
-class ssgBase;
/*****************************************************************
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;
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();
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
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 :-(
#define _FG_AIMGR_HXX
#include <simgear/structure/subsystem_mgr.hxx>
-#include <simgear/structure/ssgSharedPtr.hxx>
#include <Main/fg_props.hxx>
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
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
# include <config.h>
#endif
+#include <osg/State>
#include <simgear/structure/subsystem_mgr.hxx>
#include <vector>
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
}
void
-FGMagRibbon::draw ()
+FGMagRibbon::draw (osg::State& state)
{
double heading = _magcompass_node->getDoubleValue();
double xoffset, yoffset;
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
FGMagRibbon (int w, int h);
virtual ~FGMagRibbon () {}
- virtual void draw ();
+ virtual void draw (osg::State& state);
private:
SGPropertyNode_ptr _magcompass_node;
return true;
}
-void fgCockpitUpdate( void ) {
+void fgCockpitUpdate( osg::State* state ) {
SG_LOG( SG_COCKPIT, SG_DEBUG,
"Cockpit: code " << ac_cockpit->code() << " status "
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 );
# 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
typedef fg_Cockpit * pCockpit;
bool fgCockpitInit( fgAIRCRAFT *cur_aircraft );
-void fgCockpitUpdate( void );
+void fgCockpitUpdate( osg::State* );
#endif /* _COCKPIT_HXX */
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 {
input.close();
}
- fgHUDReshape();
-
if ( HUDtext ) {
// this chunk of code is not necessarily thread safe if the
// compiler optimizer reorders these statements. Note that
//$$$ 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;
}
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();
glTranslatef(-320, -240, -1);
// Do the deed
- drawHUD();
+ drawHUD(state);
// Clean up our mess
glMatrixMode(GL_PROJECTION);
}
-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);
glPushMatrix();
glLoadIdentity();
- drawHUD();
+ drawHUD(state);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
}
-void drawHUD()
+void drawHUD(osg::State* state)
{
if ( !HUD_deque.size() ) // Trust everyone, but ALWAYS cut the cards!
return;
#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>
#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 );
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);
// $$$ end - added, VS Renganathan, 13 Oct 2K
extern char *get_formated_gmt_time( void );
-extern void fgHUDReshape(void);
enum hudinstype{ HUDno_instr,
HUDscale,
};
-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
};
-//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 );
-*/
-
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;
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
}
#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>
// 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;
}
-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();
}
}
+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() ) {
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));
}
/**
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());
}
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();
}
}
glEnable(GL_CLIP_PLANE2);
glEnable(GL_CLIP_PLANE3);
glPopMatrix();
- instr->draw();
+ instr->draw(state);
glPopMatrix();
}
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);
}
/**
* 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;
}
/**
}
void
-FGPanelInstrument::drawHotspots()
+FGPanelInstrument::drawHotspots(osg::State& state)
{
for ( unsigned int i = 0; i < _actions.size(); i++ ) {
FGPanelAction* a = _actions[i];
}
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();
}
}
}
void
-FGSpecialInstrument::draw ()
+FGSpecialInstrument::draw (osg::State& state)
{
complex->draw();
}
}
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);
}
}
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) {
glTexCoord2f(_texture.getMaxX(), _texture.getMaxY()); glVertex2f(w2, h2);
glTexCoord2f(_texture.getMinX(), _texture.getMaxY()); glVertex2f(-w2, h2);
glEnd();
+ state.popStateSet();
+ state.apply();
}
}
}
void
-FGTextLayer::draw ()
+FGTextLayer::draw (osg::State& state)
{
if (test()) {
glColor4fv(_color);
}
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;
}
}
# include <windows.h>
#endif
+#include <osg/ref_ptr>
+#include <osg/StateSet>
+#include <osg/Texture2D>
+
#include <plib/fnt.h>
#include <simgear/compiler.h>
SG_USING_STD(map);
-class ssgTexture;
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;
};
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;
private:
string _path;
- ssgTexture * _texture;
+ osg::ref_ptr<osg::StateSet> _texture;
float _minX, _minY, _maxX, _maxY;
};
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();
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;
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;
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; }
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);
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);
//FGSpecialInstrument (int x, int y, int w, int h);
virtual ~FGSpecialInstrument ();
- virtual void draw ();
+ virtual void draw (osg::State& state);
protected:
DCLGPS* complex;
public:
FGGroupLayer ();
virtual ~FGGroupLayer ();
- virtual void draw ();
+ virtual void draw (osg::State& state);
// transfer pointer ownership
virtual void addLayer (FGInstrumentLayer * layer);
protected:
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;
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);
public:
// Transfer pointers!!
FGSwitchLayer ();
- virtual void draw ();
+ virtual void draw (osg::State& state);
};
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;
}
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
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;
}
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();
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
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
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;
}
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;
}
}
// 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);
}
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;
}
#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>
#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.
// 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;
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
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.
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);
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
}
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;
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];
}
}
}
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;
// *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;
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;
}
// 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)
// 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;
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)
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;
}
#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:
// 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
// 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.
// 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;
// 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);
};
# endif
#endif
-#include <plib/ssg.h>
-
#include <simgear/constants.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/misc/sg_path.hxx>
}
FGRenderer *renderer = globals->get_renderer();
- renderer->init();
+// renderer->init();
renderer->resize( fgGetInt("/sim/startup/xsize"),
fgGetInt("/sim/startup/ysize") );
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) {
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*/
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 );
fgSetBool("/sim/signals/screenshot", true);
FGRenderer *renderer = globals->get_renderer();
- renderer->init();
+// renderer->init();
renderer->resize( fgGetInt("/sim/startup/xsize"),
fgGetInt("/sim/startup/ysize") );
#include <Scenery/scenery.hxx>
#include <Main/renderer.hxx>
-#include <plib/ssg.h>
#include <simgear/math/sg_geodesy.hxx>
SG_USING_STD(ifstream);
}
-void HUD::draw()
+void HUD::draw(osg::State&)
{
if (!isVisible())
return;
SG_USING_STD(vector);
SG_USING_NAMESPACE(std);
+#include <osg/State>
+
#include <plib/sg.h>
#include <simgear/math/SGLimits.hxx>
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 *);
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;
curr_view->setGoalPitchOffset_deg(gpo);
}
//Set the camera back to the current view
- ssgSetCamera((sgVec4 *)curr_view);
+ // OSGFIXME
+// ssgSetCamera((sgVec4 *)curr_view);
glPopAttrib();
}
# include "config.h"
#endif
-#include <plib/ssg.h>
#include <simgear/screen/extensions.hxx>
#include <simgear/screen/RenderTexture.h>
#include <simgear/debug/logstream.hxx>
#include "od_gauge.hxx"
FGODGauge::FGODGauge() :
- rtAvailable( false ),
- rt( 0 )
+ rtAvailable( false )// ,
+// rt( 0 )
{
}
// 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 () {
}
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) {
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();
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 () ;
}
#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.
*/
* 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
* @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);
//
// $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},
}
void RenderArea2D::draw() {
+#if 0
glDisable(GL_TEXTURE_2D);
/*
glColor3f(1, 1, 0);
}
glEnable(GL_TEXTURE_2D);
+#endif
}
// Set clipping region in logical units
// -----------------------------------------
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
}
# include <config.h>
#endif
+#include <plib/sg.h>
#include <simgear/compiler.h>
-#include <plib/ssg.h>
#include <vector>
SG_USING_STD(vector);
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);
void
wxRadarBg::update (double delta_time_sec)
{
+ //OSGFIXME
+#if 0
if ( ! sim_init_done ) {
if ( ! fgGetBool("sim/sceneryloaded", false) )
return;
// 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();
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 );
glEnable(GL_ALPHA_TEST);
}
glPopMatrix();
- odg->endCapture( resultTexture->getHandle() );
+ odg->endCapture( resultTexture.get() );
+#endif
}
#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 {
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;
$(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 \
-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 = \
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();
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 !!!
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");
// lighting->addKid( airport );
// build our custom render states
- globals->get_renderer()->build_states();
fgSplashProgress("initializing subsystems");
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
# 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 (?)
// 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()
{
#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
} 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 ) {
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;
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;
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.
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");
( 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 ) {
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()
*/
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();
<< " 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;
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();
}
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;
// cout << "setFOV(" << viewmgr->get_current_view()->get_h_fov()
// << ", " << viewmgr->get_current_view()->get_v_fov() << ")"
// << endl;
-
}
-
- fgHUDReshape();
-
}
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()
// << " 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);
}
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 );
}
* 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();
}
{
// 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
// 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;
}
void init();
- void build_states();
static void resize(int width, int height );
// calling update( refresh_camera_settings = false ) will not
#include <string.h> // strcmp
#include <plib/sg.h>
-#include <plib/ssg.h>
#include <simgear/compiler.h>
#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
FGAircraftModel::FGAircraftModel ()
: _aircraft(0),
- _selector(new ssgSelector),
- _scene(new ssgRoot),
+ _selector(new osg::Switch),
+ _scene(new osg::Group),
_nearplane(0.10f),
_farplane(1000.0f)
{
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");
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
_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
-// 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;
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;
#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;
}
// 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;
* 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
#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>
SG_USING_STD(vector);
-extern SGShadowVolume *shadows;
+// OSGFIXME
+// extern SGShadowVolume *shadows;
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];
}
}
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"),
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());
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;
+// }
}
}
}
}
-void
-FGModelMgr::draw ()
-{
-// ssgSetNearFar(_nearplane, _farplane);
-// ssgCullAndDraw(_scene);
-}
-
-
\f
////////////////////////////////////////////////////////////////////////
// Implementation of FGModelMgr::Instance
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;
*/
virtual void remove_instance (Instance * instance);
- virtual void draw ();
-
-
private:
/**
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 )
{
// 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();
// "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()
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)
// 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
// 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.
return _panel->doLocalMouseAction(button, updown, panelX, panelY);
}
-void FGPanelNode::die()
-{
- SG_LOG(SG_ALL,SG_ALERT,"Unimplemented function called on FGPanelNode");
- exit(1);
-}
-
#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;
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.
// 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];
};
# 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"
libScenery_a_SOURCES = \
FGTileLoader.cxx FGTileLoader.hxx \
- hitlist.cxx hitlist.hxx \
newcache.cxx newcache.hxx \
scenery.cxx scenery.hxx \
tileentry.cxx tileentry.hxx \
#include <math.h>
#include <plib/sg.h>
-#include <plib/ssg.h>
#include <simgear/sg_inlines.h>
#include <simgear/debug/logstream.hxx>
#include <vector>
SG_USING_STD(vector);
-#include <plib/ssg.h>
-
class ssgEntity;
class ssgBranch;
+class ssgLeaf;
class FGHitRec {
# 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>
}
// 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());
}
#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"
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
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) {
}
}
- // 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());
}
}
}
if (replaced_center)
set_center( saved_center );
- return hit;
+ return hits;
}
bool
}
}
- // 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;
}
#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;
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:
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);
};
#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>
#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>
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),
// 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;
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;
}
// 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;
}
// 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.
// 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();
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.
}
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.
}
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.
}
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
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 ) )
// 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!" );
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() );
}
}
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
} 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;
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;
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" );
}
// 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" );
}
// 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" );
}
// 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" );
}
// 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" );
#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>
typedef point_list::const_iterator const_point_list_iterator;
-class ssgLeaf;
-class ssgBranch;
-class ssgTransform;
-class ssgSelector;
-class ssgRangeSelector;
-class ssgVertexArray;
class FGTileEntry;
string model_path;
string texture_path;
FGTileEntry *tile;
- ssgSharedPtr<ssgTransform> obj_trans;
+ osg::ref_ptr<osg::MatrixTransform> obj_trans;
SGBucket bucket;
bool cache_obj;
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;
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(); }
};
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)
// - 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
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;
*/
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
/**
* 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; }
# include <config.h>
#endif
-#include <plib/ssg.h>
-
#include <simgear/constants.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/math/point3d.hxx>
#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>
bool FGTileMgr::tile_filter = true;
-extern SGShadowVolume *shadows;
-
// Constructor
FGTileMgr::FGTileMgr():
state( Start ),
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 );
// 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(),
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());
// 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)
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;
_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 )
}
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;
// 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 );