From: Durk Talsma Date: Tue, 26 Apr 2011 17:18:28 +0000 (+0200) Subject: * Added a pure virtual render() function to FGATController that can be used to implem... X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=7e604f22a70c508addb441bc7c437be6dbe4dac0;p=flightgear.git * Added a pure virtual render() function to FGATController that can be used to implement traffic visualization * Allow position and intentions to be monitored and updated by the Startup controller * Added a "parent" pointer to the startup controller to allow communication with the groundnetwork. * Implemented a render() function for the Startup controller * Renamed "FGGroundNetwork::getRenderNode() to FGGroundnetwork::render() --- diff --git a/src/ATC/atc_mgr.cxx b/src/ATC/atc_mgr.cxx index a05654cfe..6f526221a 100644 --- a/src/ATC/atc_mgr.cxx +++ b/src/ATC/atc_mgr.cxx @@ -184,11 +184,10 @@ void FGATCManager::update ( double time ) { heading, speed, altitude, time); - } - string airport = fgGetString("/sim/presets/airport-id"); - FGAirport *apt = FGAirport::findByIdent(airport); - osg::Node* node = apt->getDynamics()->getGroundNetwork()->getRenderNode(); - //cerr << "Adding groundnetWork to the scenegraph::update" << endl; - - globals->get_scenery()->get_scene_graph()->addChild(node); + //string airport = fgGetString("/sim/presets/airport-id"); + //FGAirport *apt = FGAirport::findByIdent(airport); + controller->render(); + //cerr << "Adding groundnetWork to the scenegraph::update" << endl; + } + //globals->get_scenery()->get_scene_graph()->addChild(node); } diff --git a/src/ATC/trafficcontrol.cxx b/src/ATC/trafficcontrol.cxx index dc7d8c5f3..43859b188 100644 --- a/src/ATC/trafficcontrol.cxx +++ b/src/ATC/trafficcontrol.cxx @@ -26,6 +26,16 @@ #include +#include +#include +#include +#include + +#include +#include +#include +#include + #include "trafficcontrol.hxx" #include "atc_mgr.hxx" #include @@ -896,13 +906,19 @@ FGATCInstruction FGTowerController::getInstruction(int id) return FGATCInstruction(); } +void FGTowerController::render() { + cerr << "FGTowerController::render function not yet implemented" << endl; +} + + /*************************************************************************** * class FGStartupController * **************************************************************************/ -FGStartupController::FGStartupController(): -FGATCController() +FGStartupController::FGStartupController(FGAirportDynamics *par): + FGATCController() { + parent = par; } void FGStartupController::announcePosition(int id, @@ -934,11 +950,13 @@ void FGStartupController::announcePosition(int id, rec.setPositionAndHeading(lat, lon, heading, speed, alt); rec.setRunway(intendedRoute->getRunway()); rec.setLeg(leg); + rec.setPositionAndIntentions(currentPosition, intendedRoute); //rec.setCallSign(callsign); rec.setAircraft(ref); rec.setHoldPosition(true); activeTraffic.push_back(rec); } else { + i->setPositionAndIntentions(currentPosition, intendedRoute); i->setPositionAndHeading(lat, lon, heading, speed, alt); } @@ -1129,6 +1147,125 @@ void FGStartupController::updateAircraftInformation(int id, double lat, double l } } +// Note that this function is copied from simgear. for maintanance purposes, it's probabtl better to make a general function out of that. +static void WorldCoordinate(osg::Matrix& obj_pos, double lat, + double lon, double elev, double hdg) +{ + SGGeod geod = SGGeod::fromDegM(lon, lat, elev); + obj_pos = geod.makeZUpFrame(); + // hdg is not a compass heading, but a counter-clockwise rotation + // around the Z axis + obj_pos.preMult(osg::Matrix::rotate(hdg * SGD_DEGREES_TO_RADIANS, + 0.0, 0.0, 1.0)); +} + + +void FGStartupController::render() +{ + + SGMaterialLib *matlib = globals->get_matlib(); + if (group) { + //int nr = ; + globals->get_scenery()->get_scene_graph()->removeChild(group); + //while (group->getNumChildren()) { + // cerr << "Number of children: " << group->getNumChildren() << endl; + simgear::EffectGeode* geode = (simgear::EffectGeode*) group->getChild(0); + //osg::MatrixTransform *obj_trans = (osg::MatrixTransform*) group->getChild(0); + //geode->releaseGLObjects(); + //group->removeChild(geode); + //delete geode; + } + group = new osg::Group; + + //for ( FGTaxiSegmentVectorIterator i = segments.begin(); i != segments.end(); i++) { + double dx = 0; + for (TrafficVectorIterator i = activeTraffic.begin(); i != activeTraffic.end(); i++) { + // Handle start point + int pos = i->getCurrentPosition(); + if (pos > 0) { + FGTaxiSegment *segment = parent->getGroundNetwork()->findSegment(pos); + SGGeod start(SGGeod::fromDeg((i->getLongitude()), (i->getLatitude()))); + SGGeod end (SGGeod::fromDeg(segment->getEnd()->getLongitude(), segment->getEnd()->getLatitude())); + + double length = SGGeodesy::distanceM(start, end); + //heading = SGGeodesy::headingDeg(start->getGeod(), end->getGeod()); + + double az2, heading; //, distanceM; + SGGeodesy::inverse(start, end, heading, az2, length); + double coveredDistance = length * 0.5; + SGGeod center; + SGGeodesy::direct(start, heading, coveredDistance, center, az2); + //cerr << "Active Aircraft : Centerpoint = (" << center.getLatitudeDeg() << ", " << center.getLongitudeDeg() << "). Heading = " << heading << endl; + /////////////////////////////////////////////////////////////////////////////// + // Make a helper function out of this + osg::Matrix obj_pos; + osg::MatrixTransform *obj_trans = new osg::MatrixTransform; + obj_trans->setDataVariance(osg::Object::STATIC); + + WorldCoordinate( obj_pos, center.getLatitudeDeg(), center.getLongitudeDeg(), parent->getElevation()+8+dx, -(heading) ); + + obj_trans->setMatrix( obj_pos ); + //osg::Vec3 center(0, 0, 0) + + float width = length /2.0; + osg::Vec3 corner(-width, 0, 0.25f); + osg::Vec3 widthVec(2*width + 1, 0, 0); + osg::Vec3 heightVec(0, 1, 0); + osg::Geometry* geometry; + geometry = osg::createTexturedQuadGeometry(corner, widthVec, heightVec); + simgear::EffectGeode* geode = new simgear::EffectGeode; + geode->setName("test"); + geode->addDrawable(geometry); + //osg::Node *custom_obj; + SGMaterial *mat = matlib->find("UnidirectionalTaper"); + if (mat) + geode->setEffect(mat->get_effect()); + obj_trans->addChild(geode); + // wire as much of the scene graph together as we can + //->addChild( obj_trans ); + group->addChild( obj_trans ); + ///////////////////////////////////////////////////////////////////// + } else { + cerr << "BIG FAT WARNING: current position is here : " << pos << endl; + } + for(intVecIterator j = (i)->getIntentions().begin(); j != (i)->getIntentions().end(); j++) { + osg::Matrix obj_pos; + int k = (*j); + if (k > 0) { + osg::MatrixTransform *obj_trans = new osg::MatrixTransform; + obj_trans->setDataVariance(osg::Object::STATIC); + FGTaxiSegment *segment = parent->getGroundNetwork()->findSegment(k); + WorldCoordinate( obj_pos, segment->getLatitude(), segment->getLongitude(), parent->getElevation()+8+dx, -(segment->getHeading()) ); + + obj_trans->setMatrix( obj_pos ); + //osg::Vec3 center(0, 0, 0) + + float width = segment->getLength() /2.0; + osg::Vec3 corner(-width, 0, 0.25f); + osg::Vec3 widthVec(2*width + 1, 0, 0); + osg::Vec3 heightVec(0, 1, 0); + osg::Geometry* geometry; + geometry = osg::createTexturedQuadGeometry(corner, widthVec, heightVec); + simgear::EffectGeode* geode = new simgear::EffectGeode; + geode->setName("test"); + geode->addDrawable(geometry); + //osg::Node *custom_obj; + SGMaterial *mat = matlib->find("UnidirectionalTaper"); + if (mat) + geode->setEffect(mat->get_effect()); + obj_trans->addChild(geode); + // wire as much of the scene graph together as we can + //->addChild( obj_trans ); + group->addChild( obj_trans ); + } else { + cerr << "BIG FAT WARNING: k is here : " << pos << endl; + } + } + dx += 0.1; + } + globals->get_scenery()->get_scene_graph()->addChild(group); +} + /*************************************************************************** * class FGApproachController @@ -1320,3 +1457,7 @@ ActiveRunway *FGApproachController::getRunway(string name) } return &(*rwy); } + +void FGApproachController::render() { + cerr << "FGApproachController::render function not yet implemented" << endl; +} diff --git a/src/ATC/trafficcontrol.hxx b/src/ATC/trafficcontrol.hxx index a60ffd468..8cc35a7e7 100644 --- a/src/ATC/trafficcontrol.hxx +++ b/src/ATC/trafficcontrol.hxx @@ -26,6 +26,10 @@ # error This library requires C++ #endif +#include +#include +#include +#include #include // There is probably a better include than sg_geodesy to get the SG_NM_TO_METER... @@ -48,6 +52,7 @@ typedef vector::iterator intVecIterator; class FGAIFlightPlan; // forward reference class FGGroundNetwork; // forward reference class FGAIAircraft; // forward reference +class FGAirportDynamics; /************************************************************************************** * class FGATCInstruction @@ -233,7 +238,7 @@ protected: time_t lastTransmission; double dt_count; - + osg::Group* group; string formatATCFrequency3_2(int ); string genTransponderCode(string fltRules); @@ -280,8 +285,10 @@ public: void setDt(double dt) { dt_count = dt;}; void transmit(FGTrafficRecord *rec, AtcMsgId msgId, AtcMsgDir msgDir, bool audible); string getGateName(FGAIAircraft *aircraft); + virtual void render() = 0; private: + AtcMsgDir lastTransmissionDirection; }; @@ -307,6 +314,7 @@ public: virtual bool hasInstruction(int id); virtual FGATCInstruction getInstruction(int id); + virtual void render(); bool hasActiveTraffic() { return activeTraffic.size() != 0; }; TrafficVector &getActiveTraffic() { return activeTraffic; }; }; @@ -321,9 +329,10 @@ class FGStartupController : public FGATCController private: TrafficVector activeTraffic; //ActiveRunwayVec activeRunways; +FGAirportDynamics *parent; public: - FGStartupController(); + FGStartupController(FGAirportDynamics *parent); virtual ~FGStartupController() {}; virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute, double lat, double lon, @@ -335,6 +344,8 @@ public: virtual bool hasInstruction(int id); virtual FGATCInstruction getInstruction(int id); + virtual void render(); + bool hasActiveTraffic() { return activeTraffic.size() != 0; }; TrafficVector &getActiveTraffic() { return activeTraffic; }; @@ -366,6 +377,8 @@ public: virtual bool hasInstruction(int id); virtual FGATCInstruction getInstruction(int id); + virtual void render(); + ActiveRunway* getRunway(string name); bool hasActiveTraffic() { return activeTraffic.size() != 0; }; diff --git a/src/Airports/dynamics.cxx b/src/Airports/dynamics.cxx index fd5025a38..398920f32 100644 --- a/src/Airports/dynamics.cxx +++ b/src/Airports/dynamics.cxx @@ -49,7 +49,7 @@ using std::random_shuffle; #include "dynamics.hxx" FGAirportDynamics::FGAirportDynamics(FGAirport * ap): -_ap(ap), rwyPrefs(ap), SIDs(ap) +_ap(ap), rwyPrefs(ap), SIDs(ap),startupController(this) { lastUpdate = 0; @@ -61,7 +61,7 @@ _ap(ap), rwyPrefs(ap), SIDs(ap) FGAirportDynamics:: FGAirportDynamics(const FGAirportDynamics & other):rwyPrefs(other. rwyPrefs), -SIDs(other.SIDs) +SIDs(other.SIDs), startupController(other.startupController) { for (FGParkingVecConstIterator ip = other.parkings.begin(); ip != other.parkings.end(); ip++) diff --git a/src/Airports/groundnetwork.cxx b/src/Airports/groundnetwork.cxx index 2c676d2e4..8554dcbaa 100644 --- a/src/Airports/groundnetwork.cxx +++ b/src/Airports/groundnetwork.cxx @@ -1103,7 +1103,7 @@ static void WorldCoordinate(osg::Matrix& obj_pos, double lat, -osg::Node* FGGroundNetwork::getRenderNode() +void FGGroundNetwork::render() { SGMaterialLib *matlib = globals->get_matlib(); @@ -1204,7 +1204,5 @@ osg::Node* FGGroundNetwork::getRenderNode() } dx += 0.1; } - - - return group; + globals->get_scenery()->get_scene_graph()->addChild(group); } \ No newline at end of file diff --git a/src/Airports/groundnetwork.hxx b/src/Airports/groundnetwork.hxx index 57295c65f..857fb0314 100644 --- a/src/Airports/groundnetwork.hxx +++ b/src/Airports/groundnetwork.hxx @@ -249,7 +249,7 @@ private: void checkHoldPosition(int id, double lat, double lon, double heading, double speed, double alt); - osg::Group* group; + public: FGGroundNetwork(); @@ -286,7 +286,8 @@ public: bool checkTransmissionState(int minState, int MaxState, TrafficVectorIterator i, time_t now, AtcMsgId msgId, AtcMsgDir msgDir); bool checkForCircularWaits(int id); - osg::Node* getRenderNode(); + virtual void render(); + };